KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > transport > http > HTTPSender


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Axis" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  */

55 package org.jboss.axis.transport.http;
56
57 import java.io.BufferedInputStream JavaDoc;
58 import java.io.BufferedOutputStream JavaDoc;
59 import java.io.ByteArrayOutputStream JavaDoc;
60 import java.io.IOException JavaDoc;
61 import java.io.InputStream JavaDoc;
62 import java.io.OutputStream JavaDoc;
63 import java.net.Socket JavaDoc;
64 import java.net.URL JavaDoc;
65 import java.util.HashMap JavaDoc;
66 import java.util.Iterator JavaDoc;
67
68 import javax.xml.soap.MimeHeader JavaDoc;
69 import javax.xml.soap.MimeHeaders JavaDoc;
70 import javax.xml.soap.SOAPException JavaDoc;
71
72 import org.jboss.axis.AxisFault;
73 import org.jboss.axis.Message;
74 import org.jboss.axis.MessageContext;
75 import org.jboss.axis.MessagePart;
76 import org.jboss.axis.components.net.BooleanHolder;
77 import org.jboss.axis.components.net.SocketFactory;
78 import org.jboss.axis.components.net.SocketFactoryFactory;
79 import org.jboss.axis.encoding.Base64;
80 import org.jboss.axis.handlers.BasicHandler;
81 import org.jboss.axis.soap.SOAP12Constants;
82 import org.jboss.axis.soap.SOAPConstants;
83 import org.jboss.axis.utils.Messages;
84 import org.jboss.logging.Logger;
85
86 /**
87  * This is meant to be used on a SOAP Client to call a SOAP server.
88  *
89  * @author Doug Davis (dug@us.ibm.com)
90  * @author Davanum Srinivas (dims@yahoo.com)
91  */

