Source Code Cross Referenced for Ajp13Generator.java in  » Sevlet-Container » jetty-extras » org » mortbay » jetty » ajp » 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 » jetty extras » org.mortbay.jetty.ajp 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        //========================================================================
002:        //Copyright 2006 Mort Bay Consulting Pty. Ltd.
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:        //http://www.apache.org/licenses/LICENSE-2.0
008:        //Unless required by applicable law or agreed to in writing, software
009:        //distributed under the License is distributed on an "AS IS" BASIS,
010:        //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011:        //See the License for the specific language governing permissions and
012:        //limitations under the License.
013:        //========================================================================
014:
015:        package org.mortbay.jetty.ajp;
016:
017:        import java.io.IOException;
018:        import java.util.HashMap;
019:        import java.util.Iterator;
020:
021:        import org.mortbay.io.Buffer;
022:        import org.mortbay.io.Buffers;
023:        import org.mortbay.io.ByteArrayBuffer;
024:        import org.mortbay.io.EndPoint;
025:        import org.mortbay.jetty.AbstractGenerator;
026:        import org.mortbay.jetty.EofException;
027:        import org.mortbay.jetty.HttpFields;
028:        import org.mortbay.jetty.HttpVersions;
029:        import org.mortbay.jetty.HttpFields.Field;
030:        import org.mortbay.log.Log;
031:        import org.mortbay.util.TypeUtil;
032:
033:        /**
034:         * @author lagdeppa (at) exist.com
035:         * @author Greg Wilkins
036:         */
037:        public class Ajp13Generator extends AbstractGenerator {
038:            private static HashMap __headerHash = new HashMap();
039:
040:            static {
041:                byte[] xA001 = { (byte) 0xA0, (byte) 0x01 };
042:                byte[] xA002 = { (byte) 0xA0, (byte) 0x02 };
043:                byte[] xA003 = { (byte) 0xA0, (byte) 0x03 };
044:                byte[] xA004 = { (byte) 0xA0, (byte) 0x04 };
045:                byte[] xA005 = { (byte) 0xA0, (byte) 0x05 };
046:                byte[] xA006 = { (byte) 0xA0, (byte) 0x06 };
047:                byte[] xA007 = { (byte) 0xA0, (byte) 0x07 };
048:                byte[] xA008 = { (byte) 0xA0, (byte) 0x08 };
049:                byte[] xA009 = { (byte) 0xA0, (byte) 0x09 };
050:                byte[] xA00A = { (byte) 0xA0, (byte) 0x0A };
051:                byte[] xA00B = { (byte) 0xA0, (byte) 0x0B };
052:                __headerHash.put("Content-Type", xA001);
053:                __headerHash.put("Content-Language", xA002);
054:                __headerHash.put("Content-Length", xA003);
055:                __headerHash.put("Date", xA004);
056:                __headerHash.put("Last-Modified", xA005);
057:                __headerHash.put("Location", xA006);
058:                __headerHash.put("Set-Cookie", xA007);
059:                __headerHash.put("Set-Cookie2", xA008);
060:                __headerHash.put("Servlet-Engine", xA009);
061:                __headerHash.put("Status", xA00A);
062:                __headerHash.put("WWW-Authenticate", xA00B);
063:
064:            }
065:
066:            private static final byte[] AJP13_END_RESPONSE = { 'A', 'B', 0, 2,
067:                    5, 1 };
068:
069:            // AB ajp respose
070:            // 0, 3 int = 3 packets in length
071:            // 6, send signal to get more data
072:            // 31, -7 byte values for int 8185 = (8 * 1024) - 7 MAX_DATA
073:            private static final byte[] AJP13_MORE_CONTENT = { 'A', 'B', 0, 3,
074:                    6, 31, -7 };
075:
076:            private static String SERVER = "Server: Jetty(6.0.x)";
077:
078:            public static void setServerVersion(String version) {
079:                SERVER = "Jetty(" + version + ")";
080:            }
081:
082:            /* ------------------------------------------------------------ */
083:            private boolean _expectMore = false;
084:
085:            private boolean _needMore = false;
086:
087:            private boolean _needEOC = false;
088:
089:            private boolean _bufferPrepared = false;
090:
091:            /* ------------------------------------------------------------ */
092:            public Ajp13Generator(Buffers buffers, EndPoint io,
093:                    int headerBufferSize, int contentBufferSize) {
094:                super (buffers, io, headerBufferSize, contentBufferSize);
095:            }
096:
097:            /* ------------------------------------------------------------ */
098:            public void reset(boolean returnBuffers) {
099:                super .reset(returnBuffers);
100:                _needEOC = false;
101:                _needMore = false;
102:                _expectMore = false;
103:                _bufferPrepared = false;
104:            }
105:
106:            /* ------------------------------------------------------------ */
107:            /**
108:             * Add content.
109:             * 
110:             * @param content
111:             * @param last
112:             * @throws IllegalArgumentException
113:             *             if <code>content</code> is
114:             *             {@link Buffer#isImmutable immutable}.
115:             * @throws IllegalStateException
116:             *             If the request is not expecting any more content, or if the
117:             *             buffers are full and cannot be flushed.
118:             * @throws IOException
119:             *             if there is a problem flushing the buffers.
120:             */
121:            public void addContent(Buffer content, boolean last)
122:                    throws IOException {
123:
124:                if (_noContent) {
125:                    content.clear();
126:                    return;
127:                }
128:
129:                if (content.isImmutable())
130:                    throw new IllegalArgumentException("immutable");
131:
132:                if (_last || _state == STATE_END) {
133:                    Log.debug("Ignoring extra content {}", content);
134:                    content.clear();
135:                    return;
136:                }
137:                _last = last;
138:
139:                // Handle any unfinished business?
140:                if (_content != null && _content.length() > 0) {
141:
142:                    flush();
143:                    if (_content != null && _content.length() > 0)
144:                        throw new IllegalStateException("FULL");
145:                }
146:
147:                _content = content;
148:
149:                _contentWritten += content.length();
150:
151:                // Handle the _content
152:                if (_head) {
153:
154:                    content.clear();
155:                    _content = null;
156:                } else {
157:                    // Yes - so we better check we have a buffer
158:                    initContent();
159:                    // Copy _content to buffer;
160:                    int len = 0;
161:                    len = _buffer.put(_content);
162:
163:                    // make sure there is space for a trailing null
164:                    if (len > 0 && _buffer.space() == 0) {
165:                        len--;
166:                        _buffer.setPutIndex(_buffer.putIndex() - 1);
167:                    }
168:
169:                    _content.skip(len);
170:
171:                    if (_content.length() == 0)
172:                        _content = null;
173:                }
174:            }
175:
176:            /* ------------------------------------------------------------ */
177:            /**
178:             * Add content.
179:             * 
180:             * @param b
181:             *            byte
182:             * @return true if the buffers are full
183:             * @throws IOException
184:             */
185:            public boolean addContent(byte b) throws IOException {
186:                if (_noContent)
187:                    return false;
188:
189:                if (_last || _state == STATE_END)
190:                    throw new IllegalStateException("Closed");
191:
192:                // Handle any unfinished business?
193:                if (_content != null && _content.length() > 0) {
194:                    flush();
195:                    if (_content != null && _content.length() > 0)
196:                        throw new IllegalStateException("FULL");
197:                }
198:
199:                _contentWritten++;
200:
201:                // Handle the _content
202:                if (_head)
203:                    return false;
204:
205:                // we better check we have a buffer
206:                initContent();
207:
208:                // Copy _content to buffer;
209:
210:                _buffer.put(b);
211:
212:                return _buffer.space() <= 1;
213:            }
214:
215:            /* ------------------------------------------------------------ */
216:            /**
217:             * Prepare buffer for unchecked writes. Prepare the generator buffer to
218:             * receive unchecked writes
219:             * 
220:             * @return the available space in the buffer.
221:             * @throws IOException
222:             */
223:            protected int prepareUncheckedAddContent() throws IOException {
224:                if (_noContent)
225:                    return -1;
226:
227:                if (_last || _state == STATE_END)
228:                    throw new IllegalStateException("Closed");
229:
230:                // Handle any unfinished business?
231:                Buffer content = _content;
232:                if (content != null && content.length() > 0) {
233:                    flush();
234:                    if (content != null && content.length() > 0)
235:                        throw new IllegalStateException("FULL");
236:                }
237:
238:                // we better check we have a buffer
239:                initContent();
240:
241:                _contentWritten -= _buffer.length();
242:
243:                // Handle the _content
244:                if (_head)
245:                    return Integer.MAX_VALUE;
246:
247:                return _buffer.space() - 1;
248:            }
249:
250:            /* ------------------------------------------------------------ */
251:            public void completeHeader(HttpFields fields,
252:                    boolean allContentAdded) throws IOException {
253:                if (_state != STATE_HEADER)
254:                    return;
255:
256:                if (_last && !allContentAdded)
257:                    throw new IllegalStateException("last?");
258:                _last = _last | allContentAdded;
259:
260:                boolean has_server = false;
261:                if (_version == HttpVersions.HTTP_1_0_ORDINAL)
262:                    _close = true;
263:
264:                // get a header buffer
265:                if (_header == null)
266:                    _header = _buffers.getBuffer(_headerBufferSize);
267:
268:                Buffer tmpbuf = _buffer;
269:                _buffer = _header;
270:
271:                try {
272:                    // start the header
273:                    _buffer.put((byte) 'A');
274:                    _buffer.put((byte) 'B');
275:                    addInt(0);
276:                    _buffer.put((byte) 0x4);
277:                    addInt(_status);
278:                    if (_reason == null)
279:                        _reason = getReasonBuffer(_status);
280:                    if (_reason == null)
281:                        _reason = new ByteArrayBuffer(TypeUtil
282:                                .toString(_status));
283:                    addBuffer(_reason);
284:
285:                    if (_status == 100 || _status == 204 || _status == 304) {
286:                        _noContent = true;
287:                        _content = null;
288:                    }
289:
290:                    // allocate 2 bytes for number of headers
291:                    int field_index = _buffer.putIndex();
292:                    addInt(0);
293:
294:                    // Add headers
295:                    Iterator i = fields.getFields();
296:                    int num_fields = 0;
297:
298:                    while (i.hasNext()) {
299:                        num_fields++;
300:                        Field f = (Field) i.next();
301:
302:                        byte[] codes = (byte[]) __headerHash.get(f.getName());
303:                        if (codes != null) {
304:                            _buffer.put(codes);
305:                        } else {
306:                            addString(f.getName());
307:                        }
308:                        addString(f.getValue());
309:                    }
310:
311:                    if (!has_server && _status > 100 && getSendServerVersion()) {
312:                        num_fields++;
313:                        addString("Server");
314:                        addString(SERVER);
315:                    }
316:
317:                    // TODO Add content length if last content known.
318:
319:                    // insert the number of headers
320:                    int tmp = _buffer.putIndex();
321:                    _buffer.setPutIndex(field_index);
322:                    addInt(num_fields);
323:                    _buffer.setPutIndex(tmp);
324:
325:                    // get the payload size ( - 4 bytes for the ajp header)
326:                    // excluding the
327:                    // ajp header
328:                    int payloadSize = _buffer.length() - 4;
329:                    // insert the total packet size on 2nd and 3rd byte that
330:                    // was previously
331:                    // allocated
332:                    addInt(2, payloadSize);
333:                } finally {
334:                    _buffer = tmpbuf;
335:                }
336:
337:                _state = STATE_CONTENT;
338:
339:            }
340:
341:            /* ------------------------------------------------------------ */
342:            /**
343:             * Complete the message.
344:             * 
345:             * @throws IOException
346:             */
347:            public void complete() throws IOException {
348:                if (_state == STATE_END)
349:                    return;
350:
351:                super .complete();
352:
353:                if (_state < STATE_FLUSHING) {
354:                    _state = STATE_FLUSHING;
355:                    _needEOC = true;
356:                }
357:
358:                flush();
359:            }
360:
361:            /* ------------------------------------------------------------ */
362:            public long flush() throws IOException {
363:                try {
364:                    if (!_expectMore && _state == STATE_HEADER)
365:                        throw new IllegalStateException("State==HEADER");
366:
367:                    prepareBuffers();
368:
369:                    if (_endp == null) {
370:                        // TODO - probably still needed!
371:                        // if (_needMore && _buffer != null)
372:                        // {
373:                        // if(!_hasSentEOC)
374:                        // _buffer.put(AJP13_MORE_CONTENT);
375:                        // }
376:                        if (!_expectMore && _needEOC && _buffer != null) {
377:                            _buffer.put(AJP13_END_RESPONSE);
378:                        }
379:                        _needEOC = false;
380:                        return 0;
381:                    }
382:
383:                    // Keep flushing while there is something to flush
384:                    // (except break below)
385:                    int total = 0;
386:                    long last_len = -1;
387:                    Flushing: while (true) {
388:                        int len = -1;
389:                        int to_flush = ((_header != null && _header.length() > 0) ? 4
390:                                : 0)
391:                                | ((_buffer != null && _buffer.length() > 0) ? 2
392:                                        : 0);
393:
394:                        switch (to_flush) {
395:                        case 7:
396:                            throw new IllegalStateException(); // should
397:                            // never
398:                            // happen!
399:                        case 6:
400:                            len = _endp.flush(_header, _buffer, null);
401:
402:                            break;
403:                        case 5:
404:                            throw new IllegalStateException(); // should
405:                            // never
406:                            // happen!
407:                        case 4:
408:                            len = _endp.flush(_header);
409:                            break;
410:                        case 3:
411:                            throw new IllegalStateException(); // should
412:                            // never
413:                            // happen!
414:                        case 2:
415:                            len = _endp.flush(_buffer);
416:
417:                            break;
418:                        case 1:
419:                            throw new IllegalStateException(); // should
420:                            // never
421:                            // happen!
422:                        case 0: {
423:                            // Nothing more we can write now.
424:                            if (_header != null)
425:                                _header.clear();
426:
427:                            _bufferPrepared = false;
428:
429:                            if (_buffer != null) {
430:                                _buffer.clear();
431:
432:                                // reserve some space for the
433:                                // header
434:                                _buffer.setPutIndex(7);
435:                                _buffer.setGetIndex(7);
436:
437:                                // Special case handling for
438:                                // small left over buffer from
439:                                // an addContent that caused a
440:                                // buffer flush.
441:                                if (_content != null
442:                                        && _content.length() < _buffer.space()
443:                                        && _state != STATE_FLUSHING) {
444:
445:                                    _buffer.put(_content);
446:                                    _content.clear();
447:                                    _content = null;
448:                                    break Flushing;
449:                                }
450:
451:                            }
452:
453:                            // Are we completely finished for now?
454:                            if (!_expectMore
455:                                    && !_needEOC
456:                                    && (_content == null || _content.length() == 0)) {
457:                                if (_state == STATE_FLUSHING)
458:                                    _state = STATE_END;
459:                                if (_state == STATE_END/* &&_close */)
460:                                    _endp.close();
461:
462:                                break Flushing;
463:                            }
464:
465:                            // Try to prepare more to write.
466:                            prepareBuffers();
467:                        }
468:                        }
469:
470:                        // If we failed to flush anything twice in a row
471:                        // break
472:                        if (len <= 0) {
473:                            if (last_len <= 0)
474:                                break Flushing;
475:                            break;
476:                        }
477:                        last_len = len;
478:                        total += len;
479:                    }
480:
481:                    return total;
482:                } catch (IOException e) {
483:                    Log.ignore(e);
484:                    throw (e instanceof  EofException) ? e : new EofException(e);
485:                }
486:
487:            }
488:
489:            /* ------------------------------------------------------------ */
490:            private void prepareBuffers() {
491:                if (!_bufferPrepared) {
492:                    // Refill buffer if possible
493:                    if (_content != null && _content.length() > 0
494:                            && _buffer != null && _buffer.space() > 0) {
495:
496:                        int len = _buffer.put(_content);
497:
498:                        // Make sure there is space for a trailing null
499:                        if (len > 0 && _buffer.space() == 0) {
500:                            len--;
501:                            _buffer.setPutIndex(_buffer.putIndex() - 1);
502:                        }
503:                        _content.skip(len);
504:
505:                        if (_content.length() == 0)
506:                            _content = null;
507:
508:                        if (_buffer.length() == 0) {
509:                            _content = null;
510:                        }
511:                    }
512:
513:                    // add header if needed
514:                    if (_buffer != null) {
515:
516:                        int payloadSize = _buffer.length();
517:
518:                        // 4 bytes for the ajp header
519:                        // 1 byte for response type
520:                        // 2 bytes for the response size
521:                        // 1 byte because we count from zero??
522:
523:                        if (payloadSize > 0) {
524:                            _bufferPrepared = true;
525:
526:                            _buffer.put((byte) 0);
527:                            int put = _buffer.putIndex();
528:                            _buffer.setGetIndex(0);
529:                            _buffer.setPutIndex(0);
530:                            _buffer.put((byte) 'A');
531:                            _buffer.put((byte) 'B');
532:                            addInt(payloadSize + 4);
533:                            _buffer.put((byte) 3);
534:                            addInt(payloadSize);
535:                            _buffer.setPutIndex(put);
536:                        }
537:                    }
538:
539:                    if (_needMore) {
540:
541:                        if (_header == null) {
542:                            _header = _buffers.getBuffer(_headerBufferSize);
543:                        }
544:
545:                        if (_buffer == null && _header != null
546:                                && _header.space() >= AJP13_MORE_CONTENT.length) {
547:                            _header.put(AJP13_MORE_CONTENT);
548:                            _needMore = false;
549:                        } else if (_buffer != null
550:                                && _buffer.space() >= AJP13_MORE_CONTENT.length) {
551:                            // send closing packet if all contents
552:                            // are added
553:                            _buffer.put(AJP13_MORE_CONTENT);
554:                            _needMore = false;
555:                            _bufferPrepared = true;
556:                        }
557:
558:                    }
559:
560:                    if (!_expectMore && _needEOC) {
561:                        if (_buffer == null
562:                                && _header.space() >= AJP13_END_RESPONSE.length) {
563:
564:                            _header.put(AJP13_END_RESPONSE);
565:                            _needEOC = false;
566:                        } else if (_buffer != null
567:                                && _buffer.space() >= AJP13_END_RESPONSE.length) {
568:                            // send closing packet if all contents
569:                            // are added
570:
571:                            _buffer.put(AJP13_END_RESPONSE);
572:                            _needEOC = false;
573:                            _bufferPrepared = true;
574:                        }
575:                    }
576:                }
577:            }
578:
579:            /* ------------------------------------------------------------ */
580:            public boolean isComplete() {
581:                return !_expectMore && _state == STATE_END;
582:            }
583:
584:            /* ------------------------------------------------------------ */
585:            private void initContent() throws IOException {
586:                if (_buffer == null) {
587:                    _buffer = _buffers.getBuffer(_contentBufferSize);
588:                    _buffer.setPutIndex(7);
589:                    _buffer.setGetIndex(7);
590:                }
591:            }
592:
593:            /* ------------------------------------------------------------ */
594:            private void addInt(int i) {
595:                _buffer.put((byte) ((i >> 8) & 0xFF));
596:                _buffer.put((byte) (i & 0xFF));
597:            }
598:
599:            /* ------------------------------------------------------------ */
600:            private void addInt(int startIndex, int i) {
601:                _buffer.poke(startIndex, (byte) ((i >> 8) & 0xFF));
602:                _buffer.poke((startIndex + 1), (byte) (i & 0xFF));
603:            }
604:
605:            /* ------------------------------------------------------------ */
606:            private void addString(String str) {
607:                if (str == null) {
608:                    addInt(0xFFFF);
609:                    return;
610:                }
611:
612:                // TODO - need to use a writer to convert, to avoid this hacky
613:                // conversion and temp buffer
614:                byte[] b = str.getBytes();
615:
616:                addInt(b.length);
617:
618:                _buffer.put(b);
619:                _buffer.put((byte) 0);
620:            }
621:
622:            /* ------------------------------------------------------------ */
623:            private void addBuffer(Buffer b) {
624:                if (b == null) {
625:                    addInt(0xFFFF);
626:                    return;
627:                }
628:
629:                addInt(b.length());
630:                _buffer.put(b);
631:                _buffer.put((byte) 0);
632:            }
633:
634:            /* ------------------------------------------------------------ */
635:            public boolean isNeedMore() {
636:                // TODO - this is not correct. See setNeedMore
637:                return _expectMore;
638:            }
639:
640:            /* ------------------------------------------------------------ */
641:            public void setNeedMore(boolean needMore) throws IOException {
642:                _needMore = needMore;
643:                if (needMore) {
644:                    _expectMore = true;
645:                    flush();
646:                }
647:            }
648:
649:            public void setExpectMore(boolean expectMore) {
650:                _expectMore = expectMore;
651:            }
652:
653:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.