KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > transport > http > SimpleAxisWorker


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.axis.transport.http;
18
19 import org.apache.axis.AxisFault;
20 import org.apache.axis.Constants;
21 import org.apache.axis.Message;
22 import org.apache.axis.MessageContext;
23 import org.apache.axis.components.logger.LogFactory;
24 import org.apache.axis.description.OperationDesc;
25 import org.apache.axis.description.ServiceDesc;
26 import org.apache.axis.encoding.Base64;
27 import org.apache.axis.message.SOAPEnvelope;
28 import org.apache.axis.message.SOAPFault;
29 import org.apache.axis.server.AxisServer;
30 import org.apache.axis.utils.Messages;
31 import org.apache.axis.utils.XMLUtils;
32 import org.apache.axis.utils.NetworkUtils;
33 import org.apache.commons.logging.Log;
34 import org.w3c.dom.Document JavaDoc;
35
36 import javax.xml.namespace.QName JavaDoc;
37 import javax.xml.soap.MimeHeader JavaDoc;
38 import javax.xml.soap.MimeHeaders JavaDoc;
39 import javax.xml.soap.SOAPMessage JavaDoc;
40
41 import java.io.OutputStream JavaDoc;
42 import java.io.ByteArrayInputStream JavaDoc;
43 import java.net.Socket JavaDoc;
44 import java.util.ArrayList JavaDoc;
45 import java.util.Iterator JavaDoc;
46
47
48 public class SimpleAxisWorker implements Runnable JavaDoc {
49     protected static Log log =
50             LogFactory.getLog(SimpleAxisWorker.class.getName());
51
52     private SimpleAxisServer server;
53     private Socket JavaDoc socket;
54
55     // Axis specific constants
56
private static String JavaDoc transportName = "SimpleHTTP";
57
58     // HTTP status codes
59
private static byte OK[] = ("200 " + Messages.getMessage("ok00")).getBytes();
60     private static byte NOCONTENT[] = ("202 " + Messages.getMessage("ok00") + "\n\n").getBytes();
61     private static byte UNAUTH[] = ("401 " + Messages.getMessage("unauth00")).getBytes();
62     private static byte SENDER[] = "400".getBytes();
63     private static byte ISE[] = ("500 " + Messages.getMessage("internalError01")).getBytes();
64
65     // HTTP prefix
66
private static byte HTTP[] = "HTTP/1.0 ".getBytes();
67
68     // Standard MIME headers for XML payload
69
private static byte XML_MIME_STUFF[] =
70             ("\r\nContent-Type: text/xml; charset=utf-8\r\n" +
71             "Content-Length: ").getBytes();
72
73     // Standard MIME headers for HTML payload
74
private static byte HTML_MIME_STUFF[] =
75             ("\r\nContent-Type: text/html; charset=utf-8\r\n" +
76             "Content-Length: ").getBytes();
77
78     // Mime/Content separator
79
private static byte SEPARATOR[] = "\r\n\r\n".getBytes();
80
81     // Tiddly little response
82
// private static final String responseStr =
83
// "<html><head><title>SimpleAxisServer</title></head>" +
84
// "<body><h1>SimpleAxisServer</h1>" +
85
// Messages.getMessage("reachedServer00") +
86
// "</html>";
87
// private static byte cannedHTMLResponse[] = responseStr.getBytes();
88

89     // ASCII character mapping to lower case
90
private static final byte[] toLower = new byte[256];
91
92     static {
93         for (int i = 0; i < 256; i++) {
94             toLower[i] = (byte) i;
95         }
96
97         for (int lc = 'a'; lc <= 'z'; lc++) {
98             toLower[lc + 'A' - 'a'] = (byte) lc;
99         }
100     }
101
102     // buffer for IO
103
private static final int BUFSIZ = 4096;
104
105     // mime header for content length
106
private static final byte lenHeader[] = "content-length: ".getBytes();
107     private static final int lenLen = lenHeader.length;
108
109     // mime header for content type
110
private static final byte typeHeader[] = (HTTPConstants.HEADER_CONTENT_TYPE.toLowerCase() + ": ").getBytes();
111     private static final int typeLen = typeHeader.length;
112
113     // mime header for content location
114
private static final byte locationHeader[] = (HTTPConstants.HEADER_CONTENT_LOCATION.toLowerCase() + ": ").getBytes();
115     private static final int locationLen = locationHeader.length;
116
117     // mime header for soap action
118
private static final byte actionHeader[] = "soapaction: ".getBytes();
119     private static final int actionLen = actionHeader.length;
120
121     // mime header for cookie
122
private static final byte cookieHeader[] = "cookie: ".getBytes();
123     private static final int cookieLen = cookieHeader.length;
124
125     // mime header for cookie2
126
private static final byte cookie2Header[] = "cookie2: ".getBytes();
127     private static final int cookie2Len = cookie2Header.length;
128
129     // HTTP header for authentication
130
private static final byte authHeader[] = "authorization: ".getBytes();
131     private static final int authLen = authHeader.length;
132
133     // mime header for GET
134
private static final byte getHeader[] = "GET".getBytes();
135
136     // mime header for POST
137
private static final byte postHeader[] = "POST".getBytes();
138
139     // header ender
140
private static final byte headerEnder[] = ": ".getBytes();
141
142     // "Basic" auth string
143
private static final byte basicAuth[] = "basic ".getBytes();
144
145     public SimpleAxisWorker(SimpleAxisServer server, Socket JavaDoc socket) {
146         this.server = server;
147         this.socket = socket;
148     }
149
150     /**
151      * Run method
152      */

153     public void run() {
154         try {
155             execute();
156         } finally {
157             SimpleAxisServer.getPool().workerDone(this, false);
158         }
159     }
160     
161     /**
162      * The main workhorse method.
163      */

164     public void execute () {
165         byte buf[] = new byte[BUFSIZ];
166         // create an Axis server
167
AxisServer engine = server.getAxisServer();
168
169         // create and initialize a message context
170
MessageContext msgContext = new MessageContext(engine);
171         Message requestMsg = null;
172
173         // Reusuable, buffered, content length controlled, InputStream
174
NonBlockingBufferedInputStream is =
175                 new NonBlockingBufferedInputStream();
176
177         // buffers for the headers we care about
178
StringBuffer JavaDoc soapAction = new StringBuffer JavaDoc();
179         StringBuffer JavaDoc httpRequest = new StringBuffer JavaDoc();
180         StringBuffer JavaDoc fileName = new StringBuffer JavaDoc();
181         StringBuffer JavaDoc cookie = new StringBuffer JavaDoc();
182         StringBuffer JavaDoc cookie2 = new StringBuffer JavaDoc();
183         StringBuffer JavaDoc authInfo = new StringBuffer JavaDoc();
184         StringBuffer JavaDoc contentType = new StringBuffer JavaDoc();
185         StringBuffer JavaDoc contentLocation = new StringBuffer JavaDoc();
186
187         Message responseMsg = null;
188
189         // prepare request (do as much as possible while waiting for the
190
// next connection). Note the next two statements are commented
191
// out. Uncomment them if you experience any problems with not
192
// resetting state between requests:
193
// msgContext = new MessageContext();
194
// requestMsg = new Message("", "String");
195
//msgContext.setProperty("transport", "HTTPTransport");
196
msgContext.setTransportName(transportName);
197
198         responseMsg = null;
199
200         try {
201             // assume the best
202
byte[] status = OK;
203
204             // assume we're not getting WSDL
205
boolean doWsdl = false;
206
207             // cookie for this session, if any
208
String JavaDoc cooky = null;
209
210             String JavaDoc methodName = null;
211
212             try {
213                 // wipe cookies if we're doing sessions
214
if (server.isSessionUsed()) {
215                     cookie.delete(0, cookie.length());
216                     cookie2.delete(0, cookie2.length());
217                 }
218                 authInfo.delete(0, authInfo.length());
219
220                 // read headers
221
is.setInputStream(socket.getInputStream());
222                 // parse all headers into hashtable
223
MimeHeaders JavaDoc requestHeaders = new MimeHeaders JavaDoc();
224                 int contentLength = parseHeaders(is, buf, contentType,
225                         contentLocation, soapAction,
226                         httpRequest, fileName,
227                         cookie, cookie2, authInfo, requestHeaders);
228                 is.setContentLength(contentLength);
229
230                 int paramIdx = fileName.toString().indexOf('?');
231                 if (paramIdx != -1) {
232                     // Got params
233
String JavaDoc params = fileName.substring(paramIdx + 1);
234                     fileName.setLength(paramIdx);
235
236                     log.debug(Messages.getMessage("filename00",
237                             fileName.toString()));
238                     log.debug(Messages.getMessage("params00",
239                             params));
240
241                     if ("wsdl".equalsIgnoreCase(params))
242                         doWsdl = true;
243
244                     if (params.startsWith("method=")) {
245                         methodName = params.substring(7);
246                     }
247                 }
248
249                 // Real and relative paths are the same for the
250
// SimpleAxisServer
251
msgContext.setProperty(Constants.MC_REALPATH,
252                         fileName.toString());
253                 msgContext.setProperty(Constants.MC_RELATIVE_PATH,
254                         fileName.toString());
255                 msgContext.setProperty(Constants.MC_JWS_CLASSDIR,
256                         "jwsClasses");
257                 msgContext.setProperty(Constants.MC_HOME_DIR, ".");
258
259                 // !!! Fix string concatenation
260
String JavaDoc url = "http://" + getLocalHost() + ":" +
261                         server.getServerSocket().getLocalPort() + "/" +
262                         fileName.toString();
263                 msgContext.setProperty(MessageContext.TRANS_URL, url);
264
265                 String JavaDoc filePart = fileName.toString();
266                 if (filePart.startsWith("axis/services/")) {
267                     String JavaDoc servicePart = filePart.substring(14);
268                     int separator = servicePart.indexOf('/');
269                     if (separator > -1) {
270                         msgContext.setProperty("objectID",
271                                        servicePart.substring(separator + 1));
272                         servicePart = servicePart.substring(0, separator);
273                     }
274                     msgContext.setTargetService(servicePart);
275                 }
276
277                 if (authInfo.length() > 0) {
278                     // Process authentication info
279
//authInfo = new StringBuffer("dXNlcjE6cGFzczE=");
280
byte[] decoded = Base64.decode(authInfo.toString());
281                     StringBuffer JavaDoc userBuf = new StringBuffer JavaDoc();
282                     StringBuffer JavaDoc pwBuf = new StringBuffer JavaDoc();
283                     StringBuffer JavaDoc authBuf = userBuf;
284                     for (int i = 0; i < decoded.length; i++) {
285                         if ((char) (decoded[i] & 0x7f) == ':') {
286                             authBuf = pwBuf;
287                             continue;
288                         }
289                         authBuf.append((char) (decoded[i] & 0x7f));
290                     }
291
292                     if (log.isDebugEnabled()) {
293                         log.debug(Messages.getMessage("user00",
294                                 userBuf.toString()));
295                     }
296
297                     msgContext.setUsername(userBuf.toString());
298                     msgContext.setPassword(pwBuf.toString());
299                 }
300
301                 // if get, then return simpleton document as response
302
if (httpRequest.toString().equals("GET")) {
303                     
304                     OutputStream JavaDoc out = socket.getOutputStream();
305                     out.write(HTTP);
306                     if(fileName.length()==0) {
307                         out.write("301 Redirect\nLocation: /axis/\n\n".getBytes());
308                         out.flush();
309                         return;
310                     }
311                     out.write(status);
312
313                     if (methodName != null) {
314                         String JavaDoc body =
315                             "<" + methodName + ">" +
316 // args +
317
"</" + methodName + ">";
318                         String JavaDoc msgtxt =
319                             "<SOAP-ENV:Envelope" +
320                             " xmlns:SOAP-ENV=\"" + Constants.URI_SOAP12_ENV + "\">" +
321                             "<SOAP-ENV:Body>" + body + "</SOAP-ENV:Body>" +
322                             "</SOAP-ENV:Envelope>";
323
324                         ByteArrayInputStream JavaDoc istream =
325                             new ByteArrayInputStream JavaDoc(msgtxt.getBytes());
326                         requestMsg = new Message(istream);
327                     } else if (doWsdl) {
328                         engine.generateWSDL(msgContext);
329
330                         Document JavaDoc doc = (Document JavaDoc) msgContext.getProperty("WSDL");
331                         if (doc != null) {
332                             XMLUtils.normalize(doc.getDocumentElement());
333                             String JavaDoc response = XMLUtils.PrettyDocumentToString(doc);
334                             byte[] respBytes = response.getBytes();
335
336                             out.write(XML_MIME_STUFF);
337                             putInt(buf, out, respBytes.length);
338                             out.write(SEPARATOR);
339                             out.write(respBytes);
340                             out.flush();
341                             return;
342                         }
343                     } else {
344                         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
345                         sb.append("<h2>And now... Some Services</h2>\n");
346                         Iterator JavaDoc i = engine.getConfig().getDeployedServices();
347                         sb.append("<ul>\n");
348                         while (i.hasNext()) {
349                             ServiceDesc sd = (ServiceDesc)i.next();
350                             sb.append("<li>\n");
351                             sb.append(sd.getName());
352                             sb.append(" <a HREF=\"services/");
353                             sb.append(sd.getName());
354                             sb.append("?wsdl\"><i>(wsdl)</i></a></li>\n");
355                             ArrayList JavaDoc operations = sd.getOperations();
356                             if (!operations.isEmpty()) {
357                                 sb.append("<ul>\n");
358                                 for (Iterator JavaDoc it = operations.iterator(); it.hasNext();) {
359                                     OperationDesc desc = (OperationDesc) it.next();
360                                     sb.append("<li>" + desc.getName());
361                                 }
362                                 sb.append("</ul>\n");
363                             }
364                         }
365                         sb.append("</ul>\n");
366
367                         byte [] bytes = sb.toString().getBytes();
368
369                         out.write(HTML_MIME_STUFF);
370                         putInt(buf, out, bytes.length);
371                         out.write(SEPARATOR);
372                         out.write(bytes);
373                         out.flush();
374                         return;
375                     }
376                 } else {
377
378                     // this may be "" if either SOAPAction: "" or if no SOAPAction at all.
379
// for now, do not complain if no SOAPAction at all
380
String JavaDoc soapActionString = soapAction.toString();
381                     if (soapActionString != null) {
382                         msgContext.setUseSOAPAction(true);
383                         msgContext.setSOAPActionURI(soapActionString);
384                     }
385                     requestMsg = new Message(is,
386                             false,
387                             contentType.toString(),
388                             contentLocation.toString()
389                     );
390                 }
391
392                 // Transfer HTTP headers to MIME headers for request message.
393
MimeHeaders JavaDoc requestMimeHeaders = requestMsg.getMimeHeaders();
394                 for (Iterator JavaDoc i = requestHeaders.getAllHeaders(); i.hasNext(); ) {
395                     MimeHeader JavaDoc requestHeader = (MimeHeader JavaDoc) i.next();
396                     requestMimeHeaders.addHeader(requestHeader.getName(), requestHeader.getValue());
397                 }
398                 msgContext.setRequestMessage(requestMsg);
399                 // put character encoding of request to message context
400
// in order to reuse it during the whole process.
401
String JavaDoc requestEncoding = (String JavaDoc) requestMsg.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
402                 if (requestEncoding != null) {
403                     msgContext.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, requestEncoding);
404                 }
405
406                 // set up session, if any
407
if (server.isSessionUsed()) {
408                     // did we get a cookie?
409
if (cookie.length() > 0) {
410                         cooky = cookie.toString().trim();
411                     } else if (cookie2.length() > 0) {
412                         cooky = cookie2.toString().trim();
413                     }
414
415                     // if cooky is null, cook up a cooky
416
if (cooky == null) {
417                         // fake one up!
418
// make it be an arbitrarily increasing number
419
// (no this is not thread safe because ++ isn't atomic)
420
int i = SimpleAxisServer.sessionIndex++;
421                         cooky = "" + i;
422                     }
423
424                     msgContext.setSession(server.createSession(cooky));
425                 }
426
427                 // invoke the Axis engine
428
engine.invoke(msgContext);
429
430                 // Retrieve the response from Axis
431
responseMsg = msgContext.getResponseMessage();
432                 
433                 if (responseMsg == null) {
434                     status = NOCONTENT;
435                 }
436             } catch (Exception JavaDoc e) {
437                 AxisFault af;
438                 if (e instanceof AxisFault) {
439                     af = (AxisFault) e;
440                     log.debug(Messages.getMessage("serverFault00"), af);
441                     QName JavaDoc faultCode = af.getFaultCode();
442                     if (Constants.FAULT_SOAP12_SENDER.equals(faultCode)) {
443                         status = SENDER;
444                     } else if ("Server.Unauthorized".equals(af.getFaultCode().getLocalPart())) {
445                         status = UNAUTH; // SC_UNAUTHORIZED
446
} else {
447                         status = ISE; // SC_INTERNAL_SERVER_ERROR
448
}
449                 } else {
450                     status = ISE; // SC_INTERNAL_SERVER_ERROR
451
af = AxisFault.makeFault(e);
452                 }
453
454                 // There may be headers we want to preserve in the
455
// response message - so if it's there, just add the
456
// FaultElement to it. Otherwise, make a new one.
457
responseMsg = msgContext.getResponseMessage();
458                 if (responseMsg == null) {
459                     responseMsg = new Message(af);
460                     responseMsg.setMessageContext(msgContext);
461                 } else {
462                     try {
463                         SOAPEnvelope env = responseMsg.getSOAPEnvelope();
464                         env.clearBody();
465                         env.addBodyElement(new SOAPFault((AxisFault) e));
466                     } catch (AxisFault fault) {
467                         // Should never reach here!
468
}
469                 }
470             }
471
472             // synchronize the character encoding of request and response
473
String JavaDoc responseEncoding = (String JavaDoc) msgContext.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
474             if (responseEncoding != null && responseMsg != null) {
475                 responseMsg.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, responseEncoding);
476             }
477             // Send it on its way...
478
OutputStream JavaDoc out = socket.getOutputStream();
479             out.write(HTTP);
480             out.write(status);
481
482             if (responseMsg != null) {
483                 if (server.isSessionUsed() && null != cooky &&
484                         0 != cooky.trim().length()) {
485                     // write cookie headers, if any
486
// don't sweat efficiency *too* badly
487
// optimize at will
488
StringBuffer JavaDoc cookieOut = new StringBuffer JavaDoc();
489                     cookieOut.append("\r\nSet-Cookie: ")
490                             .append(cooky)
491                             .append("\r\nSet-Cookie2: ")
492                             .append(cooky);
493                     // OH, THE HUMILITY! yes this is inefficient.
494
out.write(cookieOut.toString().getBytes());
495                 }
496
497                 //out.write(XML_MIME_STUFF);
498
out.write(("\r\n" + HTTPConstants.HEADER_CONTENT_TYPE + ": " + responseMsg.getContentType(msgContext.getSOAPConstants())).getBytes());
499                 // Writing the length causes the entire message to be decoded twice.
500
//out.write(("\r\n" + HTTPConstants.HEADER_CONTENT_LENGTH + ": " + responseMsg.getContentLength()).getBytes());
501
// putInt(out, response.length);
502

503                 // Transfer MIME headers to HTTP headers for response message.
504
for (Iterator JavaDoc i = responseMsg.getMimeHeaders().getAllHeaders(); i.hasNext(); ) {
505                     MimeHeader JavaDoc responseHeader = (MimeHeader JavaDoc) i.next();
506                     out.write('\r');
507                     out.write('\n');
508                     out.write(responseHeader.getName().getBytes());
509                     out.write(headerEnder);
510                     out.write(responseHeader.getValue().getBytes());
511                 }
512
513                 out.write(SEPARATOR);
514                 responseMsg.writeTo(out);
515             }
516
517             // out.write(response);
518
out.flush();
519         } catch (Exception JavaDoc e) {
520             log.info(Messages.getMessage("exception00"), e);
521         } finally {
522             try {
523                 if (socket != null) socket.close();
524             } catch (Exception JavaDoc e) {
525             }
526         }
527         if (msgContext.getProperty(MessageContext.QUIT_REQUESTED) != null) {
528             // why then, quit!
529
try {
530                 server.stop();
531             } catch (Exception JavaDoc e) {
532             }
533         }
534
535     }
536
537     protected void invokeMethodFromGet(String JavaDoc methodName, String JavaDoc args) throws Exception JavaDoc {
538
539     }
540
541     /**
542      * Read all mime headers, returning the value of Content-Length and
543      * SOAPAction.
544      * @param is InputStream to read from
545      * @param contentType The content type.
546      * @param contentLocation The content location
547      * @param soapAction StringBuffer to return the soapAction into
548      * @param httpRequest StringBuffer for GET / POST
549      * @param cookie first cookie header (if doSessions)
550      * @param cookie2 second cookie header (if doSessions)
551      * @param headers HTTP headers to transfer to MIME headers
552      * @return Content-Length
553      */

