1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.ajp;
15
16 import java.io.IOException;
17 import java.io.InterruptedIOException;
18
19 import javax.servlet.ServletInputStream;
20
21 import org.eclipse.jetty.http.HttpTokens;
22 import org.eclipse.jetty.http.Parser;
23 import org.eclipse.jetty.io.Buffer;
24 import org.eclipse.jetty.io.BufferUtil;
25 import org.eclipse.jetty.io.Buffers;
26 import org.eclipse.jetty.io.EndPoint;
27 import org.eclipse.jetty.io.EofException;
28 import org.eclipse.jetty.io.View;
29 import org.eclipse.jetty.util.log.Log;
30
31
32
33
34 public class Ajp13Parser implements Parser
35 {
36 private final static int STATE_START = -1;
37 private final static int STATE_END = 0;
38 private final static int STATE_AJP13CHUNK_START = 1;
39 private final static int STATE_AJP13CHUNK = 2;
40
41 private int _state = STATE_START;
42 private long _contentLength;
43 private long _contentPosition;
44 private int _chunkLength;
45 private int _chunkPosition;
46 private int _headers;
47 private Buffers _buffers;
48 private EndPoint _endp;
49 private Buffer _buffer;
50 private Buffer _header;
51 private Buffer _body;
52 private View _contentView = new View();
53 private EventHandler _handler;
54 private Ajp13Generator _generator;
55 private View _tok0;
56 private View _tok1;
57 protected int _length;
58 protected int _packetLength;
59
60
61
62 public Ajp13Parser(Buffers buffers, EndPoint endPoint)
63 {
64 _buffers = buffers;
65 _endp = endPoint;
66 }
67
68
69 public void setEventHandler(EventHandler handler)
70 {
71 _handler=handler;
72 }
73
74
75 public void setGenerator(Ajp13Generator generator)
76 {
77 _generator=generator;
78 }
79
80
81 public long getContentLength()
82 {
83 return _contentLength;
84 }
85
86
87 public int getState()
88 {
89 return _state;
90 }
91
92
93 public boolean inContentState()
94 {
95 return _state > 0;
96 }
97
98
99 public boolean inHeaderState()
100 {
101 return _state < 0;
102 }
103
104
105 public boolean isIdle()
106 {
107 return _state == STATE_START;
108 }
109
110
111 public boolean isComplete()
112 {
113 return _state == STATE_END;
114 }
115
116
117 public boolean isMoreInBuffer()
118 {
119
120 if (_header != null && _header.hasContent() || _body != null && _body.hasContent())
121 return true;
122
123 return false;
124 }
125
126
127 public boolean isState(int state)
128 {
129 return _state == state;
130 }
131
132
133 public void parse() throws IOException
134 {
135 if (_state == STATE_END)
136 reset(false);
137 if (_state != STATE_START)
138 throw new IllegalStateException("!START");
139
140
141 while (!isComplete())
142 {
143 parseNext();
144 }
145 }
146
147
148 public long parseAvailable() throws IOException
149 {
150 long len = parseNext();
151 long total = len > 0 ? len : 0;
152
153
154 while (!isComplete() && _buffer != null && _buffer.length() > 0)
155 {
156 len = parseNext();
157 if (len > 0)
158 total += len;
159 else
160 break;
161 }
162 return total;
163 }
164
165
166 private int fill() throws IOException
167 {
168 int filled = -1;
169 if (_body != null && _buffer != _body)
170 {
171
172
173
174 if(_header.length() > 0)
175 {
176
177 _body.put(_header);
178 }
179
180 _buffer = _body;
181
182 if (_buffer.length()>0)
183 {
184 filled = _buffer.length();
185 return filled;
186 }
187 }
188
189 if (_buffer.markIndex() == 0 && _buffer.putIndex() == _buffer.capacity())
190 throw new IOException("FULL");
191 if (_endp != null && filled <= 0)
192 {
193
194
195 if (_buffer == _body)
196 _buffer.compact();
197
198 if (_buffer.space() == 0)
199 throw new IOException("FULL");
200
201 try
202 {
203 filled = _endp.fill(_buffer);
204 }
205 catch (IOException e)
206 {
207
208 Log.debug(e);
209 reset(true);
210 throw (e instanceof EofException) ? e : new EofException(e);
211 }
212 }
213
214 if (filled < 0)
215 {
216 if (_state > STATE_END)
217 {
218 _state = STATE_END;
219 _handler.messageComplete(_contentPosition);
220 return filled;
221 }
222 reset(true);
223 throw new EofException();
224 }
225
226 return filled;
227 }
228
229 volatile int _seq=0;
230
231 public long parseNext() throws IOException
232 {
233 long total_filled = -1;
234
235 if (_buffer == null)
236 {
237 if (_header == null)
238 _header = _buffers.getHeader();
239
240 _buffer = _header;
241 _tok0 = new View(_header);
242 _tok1 = new View(_header);
243 _tok0.setPutIndex(_tok0.getIndex());
244 _tok1.setPutIndex(_tok1.getIndex());
245 }
246
247 if (_state == STATE_END)
248 throw new IllegalStateException("STATE_END");
249 if (_state > STATE_END && _contentPosition == _contentLength)
250 {
251 _state = STATE_END;
252 _handler.messageComplete(_contentPosition);
253 return total_filled;
254 }
255
256 if (_state < 0)
257 {
258
259 if (_packetLength<=0)
260 {
261 if (_buffer.length()<4)
262 {
263 if (total_filled<0)
264 total_filled=0;
265 total_filled+=fill();
266 if (_buffer.length()<4)
267 return total_filled;
268 }
269
270 _contentLength = HttpTokens.UNKNOWN_CONTENT;
271 int _magic = Ajp13RequestPacket.getInt(_buffer);
272 if (_magic != Ajp13RequestHeaders.MAGIC)
273 throw new IOException("Bad AJP13 rcv packet: " + "0x" + Integer.toHexString(_magic) + " expected " + "0x" + Integer.toHexString(Ajp13RequestHeaders.MAGIC) + " " + this);
274
275
276 _packetLength = Ajp13RequestPacket.getInt(_buffer);
277 if (_packetLength > Ajp13Packet.MAX_PACKET_SIZE)
278 throw new IOException("AJP13 packet (" + _packetLength + "bytes) too large for buffer");
279
280 }
281
282 if (_buffer.length() < _packetLength)
283 {
284 if (total_filled<0)
285 total_filled=0;
286 total_filled+=fill();
287 if (_buffer.length() < _packetLength)
288 return total_filled;
289 }
290
291
292 Buffer bufHeaderName = null;
293 Buffer bufHeaderValue = null;
294 int attr_type = 0;
295
296 byte packetType = Ajp13RequestPacket.getByte(_buffer);
297
298 switch (packetType)
299 {
300 case Ajp13Packet.FORWARD_REQUEST_ORDINAL:
301 _handler.startForwardRequest();
302 break;
303 case Ajp13Packet.CPING_REQUEST_ORDINAL:
304 (_generator).sendCPong();
305
306 if(_header != null)
307 {
308 _buffers.returnBuffer(_header);
309 _header = null;
310 }
311
312 if(_body != null)
313 {
314 _buffers.returnBuffer(_body);
315 _body = null;
316 }
317
318 _buffer= null;
319
320 reset(true);
321
322 return -1;
323 case Ajp13Packet.SHUTDOWN_ORDINAL:
324 shutdownRequest();
325
326 return -1;
327
328 default:
329
330
331 Log.warn("AJP13 message type ({PING}: "+packetType+" ) not supported/recognized as an AJP request");
332 throw new IllegalStateException("PING is not implemented");
333 }
334
335
336 _handler.parsedMethod(Ajp13RequestPacket.getMethod(_buffer));
337 _handler.parsedProtocol(Ajp13RequestPacket.getString(_buffer, _tok0));
338 _handler.parsedUri(Ajp13RequestPacket.getString(_buffer, _tok1));
339 _handler.parsedRemoteAddr(Ajp13RequestPacket.getString(_buffer, _tok1));
340 _handler.parsedRemoteHost(Ajp13RequestPacket.getString(_buffer, _tok1));
341 _handler.parsedServerName(Ajp13RequestPacket.getString(_buffer, _tok1));
342 _handler.parsedServerPort(Ajp13RequestPacket.getInt(_buffer));
343 _handler.parsedSslSecure(Ajp13RequestPacket.getBool(_buffer));
344
345
346 _headers = Ajp13RequestPacket.getInt(_buffer);
347
348 for (int h=0;h<_headers;h++)
349 {
350 bufHeaderName = Ajp13RequestPacket.getHeaderName(_buffer, _tok0);
351 bufHeaderValue = Ajp13RequestPacket.getString(_buffer, _tok1);
352
353 if (bufHeaderName != null && bufHeaderName.toString().equals(Ajp13RequestHeaders.CONTENT_LENGTH))
354 {
355 _contentLength = BufferUtil.toLong(bufHeaderValue);
356 if (_contentLength == 0)
357 _contentLength = HttpTokens.NO_CONTENT;
358 }
359
360 _handler.parsedHeader(bufHeaderName, bufHeaderValue);
361 }
362
363
364
365 attr_type = Ajp13RequestPacket.getByte(_buffer) & 0xff;
366 while (attr_type != 0xFF)
367 {
368 switch (attr_type)
369 {
370
371
372
373
374 case Ajp13RequestHeaders.REMOTE_USER_ATTR:
375 _handler.parsedRemoteUser(Ajp13RequestPacket.getString(_buffer, _tok1));
376 break;
377 case Ajp13RequestHeaders.AUTH_TYPE_ATTR:
378
379 _handler.parsedAuthorizationType(Ajp13RequestPacket.getString(_buffer, _tok1));
380 break;
381
382 case Ajp13RequestHeaders.QUERY_STRING_ATTR:
383 _handler.parsedQueryString(Ajp13RequestPacket.getString(_buffer, _tok1));
384 break;
385
386 case Ajp13RequestHeaders.JVM_ROUTE_ATTR:
387
388
389
390
391 _handler.parsedRequestAttribute("org.eclipse.http.ajp.JVMRoute", Ajp13RequestPacket.getString(_buffer, _tok1));
392 break;
393
394 case Ajp13RequestHeaders.SSL_CERT_ATTR:
395 _handler.parsedSslCert(Ajp13RequestPacket.getString(_buffer, _tok1));
396 break;
397
398 case Ajp13RequestHeaders.SSL_CIPHER_ATTR:
399 _handler.parsedSslCipher(Ajp13RequestPacket.getString(_buffer, _tok1));
400
401 break;
402
403 case Ajp13RequestHeaders.SSL_SESSION_ATTR:
404 _handler.parsedSslSession(Ajp13RequestPacket.getString(_buffer, _tok1));
405 break;
406
407 case Ajp13RequestHeaders.REQUEST_ATTR:
408 _handler.parsedRequestAttribute(Ajp13RequestPacket.getString(_buffer, _tok0).toString(), Ajp13RequestPacket.getString(_buffer, _tok1));
409 break;
410
411
412
413
414
415
416 case Ajp13RequestHeaders.SSL_KEYSIZE_ATTR:
417
418
419
420
421
422 int length = Ajp13RequestPacket.getInt(_buffer);
423
424 if (length>0 && length<16)
425 {
426
427 _buffer.skip(-2);
428 _handler.parsedSslKeySize(Integer.parseInt(Ajp13RequestPacket.getString(_buffer, _tok1).toString()));
429 }
430 else
431 _handler.parsedSslKeySize(length);
432
433 break;
434
435
436
437
438
439
440 case Ajp13RequestHeaders.SECRET_ATTR:
441
442
443
444
445
446 break;
447
448 case Ajp13RequestHeaders.STORED_METHOD_ATTR:
449
450
451
452
453 break;
454
455
456 case Ajp13RequestHeaders.CONTEXT_ATTR:
457 _handler.parsedContextPath(Ajp13RequestPacket.getString(_buffer, _tok1));
458 break;
459 case Ajp13RequestHeaders.SERVLET_PATH_ATTR:
460 _handler.parsedServletPath(Ajp13RequestPacket.getString(_buffer, _tok1));
461
462 break;
463 default:
464 Log.warn("Unsupported Ajp13 Request Attribute {}", new Integer(attr_type));
465 break;
466 }
467
468 attr_type = Ajp13RequestPacket.getByte(_buffer) & 0xff;
469 }
470
471 _contentPosition = 0;
472 switch ((int) _contentLength)
473 {
474
475 case HttpTokens.NO_CONTENT:
476 _state = STATE_END;
477 _handler.headerComplete();
478 _handler.messageComplete(_contentPosition);
479
480 break;
481
482 case HttpTokens.UNKNOWN_CONTENT:
483
484 _generator.getBodyChunk();
485 if (_buffers != null && _body == null && _buffer == _header && _header.length() <= 0)
486 {
487 _body = _buffers.getBuffer();
488 _body.clear();
489 }
490 _state = STATE_AJP13CHUNK_START;
491 _handler.headerComplete();
492
493 return total_filled;
494
495 default:
496
497 if (_buffers != null && _body == null && _buffer == _header && _contentLength > (_header.capacity() - _header.getIndex()))
498 {
499 _body = _buffers.getBuffer();
500 _body.clear();
501
502 }
503 _state = STATE_AJP13CHUNK_START;
504 _handler.headerComplete();
505 return total_filled;
506 }
507 }
508
509 Buffer chunk;
510
511 while (_state>STATE_END)
512 {
513 switch (_state)
514 {
515 case STATE_AJP13CHUNK_START:
516 if (_buffer.length()<6)
517 {
518 if (total_filled<0)
519 total_filled=0;
520 total_filled+=fill();
521 if (_buffer.length()<6)
522 return total_filled;
523 }
524 int _magic=Ajp13RequestPacket.getInt(_buffer);
525 if (_magic!=Ajp13RequestHeaders.MAGIC)
526 {
527 throw new IOException("Bad AJP13 rcv packet: "+"0x"+Integer.toHexString(_magic)+" expected "+"0x"
528 +Integer.toHexString(Ajp13RequestHeaders.MAGIC)+" "+this);
529 }
530 _chunkPosition=0;
531 _chunkLength=Ajp13RequestPacket.getInt(_buffer)-2;
532 Ajp13RequestPacket.getInt(_buffer);
533 if (_chunkLength==0)
534 {
535 _state=STATE_END;
536 _generator.gotBody();
537 _handler.messageComplete(_contentPosition);
538 return total_filled;
539 }
540 _state=STATE_AJP13CHUNK;
541 break;
542
543 case STATE_AJP13CHUNK:
544 if (_buffer.length()<_chunkLength)
545 {
546 if (total_filled<0)
547 total_filled=0;
548 total_filled+=fill();
549 if (_buffer.length()<_chunkLength)
550 return total_filled;
551 }
552
553 int remaining=_chunkLength-_chunkPosition;
554
555 if (remaining==0)
556 {
557 _state=STATE_AJP13CHUNK_START;
558 if (_contentPosition<_contentLength)
559 {
560 _generator.getBodyChunk();
561 }
562 else
563 {
564 _generator.gotBody();
565 }
566
567 return total_filled;
568 }
569
570 if (_buffer.length()<remaining)
571 {
572 remaining=_buffer.length();
573 }
574
575 chunk=Ajp13RequestPacket.get(_buffer,remaining);
576
577 _contentPosition+=chunk.length();
578 _chunkPosition+=chunk.length();
579 _contentView.update(chunk);
580
581 remaining=_chunkLength-_chunkPosition;
582
583 if (remaining==0)
584 {
585 _state=STATE_AJP13CHUNK_START;
586 if (_contentPosition<_contentLength || _contentLength == HttpTokens.UNKNOWN_CONTENT)
587 {
588 _generator.getBodyChunk();
589 }
590 else
591 {
592 _generator.gotBody();
593 }
594 }
595
596 _handler.content(chunk);
597
598 return total_filled;
599
600 default:
601 throw new IllegalStateException("Invalid Content State");
602
603 }
604
605 }
606
607 return total_filled;
608 }
609
610
611 public void reset(boolean returnBuffers)
612 {
613 _state = STATE_START;
614 _contentLength = HttpTokens.UNKNOWN_CONTENT;
615 _contentPosition = 0;
616 _length = 0;
617 _packetLength = 0;
618
619 if (_body != null)
620 {
621 if (_body.hasContent())
622 {
623 _header.setMarkIndex(-1);
624 _header.compact();
625
626
627 _body.skip(_header.put(_body));
628
629 }
630
631 if (_body.length() == 0)
632 {
633 if (_buffers != null && returnBuffers)
634 _buffers.returnBuffer(_body);
635 _body = null;
636 }
637 else
638 {
639 _body.setMarkIndex(-1);
640 _body.compact();
641 }
642 }
643
644 if (_header != null)
645 {
646 _header.setMarkIndex(-1);
647 if (!_header.hasContent() && _buffers != null && returnBuffers)
648 {
649 _buffers.returnBuffer(_header);
650 _header = null;
651 _buffer = null;
652 }
653 else
654 {
655 _header.compact();
656 _tok0.update(_header);
657 _tok0.update(0, 0);
658 _tok1.update(_header);
659 _tok1.update(0, 0);
660 }
661 }
662
663 _buffer = _header;
664 }
665
666
667 Buffer getHeaderBuffer()
668 {
669 return _buffer;
670 }
671
672 private void shutdownRequest()
673 {
674 _state = STATE_END;
675
676 if(!Ajp13SocketConnector.__allowShutdown)
677 {
678 Log.warn("AJP13: Shutdown Request is Denied, allowShutdown is set to false!!!");
679 return;
680 }
681
682 if(Ajp13SocketConnector.__secretWord != null)
683 {
684 Log.warn("AJP13: Validating Secret Word");
685 try
686 {
687 String secretWord = Ajp13RequestPacket.getString(_buffer, _tok1).toString();
688
689 if(!Ajp13SocketConnector.__secretWord.equals(secretWord))
690 {
691 Log.warn("AJP13: Shutdown Request Denied, Invalid Sercret word!!!");
692 throw new IllegalStateException("AJP13: Secret Word is Invalid: Peer has requested shutdown but, Secret Word did not match");
693 }
694 }
695 catch (Exception e)
696 {
697 Log.warn("AJP13: Secret Word is Required!!!");
698 Log.debug(e);
699 throw new IllegalStateException("AJP13: Secret Word is Required: Peer has requested shutdown but, has not provided a Secret Word");
700 }
701
702
703 Log.warn("AJP13: Shutdown Request is Denied, allowShutdown is set to false!!!");
704 return;
705 }
706
707 Log.warn("AJP13: Peer Has Requested for Shutdown!!!");
708 Log.warn("AJP13: Jetty 6 is shutting down !!!");
709 System.exit(0);
710 }
711
712
713 public interface EventHandler
714 {
715
716
717
718
719 public void content(Buffer ref) throws IOException;
720
721 public void headerComplete() throws IOException;
722
723 public void messageComplete(long contextLength) throws IOException;
724
725 public void parsedHeader(Buffer name, Buffer value) throws IOException;
726
727 public void parsedMethod(Buffer method) throws IOException;
728
729 public void parsedProtocol(Buffer protocol) throws IOException;
730
731 public void parsedQueryString(Buffer value) throws IOException;
732
733 public void parsedRemoteAddr(Buffer addr) throws IOException;
734
735 public void parsedRemoteHost(Buffer host) throws IOException;
736
737 public void parsedRequestAttribute(String key, Buffer value) throws IOException;
738
739 public void parsedRequestAttribute(String key, int value) throws IOException;
740
741 public void parsedServerName(Buffer name) throws IOException;
742
743 public void parsedServerPort(int port) throws IOException;
744
745 public void parsedSslSecure(boolean secure) throws IOException;
746
747 public void parsedUri(Buffer uri) throws IOException;
748
749 public void startForwardRequest() throws IOException;
750
751 public void parsedAuthorizationType(Buffer authType) throws IOException;
752
753 public void parsedRemoteUser(Buffer remoteUser) throws IOException;
754
755 public void parsedServletPath(Buffer servletPath) throws IOException;
756
757 public void parsedContextPath(Buffer context) throws IOException;
758
759 public void parsedSslCert(Buffer sslCert) throws IOException;
760
761 public void parsedSslCipher(Buffer sslCipher) throws IOException;
762
763 public void parsedSslSession(Buffer sslSession) throws IOException;
764
765 public void parsedSslKeySize(int keySize) throws IOException;
766
767
768
769
770
771 }
772
773
774
775
776
777
778 public static class Input extends ServletInputStream
779 {
780 private Ajp13Parser _parser;
781 private EndPoint _endp;
782 private long _maxIdleTime;
783 private View _content;
784
785
786 public Input(Ajp13Parser parser, long maxIdleTime)
787 {
788 _parser = parser;
789 _endp = parser._endp;
790 _maxIdleTime = maxIdleTime;
791 _content = _parser._contentView;
792 }
793
794
795 @Override
796 public int read() throws IOException
797 {
798 int c = -1;
799 if (blockForContent())
800 c = 0xff & _content.get();
801 return c;
802 }
803
804
805
806
807
808 @Override
809 public int read(byte[] b, int off, int len) throws IOException
810 {
811 int l = -1;
812 if (blockForContent())
813 l = _content.get(b, off, len);
814 return l;
815 }
816
817
818 private boolean blockForContent() throws IOException
819 {
820 if (_content.length() > 0)
821 return true;
822 if (_parser.isState(Ajp13Parser.STATE_END) || _parser.isState(Ajp13Parser.STATE_START))
823 return false;
824
825
826 if (_endp == null)
827 _parser.parseNext();
828
829
830 else if (_endp.isBlocking())
831 {
832 _parser.parseNext();
833
834
835 while (_content.length() == 0 && !_parser.isState(Ajp13Parser.STATE_END))
836 {
837
838 _parser.parseNext();
839 }
840 }
841 else
842 {
843 long filled = _parser.parseNext();
844 boolean blocked = false;
845
846
847
848 while (_content.length() == 0 && !_parser.isState(Ajp13Parser.STATE_END))
849 {
850
851
852 if (filled > 0)
853 blocked = false;
854 else if (filled == 0)
855 {
856 if (blocked)
857 throw new InterruptedIOException("timeout");
858
859 blocked = true;
860 _endp.blockReadable(_maxIdleTime);
861 }
862
863
864 filled = _parser.parseNext();
865 }
866 }
867
868 return _content.length() > 0;
869 }
870
871 }
872 }