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