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