92 public class HTTPSender extends BasicHandler
93 {
94
95    private static Logger log = Logger.getLogger(HTTPSender.class.getName());
96
97    /**
98     * invoke creates a socket connection, sends the request SOAP message and then
99     * reads the response SOAP message back from the SOAP server
100     *
101     * @param msgContext the messsage context
102     * @throws AxisFault
103     */

104    public void invoke(MessageContext msgContext) throws AxisFault
105    {
106
107       if (log.isDebugEnabled())
108       {
109          log.debug(Messages.getMessage("enter00", "HTTPSender::invoke"));
110       }
111       try
112       {
113          BooleanHolder useFullURL = new BooleanHolder(false);
114          StringBuffer JavaDoc otherHeaders = new StringBuffer JavaDoc();
115          URL JavaDoc targetURL = new URL JavaDoc(msgContext.getStrProp(MessageContext.TRANS_URL));
116          String JavaDoc host = targetURL.getHost();
117          int port = targetURL.getPort();
118          Socket JavaDoc sock = null;
119
120          log.debug("TargetURL: " + targetURL);
121
122          sock = getSocket(targetURL.getProtocol(), host, port, otherHeaders, useFullURL, msgContext.getTransportOptions());
123
124          // optionally set a timeout for the request
125
if (msgContext.getTimeout() != 0)
126          {
127             sock.setSoTimeout(msgContext.getTimeout());
128          }
129
130          // Send the SOAP request to the server
131
InputStream JavaDoc inp = writeToSocket(sock, msgContext, targetURL, otherHeaders, host, port, useFullURL);
132
133          // Read the response back from the server
134
MimeHeaders JavaDoc headers = new MimeHeaders JavaDoc();
135          inp = readHeadersFromSocket(sock, msgContext, inp, headers);
136          readFromSocket(sock, msgContext, inp, headers);
137       }
138       catch (Exception JavaDoc e)
139       {
140          log.debug(e.getMessage(), e);
141          throw AxisFault.makeFault(e);
142       }
143       if (log.isDebugEnabled())
144       {
145          log.debug(Messages.getMessage("exit00",
146                  "HTTPDispatchHandler::invoke"));
147       }
148    }
149
150    /**
151     * Creates a socket connection to the SOAP server
152     *
153     * @param protocol "http" for standard, "https" for ssl.
154     * @param host host name
155     * @param port port to connect to
156     * @param otherHeaders buffer for storing additional headers that need to be sent
157     * @param useFullURL flag to indicate if the complete URL has to be sent
158     * @return the socket
159     * @throws IOException
160     */

161    private Socket JavaDoc getSocket(String JavaDoc protocol,
162                             String JavaDoc host, int port, StringBuffer JavaDoc otherHeaders, BooleanHolder useFullURL, HashMap JavaDoc options)
163            throws Exception JavaDoc
164    {
165       SocketFactory factory = SocketFactoryFactory.getFactory(protocol, options);
166       return factory.create(host, port, otherHeaders, useFullURL);
167    }
168
169    /**
170     * Send the soap request message to the server
171     *
172     * @param sock socket
173     * @param msgContext message context
174     * @param tmpURL url to connect to
175     * @param otherHeaders other headers if any
176     * @param host host name
177     * @param port port
178     * @param useFullURL flag to indicate if the whole url needs to be sent
179     * @throws IOException
180     */

181    private InputStream JavaDoc writeToSocket(Socket JavaDoc sock, MessageContext msgContext, URL JavaDoc tmpURL,
182                                      StringBuffer JavaDoc otherHeaders, String JavaDoc host, int port,
183                                      BooleanHolder useFullURL)
184            throws IOException JavaDoc
185    {
186
187       String JavaDoc userID = null;
188       String JavaDoc passwd = null;
189
190       userID = msgContext.getUsername();
191       passwd = msgContext.getPassword();
192
193       // Get SOAPAction, default to ""
194
String JavaDoc action = msgContext.useSOAPAction()
195               ? msgContext.getSOAPActionURI()
196               : "";
197
198       if (action == null)
199       {
200          action = "";
201       }
202
203       // if UserID is not part of the context, but is in the URL, use
204
// the one in the URL.
205
if ((userID == null) && (tmpURL.getUserInfo() != null))
206       {
207          String JavaDoc info = tmpURL.getUserInfo();
208          int sep = info.indexOf(':');
209
210          if ((sep >= 0) && (sep + 1 < info.length()))
211          {
212             userID = info.substring(0, sep);
213             passwd = info.substring(sep + 1);
214          }
215          else
216          {
217             userID = info;
218          }
219       }
220       if (userID != null)
221       {
222          StringBuffer JavaDoc tmpBuf = new StringBuffer JavaDoc();
223
224          tmpBuf.append(userID).append(":").append((passwd == null)
225                  ? ""
226                  : passwd);
227          otherHeaders.append(HTTPConstants.HEADER_AUTHORIZATION)
228                  .append(": Basic ")
229                  .append(Base64.encode(tmpBuf.toString().getBytes()))
230                  .append("\r\n");
231       }
232
233       // don't forget the cookies!
234
// mmm... cookies
235
if (msgContext.getMaintainSession())
236       {
237          String JavaDoc cookie = msgContext.getStrProp(HTTPConstants.HEADER_COOKIE);
238          String JavaDoc cookie2 = msgContext.getStrProp(HTTPConstants.HEADER_COOKIE2);
239
240          if (cookie != null)
241          {
242             otherHeaders.append(HTTPConstants.HEADER_COOKIE).append(": ")
243                     .append(cookie).append("\r\n");
244          }
245          if (cookie2 != null)
246          {
247             otherHeaders.append(HTTPConstants.HEADER_COOKIE2).append(": ")
248                     .append(cookie2).append("\r\n");
249          }
250       }
251
252       StringBuffer JavaDoc header = new StringBuffer JavaDoc();
253
254       String JavaDoc webMethod = null;
255       boolean posting = true;
256
257       // If we're SOAP 1.2, allow the web method to be set from the
258
// MessageContext.
259
if (msgContext.getSOAPConstants() == SOAPConstants.SOAP12_CONSTANTS)
260          webMethod = msgContext.getStrProp(SOAP12Constants.PROP_WEBMETHOD);
261       if (webMethod == null)
262       {
263          webMethod = HTTPConstants.HEADER_POST;
264       }
265       else
266       {
267          posting = webMethod.equals(HTTPConstants.HEADER_POST);
268       }
269
270       header.append(webMethod).append(" ");
271       if (useFullURL.value)
272       {
273          header.append(tmpURL.toExternalForm());
274       }
275       else
276       {
277          header.append((((tmpURL.getFile() == null)
278                  || tmpURL.getFile().equals(""))
279                  ? "/"
280                  : tmpURL.getFile()));
281       }
282
283       Message requestMsg = msgContext.getRequestMessage();
284
285       boolean http10 = true; //True if this is to use HTTP 1.0 / false HTTP 1.1
286
boolean httpChunkStream = false; //Use HTTP chunking or not.
287
boolean httpContinueExpected = false; //Under HTTP 1.1 if false you *MAY* need to wait for a 100 rc,
288
// if true the server MUST reply with 100 continue.
289
String JavaDoc httpConnection = null;
290
291       String JavaDoc httpver = msgContext.getStrProp(MessageContext.HTTP_TRANSPORT_VERSION);
292       if (null == httpver) httpver = HTTPConstants.HEADER_PROTOCOL_V10;
293       httpver = httpver.trim();
294       if (httpver.equals(HTTPConstants.HEADER_PROTOCOL_V11))
295       {
296          http10 = false;
297       }
298
299       // Merge in user defined headers
300
MimeHeaders JavaDoc mimeHeaders = requestMsg.getMimeHeaders();
301       if (mimeHeaders != null)
302       {
303          Iterator JavaDoc i = mimeHeaders.getAllHeaders();
304          while (i.hasNext())
305          {
306             MimeHeader JavaDoc mimeHeader = (MimeHeader JavaDoc) i.next();
307             String JavaDoc name = mimeHeader.getName();
308             String JavaDoc value = mimeHeader.getValue();
309             if (name.equalsIgnoreCase(HTTPConstants.HEADER_TRANSFER_ENCODING))
310             {
311                if (!http10)
312                {
313                   if (null != value && value.trim().equalsIgnoreCase(HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED))
314                      httpChunkStream = true;
315                }
316             }
317             else if (name.equalsIgnoreCase(HTTPConstants.HEADER_HOST))
318             {
319                //ignore
320
}
321             else if (name.equalsIgnoreCase(HTTPConstants.HEADER_CONTENT_TYPE))
322             {
323                //ignore
324
}
325             else if (name.equalsIgnoreCase(HTTPConstants.HEADER_SOAP_ACTION))
326             {
327                // Allow a client to override the action if desired
328
action = value;
329             }
330             else if (name.equalsIgnoreCase(HTTPConstants.HEADER_CONTENT_LENGTH))
331             {
332                //ignore
333
}
334             else if (name.equalsIgnoreCase(HTTPConstants.HEADER_COOKIE))
335             {
336                //ignore
337
}
338             else if (name.equalsIgnoreCase(HTTPConstants.HEADER_COOKIE2))
339             {
340                //ignore
341
}
342             else if (name.equalsIgnoreCase(HTTPConstants.HEADER_AUTHORIZATION))
343             {
344                //ignore
345
}
346             else if (name.equalsIgnoreCase(HTTPConstants.HEADER_PROXY_AUTHORIZATION))
347             {
348                //ignore
349
}
350             else if (name.equalsIgnoreCase(HTTPConstants.HEADER_CONNECTION))
351             {
352                if (!http10)
353                {
354                   if (value.trim().equalsIgnoreCase(HTTPConstants.HEADER_CONNECTION_CLOSE))
355                      httpConnection = HTTPConstants.HEADER_CONNECTION_CLOSE;
356                }
357                //HTTP 1.0 will always close.
358
//HTTP 1.1 will use persistent. //no need to specify
359
}
360             else if (!http10 && name.equalsIgnoreCase(HTTPConstants.HEADER_EXPECT))
361             {
362                   if (null != value && value.trim().equalsIgnoreCase(HTTPConstants.HEADER_EXPECT_100_Continue))
363                      httpContinueExpected = true;
364             }
365             else
366             {
367                otherHeaders.append(name).append(": ").append(value + "\r\n");
368             }
369          }
370       }
371
372       if (!http10)
373          httpConnection = HTTPConstants.HEADER_CONNECTION_CLOSE; //Force close for now.
374

375       header.append(" ");
376       header.append(http10 ? HTTPConstants.HEADER_PROTOCOL_10 :
377               HTTPConstants.HEADER_PROTOCOL_11)
378               .append("\r\n");
379       if (posting)
380       {
381          header.append(HTTPConstants.HEADER_CONTENT_TYPE)
382                  .append(": ")
383                  .append(requestMsg.getContentType(msgContext.getSOAPConstants()))
384                  .append("\r\n");
385       }
386       header.append(HTTPConstants.HEADER_ACCEPT)//Limit to the types that are meaningful to us.
387
.append(": ")
388               .append(HTTPConstants.HEADER_ACCEPT_APPL_SOAP)
389               .append(", ")
390               .append(HTTPConstants.HEADER_ACCEPT_APPLICATION_DIME)
391               .append(", ")
392               .append(HTTPConstants.HEADER_ACCEPT_MULTIPART_RELATED)
393               .append(", ")
394               .append(HTTPConstants.HEADER_ACCEPT_TEXT_ALL)
395               .append("\r\n")
396               .append(HTTPConstants.HEADER_USER_AGENT)//Tell who we are.
397
.append(": ")
398               .append(Messages.getMessage("axisUserAgent"))
399               .append("\r\n")
400               .append(HTTPConstants.HEADER_HOST)//used for virtual connections
401
.append(": ")
402               .append(host)
403               .append((port == -1) ? ("") : (":" + port))
404               .append("\r\n")
405               .append(HTTPConstants.HEADER_CACHE_CONTROL)//Stop caching proxies from caching SOAP reqeuest.
406
.append(": ")
407               .append(HTTPConstants.HEADER_CACHE_CONTROL_NOCACHE)
408               .append("\r\n")
409               .append(HTTPConstants.HEADER_PRAGMA)
410               .append(": ")
411               .append(HTTPConstants.HEADER_CACHE_CONTROL_NOCACHE)
412               .append("\r\n")
413               .append(HTTPConstants.HEADER_SOAP_ACTION)//The SOAP action.
414
.append(": \"")
415               .append(action)
416               .append("\"\r\n");
417
418       if (posting)
419       {
420          if (!httpChunkStream)
421          {
422             //Content length MUST be sent on HTTP 1.0 requests.
423
header.append(HTTPConstants.HEADER_CONTENT_LENGTH)
424                     .append(": ")
425                     .append(requestMsg.getContentLength())
426                     .append("\r\n");
427          }
428          else
429          {
430             //Do http chunking.
431
header.append(HTTPConstants.HEADER_TRANSFER_ENCODING)
432                     .append(": ")
433                     .append(HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED)
434                     .append("\r\n");
435          }
436       }
437
438       if (null != httpConnection)
439       {
440          header.append(HTTPConstants.HEADER_CONNECTION);
441          header.append(": ");
442          header.append(httpConnection);
443          header.append("\r\n");
444       }
445
446       if (null != otherHeaders)
447       {
448          //Add other headers to the end.
449
//for pre java1.4 support, we have to turn the string buffer argument into
450
//a string before appending.
451
header.append(otherHeaders.toString());
452       }
453
454
455       header.append("\r\n"); //The empty line to start the BODY.
456

457       OutputStream JavaDoc out = sock.getOutputStream();
458
459       if (!posting)
460       {
461          out.write(header.toString()
462                  .getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING));
463          out.flush();
464          return null;
465       }
466
467       InputStream JavaDoc inp = null;
468
469       if (httpChunkStream)
470       {
471          out.write(header.toString()
472                  .getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING));
473       }
474
475       if (httpContinueExpected)
476       {
477          // We need to get a reply from the server as to whether
478
// it wants us send anything more.
479
out.flush();
480          MimeHeaders JavaDoc cheaders = new MimeHeaders JavaDoc();
481          inp = readHeadersFromSocket(sock, msgContext, null, cheaders);
482          int returnCode = -1;
483          Integer JavaDoc Irc = (Integer JavaDoc)msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE);
484          if (null != Irc) returnCode = Irc.intValue();
485          if (100 == returnCode)
486          {
487             // got 100 we may continue.
488
msgContext.removeProperty(HTTPConstants.MC_HTTP_STATUS_CODE);
489             msgContext.removeProperty(HTTPConstants.MC_HTTP_STATUS_MESSAGE);
490          }
491          else
492          {
493             // If no 100 Continue then we must not send anything!
494
String JavaDoc statusMessage = (String JavaDoc)
495                     msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_MESSAGE);
496
497             AxisFault fault = new AxisFault("HTTP", "(" + returnCode + ")" + statusMessage, null, null);
498
499             fault.setFaultDetailString(Messages.getMessage("return01",
500                     "" + returnCode, ""));
501             throw fault;
502          }
503       }
504
505       try
506       {
507          if (httpChunkStream == false)
508          {
509             out = new BufferedOutputStream JavaDoc(out, 8 * 1024);
510             out.write(header.toString().getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING));
511             requestMsg.writeTo(out);
512             // Flush ONLY once.
513
out.flush();
514          }
515          else
516          {
517             ChunkedOutputStream chunkedOutputStream = new ChunkedOutputStream(out);
518             out = new BufferedOutputStream JavaDoc(chunkedOutputStream, 8 * 1024);
519             requestMsg.writeTo(out);
520             out.flush();
521             chunkedOutputStream.eos();
522          }
523       }
524       catch (SOAPException JavaDoc e)
525       {
526          log.debug("Cannot serialize request message", e);
527       }
528
529       if (log.isDebugEnabled())
530       {
531          log.debug("XML request sent");
532          log.debug("----------------------------------------------");
533          MessagePart msgPart = (MessagePart)requestMsg.getSOAPPart();
534          String JavaDoc xmlMessage = msgPart.getAsString();
535          log.debug("----------------------------------------------");
536          log.debug(xmlMessage);
537          log.debug("----------------------------------------------");
538       }
539
540       return inp;
541    }
542
543    private InputStream JavaDoc readHeadersFromSocket(Socket JavaDoc sock, MessageContext msgContext, InputStream JavaDoc inp, MimeHeaders JavaDoc headers)
544            throws IOException JavaDoc
545    {
546       byte b = 0;
547       int len = 0;
548       int colonIndex = -1;
549       String JavaDoc name, value;
550       int returnCode = 0;
551       if (null == inp) inp = new BufferedInputStream JavaDoc(sock.getInputStream());
552
553       if (headers == null)
554          headers = new MimeHeaders JavaDoc();
555
556       // Should help performance. Temporary fix only till its all stream oriented.
557
// Need to add logic for getting the version # and the return code
558
// but that's for tomorrow!
559

560       /* Logic to read HTTP response headers */
561       boolean readTooMuch = false;
562
563       for (ByteArrayOutputStream JavaDoc buf = new ByteArrayOutputStream JavaDoc(4097); ;)
564       {
565          if (!readTooMuch)
566          {
567             b = (byte)inp.read();
568          }
569          if (b == -1)
570          {
571             break;
572          }
573          readTooMuch = false;
574          if ((b != '\r') && (b != '\n'))
575          {
576             if ((b == ':') && (colonIndex == -1))
577             {
578                colonIndex = len;
579             }
580             len++;
581             buf.write(b);
582          }
583          else if (b == '\r')
584          {
585             continue;
586          }
587          else
588          { // b== '\n'
589
if (len == 0)
590             {
591                break;
592             }
593             b = (byte)inp.read();
594             readTooMuch = true;
595
596             // A space or tab at the begining of a line means the header continues.
597
if ((b == ' ') || (b == '\t'))
598             {
599                continue;
600             }
601             buf.close();
602             byte[] hdata = buf.toByteArray();
603             buf.reset();
604             if (colonIndex != -1)
605             {
606                name =
607                        new String JavaDoc(hdata, 0, colonIndex,
608                                HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING);
609                value =
610                        new String JavaDoc(hdata, colonIndex + 1, len - 1 - colonIndex,
611                                HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING);
612                colonIndex = -1;
613             }
614             else
615             {
616
617                name =
618                        new String JavaDoc(hdata, 0, len,
619                                HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING);
620                value = "";
621             }
622             if (log.isDebugEnabled())
623             {
624                log.debug(name + value);
625             }
626             if (msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE)
627                     == null)
628             {
629
630                // Reader status code
631
int start = name.indexOf(' ') + 1;
632                String JavaDoc tmp = name.substring(start).trim();
633                int end = tmp.indexOf(' ');
634
635                if (end != -1)
636                {
637                   tmp = tmp.substring(0, end);
638                }
639                returnCode = Integer.parseInt(tmp);
640                msgContext.setProperty(HTTPConstants.MC_HTTP_STATUS_CODE,
641                        new Integer JavaDoc(returnCode));
642                msgContext.setProperty(HTTPConstants.MC_HTTP_STATUS_MESSAGE,
643                        name.substring(start + end + 1));
644             }
645             else
646             {
647                //headers.put(name.toLowerCase(), value);
648
headers.addHeader(name, value.trim());
649             }
650             len = 0;
651          }
652       }
653
654       return inp;
655    }
656
657    /**
658     * Reads the SOAP response back from the server
659     *
660     * @param sock socket
661     * @param msgContext message context
662     * @throws IOException
663     */

