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
230 public long parseNext() throws IOException
231 {
232 long total_filled = -1;
233
234 if (_buffer == null)
235 {
236 if (_header == null)
237 _header = _buffers.getHeader();
238
239 _buffer = _header;
240 _tok0 = new View(_header);
241 _tok1 = new View(_header);
242 _tok0.setPutIndex(_tok0.getIndex());
243 _tok1.setPutIndex(_tok1.getIndex());
244 }
245
246 if (_state == STATE_END)
247 throw new IllegalStateException("STATE_END");
248 if (_state > STATE_END && _contentPosition == _contentLength)
249 {
250 _state = STATE_END;
251 _handler.messageComplete(_contentPosition);
252 return total_filled;
253 }
254
255 if (_state < 0)
256 {
257
258 if (_packetLength<=0)
259 {
260 if (_buffer.length()<4)
261 {
262 if (total_filled<0)
263 total_filled=0;
264 total_filled+=fill();
265 if (_buffer.length()<4)
266 return total_filled;
267 }
268
269 _contentLength = HttpTokens.UNKNOWN_CONTENT;
270 int _magic = Ajp13RequestPacket.getInt(_buffer);
271 if (_magic != Ajp13RequestHeaders.MAGIC)
272 throw new IOException("Bad AJP13 rcv packet: " + "0x" + Integer.toHexString(_magic) + " expected " + "0x" + Integer.toHexString(Ajp13RequestHeaders.MAGIC) + " " + this);
273
274
275 _packetLength = Ajp13RequestPacket.getInt(_buffer);
276 if (_packetLength > Ajp13Packet.MAX_PACKET_SIZE)
277 throw new IOException("AJP13 packet (" + _packetLength + "bytes) too large for buffer");
278
279 }
280
281 if (_buffer.length() < _packetLength)
282 {
283 if (total_filled<0)
284 total_filled=0;
285 total_filled+=fill();
286 if (_buffer.length() < _packetLength)
287 return total_filled;
288 }
289
290
291 Buffer bufHeaderName = null;
292 Buffer bufHeaderValue = null;
293 int attr_type = 0;
294
295 byte packetType = Ajp13RequestPacket.getByte(_buffer);
296
297 switch (packetType)
298 {
299 case Ajp13Packet.FORWARD_REQUEST_ORDINAL:
300 _handler.startForwardRequest();
301 break;
302 case Ajp13Packet.CPING_REQUEST_ORDINAL:
303 ((Ajp13Generator) _generator).sendCPong();
304
305 if(_header != null)
306 {
307 _buffers.returnBuffer(_header);
308 _header = null;
309 }
310
311 if(_body != null)
312 {
313 _buffers.returnBuffer(_body);
314 _body = null;
315 }
316
317 _buffer= null;
318
319 reset(true);
320
321 return -1;
322 case Ajp13Packet.SHUTDOWN_ORDINAL:
323 shutdownRequest();
324
325 return -1;
326
327 default:
328
329
330 Log.warn("AJP13 message type ({PING}: "+packetType+" ) not supported/recognized as an AJP request");
331 throw new IllegalStateException("PING is not implemented");
332 }
333
334
335 _handler.parsedMethod(Ajp13RequestPacket.getMethod(_buffer));
336 _handler.parsedProtocol(Ajp13RequestPacket.getString(_buffer, _tok0));
337 _handler.parsedUri(Ajp13RequestPacket.getString(_buffer, _tok1));
338 _handler.parsedRemoteAddr(Ajp13RequestPacket.getString(_buffer, _tok1));
339 _handler.parsedRemoteHost(Ajp13RequestPacket.getString(_buffer, _tok1));
340 _handler.parsedServerName(Ajp13RequestPacket.getString(_buffer, _tok1));
341 _handler.parsedServerPort(Ajp13RequestPacket.getInt(_buffer));
342 _handler.parsedSslSecure(Ajp13RequestPacket.getBool(_buffer));
343
344
345 _headers = Ajp13RequestPacket.getInt(_buffer);
346
347 for (int h=0;h<_headers;h++)
348 {
349 bufHeaderName = Ajp13RequestPacket.getHeaderName(_buffer, _tok0);
350 bufHeaderValue = Ajp13RequestPacket.getString(_buffer, _tok1);
351
352 if (bufHeaderName != null && bufHeaderName.toString().equals(Ajp13RequestHeaders.CONTENT_LENGTH))
353 {
354 _contentLength = BufferUtil.toLong(bufHeaderValue);
355 if (_contentLength == 0)
356 _contentLength = HttpTokens.NO_CONTENT;
357 }
358
359 _handler.parsedHeader(bufHeaderName, bufHeaderValue);
360 }
361
362
363
364 attr_type = Ajp13RequestPacket.getByte(_buffer) & 0xff;
365 while (attr_type != 0xFF)
366 {
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
472
473
474
475
476 _contentPosition = 0;
477 switch ((int) _contentLength)
478 {
479
480 case HttpTokens.NO_CONTENT:
481 _state = STATE_END;
482 _handler.headerComplete();
483 _handler.messageComplete(_contentPosition);
484
485 break;
486
487 case HttpTokens.UNKNOWN_CONTENT:
488
489 _generator.getBodyChunk();
490 if (_buffers != null && _body == null && _buffer == _header && _header.length() <= 0)
491 {
492 _body = _buffers.getBuffer();
493 _body.clear();
494 }
495 _state = STATE_AJP13CHUNK_START;
496 _handler.headerComplete();
497
498 return total_filled;
499
500 default:
501
502 if (_buffers != null && _body == null && _buffer == _header && _contentLength > (_header.capacity() - _header.getIndex()))
503 {
504 _body = _buffers.getBuffer();
505 _body.clear();
506
507 }
508 _state = STATE_AJP13CHUNK_START;
509 _handler.headerComplete();
510 return total_filled;
511 }
512 }
513
514
515 Buffer chunk;
516
517 while (_state>STATE_END)
518 {
519 switch (_state)
520 {
521 case STATE_AJP13CHUNK_START:
522 if (_buffer.length()<6)
523 {
524 if (total_filled<0)
525 total_filled=0;
526 total_filled+=fill();
527 if (_buffer.length()<6)
528 return total_filled;
529 }
530 int _magic=Ajp13RequestPacket.getInt(_buffer);
531 if (_magic!=Ajp13RequestHeaders.MAGIC)
532 {
533 throw new IOException("Bad AJP13 rcv packet: "+"0x"+Integer.toHexString(_magic)+" expected "+"0x"
534 +Integer.toHexString(Ajp13RequestHeaders.MAGIC)+" "+this);
535 }
536 _chunkPosition=0;
537 _chunkLength=Ajp13RequestPacket.getInt(_buffer)-2;
538 Ajp13RequestPacket.getInt(_buffer);
539 if (_chunkLength==0)
540 {
541 _state=STATE_END;
542 _generator.gotBody();
543 _handler.messageComplete(_contentPosition);
544 return total_filled;
545 }
546 _state=STATE_AJP13CHUNK;
547
548 case STATE_AJP13CHUNK:
549 if (_buffer.length()<_chunkLength)
550 {
551 if (total_filled<0)
552 total_filled=0;
553 total_filled+=fill();
554 if (_buffer.length()<_chunkLength)
555 return total_filled;
556 }
557
558 int remaining=_chunkLength-_chunkPosition;
559
560 if (remaining==0)
561 {
562 _state=STATE_AJP13CHUNK_START;
563 if (_contentPosition<_contentLength)
564 {
565 _generator.getBodyChunk();
566 }
567 else
568 {
569 _generator.gotBody();
570 }
571
572 return total_filled;
573 }
574
575 if (_buffer.length()<remaining)
576 {
577 remaining=_buffer.length();
578 }
579
580 chunk=Ajp13RequestPacket.get(_buffer,(int)remaining);
581 _contentPosition+=chunk.length();
582 _chunkPosition+=chunk.length();
583 _contentView.update(chunk);
584
585 remaining=_chunkLength-_chunkPosition;
586
587 if (remaining==0)
588 {
589 _state=STATE_AJP13CHUNK_START;
590 if (_contentPosition<_contentLength || _contentLength == HttpTokens.UNKNOWN_CONTENT)
591 {
592 _generator.getBodyChunk();
593 }
594 else
595 {
596 _generator.gotBody();
597 }
598 }
599
600 _handler.content(chunk);
601
602 return total_filled;
603
604 default:
605 throw new IllegalStateException("Invalid Content State");
606
607 }
608
609 }
610
611 return total_filled;
612 }
613
614
615 public void reset(boolean returnBuffers)
616 {
617 _state = STATE_START;
618 _contentLength = HttpTokens.UNKNOWN_CONTENT;
619 _contentPosition = 0;
620 _length = 0;
621 _packetLength = 0;
622
623 if (_body != null)
624 {
625 if (_body.hasContent())
626 {
627 _header.setMarkIndex(-1);
628 _header.compact();
629
630
631 _body.skip(_header.put(_body));
632
633 }
634
635 if (_body.length() == 0)
636 {
637 if (_buffers != null && returnBuffers)
638 _buffers.returnBuffer(_body);
639 _body = null;
640 }
641 else
642 {
643 _body.setMarkIndex(-1);
644 _body.compact();
645 }
646 }
647
648 if (_header != null)
649 {
650 _header.setMarkIndex(-1);
651 if (!_header.hasContent() && _buffers != null && returnBuffers)
652 {
653 _buffers.returnBuffer(_header);
654 _header = null;
655 _buffer = null;
656 }
657 else
658 {
659 _header.compact();
660 _tok0.update(_header);
661 _tok0.update(0, 0);
662 _tok1.update(_header);
663 _tok1.update(0, 0);
664 }
665 }
666
667 _buffer = _header;
668 }
669
670
671 Buffer getHeaderBuffer()
672 {
673 return _buffer;
674 }
675
676 private void shutdownRequest()
677 {
678 _state = STATE_END;
679
680 if(!Ajp13SocketConnector.__allowShutdown)
681 {
682 Log.warn("AJP13: Shutdown Request is Denied, allowShutdown is set to false!!!");
683 return;
684 }
685
686 if(Ajp13SocketConnector.__secretWord != null)
687 {
688 Log.warn("AJP13: Validating Secret Word");
689 try
690 {
691 String secretWord = Ajp13RequestPacket.getString(_buffer, _tok1).toString();
692
693 if(!Ajp13SocketConnector.__secretWord.equals(secretWord))
694 {
695 Log.warn("AJP13: Shutdown Request Denied, Invalid Sercret word!!!");
696 throw new IllegalStateException("AJP13: Secret Word is Invalid: Peer has requested shutdown but, Secret Word did not match");
697 }
698 }
699 catch (Exception e)
700 {
701 Log.warn("AJP13: Secret Word is Required!!!");
702 Log.debug(e);
703 throw new IllegalStateException("AJP13: Secret Word is Required: Peer has requested shutdown but, has not provided a Secret Word");
704 }
705
706
707 Log.warn("AJP13: Shutdown Request is Denied, allowShutdown is set to false!!!");
708 return;
709 }
710
711 Log.warn("AJP13: Peer Has Requested for Shutdown!!!");
712 Log.warn("AJP13: Jetty 6 is shutting down !!!");
713 System.exit(0);
714 }
715
716
717 public interface EventHandler
718 {
719
720
721
722
723 public void content(Buffer ref) throws IOException;
724
725 public void headerComplete() throws IOException;
726
727 public void messageComplete(long contextLength) throws IOException;
728
729 public void parsedHeader(Buffer name, Buffer value) throws IOException;
730
731 public void parsedMethod(Buffer method) throws IOException;
732
733 public void parsedProtocol(Buffer protocol) throws IOException;
734
735 public void parsedQueryString(Buffer value) throws IOException;
736
737 public void parsedRemoteAddr(Buffer addr) throws IOException;
738
739 public void parsedRemoteHost(Buffer host) throws IOException;
740
741 public void parsedRequestAttribute(String key, Buffer value) throws IOException;
742
743 public void parsedRequestAttribute(String key, int value) throws IOException;
744
745 public void parsedServerName(Buffer name) throws IOException;
746
747 public void parsedServerPort(int port) throws IOException;
748
749 public void parsedSslSecure(boolean secure) throws IOException;
750
751 public void parsedUri(Buffer uri) throws IOException;
752
753 public void startForwardRequest() throws IOException;
754
755 public void parsedAuthorizationType(Buffer authType) throws IOException;
756
757 public void parsedRemoteUser(Buffer remoteUser) throws IOException;
758
759 public void parsedServletPath(Buffer servletPath) throws IOException;
760
761 public void parsedContextPath(Buffer context) throws IOException;
762
763 public void parsedSslCert(Buffer sslCert) throws IOException;
764
765 public void parsedSslCipher(Buffer sslCipher) throws IOException;
766
767 public void parsedSslSession(Buffer sslSession) throws IOException;
768
769 public void parsedSslKeySize(int keySize) throws IOException;
770
771
772
773
774
775 }
776
777
778
779
780
781
782 public static class Input extends ServletInputStream
783 {
784 private Ajp13Parser _parser;
785 private EndPoint _endp;
786 private long _maxIdleTime;
787 private View _content;
788
789
790 public Input(Ajp13Parser parser, long maxIdleTime)
791 {
792 _parser = parser;
793 _endp = parser._endp;
794 _maxIdleTime = maxIdleTime;
795 _content = _parser._contentView;
796 }
797
798
799 public int read() throws IOException
800 {
801 int c = -1;
802 if (blockForContent())
803 c = 0xff & _content.get();
804 return c;
805 }
806
807
808
809
810
811 public int read(byte[] b, int off, int len) throws IOException
812 {
813 int l = -1;
814 if (blockForContent())
815 l = _content.get(b, off, len);
816 return l;
817 }
818
819
820 private boolean blockForContent() throws IOException
821 {
822 if (_content.length() > 0)
823 return true;
824 if (_parser.isState(Ajp13Parser.STATE_END))
825 return false;
826
827
828 if (_endp == null)
829 _parser.parseNext();
830
831
832 else if (_endp.isBlocking())
833 {
834 _parser.parseNext();
835
836
837 while (_content.length() == 0 && !_parser.isState(Ajp13Parser.STATE_END))
838 {
839
840 _parser.parseNext();
841 }
842 }
843 else
844 {
845 long filled = _parser.parseNext();
846 boolean blocked = false;
847
848
849
850 while (_content.length() == 0 && !_parser.isState(Ajp13Parser.STATE_END))
851 {
852
853
854 if (filled > 0)
855 blocked = false;
856 else if (filled == 0)
857 {
858 if (blocked)
859 throw new InterruptedIOException("timeout");
860
861 blocked = true;
862 _endp.blockReadable(_maxIdleTime);
863 }
864
865
866 filled = _parser.parseNext();
867 }
868 }
869
870 return _content.length() > 0;
871 }
872
873 }
874 }