Source Code Cross Referenced for HandlerRequest.java in  » Sevlet-Container » tomcat-connectors » org » apache » jk » common » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Sevlet Container » tomcat connectors » org.apache.jk.common 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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