554     private int parseHeaders(NonBlockingBufferedInputStream is,
555                              byte buf[],
556                              StringBuffer JavaDoc contentType,
557                              StringBuffer JavaDoc contentLocation,
558                              StringBuffer JavaDoc soapAction,
559                              StringBuffer JavaDoc httpRequest,
560                              StringBuffer JavaDoc fileName,
561                              StringBuffer JavaDoc cookie,
562                              StringBuffer JavaDoc cookie2,
563                              StringBuffer JavaDoc authInfo,
564                              MimeHeaders JavaDoc headers)
565             throws java.io.IOException JavaDoc {
566         int n;
567         int len = 0;
568
569         // parse first line as GET or POST
570
n = this.readLine(is, buf, 0, buf.length);
571         if (n < 0) {
572             // nothing!
573
throw new java.io.IOException JavaDoc(Messages.getMessage("unexpectedEOS00"));
574         }
575
576         // which does it begin with?
577
httpRequest.delete(0, httpRequest.length());
578         fileName.delete(0, fileName.length());
579         contentType.delete(0, contentType.length());
580         contentLocation.delete(0, contentLocation.length());
581
582         if (buf[0] == getHeader[0]) {
583             httpRequest.append("GET");
584             for (int i = 0; i < n - 5; i++) {
585                 char c = (char) (buf[i + 5] & 0x7f);
586                 if (c == ' ')
587                     break;
588                 fileName.append(c);
589             }
590             log.debug(Messages.getMessage("filename01", "SimpleAxisServer", fileName.toString()));
591             return 0;
592         } else if (buf[0] == postHeader[0]) {
593             httpRequest.append("POST");
594             for (int i = 0; i < n - 6; i++) {
595                 char c = (char) (buf[i + 6] & 0x7f);
596                 if (c == ' ')
597                     break;
598                 fileName.append(c);
599             }
600             log.debug(Messages.getMessage("filename01", "SimpleAxisServer", fileName.toString()));
601         } else {
602             throw new java.io.IOException JavaDoc(Messages.getMessage("badRequest00"));
603         }
604
605         while ((n = readLine(is, buf, 0, buf.length)) > 0) {
606
607             if ((n <= 2) && (buf[0] == '\n' || buf[0] == '\r') && (len > 0)) break;
608
609             // RobJ gutted the previous logic; it was too hard to extend for more headers.
610
// Now, all it does is search forwards for ": " in the buf,
611
// then do a length / byte compare.
612
// Hopefully this is still somewhat efficient (Sam is watching!).
613

614             // First, search forwards for ": "
615
int endHeaderIndex = 0;
616             while (endHeaderIndex < n && toLower[buf[endHeaderIndex]] != headerEnder[0]) {
617                 endHeaderIndex++;
618             }
619             endHeaderIndex += 2;
620             // endHeaderIndex now points _just past_ the ": ", and is
621
// comparable to the various lenLen, actionLen, etc. values
622

623             // convenience; i gets pre-incremented, so initialize it to one less
624
int i = endHeaderIndex - 1;
625
626             // which header did we find?
627
if (endHeaderIndex == lenLen && matches(buf, lenHeader)) {
628                 // parse content length
629

630                 while ((++i < n) && (buf[i] >= '0') && (buf[i] <= '9')) {
631                     len = (len * 10) + (buf[i] - '0');
632                 }
633                 headers.addHeader(HTTPConstants.HEADER_CONTENT_LENGTH, String.valueOf(len));
634
635             } else if (endHeaderIndex == actionLen
636                     && matches(buf, actionHeader)) {
637
638                 soapAction.delete(0, soapAction.length());
639                 // skip initial '"'
640
i++;
641                 while ((++i < n) && (buf[i] != '"')) {
642                     soapAction.append((char) (buf[i] & 0x7f));
643                 }
644                 headers.addHeader(HTTPConstants.HEADER_SOAP_ACTION, "\"" + soapAction.toString() + "\"");
645
646             } else if (server.isSessionUsed() && endHeaderIndex == cookieLen
647                     && matches(buf, cookieHeader)) {
648
649                 // keep everything up to first ;
650
while ((++i < n) && (buf[i] != ';') && (buf[i] != '\r') && (buf[i] != '\n')) {
651                     cookie.append((char) (buf[i] & 0x7f));
652                 }
653                 headers.addHeader("Set-Cookie", cookie.toString());
654
655             } else if (server.isSessionUsed() && endHeaderIndex == cookie2Len
656                     && matches(buf, cookie2Header)) {
657
658                 // keep everything up to first ;
659
while ((++i < n) && (buf[i] != ';') && (buf[i] != '\r') && (buf[i] != '\n')) {
660                     cookie2.append((char) (buf[i] & 0x7f));
661                 }
662                 headers.addHeader("Set-Cookie2", cookie.toString());
663
664             } else if (endHeaderIndex == authLen && matches(buf, authHeader)) {
665                 if (matches(buf, endHeaderIndex, basicAuth)) {
666                     i += basicAuth.length;
667                     while (++i < n && (buf[i] != '\r') && (buf[i] != '\n')) {
668                         if (buf[i] == ' ') continue;
669                         authInfo.append((char) (buf[i] & 0x7f));
670                     }
671                     headers.addHeader(HTTPConstants.HEADER_AUTHORIZATION, new String JavaDoc(basicAuth) + authInfo.toString());
672                 } else {
673                     throw new java.io.IOException JavaDoc(
674                             Messages.getMessage("badAuth00"));
675                 }
676             } else if (endHeaderIndex == locationLen && matches(buf, locationHeader)) {
677                 while (++i < n && (buf[i] != '\r') && (buf[i] != '\n')) {
678                     if (buf[i] == ' ') continue;
679                     contentLocation.append((char) (buf[i] & 0x7f));
680                 }
681                 headers.addHeader(HTTPConstants.HEADER_CONTENT_LOCATION, contentLocation.toString());
682             } else if (endHeaderIndex == typeLen && matches(buf, typeHeader)) {
683                 while (++i < n && (buf[i] != '\r') && (buf[i] != '\n')) {
684                     if (buf[i] == ' ') continue;
685                     contentType.append((char) (buf[i] & 0x7f));
686                 }
687                 headers.addHeader(HTTPConstants.HEADER_CONTENT_TYPE, contentLocation.toString());
688             } else {
689                 String JavaDoc customHeaderName = new String JavaDoc(buf, 0, endHeaderIndex - 2);
690                 StringBuffer JavaDoc customHeaderValue = new StringBuffer JavaDoc();
691                 while (++i < n && (buf[i] != '\r') && (buf[i] != '\n')) {
692                     if (buf[i] == ' ') continue;
693                     customHeaderValue.append((char) (buf[i] & 0x7f));
694                 }
695                 headers.addHeader(customHeaderName, customHeaderValue.toString());
696             }
697
698         }
699         return len;
700     }
701
702     /**
703      * does tolower[buf] match the target byte array, up to the target's length?
704      */

