e.g. Calendar Search Help
You must enter a value before pressing Search
tomcat

Class: org.apache.jk.common.HandlerRequest   ©

 OK to copy?
001 /*
002  *  Copyright 1999-2004 The Apache Software Foundation
003  *
004  *  Licensed under the Apache License, Version 2.0 (the "License");
005  *  you may not use this file except in compliance with the License.
006  *  You may obtain a copy of the License at
007  *
008  *      http://www.apache.org/licenses/LICENSE-2.0
009  *
010  *  Unless required by applicable law or agreed to in writing, software
011  *  distributed under the License is distributed on an "AS IS" BASIS,
012  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013  *  See the License for the specific language governing permissions and
014  *  limitations under the License.
015  */
016 
017 package org.apache.jk.common;
018 
019 import java.io.File;
020 import java.io.FileOutputStream;
021 import java.io.IOException;
022 import java.io.CharConversionException;
023 import java.net.InetAddress;
024 import java.util.Properties;
025 import javax.management.ObjectName;
026 
027 import org.apache.commons.modeler.Registry;
028 import org.apache.coyote.Request;
029 import org.apache.coyote.RequestGroupInfo;
030 import org.apache.coyote.RequestInfo;
031 import org.apache.coyote.Response;
032 import org.apache.coyote.Constants;
033 import org.apache.jk.core.JkHandler;
034 import org.apache.jk.core.Msg;
035 import org.apache.jk.core.MsgContext;
036 import org.apache.jk.core.WorkerEnv;
037 import org.apache.jk.core.JkChannel;
038 import org.apache.tomcat.util.buf.ByteChunk;
039 import org.apache.tomcat.util.buf.CharChunk;
040 import org.apache.tomcat.util.buf.HexUtils;
041 import org.apache.tomcat.util.buf.MessageBytes;
042 import org.apache.tomcat.util.http.MimeHeaders;
043 import org.apache.tomcat.util.net.SSLSupport;
044 import org.apache.tomcat.util.threads.ThreadWithAttributes;
045 
046 /**
047  * Handle messages related with basic request information.
048  *
049  * This object can handle the following incoming messages:
050  * - "FORWARD_REQUEST" input message ( sent when a request is passed from the
051  *   web server )
052  * - "RECEIVE_BODY_CHUNK" input ( sent by container to pass more body, in
053  *   response to GET_BODY_CHUNK )
054  *
055  * It can handle the following outgoing messages:
056  * - SEND_HEADERS. Pass the status code and headers.
057  * - SEND_BODY_CHUNK. Send a chunk of body
058  * - GET_BODY_CHUNK. Request a chunk of body data
059  * - END_RESPONSE. Notify the end of a request processing.
060  *
061  * @author Henri Gomez [hgomez@apache.org]
062  * @author Dan Milstein [danmil@shore.net]
063  * @author Keith Wannamaker [Keith@Wannamaker.org]
064  * @author Costin Manolache
065  */
066 public class HandlerRequest extends JkHandler
067 {
068     private static org.apache.commons.logging.Log log=
069         org.apache.commons.logging.LogFactory.getLog( HandlerRequest.class );
070 
071     // XXX Will move to a registry system.
072     
073     // Prefix codes for message types from server to container
074     public static final byte JK_AJP13_FORWARD_REQUEST   = 2;
075         public static final byte JK_AJP13_SHUTDOWN          = 7;
076         public static final byte JK_AJP13_PING_REQUEST      = 8;
077         public static final byte JK_AJP13_CPING_REQUEST     = 10;
078 
079     // Prefix codes for message types from container to server
080     public static final byte JK_AJP13_SEND_BODY_CHUNK   = 3;
081     public static final byte JK_AJP13_SEND_HEADERS      = 4;
082     public static final byte JK_AJP13_END_RESPONSE      = 5;
083         public static final byte JK_AJP13_GET_BODY_CHUNK    = 6;
084         public static final byte JK_AJP13_CPONG_REPLY       = 9;
085     
086     // Integer codes for common response header strings
087     public static final int SC_RESP_CONTENT_TYPE        = 0xA001;
088     public static final int SC_RESP_CONTENT_LANGUAGE    = 0xA002;
089     public static final int SC_RESP_CONTENT_LENGTH      = 0xA003;
090     public static final int SC_RESP_DATE                = 0xA004;
091     public static final int SC_RESP_LAST_MODIFIED       = 0xA005;
092     public static final int SC_RESP_LOCATION            = 0xA006;
093     public static final int SC_RESP_SET_COOKIE          = 0xA007;
094     public static final int SC_RESP_SET_COOKIE2         = 0xA008;
095     public static final int SC_RESP_SERVLET_ENGINE      = 0xA009;
096     public static final int SC_RESP_STATUS              = 0xA00A;
097     public static final int SC_RESP_WWW_AUTHENTICATE    = 0xA00B;
098         
099     // Integer codes for common (optional) request attribute names
100     public static final byte SC_A_CONTEXT       = 1;  // XXX Unused
101     public static final byte SC_A_SERVLET_PATH  = 2;  // XXX Unused
102     public static final byte SC_A_REMOTE_USER   = 3;
103     public static final byte SC_A_AUTH_TYPE     = 4;
104     public static final byte SC_A_QUERY_STRING  = 5;
105     public static final byte SC_A_JVM_ROUTE     = 6;
106     public static final byte SC_A_SSL_CERT      = 7;
107     public static final byte SC_A_SSL_CIPHER    = 8;
108     public static final byte SC_A_SSL_SESSION   = 9;
109     public static final byte SC_A_SSL_KEYSIZE   = 11;
110     public static final byte SC_A_SECRET        = 12;
111     public static final byte SC_A_STORED_METHOD = 13;
112 
113     // Used for attributes which are not in the list above
114     public static final byte SC_A_REQ_ATTRIBUTE = 10; 
115 
116     // Terminates list of attributes
117     public static final byte SC_A_ARE_DONE      = (byte)0xFF;
118     
119     // Translates integer codes to names of HTTP methods
120     public static final String []methodTransArray = {
121         "OPTIONS",
122         "GET",
123         "HEAD",
124         "POST",
125         "PUT",
126         "DELETE",
127         "TRACE",
128         "PROPFIND",
129         "PROPPATCH",
130         "MKCOL",
131         "COPY",
132         "MOVE",
133         "LOCK",
134         "UNLOCK",
135         "ACL",
136         "REPORT",
137         "VERSION-CONTROL",
138         "CHECKIN",
139         "CHECKOUT",
140         "UNCHECKOUT",
141         "SEARCH",
142         "MKWORKSPACE",
143         "UPDATE",
144         "LABEL",
145         "MERGE",
146         "BASELINE-CONTROL",
147         "MKACTIVITY"
148     };
149     public static final int SC_M_JK_STORED = (byte) 0xFF;
150     
151     // id's for common request headers
152     public static final int SC_REQ_ACCEPT          = 1;
153     public static final int SC_REQ_ACCEPT_CHARSET  = 2;
154     public static final int SC_REQ_ACCEPT_ENCODING = 3;
155     public static final int SC_REQ_ACCEPT_LANGUAGE = 4;
156     public static final int SC_REQ_AUTHORIZATION   = 5;
157     public static final int SC_REQ_CONNECTION      = 6;
158     public static final int SC_REQ_CONTENT_TYPE    = 7;
159     public static final int SC_REQ_CONTENT_LENGTH  = 8;
160     public static final int SC_REQ_COOKIE          = 9;
161     public static final int SC_REQ_COOKIE2         = 10;
162     public static final int SC_REQ_HOST            = 11;
163     public static final int SC_REQ_PRAGMA          = 12;
164     public static final int SC_REQ_REFERER         = 13;
165     public static final int SC_REQ_USER_AGENT      = 14;
166     // AJP14 new header
167     public static final byte SC_A_SSL_KEY_SIZE  = 11; // XXX ??? 
168 
169     // Translates integer codes to request header names    
170     public static final String []headerTransArray = {
171         "accept",
172         "accept-charset",
173         "accept-encoding",
174         "accept-language",
175         "authorization",
176         "connection",
177         "content-type",
178         "content-length",
179         "cookie",
180         "cookie2",
181         "host",
182         "pragma",
183         "referer",
184         "user-agent"
185     };
186 
187     /*
188      * Note for Host parsing.
189      */
190     public static final int HOSTBUFFER = 10;
191 
192     HandlerDispatch dispatch;
193     String ajpidDir="conf";
194     
195 
196     public HandlerRequest() 
197     {
198     }
199 
200     public void init() {
201         dispatch=(HandlerDispatch)wEnv.getHandler( "dispatch" );
202         if( dispatch != null ) {
203             // register incoming message handlers
204             dispatch.registerMessageType( JK_AJP13_FORWARD_REQUEST,
205                                           "JK_AJP13_FORWARD_REQUEST",
206                                           this, null); // 2
207             
208             dispatch.registerMessageType( JK_AJP13_SHUTDOWN,
209                                           "JK_AJP13_SHUTDOWN",
210                                           this, null); // 7
211             
212             dispatch.registerMessageType( JK_AJP13_CPING_REQUEST,
213                                           "JK_AJP13_CPING_REQUEST",
214                                            this, null); // 10
215             dispatch.registerMessageType( HANDLE_THREAD_END,
216                                          "HANDLE_THREAD_END",
217                                          this, null);
218             // register outgoing messages handler
219             dispatch.registerMessageType( JK_AJP13_SEND_BODY_CHUNK, // 3
220                                           "JK_AJP13_SEND_BODY_CHUNK",
221                                           this,null );
222         }
223 
224         bodyNote=wEnv.getNoteId( WorkerEnv.ENDPOINT_NOTE, "jkInputStream" );
225         tmpBufNote=wEnv.getNoteId( WorkerEnv.ENDPOINT_NOTE, "tmpBuf" );
226         secretNote=wEnv.getNoteId( WorkerEnv.ENDPOINT_NOTE, "secret" );
227 
228         if( next==null )
229             next=wEnv.getHandler( "container" );
230         if( log.isDebugEnabled() )
231             log.debug( "Container handler " + next + " " + next.getName() +
232                        " " + next.getClass().getName());
233 
234         // should happen on start()
235         generateAjp13Id();
236     }
237 
238     public void setSecret( String s ) {
239         requiredSecret=s;
240     }
241 
242     public void setUseSecret( boolean b ) {
243         requiredSecret=Double.toString(Math.random());
244     }
245 
246     public void setDecodedUri( boolean b ) {
247         decoded=b;
248     }
249 
250     public boolean isTomcatAuthentication() {
251         return tomcatAuthentication;
252     }
253 
254     public void setTomcatAuthentication(boolean newTomcatAuthentication) {
255         tomcatAuthentication = newTomcatAuthentication;
256     }
257     
258     public void setAjpidDir( String path ) {
259         if( "".equals( path ) ) path=null;
260         ajpidDir=path;
261     }
262 
263     /**
264      * Set the flag to tell if we JMX register requests.
265      */
266     public void setRegisterRequests(boolean srr) {
267         registerRequests = srr;
268     }
269 
270     /**
271      * Get the flag to tell if we JMX register requests.
272      */
273     public boolean getRegisterRequests() {
274         return registerRequests;
275     }
276 
277     // -------------------- Ajp13.id --------------------
278 
279     private void generateAjp13Id() {
280         int portInt=8009; // tcpCon.getPort();
281         InetAddress address=null; // tcpCon.getAddress();
282 
283         if( requiredSecret == null )
284             return;
285         
286         File f1=new File( wEnv.getJkHome() );
287         File f2=new File( f1, "conf" );
288         
289         if( ! f2.exists() ) {
290             log.error( "No conf dir for ajp13.id " + f2 );
291             return;
292         }
293         
294         File sf=new File( f2, "ajp13.id");
295         
296         if( log.isDebugEnabled())
297             log.debug( "Using stop file: "+sf);
298 
299         try {
300             Properties props=new Properties();
301 
302             props.put( "port", Integer.toString( portInt ));
303             if( address!=null ) {
304                 props.put( "address", address.getHostAddress() );
305             }
306             if( requiredSecret !=null ) {
307                 props.put( "secret", requiredSecret );
308             }
309 
310             FileOutputStream stopF=new FileOutputStream( sf );
Rate311             props.save( stopF, "Automatically generated, don't edit" );
312         } catch( IOException ex ) {
313             log.debug( "Can't create stop file: "+sf );
314             ex.printStackTrace();
315         }
316     }
317     
318     // -------------------- Incoming message --------------------
319     String requiredSecret=null;
320     int bodyNote;
321     int tmpBufNote;
322     int secretNote;
323 
324     boolean decoded=true;
325     boolean tomcatAuthentication=true;
326     boolean registerRequests=true;
327     
328     public int invoke(Msg msg, MsgContext ep ) 
329         throws IOException
330     {
331         int type=msg.getByte();
332         ThreadWithAttributes twa = null;
333         if (Thread.currentThread() instanceof ThreadWithAttributes) {
334             twa = (ThreadWithAttributes) Thread.currentThread();
335         }
336         Object control=ep.getControl();
337 
338         MessageBytes tmpMB=(MessageBytes)ep.getNote( tmpBufNote );
339         if( tmpMB==null ) {
340             tmpMB=new MessageBytes();
341             ep.setNote( tmpBufNote, tmpMB);
342         }
343         if( log.isDebugEnabled() )
344             log.debug( "Handling " + type );
345         
346         switch( type ) {
347         case JK_AJP13_FORWARD_REQUEST:
348             try {
349                 if (twa != null) {
350                     twa.setCurrentStage(control, "JkDecode");
351                 }
352                 decodeRequest( msg, ep, tmpMB );
353                 if (twa != null) {
354                     twa.setCurrentStage(control, "JkService");
355                     twa.setParam(control,
356                                  ((Request)ep.getRequest()).unparsedURI());
357                 }
358             } catch( Exception ex ) {
359                 log.error( "Error decoding request ", ex );
360                 msg.dump( "Incomming message");
361                 return ERROR;
362             }
363 
364             if( requiredSecret != null ) {
365                 String epSecret=(String)ep.getNote( secretNote );
366                 if( epSecret==null || ! requiredSecret.equals( epSecret ) )
367                     return ERROR;
368             }
369             /* XXX it should be computed from request, by workerEnv */
370             if(log.isDebugEnabled() )
371                 log.debug("Calling next " + next.getName() + " " +
372                   next.getClass().getName());
373 
374             int err= next.invoke( msg, ep );
375             if (twa != null) {
376                 twa.setCurrentStage(control, "JkDone");
377             }
378 
379             if( log.isDebugEnabled() )
380                 log.debug( "Invoke returned " + err );
381             return err;
382         case JK_AJP13_SHUTDOWN:
383             String epSecret=null;
384             if( msg.getLen() > 3 ) {
385                 // we have a secret
386                 msg.getBytes( tmpMB );
387                 epSecret=tmpMB.toString();
388             }
389             
390             if( requiredSecret != null &&
391                 requiredSecret.equals( epSecret ) ) {
392                 if( log.isDebugEnabled() )
393                     log.debug("Received wrong secret, no shutdown ");
394                 return ERROR;
395             }
396 
397             // XXX add isSameAddress check
398             JkChannel ch=ep.getSource();
399         if( !ch.isSameAddress(ep) ) {
400         log.error("Shutdown request not from 'same address' ");
401         return ERROR;
402         }
403 
404             // forward to the default handler - it'll do the shutdown
405             next.invoke( msg, ep );
406 
407             log.info("Exiting");
408             System.exit(0);
409             
410             return OK;
411 
412             // We got a PING REQUEST, quickly respond with a PONG
413         case JK_AJP13_CPING_REQUEST:
414             msg.reset();
415             msg.appendByte(JK_AJP13_CPONG_REPLY);
416             ep.setType( JkHandler.HANDLE_SEND_PACKET );
417             ep.getSource().send( msg, ep );
418         return OK;
419 
420         case HANDLE_THREAD_END:
421             return OK;
422 
423         default:
424             log.info("Unknown message " + type);
425         }
426 
427         return OK;
428     }
429 
430     static int count = 0;
431 
432     private int decodeRequest( Msg msg, MsgContext ep, MessageBytes tmpMB )
433         throws IOException
434     {
435         // FORWARD_REQUEST handler
436         Request req=(Request)ep.getRequest();
437         if( req==null ) {
438             req=new Request();
439             Response res=new Response();
440             req.setResponse(res);
441             ep.setRequest( req );
442             if( registerRequests ) {
443         ep.getSource().registerRequest(req, ep, count++);
444             }
445         }
446 
447     RequestInfo rp = req.getRequestProcessor();
448     rp.setStage(Constants.STAGE_PARSE);
449         MessageBytes tmpMB2 = (MessageBytes)req.getNote(WorkerEnv.SSL_CERT_NOTE);
450         if(tmpMB2 != null) {
451             tmpMB2.recycle();
452         }
453         req.setStartTime(System.currentTimeMillis());
454         JkInputStream jkBody=(JkInputStream)ep.getNote( bodyNote );
455         if( jkBody==null ) {
456             jkBody=new JkInputStream();
457             jkBody.setMsgContext( ep );
458 
459             ep.setNote( bodyNote, jkBody );
460         }
461 
462         jkBody.recycle();
463         
464         // Translate the HTTP method code to a String.
465         byte methodCode = msg.getByte();
466         if (methodCode != SC_M_JK_STORED) {
467             String mName=methodTransArray[(int)methodCode - 1];
468             req.method().setString(mName);
469         }
470 
471         msg.getBytes(req.protocol()); 
472         msg.getBytes(req.requestURI());
473 
474         msg.getBytes(req.remoteAddr());
475         msg.getBytes(req.remoteHost());
476         msg.getBytes(req.localName());
477         req.setLocalPort(msg.getInt());
478 
479         boolean isSSL = msg.getByte() != 0;
480         if( isSSL ) {
481             // XXX req.setSecure( true );
482             req.scheme().setString("https");
483         }
484 
485         decodeHeaders( ep, msg, req, tmpMB );
486 
487         decodeAttributes( ep, msg, req, tmpMB );
488 
489     rp.setStage(Constants.STAGE_PREPARE);
490         MessageBytes valueMB = req.getMimeHeaders().getValue("host");
491         parseHost(valueMB, req);
492         // set cookies on request now that we have all headers
493         req.getCookies().setHeaders(req.getMimeHeaders());
494 
495         // Check to see if there should be a body packet coming along
496         // immediately after
497         int cl=req.getContentLength();
498         if(cl > 0) {
499             jkBody.setContentLength( cl );
500             jkBody.receive();
501         }
502     
503         if (log.isTraceEnabled()) {
504             log.trace(req.toString());
505          }
506 
507         return OK;
508     }
509         
510     private int decodeAttributes( MsgContext ep, Msg msg, Request req,
511                                   MessageBytes tmpMB) {
512         boolean moreAttr=true;
513 
514         while( moreAttr ) {
515             byte attributeCode=msg.getByte();
516             if( attributeCode == SC_A_ARE_DONE )
517                 return 200;
518 
519             /* Special case ( XXX in future API make it separate type !)
520              */
521             if( attributeCode == SC_A_SSL_KEY_SIZE ) {
522                 // Bug 1326: it's an Integer.
523                 req.setAttribute(SSLSupport.KEY_SIZE_KEY,
524                                  new Integer( msg.getInt()));
525                //Integer.toString(msg.getInt()));
526             }
527 
528             if( attributeCode == SC_A_REQ_ATTRIBUTE ) {
529                 // 2 strings ???...
530                 msg.getBytes( tmpMB );
531                 String n=tmpMB.toString();
532                 msg.getBytes( tmpMB );
533                 String v=tmpMB.toString();
534                 req.setAttribute(n, v );
535             }
536 
537 
538             // 1 string attributes
539             switch(attributeCode) {
540             case SC_A_CONTEXT      :
541                 msg.getBytes( tmpMB );
542                 // nothing
543                 break;
544                 
545             case SC_A_SERVLET_PATH :
546                 msg.getBytes( tmpMB );
547                 // nothing 
548                 break;
549                 
550             case SC_A_REMOTE_USER  :
551                 if( tomcatAuthentication ) {
552                     // ignore server
553                     msg.getBytes( tmpMB );
554                 } else {
555                     msg.getBytes(req.getRemoteUser());
556                 }
557                 break;
558                 
559             case SC_A_AUTH_TYPE    :
560                 if( tomcatAuthentication ) {
561                     // ignore server
562                     msg.getBytes( tmpMB );
563                 } else {
564                     msg.getBytes(req.getAuthType());
565                 }
566                 break;
567                 
568             case SC_A_QUERY_STRING :
569                 msg.getBytes(req.queryString());
570                 break;
571                 
572             case SC_A_JVM_ROUTE    :
573                 msg.getBytes(req.instanceId());
574                 break;
575                 
576             case SC_A_SSL_CERT     :
577                 req.scheme().setString( "https" );
578                 // Transform the string into certificate.
579                 MessageBytes tmpMB2 = (MessageBytes)req.getNote(WorkerEnv.SSL_CERT_NOTE);
580                 if(tmpMB2 == null) {
581                     tmpMB2 = new MessageBytes();
582                     req.setNote(WorkerEnv.SSL_CERT_NOTE, tmpMB2);
583                 }
584                 // SSL certificate extraction is costy, moved to JkCoyoteHandler
585                 msg.getBytes(tmpMB2);
586                 break;
587                 
588             case SC_A_SSL_CIPHER   :
589                 req.scheme().setString( "https" );
590                 msg.getBytes(tmpMB);
591                 req.setAttribute(SSLSupport.CIPHER_SUITE_KEY,
592                                  tmpMB.toString());
593                 break;
594                 
595             case SC_A_SSL_SESSION  :
596                 req.scheme().setString( "https" );
597                 msg.getBytes(tmpMB);
598                 req.setAttribute(SSLSupport.SESSION_ID_KEY, 
599                                   tmpMB.toString());
600                 break;
601                 
602             case SC_A_SECRET  :
603                 msg.getBytes(tmpMB);
604                 String secret=tmpMB.toString();
605                 log.info("Secret: " + secret );
606                 // endpoint note
607                 ep.setNote( secretNote, secret );
608                 break;
609                 
610             case SC_A_STORED_METHOD:
611                 msg.getBytes(req.method()); 
612                 break;
613                 
614             default:
615                 break; // ignore, we don't know about it - backward compat
616             }
617         }
618         return 200;
619     }
620     
621     private void decodeHeaders( MsgContext ep, Msg msg, Request req,
622                                 MessageBytes tmpMB ) {
623         // Decode headers
624         MimeHeaders headers = req.getMimeHeaders();
625 
626         int hCount = msg.getInt();
627         for(int i = 0 ; i < hCount ; i++) {
628             String hName = null;
629 
630             // Header names are encoded as either an integer code starting
631             // with 0xA0, or as a normal string (in which case the first
632             // two bytes are the length).
633             int isc = msg.peekInt();
634             int hId = isc & 0xFF;
635 
636             MessageBytes vMB=null;
637             isc &= 0xFF00;
638             if(0xA000 == isc) {
639                 msg.getInt(); // To advance the read position
640                 hName = headerTransArray[hId - 1];
641                 vMB=headers.addValue( hName );
642             } else {
643                 // reset hId -- if the header currently being read
644                 // happens to be 7 or 8 bytes long, the code below
645                 // will think it's the content-type header or the
646                 // content-length header - SC_REQ_CONTENT_TYPE=7,
647                 // SC_REQ_CONTENT_LENGTH=8 - leading to unexpected
648                 // behaviour.  see bug 5861 for more information.
649                 hId = -1;
650                 msg.getBytes( tmpMB );
651                 ByteChunk bc=tmpMB.getByteChunk();
652                 //hName=tmpMB.toString();
653                 //                vMB=headers.addValue( hName );
654                 vMB=headers.addValue( bc.getBuffer(),
655                                       bc.getStart(), bc.getLength() );
656             }
657 
658             msg.getBytes(vMB);
659 
660             if (hId == SC_REQ_CONTENT_LENGTH ||
661                 tmpMB.equalsIgnoreCase("Content-Length")) {
662                 // just read the content-length header, so set it
663                 int contentLength = (vMB == null) ? -1 : vMB.getInt();
664                 req.setContentLength(contentLength);
665             } else if (hId == SC_REQ_CONTENT_TYPE ||
666                        tmpMB.equalsIgnoreCase("Content-Type")) {
667                 // just read the content-type header, so set it
668                 ByteChunk bchunk = vMB.getByteChunk();
669                 req.contentType().setBytes(bchunk.getBytes(),
670                                            bchunk.getOffset(),
671                                            bchunk.getLength());
672             }
673         }
674     }
675 
676     /**
677      * Parse host.
678      */
679     private void parseHost(MessageBytes valueMB, Request request) 
680         throws IOException {
681 
682         if (valueMB == null || valueMB.isNull()) {
683             // HTTP/1.0
684             // Default is what the socket tells us. Overriden if a host is 
685             // found/parsed
686             request.setServerPort(request.getLocalPort());
687             request.serverName().duplicate(request.localName());
688             return;
689         }
690 
691         ByteChunk valueBC = valueMB.getByteChunk();
692         byte[] valueB = valueBC.getBytes();
693         int valueL = valueBC.getLength();
694         int valueS = valueBC.getStart();
695         int colonPos = -1;
696         CharChunk hostNameC = (CharChunk)request.getNote(HOSTBUFFER);
697         if(hostNameC == null) {
698             hostNameC = new CharChunk(valueL);
699             request.setNote(HOSTBUFFER, hostNameC);
700         }
701         hostNameC.recycle();
702 
703         boolean ipv6 = (valueB[valueS] == '[');
704         boolean bracketClosed = false;
705         for (int i = 0; i < valueL; i++) {
706             char b = (char) valueB[i + valueS];
707             hostNameC.append(b);
708             if (b == ']') {
709                 bracketClosed = true;
710             } else if (b == ':') {
711                 if (!ipv6 || bracketClosed) {
712                     colonPos = i;
713                     break;
714                 }
715             }
716         }
717 
718         if (colonPos < 0) {
719             if (request.scheme().equalsIgnoreCase("https")) {
720                 // 80 - Default HTTTP port
721                 request.setServerPort(443);
722             } else {
723                 // 443 - Default HTTPS port
724                 request.setServerPort(80);
725             }
726             request.serverName().setChars(hostNameC.getChars(), 
727                                           hostNameC.getStart(), 
728                                           hostNameC.getLength());
729         } else {
730 
731             request.serverName().setChars(hostNameC.getChars(), 
732                                           hostNameC.getStart(), colonPos);
733 
734             int port = 0;
735             int mult = 1;
736             for (int i = valueL - 1; i > colonPos; i--) {
737                 int charValue = HexUtils.DEC[(int) valueB[i + valueS]];
738                 if (charValue == -1) {
739                     // Invalid character
740                     throw new CharConversionException("Invalid char in port: " + valueB[i + valueS]); 
741                 }
742                 port = port + (charValue * mult);
743                 mult = 10 * mult;
744             }
745             request.setServerPort(port);
746 
747         }
748 
749     }
750 
751 }

            
All Examples in File:
Example
Line
Rating (found
useful by...)
311 0% of 0