private InputStream writeToSocket()

in axis-rt-core/src/main/java/org/apache/axis/transport/http/HTTPSender.java [209:522]


    private InputStream writeToSocket(SocketHolder sockHolder,
            MessageContext msgContext, URL tmpURL,
            StringBuffer otherHeaders, String host, int port, int timeout,
            BooleanHolder useFullURL)
            throws Exception {

        String userID = msgContext.getUsername();
        String passwd = msgContext.getPassword();

        // Get SOAPAction, default to ""
        String action = msgContext.useSOAPAction()
                ? msgContext.getSOAPActionURI()
                : "";

        if (action == null) {
            action = "";
        }

        // if UserID is not part of the context, but is in the URL, use
        // the one in the URL.
        if ((userID == null) && (tmpURL.getUserInfo() != null)) {
            String info = tmpURL.getUserInfo();
            int sep = info.indexOf(':');

            if ((sep >= 0) && (sep + 1 < info.length())) {
                userID = info.substring(0, sep);
                passwd = info.substring(sep + 1);
            } else {
                userID = info;
            }
        }
        if (userID != null) {
            StringBuffer tmpBuf = new StringBuffer();

            tmpBuf.append(userID).append(":").append((passwd == null)
                    ? ""
                    : passwd);
            otherHeaders.append(HTTPConstants.HEADER_AUTHORIZATION)
                    .append(": Basic ")
                    .append(Base64.encode(tmpBuf.toString().getBytes()))
                    .append("\r\n");
        }

        // don't forget the cookies!
        // mmm... cookies
        if (msgContext.getMaintainSession()) {
            fillHeaders(msgContext, HTTPConstants.HEADER_COOKIE, otherHeaders);
            fillHeaders(msgContext, HTTPConstants.HEADER_COOKIE2, otherHeaders);
        }

        StringBuffer header2 = new StringBuffer();

        String webMethod = null;
        boolean posting = true;

        Message reqMessage = msgContext.getRequestMessage();

        boolean http10 = true; //True if this is to use HTTP 1.0 / false HTTP 1.1
        boolean httpChunkStream = false; //Use HTTP chunking or not.
        boolean httpContinueExpected = false; //Under HTTP 1.1 if false you *MAY* need to wait for a 100 rc,
                                              //  if true the server MUST reply with 100 continue.
        String httpConnection = null;

        String httpver = msgContext.getStrProp(MessageContext.HTTP_TRANSPORT_VERSION);
        if (null == httpver) {
            httpver = HTTPConstants.HEADER_PROTOCOL_V10;
        }
        httpver = httpver.trim();
        if (httpver.equals(HTTPConstants.HEADER_PROTOCOL_V11)) {
            http10 = false;
        }

        //process user defined headers for information.
        Hashtable userHeaderTable = (Hashtable) msgContext.
                getProperty(HTTPConstants.REQUEST_HEADERS);

        if (userHeaderTable != null) {
            if (null == otherHeaders) {
                otherHeaders = new StringBuffer(1024);
            }

            for (java.util.Iterator e = userHeaderTable.entrySet().iterator();
                 e.hasNext();) {

                java.util.Map.Entry me = (java.util.Map.Entry) e.next();
                Object keyObj = me.getKey();
                if (null == keyObj) continue;
                String key = keyObj.toString().trim();

                if (key.equalsIgnoreCase(HTTPConstants.HEADER_TRANSFER_ENCODING)) {
                    if (!http10) {
                        String val = me.getValue().toString();
                        if (null != val && val.trim().equalsIgnoreCase(HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED))
                            httpChunkStream = true;
                    }
                } else if (key.equalsIgnoreCase(HTTPConstants.HEADER_CONNECTION)) {
                    if (!http10) {
                        String val = me.getValue().toString();
                        if (val.trim().equalsIgnoreCase(HTTPConstants.HEADER_CONNECTION_CLOSE))
                            httpConnection = HTTPConstants.HEADER_CONNECTION_CLOSE;
                    }
                    //HTTP 1.0 will always close.
                    //HTTP 1.1 will use persistent. //no need to specify
                } else {
                    if( !http10 && key.equalsIgnoreCase(HTTPConstants.HEADER_EXPECT)) {
                        String val = me.getValue().toString();
                        if (null != val && val.trim().equalsIgnoreCase(HTTPConstants.HEADER_EXPECT_100_Continue))
                            httpContinueExpected = true;
                    }

                    otherHeaders.append(key).append(": ").append(me.getValue()).append("\r\n");
                }
            }
        }

        if (!http10) {
            //Force close for now.
            //TODO HTTP/1.1
            httpConnection = HTTPConstants.HEADER_CONNECTION_CLOSE;
        }

        header2.append(" ");
        header2.append(http10 ? HTTPConstants.HEADER_PROTOCOL_10 :
                HTTPConstants.HEADER_PROTOCOL_11)
                .append("\r\n");
        MimeHeaders mimeHeaders = reqMessage.getMimeHeaders();

        if (posting) {
            String contentType;
            final String[] header = mimeHeaders.getHeader(HTTPConstants.HEADER_CONTENT_TYPE);
            if (header != null && header.length > 0) {
                contentType = mimeHeaders.getHeader(HTTPConstants.HEADER_CONTENT_TYPE)[0];
            } else {
                contentType = reqMessage.getContentType(msgContext.getSOAPConstants());
            }
            
            //fix for AXIS-2027
            if (contentType == null || contentType.equals("")) {
            	throw new Exception(Messages.getMessage("missingContentType"));
            }
            header2.append(HTTPConstants.HEADER_CONTENT_TYPE)
                    .append(": ")
                    .append(contentType)
                    .append("\r\n");
        }

        header2.append(ACCEPT_HEADERS)
                .append(HTTPConstants.HEADER_HOST)  //used for virtual connections
                .append(": ")
                .append(host)
                .append((port == -1)?(""):(":" + port))
                .append("\r\n")
                .append(CACHE_HEADERS)
                .append(HTTPConstants.HEADER_SOAP_ACTION)  //The SOAP action.
                .append(": \"")
                .append(action)
                .append("\"\r\n");

        if (posting) {
            if (!httpChunkStream) {
                //Content length MUST be sent on HTTP 1.0 requests.
                header2.append(HTTPConstants.HEADER_CONTENT_LENGTH)
                        .append(": ")
                        .append(reqMessage.getContentLength())
                        .append("\r\n");
            } else {
                //Do http chunking.
                header2.append(CHUNKED_HEADER);
            }
        }

        // Transfer MIME headers of SOAPMessage to HTTP headers. 
        if (mimeHeaders != null) {
            for (Iterator i = mimeHeaders.getAllHeaders(); i.hasNext(); ) {
                MimeHeader mimeHeader = (MimeHeader) i.next();
                String headerName = mimeHeader.getName();
                if (headerName.equals(HTTPConstants.HEADER_CONTENT_TYPE)
                        || headerName.equals(HTTPConstants.HEADER_SOAP_ACTION)) {
                        continue;
                }
                header2.append(mimeHeader.getName())
                .append(": ")
                .append(mimeHeader.getValue())
                .append("\r\n");
            }
        }

        if (null != httpConnection) {
            header2.append(HTTPConstants.HEADER_CONNECTION);
            header2.append(": ");
            header2.append(httpConnection);
            header2.append("\r\n");
        }

        getSocket(sockHolder, msgContext, targetURL.getProtocol(),
                  host, port, timeout, otherHeaders, useFullURL);
        
        if (null != otherHeaders) {
            //Add other headers to the end.
            //for pre java1.4 support, we have to turn the string buffer argument into
            //a string before appending.
            header2.append(otherHeaders.toString());
        }

        header2.append("\r\n"); //The empty line to start the BODY.

        StringBuffer header = new StringBuffer();
        
        // If we're SOAP 1.2, allow the web method to be set from the
        // MessageContext.
        if (msgContext.getSOAPConstants() == SOAPConstants.SOAP12_CONSTANTS) {
            webMethod = msgContext.getStrProp(SOAP12Constants.PROP_WEBMETHOD);
        }
        if (webMethod == null) {
            webMethod = HTTPConstants.HEADER_POST;
        } else {
            posting = webMethod.equals(HTTPConstants.HEADER_POST);
        }

        header.append(webMethod).append(" ");
        if (useFullURL.value) {
            header.append(tmpURL.toExternalForm());
        } else {
            header.append((((tmpURL.getFile() == null)
                    || tmpURL.getFile().equals(""))
                    ? "/"
                    : tmpURL.getFile()));
        }
        header.append(header2.toString());

        OutputStream out = sockHolder.getSocket().getOutputStream();

        if (!posting) {
            out.write(header.toString()
                    .getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING));
            out.flush();
            return null;
        }

        InputStream inp = null;

        if (httpChunkStream || httpContinueExpected) {
            out.write(header.toString()
                    .getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING));
        }

        if(httpContinueExpected ){ //We need to get a reply from the server as to whether
            // it wants us send anything more.
            out.flush();
            Hashtable cheaders= new Hashtable ();
            inp = readHeadersFromSocket(sockHolder, msgContext, null, cheaders);
            int returnCode= -1;
            Integer Irc= (Integer)msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE);
            if(null != Irc) {
                returnCode= Irc.intValue();
            }
            if(100 == returnCode){  // got 100 we may continue.
                //Need todo a little msgContext house keeping....
                msgContext.removeProperty(HTTPConstants.MC_HTTP_STATUS_CODE);
                msgContext.removeProperty(HTTPConstants.MC_HTTP_STATUS_MESSAGE);
            }
            else{ //If no 100 Continue then we must not send anything!
                String statusMessage= (String)
                        msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_MESSAGE);

                AxisFault fault = new AxisFault("HTTP", "(" + returnCode+ ")" + statusMessage, null, null);

                fault.setFaultDetailString(Messages.getMessage("return01",
                                                               "" + returnCode, ""));
                throw fault;
            }
        }
        ByteArrayOutputStream baos = null;
        if (log.isDebugEnabled()) {
            log.debug(Messages.getMessage("xmlSent00"));
            log.debug("---------------------------------------------------");
            baos = new ByteArrayOutputStream();
        }
        if (httpChunkStream) {
            ChunkedOutputStream chunkedOutputStream = new ChunkedOutputStream(out);
            out = new BufferedOutputStream(chunkedOutputStream, Constants.HTTP_TXR_BUFFER_SIZE);
            try {
                if(baos != null) {
                    out = new TeeOutputStream(out, baos);
                }
                reqMessage.writeTo(out);
            } catch (SOAPException e) {
                log.error(Messages.getMessage("exception00"), e);
            }
            out.flush();
            chunkedOutputStream.eos();
        } else {
            out = new BufferedOutputStream(out, Constants.HTTP_TXR_BUFFER_SIZE);
            try {
                if (!httpContinueExpected) {
                    out.write(header.toString()
                            .getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING));
                }
                if(baos != null) {
                    out = new TeeOutputStream(out, baos);
                }
                reqMessage.writeTo(out);
            } catch (SOAPException e) {
                log.error(Messages.getMessage("exception00"), e);
            }
            // Flush ONLY once.
            out.flush();
        }
        if (log.isDebugEnabled()) {
            log.debug(header + new String(baos.toByteArray()));
        }

        return inp;
    }