Coverage Report - org.mule.transport.soap.axis.extensions.MuleHttpSender
 
Classes in this File Line Coverage Branch Coverage Complexity
MuleHttpSender
0%
0/342
0%
0/222
0
 
 1  
 /*
 2  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 3  
  * The software in this package is published under the terms of the CPAL v1.0
 4  
  * license, a copy of which has been included with this distribution in the
 5  
  * LICENSE.txt file.
 6  
  */
 7  
 package org.mule.transport.soap.axis.extensions;
 8  
 
 9  
 import org.mule.module.cxf.SoapConstants;
 10  
 import org.mule.util.StringUtils;
 11  
 import org.mule.util.SystemUtils;
 12  
 
 13  
 import java.io.BufferedInputStream;
 14  
 import java.io.BufferedOutputStream;
 15  
 import java.io.IOException;
 16  
 import java.io.InputStream;
 17  
 import java.io.OutputStream;
 18  
 import java.net.Socket;
 19  
 import java.net.URL;
 20  
 import java.util.Enumeration;
 21  
 import java.util.Hashtable;
 22  
 import java.util.Iterator;
 23  
 
 24  
 import javax.xml.soap.MimeHeader;
 25  
 import javax.xml.soap.MimeHeaders;
 26  
 import javax.xml.soap.SOAPException;
 27  
 
 28  
 import org.apache.axis.AxisFault;
 29  
 import org.apache.axis.Constants;
 30  
 import org.apache.axis.Message;
 31  
 import org.apache.axis.MessageContext;
 32  
 import org.apache.axis.client.Call;
 33  
 import org.apache.axis.components.logger.LogFactory;
 34  
 import org.apache.axis.components.net.BooleanHolder;
 35  
 import org.apache.axis.components.net.DefaultSocketFactory;
 36  
 import org.apache.axis.components.net.SocketFactory;
 37  
 import org.apache.axis.components.net.SocketFactoryFactory;
 38  
 import org.apache.axis.encoding.Base64;
 39  
 import org.apache.axis.handlers.BasicHandler;
 40  
 import org.apache.axis.soap.SOAP12Constants;
 41  
 import org.apache.axis.soap.SOAPConstants;
 42  
 import org.apache.axis.transport.http.ChunkedInputStream;
 43  
 import org.apache.axis.transport.http.ChunkedOutputStream;
 44  
 import org.apache.axis.transport.http.HTTPConstants;
 45  
 import org.apache.axis.transport.http.HTTPSender;
 46  
 import org.apache.axis.transport.http.SocketHolder;
 47  
 import org.apache.axis.transport.http.SocketInputStream;
 48  
 import org.apache.axis.utils.Messages;
 49  
 import org.apache.axis.utils.TeeOutputStream;
 50  
 import org.apache.commons.io.output.ByteArrayOutputStream;
 51  
 import org.apache.commons.logging.Log;
 52  
 
 53  
 /**
 54  
  * <code>MuleHttpSender</code> is a rewrite of the Axis HttpSender. Unfortunately,
 55  
  * the Axis implementation is not extensible so this class is a copy of it with
 56  
  * modifications. The enhancements made are to allow for asynchronous Http method
 57  
  * calls which Mule initiates when the endpoint is asynchronous.
 58  
  *
 59  
  * @deprecated Use the UniversalSender instead
 60  
  */
 61  
 @Deprecated
 62  0
 public class MuleHttpSender extends BasicHandler
 63  
 {
 64  
     /**
 65  
      * Serial version
 66  
      */
 67  
     private static final long serialVersionUID = -1730816323289419500L;
 68  
 
 69  0
     protected static final Log log = LogFactory.getLog(HTTPSender.class.getName());
 70  
 
 71  0
     private static final String ACCEPT_HEADERS = HTTPConstants.HEADER_ACCEPT
 72  
                                                  // limit to the types that are
 73  
                                                     // meaningful to us.
 74  
                                                  + ": " + HTTPConstants.HEADER_ACCEPT_APPL_SOAP + ", "
 75  
                                                  + HTTPConstants.HEADER_ACCEPT_APPLICATION_DIME + ", "
 76  
                                                  + HTTPConstants.HEADER_ACCEPT_MULTIPART_RELATED + ", "
 77  
                                                  + HTTPConstants.HEADER_ACCEPT_TEXT_ALL + "\r\n"
 78  
                                                  + HTTPConstants.HEADER_USER_AGENT // Tell
 79  
                                                                                     // who
 80  
                                                                                     // we
 81  
                                                                                     // are.
 82  
                                                  + ": " + Messages.getMessage("axisUserAgent") + "\r\n";
 83  
 
 84  
     private static final String CACHE_HEADERS = HTTPConstants.HEADER_CACHE_CONTROL
 85  
                                                 // stop caching proxies from caching
 86  
                                                 // SOAP request.
 87  
                                                 + ": " + HTTPConstants.HEADER_CACHE_CONTROL_NOCACHE + "\r\n"
 88  
                                                 + HTTPConstants.HEADER_PRAGMA + ": "
 89  
                                                 + HTTPConstants.HEADER_CACHE_CONTROL_NOCACHE + "\r\n";
 90  
 
 91  0
     private static final String CHUNKED_HEADER = HTTPConstants.HEADER_TRANSFER_ENCODING + ": "
 92  
                                                  + HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED + "\r\n";
 93  
 
 94  0
     private static final String HEADER_CONTENT_TYPE_LC = HTTPConstants.HEADER_CONTENT_TYPE.toLowerCase();
 95  
 
 96  0
     private static final String HEADER_LOCATION_LC = HTTPConstants.HEADER_LOCATION.toLowerCase();
 97  
 
 98  0
     private static final String HEADER_CONTENT_LOCATION_LC = HTTPConstants.HEADER_CONTENT_LOCATION.toLowerCase();
 99  
 
 100  0
     private static final String HEADER_CONTENT_LENGTH_LC = HTTPConstants.HEADER_CONTENT_LENGTH.toLowerCase();
 101  
 
 102  0
     private static final String HEADER_TRANSFER_ENCODING_LC = HTTPConstants.HEADER_TRANSFER_ENCODING.toLowerCase();
 103  
 
 104  
     /**
 105  
      * the url; used for error reporting
 106  
      */
 107  
     URL targetURL;
 108  
 
 109  
     /**
 110  
      * invoke creates a socket connection, sends the request SOAP message and then
 111  
      * reads the response SOAP message back from the SOAP server
 112  
      * 
 113  
      * @param msgContext the messsage context
 114  
      * @throws AxisFault
 115  
      */
 116  
     public void invoke(MessageContext msgContext) throws AxisFault
 117  
     {
 118  
 
 119  0
         if (log.isDebugEnabled())
 120  
         {
 121  0
             log.debug(Messages.getMessage("enter00", "HTTPSender::invoke"));
 122  
         }
 123  
         try
 124  
         {
 125  0
             Call call = (Call)msgContext.getProperty("call_object");
 126  0
             String transURL = msgContext.getStrProp(MessageContext.TRANS_URL);
 127  0
             String uri = transURL;
 128  0
             if (call != null && call.useSOAPAction())
 129  
             {
 130  0
                 uri = call.getSOAPActionURI();
 131  
             }
 132  0
             msgContext.setProperty(SoapConstants.SOAP_ACTION_PROPERTY_CAPS, uri);
 133  
 
 134  0
             BooleanHolder useFullURL = new BooleanHolder(false);
 135  0
             StringBuffer otherHeaders = new StringBuffer(64);
 136  0
             targetURL = new URL(transURL);
 137  0
             String host = targetURL.getHost();
 138  0
             int port = targetURL.getPort();
 139  
 
 140  0
             SocketHolder socketHolder = new SocketHolder(null);
 141  
 
 142  
             // Send the SOAP request to the server
 143  0
             InputStream inp = writeToSocket(socketHolder, msgContext, targetURL, otherHeaders, host, port,
 144  
                 msgContext.getTimeout(), useFullURL);
 145  
 
 146  0
             if (msgContext.isClient() && call != null)
 147  
             {
 148  0
                 if (Boolean.TRUE.equals(call.getProperty("axis.one.way")))
 149  
                 {
 150  0
                     return;
 151  
                 }
 152  
             }
 153  
 
 154  
             // Read the response back from the server
 155  0
             Hashtable headers = new Hashtable();
 156  0
             inp = readHeadersFromSocket(socketHolder, msgContext, inp, headers);
 157  0
             readFromSocket(socketHolder, msgContext, inp, headers);
 158  
         }
 159  0
         catch (Exception e)
 160  
         {
 161  0
             log.debug(e);
 162  0
             throw AxisFault.makeFault(e);
 163  0
         }
 164  0
         if (log.isDebugEnabled())
 165  
         {
 166  0
             log.debug(Messages.getMessage("exit00", "HTTPDispatchHandler::invoke"));
 167  
         }
 168  0
     }
 169  
 
 170  
     /**
 171  
      * Creates a socket connection to the SOAP server
 172  
      * 
 173  
      * @param protocol "http" for standard, "https" for ssl.
 174  
      * @param host host name
 175  
      * @param port port to connect to
 176  
      * @param otherHeaders buffer for storing additional headers that need to be sent
 177  
      * @param useFullURL flag to indicate if the complete URL has to be sent
 178  
      * @throws java.io.IOException
 179  
      */
 180  
     protected void getSocket(SocketHolder sockHolder,
 181  
                              MessageContext msgContext,
 182  
                              String protocol,
 183  
                              String host,
 184  
                              int port,
 185  
                              int timeout,
 186  
                              StringBuffer otherHeaders,
 187  
                              BooleanHolder useFullURL) throws Exception
 188  
     {
 189  0
         Hashtable options = getOptions();
 190  0
         if (timeout > 0)
 191  
         {
 192  0
             if (options == null)
 193  
             {
 194  0
                 options = new Hashtable();
 195  
             }
 196  0
             options.put(DefaultSocketFactory.CONNECT_TIMEOUT, Integer.toString(timeout));
 197  
         }
 198  0
         SocketFactory factory = SocketFactoryFactory.getFactory(protocol, options);
 199  0
         if (factory == null)
 200  
         {
 201  0
             throw new IOException(Messages.getMessage("noSocketFactory", protocol));
 202  
         }
 203  
         // log.fatal("Axis client: connect on socket: " + host + ":" + port);
 204  0
         Socket sock = null;
 205  
         try
 206  
         {
 207  0
             sock = factory.create(host, port, otherHeaders, useFullURL);
 208  
         }
 209  0
         catch (Exception e)
 210  
         {
 211  0
             Thread.sleep(1000);
 212  
             try
 213  
             {
 214  0
                 sock = factory.create(host, port, otherHeaders, useFullURL);
 215  
             }
 216  0
             catch (Exception e1)
 217  
             {
 218  0
                 log.fatal("Axis client Failed: connect on socket: " + host + ":" + port, e);
 219  0
                 throw e;
 220  0
             }
 221  0
         }
 222  0
         if (timeout > 0)
 223  
         {
 224  0
             sock.setSoTimeout(timeout);
 225  
         }
 226  0
         sockHolder.setSocket(sock);
 227  0
     }
 228  
 
 229  
     /**
 230  
      * Send the soap request message to the server
 231  
      * 
 232  
      * @param msgContext message context
 233  
      * @param tmpURL url to connect to
 234  
      * @param otherHeaders other headers if any
 235  
      * @param host host name
 236  
      * @param port port
 237  
      * @param useFullURL flag to indicate if the whole url needs to be sent
 238  
      * @throws IOException
 239  
      */
 240  
     private InputStream writeToSocket(SocketHolder sockHolder,
 241  
                                       MessageContext msgContext,
 242  
                                       URL tmpURL,
 243  
                                       StringBuffer otherHeaders,
 244  
                                       String host,
 245  
                                       int port,
 246  
                                       int timeout,
 247  
                                       BooleanHolder useFullURL) throws Exception
 248  
     {
 249  
 
 250  0
         String userID = msgContext.getUsername();
 251  0
         String passwd = msgContext.getPassword();
 252  
 
 253  
         // Get SOAPAction, default to ""
 254  0
         String action = msgContext.useSOAPAction() ? msgContext.getSOAPActionURI() : "";
 255  
 
 256  0
         if (action == null)
 257  
         {
 258  0
             action = "";
 259  
         }
 260  
 
 261  
         // if UserID is not part of the context, but is in the URL, use
 262  
         // the one in the URL.
 263  0
         if ((userID == null) && (tmpURL.getUserInfo() != null))
 264  
         {
 265  0
             String info = tmpURL.getUserInfo();
 266  0
             int sep = info.indexOf(':');
 267  
 
 268  0
             if ((sep >= 0) && (sep + 1 < info.length()))
 269  
             {
 270  0
                 userID = info.substring(0, sep);
 271  0
                 passwd = info.substring(sep + 1);
 272  
             }
 273  
             else
 274  
             {
 275  0
                 userID = info;
 276  
             }
 277  
         }
 278  0
         if (userID != null)
 279  
         {
 280  0
             StringBuffer tmpBuf = new StringBuffer(64);
 281  0
             tmpBuf.append(userID).append(":").append((passwd == null) ? "" : passwd);
 282  0
             otherHeaders.append(HTTPConstants.HEADER_AUTHORIZATION).append(": Basic ").append(
 283  
                 Base64.encode(tmpBuf.toString().getBytes())).append("\r\n");
 284  
         }
 285  
 
 286  
         // don't forget the cookies!
 287  
         // mmm... cookies
 288  0
         if (msgContext.getMaintainSession())
 289  
         {
 290  0
             String cookie = msgContext.getStrProp(HTTPConstants.HEADER_COOKIE);
 291  0
             String cookie2 = msgContext.getStrProp(HTTPConstants.HEADER_COOKIE2);
 292  
 
 293  0
             if (cookie != null)
 294  
             {
 295  0
                 otherHeaders.append(HTTPConstants.HEADER_COOKIE).append(": ").append(cookie).append("\r\n");
 296  
             }
 297  0
             if (cookie2 != null)
 298  
             {
 299  0
                 otherHeaders.append(HTTPConstants.HEADER_COOKIE2).append(": ").append(cookie2).append("\r\n");
 300  
             }
 301  
         }
 302  
 
 303  0
         StringBuffer header2 = new StringBuffer(64);
 304  
 
 305  0
         String webMethod = null;
 306  0
         boolean posting = true;
 307  
 
 308  0
         Message reqMessage = msgContext.getRequestMessage();
 309  
 
 310  0
         boolean http10 = true; // True if this is to use HTTP 1.0 / false HTTP
 311  
         // 1.1
 312  0
         boolean httpChunkStream = false; // Use HTTP chunking or not.
 313  0
         boolean httpContinueExpected = false; // Under HTTP 1.1 if false you
 314  
         // *MAY* need to wait for a 100
 315  
         // rc,
 316  
         // if true the server MUST reply with 100 continue.
 317  0
         String httpConnection = null;
 318  
 
 319  0
         String httpver = msgContext.getStrProp(MessageContext.HTTP_TRANSPORT_VERSION);
 320  0
         if (null == httpver)
 321  
         {
 322  0
             httpver = HTTPConstants.HEADER_PROTOCOL_V10;
 323  
         }
 324  0
         httpver = httpver.trim();
 325  0
         if (httpver.equals(HTTPConstants.HEADER_PROTOCOL_V11))
 326  
         {
 327  0
             http10 = false;
 328  
         }
 329  
 
 330  
         // process user defined headers for information.
 331  0
         Hashtable userHeaderTable = (Hashtable)msgContext.getProperty(HTTPConstants.REQUEST_HEADERS);
 332  
 
 333  0
         if (userHeaderTable != null)
 334  
         {
 335  0
             if (null == otherHeaders)
 336  
             {
 337  0
                 otherHeaders = new StringBuffer(1024);
 338  
             }
 339  
 
 340  0
             for (java.util.Iterator e = userHeaderTable.entrySet().iterator(); e.hasNext();)
 341  
             {
 342  
 
 343  0
                 java.util.Map.Entry me = (java.util.Map.Entry)e.next();
 344  0
                 Object keyObj = me.getKey();
 345  0
                 if (null == keyObj)
 346  
                 {
 347  0
                     continue;
 348  
                 }
 349  0
                 String key = keyObj.toString().trim();
 350  
 
 351  0
                 if (key.equalsIgnoreCase(HTTPConstants.HEADER_TRANSFER_ENCODING))
 352  
                 {
 353  0
                     if (!http10)
 354  
                     {
 355  0
                         String val = me.getValue().toString();
 356  0
                         if (null != val
 357  
                             && val.trim().equalsIgnoreCase(HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED))
 358  
                         {
 359  0
                             httpChunkStream = true;
 360  
                         }
 361  0
                     }
 362  
                 }
 363  0
                 else if (key.equalsIgnoreCase(HTTPConstants.HEADER_CONNECTION))
 364  
                 {
 365  0
                     if (!http10)
 366  
                     {
 367  0
                         String val = me.getValue().toString();
 368  0
                         if (val.trim().equalsIgnoreCase(HTTPConstants.HEADER_CONNECTION_CLOSE))
 369  
                         {
 370  0
                             httpConnection = HTTPConstants.HEADER_CONNECTION_CLOSE;
 371  
                         }
 372  0
                     }
 373  
                     // HTTP 1.0 will always close.
 374  
                     // HTTP 1.1 will use persistent. //no need to specify
 375  
                 }
 376  
                 else
 377  
                 {
 378  0
                     if (!http10 && key.equalsIgnoreCase(HTTPConstants.HEADER_EXPECT))
 379  
                     {
 380  0
                         String val = me.getValue().toString();
 381  0
                         if (null != val
 382  
                             && val.trim().equalsIgnoreCase(HTTPConstants.HEADER_EXPECT_100_Continue))
 383  
                         {
 384  0
                             httpContinueExpected = true;
 385  
                         }
 386  
                     }
 387  
 
 388  0
                     otherHeaders.append(key).append(": ").append(me.getValue()).append("\r\n");
 389  
                 }
 390  0
             }
 391  
         }
 392  
 
 393  0
         if (!http10)
 394  
         {
 395  
             // Force close for now.
 396  
             // TODO HTTP/1.1
 397  0
             httpConnection = HTTPConstants.HEADER_CONNECTION_CLOSE;
 398  
         }
 399  
 
 400  0
         header2.append(" ");
 401  0
         header2.append(http10 ? HTTPConstants.HEADER_PROTOCOL_10 : HTTPConstants.HEADER_PROTOCOL_11).append(
 402  
             "\r\n");
 403  0
         MimeHeaders mimeHeaders = reqMessage.getMimeHeaders();
 404  
 
 405  0
         if (posting)
 406  
         {
 407  
             String contentType;
 408  0
             if (mimeHeaders.getHeader(HTTPConstants.HEADER_CONTENT_TYPE) != null)
 409  
             {
 410  0
                 contentType = mimeHeaders.getHeader(HTTPConstants.HEADER_CONTENT_TYPE)[0];
 411  
             }
 412  
             else
 413  
             {
 414  0
                 contentType = reqMessage.getContentType(msgContext.getSOAPConstants());
 415  
             }
 416  0
             header2.append(HTTPConstants.HEADER_CONTENT_TYPE).append(": ").append(contentType).append("\r\n");
 417  
         }
 418  
 
 419  0
         header2.append(ACCEPT_HEADERS).append(HTTPConstants.HEADER_HOST)
 420  
         // used for virtual connections
 421  
             .append(": ")
 422  
             .append(host)
 423  
             .append((port == -1) ? ("") : (":" + port))
 424  
             .append("\r\n")
 425  
             .append(CACHE_HEADERS)
 426  
             .append(HTTPConstants.HEADER_SOAP_ACTION)
 427  
             // The SOAP action.
 428  
             .append(": \"")
 429  
             .append(action)
 430  
             .append("\"\r\n");
 431  
 
 432  0
         if (posting)
 433  
         {
 434  0
             if (!httpChunkStream)
 435  
             {
 436  
                 // Content length MUST be sent on HTTP 1.0 requests.
 437  0
                 header2.append(HTTPConstants.HEADER_CONTENT_LENGTH).append(": ").append(
 438  
                     reqMessage.getContentLength()).append("\r\n");
 439  
             }
 440  
             else
 441  
             {
 442  
                 // Do http chunking.
 443  0
                 header2.append(CHUNKED_HEADER);
 444  
             }
 445  
         }
 446  
 
 447  
         // Transfer MIME headers of SOAPMessage to HTTP headers.
 448  0
         if (mimeHeaders != null)
 449  
         {
 450  0
             for (Iterator i = mimeHeaders.getAllHeaders(); i.hasNext();)
 451  
             {
 452  0
                 MimeHeader mimeHeader = (MimeHeader)i.next();
 453  0
                 String headerName = mimeHeader.getName();
 454  0
                 if (headerName.equals(HTTPConstants.HEADER_CONTENT_TYPE)
 455  
                     || headerName.equals(HTTPConstants.HEADER_SOAP_ACTION))
 456  
                 {
 457  0
                     continue;
 458  
                 }
 459  0
                 header2.append(mimeHeader.getName())
 460  
                     .append(": ")
 461  
                     .append(mimeHeader.getValue())
 462  
                     .append("\r\n");
 463  0
             }
 464  
         }
 465  
 
 466  0
         if (null != httpConnection)
 467  
         {
 468  0
             header2.append(HTTPConstants.HEADER_CONNECTION);
 469  0
             header2.append(": ");
 470  0
             header2.append(httpConnection);
 471  0
             header2.append("\r\n");
 472  
         }
 473  
 
 474  0
         getSocket(sockHolder, msgContext, targetURL.getProtocol(), host, port, timeout, otherHeaders,
 475  
             useFullURL);
 476  
 
 477  0
         if (null != otherHeaders)
 478  
         {
 479  
             // Add other headers to the end.
 480  
             // for pre java1.4 support, we have to turn the string buffer
 481  
             // argument into
 482  
             // a string before appending.
 483  0
             header2.append(otherHeaders.toString());
 484  
         }
 485  
 
 486  0
         header2.append("\r\n"); // The empty line to start the BODY.
 487  
 
 488  0
         StringBuffer header = new StringBuffer(128);
 489  
 
 490  
         // If we're SOAP 1.2, allow the web method to be set from the
 491  
         // MessageContext.
 492  0
         if (msgContext.getSOAPConstants() == SOAPConstants.SOAP12_CONSTANTS)
 493  
         {
 494  0
             webMethod = msgContext.getStrProp(SOAP12Constants.PROP_WEBMETHOD);
 495  
         }
 496  0
         if (webMethod == null)
 497  
         {
 498  0
             webMethod = HTTPConstants.HEADER_POST;
 499  
         }
 500  
         else
 501  
         {
 502  0
             posting = webMethod.equals(HTTPConstants.HEADER_POST);
 503  
         }
 504  
 
 505  0
         header.append(webMethod).append(" ");
 506  0
         if (useFullURL.value)
 507  
         {
 508  0
             header.append(tmpURL.toExternalForm());
 509  
         }
 510  
         else
 511  
         {
 512  0
             header.append(StringUtils.isEmpty(tmpURL.getFile()) ? "/" : tmpURL.getFile());
 513  
         }
 514  0
         header.append(header2.toString());
 515  
 
 516  0
         OutputStream out = sockHolder.getSocket().getOutputStream();
 517  
 
 518  0
         if (!posting)
 519  
         {
 520  0
             out.write(header.toString().getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING));
 521  0
             out.flush();
 522  0
             return null;
 523  
         }
 524  
 
 525  0
         InputStream inp = null;
 526  
 
 527  0
         if (httpChunkStream || httpContinueExpected)
 528  
         {
 529  0
             out.write(header.toString().getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING));
 530  
         }
 531  
 
 532  0
         if (httpContinueExpected)
 533  
         { // We need to get a reply from the server as
 534  
             // to whether
 535  
             // it wants us send anything more.
 536  0
             out.flush();
 537  0
             Hashtable cheaders = new Hashtable();
 538  0
             inp = readHeadersFromSocket(sockHolder, msgContext, null, cheaders);
 539  0
             int returnCode = -1;
 540  0
             Integer Irc = (Integer)msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE);
 541  0
             if (null != Irc)
 542  
             {
 543  0
                 returnCode = Irc.intValue();
 544  
             }
 545  0
             if (100 == returnCode)
 546  
             { // got 100 we may continue.
 547  
                 // Need TODO a little msgContext house keeping....
 548  0
                 msgContext.removeProperty(HTTPConstants.MC_HTTP_STATUS_CODE);
 549  0
                 msgContext.removeProperty(HTTPConstants.MC_HTTP_STATUS_MESSAGE);
 550  
             }
 551  
             else
 552  
             { // If no 100 Continue then we must not send anything!
 553  0
                 String statusMessage = (String)msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_MESSAGE);
 554  
 
 555  0
                 AxisFault fault = new AxisFault("HTTP", "(" + returnCode + ")" + statusMessage, null, null);
 556  
 
 557  0
                 fault.setFaultDetailString(Messages.getMessage("return01", String.valueOf(returnCode), ""));
 558  0
                 throw fault;
 559  
             }
 560  
         }
 561  0
         ByteArrayOutputStream baos = null;
 562  0
         if (log.isDebugEnabled())
 563  
         {
 564  0
             log.debug(Messages.getMessage("xmlSent00"));
 565  0
             log.debug("---------------------------------------------------");
 566  0
             baos = new ByteArrayOutputStream();
 567  
         }
 568  0
         if (httpChunkStream)
 569  
         {
 570  0
             ChunkedOutputStream chunkedOutputStream = new ChunkedOutputStream(out);
 571  0
             out = new BufferedOutputStream(chunkedOutputStream, Constants.HTTP_TXR_BUFFER_SIZE);
 572  
             try
 573  
             {
 574  0
                 if (baos != null)
 575  
                 {
 576  0
                     out = new TeeOutputStream(out, baos);
 577  
                 }
 578  0
                 reqMessage.writeTo(out);
 579  
             }
 580  0
             catch (SOAPException e)
 581  
             {
 582  0
                 log.error(Messages.getMessage("exception00"), e);
 583  0
             }
 584  0
             out.flush();
 585  0
             chunkedOutputStream.eos();
 586  0
         }
 587  
         else
 588  
         {
 589  0
             out = new BufferedOutputStream(out, Constants.HTTP_TXR_BUFFER_SIZE);
 590  
             try
 591  
             {
 592  0
                 if (!httpContinueExpected)
 593  
                 {
 594  0
                     out.write(header.toString().getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING));
 595  
                 }
 596  0
                 if (baos != null)
 597  
                 {
 598  0
                     out = new TeeOutputStream(out, baos);
 599  
                 }
 600  0
                 reqMessage.writeTo(out);
 601  
             }
 602  0
             catch (SOAPException e)
 603  
             {
 604  0
                 throw e;
 605  
             }
 606  
             finally
 607  
             {
 608  
                 // Flush ONLY once.
 609  0
                 out.flush();
 610  0
             }
 611  
 
 612  
         }
 613  
 
 614  0
         if (log.isDebugEnabled() && baos != null)
 615  
         {
 616  0
             log.debug(header + new String(baos.toByteArray()));
 617  
         }
 618  
 
 619  0
         return inp;
 620  
     }
 621  
 
 622  
     private InputStream readHeadersFromSocket(SocketHolder sockHolder,
 623  
                                               MessageContext msgContext,
 624  
                                               InputStream inp,
 625  
                                               Hashtable headers) throws IOException
 626  
     {
 627  0
         byte b = 0;
 628  0
         int len = 0;
 629  0
         int colonIndex = -1;
 630  
         String name, value;
 631  0
         int returnCode = 0;
 632  0
         if (null == inp)
 633  
         {
 634  0
             inp = new BufferedInputStream(sockHolder.getSocket().getInputStream());
 635  
         }
 636  
 
 637  0
         if (headers == null)
 638  
         {
 639  0
             headers = new Hashtable();
 640  
         }
 641  
 
 642  
         // Should help performance. Temporary fix only till its all stream
 643  
         // oriented.
 644  
         // Need to add logic for getting the version # and the return code
 645  
         // but that's for tomorrow!
 646  
 
 647  
         /* Logic to read HTTP response headers */
 648  0
         boolean readTooMuch = false;
 649  
 
 650  0
         for (ByteArrayOutputStream buf = new ByteArrayOutputStream(4097);;)
 651  
         {
 652  0
             if (!readTooMuch)
 653  
             {
 654  0
                 b = (byte)inp.read();
 655  
             }
 656  0
             if (b == -1)
 657  
             {
 658  0
                 break;
 659  
             }
 660  0
             readTooMuch = false;
 661  0
             if ((b != '\r') && (b != '\n'))
 662  
             {
 663  0
                 if ((b == ':') && (colonIndex == -1))
 664  
                 {
 665  0
                     colonIndex = len;
 666  
                 }
 667  0
                 len++;
 668  0
                 buf.write(b);
 669  
             }
 670  0
             else if (b == '\r')
 671  
             {
 672  0
                 continue;
 673  
             }
 674  
             else
 675  
             { // b== '\n'
 676  0
                 if (len == 0)
 677  
                 {
 678  0
                     break;
 679  
                 }
 680  0
                 b = (byte)inp.read();
 681  0
                 readTooMuch = true;
 682  
 
 683  
                 // A space or tab at the begining of a line means the header
 684  
                 // continues.
 685  0
                 if ((b == ' ') || (b == '\t'))
 686  
                 {
 687  0
                     continue;
 688  
                 }
 689  0
                 buf.close();
 690  0
                 byte[] hdata = buf.toByteArray();
 691  0
                 buf.reset();
 692  0
                 if (colonIndex != -1)
 693  
                 {
 694  0
                     name = new String(hdata, 0, colonIndex, HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING);
 695  0
                     value = new String(hdata, colonIndex + 1, len - 1 - colonIndex,
 696  
                         HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING);
 697  0
                     colonIndex = -1;
 698  
                 }
 699  
                 else
 700  
                 {
 701  
 
 702  0
                     name = new String(hdata, 0, len, HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING);
 703  0
                     value = "";
 704  
                 }
 705  0
                 if (log.isDebugEnabled())
 706  
                 {
 707  0
                     log.debug(name + value);
 708  
                 }
 709  0
                 if (msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE) == null)
 710  
                 {
 711  
 
 712  
                     // Reader status code
 713  0
                     int start = name.indexOf(' ') + 1;
 714  0
                     String tmp = name.substring(start).trim();
 715  0
                     int end = tmp.indexOf(' ');
 716  
 
 717  0
                     if (end != -1)
 718  
                     {
 719  0
                         tmp = tmp.substring(0, end);
 720  
                     }
 721  0
                     returnCode = Integer.parseInt(tmp);
 722  0
                     msgContext.setProperty(HTTPConstants.MC_HTTP_STATUS_CODE, new Integer(returnCode));
 723  0
                     msgContext.setProperty(HTTPConstants.MC_HTTP_STATUS_MESSAGE, name.substring(start + end
 724  
                                                                                                 + 1));
 725  0
                 }
 726  
                 else
 727  
                 {
 728  0
                     headers.put(name.toLowerCase(), value);
 729  
                 }
 730  0
                 len = 0;
 731  0
             }
 732  
         }
 733  
 
 734  0
         return inp;
 735  
     }
 736  
 
 737  
     /**
 738  
      * Reads the SOAP response back from the server
 739  
      * 
 740  
      * @param msgContext message context
 741  
      * @throws IOException
 742  
      */
 743  
     private InputStream readFromSocket(SocketHolder socketHolder,
 744  
                                        MessageContext msgContext,
 745  
                                        InputStream inp,
 746  
                                        Hashtable headers) throws IOException
 747  
     {
 748  0
         Message outMsg = null;
 749  
         byte b;
 750  
 
 751  0
         Integer rc = (Integer)msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE);
 752  0
         int returnCode = 0;
 753  0
         if (rc != null)
 754  
         {
 755  0
             returnCode = rc.intValue();
 756  
         }
 757  
         else
 758  
         {
 759  
             // No return code?? Should have one by now.
 760  
         }
 761  
 
 762  
         /* All HTTP headers have been read. */
 763  0
         String contentType = (String)headers.get(HEADER_CONTENT_TYPE_LC);
 764  
 
 765  0
         contentType = (null == contentType) ? null : contentType.trim();
 766  
 
 767  0
         String location = (String)headers.get(HEADER_LOCATION_LC);
 768  
 
 769  0
         location = (null == location) ? null : location.trim();
 770  
 
 771  0
         if ((returnCode > 199) && (returnCode < 300))
 772  
         {
 773  0
             if (returnCode == 202)
 774  
             {
 775  0
                 return inp;
 776  
             }
 777  
             // SOAP return is OK - so fall through
 778  
         }
 779  0
         else if (msgContext.getSOAPConstants() == SOAPConstants.SOAP12_CONSTANTS)
 780  
         {
 781  
             // For now, if we're SOAP 1.2, fall through, since the range of
 782  
             // valid result codes is much greater
 783  
         }
 784  0
         else if ((contentType != null) && !contentType.startsWith("text/html")
 785  
                  && ((returnCode > 499) && (returnCode < 600)))
 786  
         {
 787  
             // SOAP Fault should be in here - so fall through
 788  
         }
 789  0
         else if ((location != null) && ((returnCode == 302) || (returnCode == 307)))
 790  
         {
 791  
             // Temporary Redirect (HTTP: 302/307)
 792  
             // close old connection
 793  0
             inp.close();
 794  0
             socketHolder.getSocket().close();
 795  
             // remove former result and set new target url
 796  0
             msgContext.removeProperty(HTTPConstants.MC_HTTP_STATUS_CODE);
 797  0
             msgContext.setProperty(MessageContext.TRANS_URL, location);
 798  
             // next try
 799  0
             invoke(msgContext);
 800  0
             return inp;
 801  
         }
 802  0
         else if (returnCode == 100)
 803  
         {
 804  0
             msgContext.removeProperty(HTTPConstants.MC_HTTP_STATUS_CODE);
 805  0
             msgContext.removeProperty(HTTPConstants.MC_HTTP_STATUS_MESSAGE);
 806  0
             readHeadersFromSocket(socketHolder, msgContext, inp, headers);
 807  0
             return readFromSocket(socketHolder, msgContext, inp, headers);
 808  
         }
 809  
         else
 810  
         {
 811  
             // Unknown return code - so wrap up the content into a
 812  
             // SOAP Fault.
 813  0
             ByteArrayOutputStream buf = new ByteArrayOutputStream(4097);
 814  
 
 815  0
             while (-1 != (b = (byte)inp.read()))
 816  
             {
 817  0
                 buf.write(b);
 818  
             }
 819  0
             String statusMessage = msgContext.getStrProp(HTTPConstants.MC_HTTP_STATUS_MESSAGE);
 820  0
             AxisFault fault = new AxisFault("HTTP", "(" + returnCode + ")" + statusMessage, null, null);
 821  
 
 822  0
             fault.setFaultDetailString(Messages.getMessage("return01", String.valueOf(returnCode), buf.toString()));
 823  0
             fault.addFaultDetail(Constants.QNAME_FAULTDETAIL_HTTPERRORCODE, Integer.toString(returnCode));
 824  0
             throw fault;
 825  
         }
 826  
 
 827  0
         String contentLocation = (String)headers.get(HEADER_CONTENT_LOCATION_LC);
 828  
 
 829  0
         contentLocation = (null == contentLocation) ? null : contentLocation.trim();
 830  
 
 831  0
         String contentLength = (String)headers.get(HEADER_CONTENT_LENGTH_LC);
 832  
 
 833  0
         contentLength = (null == contentLength) ? null : contentLength.trim();
 834  
 
 835  0
         String transferEncoding = (String)headers.get(HEADER_TRANSFER_ENCODING_LC);
 836  
 
 837  0
         if (null != transferEncoding)
 838  
         {
 839  0
             transferEncoding = transferEncoding.trim().toLowerCase();
 840  0
             if (transferEncoding.equals(HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED))
 841  
             {
 842  0
                 inp = new ChunkedInputStream(inp);
 843  
             }
 844  
         }
 845  
 
 846  0
         outMsg = new Message(new SocketInputStream(inp, socketHolder.getSocket()), false, contentType,
 847  
             contentLocation);
 848  
         // Transfer HTTP headers of HTTP message to MIME headers of SOAP message
 849  0
         MimeHeaders mimeHeaders = outMsg.getMimeHeaders();
 850  0
         for (Enumeration e = headers.keys(); e.hasMoreElements();)
 851  
         {
 852  0
             String key = (String)e.nextElement();
 853  0
             mimeHeaders.addHeader(key, ((String)headers.get(key)).trim());
 854  0
         }
 855  0
         outMsg.setMessageType(Message.RESPONSE);
 856  0
         msgContext.setResponseMessage(outMsg);
 857  0
         if (log.isDebugEnabled())
 858  
         {
 859  0
             if (null == contentLength)
 860  
             {
 861  0
                 log.debug(SystemUtils.LINE_SEPARATOR + Messages.getMessage("no00", "Content-Length"));
 862  
             }
 863  0
             log.debug(SystemUtils.LINE_SEPARATOR + Messages.getMessage("xmlRecd00"));
 864  0
             log.debug("-----------------------------------------------");
 865  0
             log.debug(outMsg.getSOAPEnvelope().toString());
 866  
         }
 867  
 
 868  
         // if we are maintaining session state,
 869  
         // handle cookies (if any)
 870  0
         if (msgContext.getMaintainSession())
 871  
         {
 872  0
             handleCookie(HTTPConstants.HEADER_COOKIE, HTTPConstants.HEADER_SET_COOKIE, headers, msgContext);
 873  0
             handleCookie(HTTPConstants.HEADER_COOKIE2, HTTPConstants.HEADER_SET_COOKIE2, headers, msgContext);
 874  
         }
 875  0
         return inp;
 876  
     }
 877  
 
 878  
     /**
 879  
      * little helper function for cookies
 880  
      * 
 881  
      * @param cookieName
 882  
      * @param setCookieName
 883  
      * @param headers
 884  
      * @param msgContext
 885  
      */
 886  
     public void handleCookie(String cookieName,
 887  
                              String setCookieName,
 888  
                              Hashtable headers,
 889  
                              MessageContext msgContext)
 890  
     {
 891  
 
 892  0
         if (headers.containsKey(setCookieName.toLowerCase()))
 893  
         {
 894  0
             String cookie = (String)headers.get(setCookieName.toLowerCase());
 895  0
             cookie = cookie.trim();
 896  
 
 897  
             // chop after first ; a la Apache SOAP (see HTTPUtils.java there)
 898  0
             int index = cookie.indexOf(';');
 899  
 
 900  0
             if (index != -1)
 901  
             {
 902  0
                 cookie = cookie.substring(0, index);
 903  
             }
 904  0
             msgContext.setProperty(cookieName, cookie);
 905  
         }
 906  0
     }
 907  
 }