664    private void readFromSocket(Socket JavaDoc sock,
665                                MessageContext msgContext,
666                                InputStream JavaDoc inp,
667                                MimeHeaders JavaDoc headers)
668            throws IOException JavaDoc
669    {
670       Message responseMsg = null;
671       byte b;
672
673       Integer JavaDoc rc = (Integer JavaDoc)msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE);
674       int returnCode = 0;
675       if (rc != null)
676       {
677          returnCode = rc.intValue();
678       }
679       else
680       {
681          // No return code?? Should have one by now.
682
}
683
684       /* All HTTP headers have been read. */
685       String JavaDoc contentType = getFirstTrimmedHeader(headers, HTTPConstants.HEADER_CONTENT_TYPE);
686
687       if ((returnCode > 199) && (returnCode < 300))
688       {
689          // SOAP return is OK - so fall through
690
}
691       else if (msgContext.getSOAPConstants() ==
692               SOAPConstants.SOAP12_CONSTANTS)
693       {
694          // For now, if we're SOAP 1.2, fall through, since the range of
695
// valid result codes is much greater
696
}
697       else if ((contentType != null) && !contentType.startsWith("text/html")
698               && ((returnCode > 499) && (returnCode < 600)))
699       {
700          // SOAP Fault should be in here - so fall through
701
}
702       else
703       {
704          // Unknown return code - so wrap up the content into a
705
// SOAP Fault.
706
ByteArrayOutputStream JavaDoc buf = new ByteArrayOutputStream JavaDoc(4097);
707
708          while (-1 != (b = (byte)inp.read()))
709          {
710             buf.write(b);
711          }
712          String JavaDoc statusMessage = msgContext.getStrProp(HTTPConstants.MC_HTTP_STATUS_MESSAGE);
713          AxisFault fault = new AxisFault("HTTP", "(" + returnCode + ")" +
714                  statusMessage, null, null);
715
716          fault.setFaultDetailString(Messages.getMessage("return01",
717                  "" + returnCode, buf.toString()));
718          throw fault;
719       }
720
721       String JavaDoc transferEncoding = getFirstTrimmedHeader(headers, HTTPConstants.HEADER_TRANSFER_ENCODING);
722
723       if (HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED.equals(transferEncoding))
724          inp = new ChunkedInputStream(inp);
725
726       InputStream JavaDoc inputStream = new SocketInputStream(inp, sock);
727
728       responseMsg = new Message(inputStream, false, headers);
729       responseMsg.setMessageType(Message.RESPONSE);
730
731       msgContext.setResponseMessage(responseMsg);
732
733       // if we are maintaining session state,
734
// handle cookies (if any)
735
if (msgContext.getMaintainSession())
736       {
737          handleCookie(HTTPConstants.HEADER_COOKIE,
738                  HTTPConstants.HEADER_SET_COOKIE, headers, msgContext);
739          handleCookie(HTTPConstants.HEADER_COOKIE2,
740                  HTTPConstants.HEADER_SET_COOKIE2, headers, msgContext);
741       }
742
743       if (log.isDebugEnabled())
744       {
745          log.debug("XML response received");
746          log.debug("----------------------------------------------");
747          MessagePart msgPart = (MessagePart)responseMsg.getSOAPPart();
748          String JavaDoc xmlMessage = new String JavaDoc(msgPart.getAsBytes());
749          log.debug("----------------------------------------------");
750          log.debug(xmlMessage);
751          log.debug("----------------------------------------------");
752       }
753    }
754
755    /**
756     * little helper function for cookies
757     *
758     * @param cookieName
759     * @param setCookieName
760     * @param headers
761     * @param msgContext
762     */

763    public void handleCookie(String JavaDoc cookieName, String JavaDoc setCookieName, MimeHeaders JavaDoc headers, MessageContext msgContext)
764    {
765
766       String JavaDoc cookie = getFirstTrimmedHeader(headers, setCookieName);
767       if (cookie == null)
768          return;
769
770       // chop after first ; a la Apache SOAP (see HTTPUtils.java there)
771
int index = cookie.indexOf(';');
772
773       if (index != -1)
774       {
775          cookie = cookie.substring(0, index);
776       }
777       msgContext.setProperty(cookieName, cookie);
778    }
779
780    private static String JavaDoc getFirstTrimmedHeader(MimeHeaders JavaDoc headers, String JavaDoc name)
781    {
782       if (headers == null)
783          return null;
784
785       String JavaDoc[] values = headers.getHeader(name);
786       if (values == null)
787          return null;
788
789       return (values[0] == null) ? null : values[0].trim();
790    }
791 }
792
Popular Tags