705     public boolean matches(byte[] buf, byte[] target) {
706         for (int i = 0; i < target.length; i++) {
707             if (toLower[buf[i]] != target[i]) {
708                 return false;
709             }
710         }
711         return true;
712     }
713
714     /**
715      * Case-insensitive match of a target byte [] to a source byte [],
716      * starting from a particular offset into the source.
717      */

718     public boolean matches(byte[] buf, int bufIdx, byte[] target) {
719         for (int i = 0; i < target.length; i++) {
720             if (toLower[buf[bufIdx + i]] != target[i]) {
721                 return false;
722             }
723         }
724         return true;
725     }
726
727     /**
728      * output an integer into the output stream
729      * @param out OutputStream to be written to
730      * @param value Integer value to be written.
731      */

732     private void putInt(byte buf[], OutputStream JavaDoc out, int value)
733             throws java.io.IOException JavaDoc {
734         int len = 0;
735         int offset = buf.length;
736
737         // negative numbers
738
if (value < 0) {
739             buf[--offset] = (byte) '-';
740             value = -value;
741             len++;
742         }
743
744         // zero
745
if (value == 0) {
746             buf[--offset] = (byte) '0';
747             len++;
748         }
749
750         // positive numbers
751
while (value > 0) {
752             buf[--offset] = (byte) (value % 10 + '0');
753             value = value / 10;
754             len++;
755         }
756
757         // write the result
758
out.write(buf, offset, len);
759     }
760
761     /**
762      * Read a single line from the input stream
763      * @param is inputstream to read from
764      * @param b byte array to read into
765      * @param off starting offset into the byte array
766      * @param len maximum number of bytes to read
767      */

768     private int readLine(NonBlockingBufferedInputStream is, byte[] b, int off, int len)
769             throws java.io.IOException JavaDoc {
770         int count = 0, c;
771
772         while ((c = is.read()) != -1) {
773             if (c != '\n' && c != '\r') {
774                 b[off++] = (byte) c;
775                 count++;
776             }
777             if (count == len) break;
778             if ('\n' == c) {
779                 int peek = is.peek(); //If the next line begins with tab or space then this is a continuation.
780
if (peek != ' ' && peek != '\t') break;
781             }
782         }
783         return count > 0 ? count : -1;
784     }
785
786     /**
787      * One method for all host name lookups.
788      */

789     public static String JavaDoc getLocalHost() {
790         return NetworkUtils.getLocalHostname();
791     }
792 }
793
Popular Tags