Mercurial Hosting > luan
comparison src/org/eclipse/jetty/http/HttpGenerator.java @ 1066:bbbda7c6e8ec
fix use of HttpGenerator._header
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 09 Nov 2016 05:48:10 -0700 |
parents | 158d1e6ac17f |
children | 56b515be91e1 |
comparison
equal
deleted
inserted
replaced
1065:158d1e6ac17f | 1066:bbbda7c6e8ec |
---|---|
148 if (_content != null && _content.remaining()>0) | 148 if (_content != null && _content.remaining()>0) |
149 { | 149 { |
150 if (_bufferChunked) | 150 if (_bufferChunked) |
151 { | 151 { |
152 JBuffer nc = _buffers.getBuffer(_content.remaining()+CHUNK_SPACE+content.remaining()); | 152 JBuffer nc = _buffers.getBuffer(_content.remaining()+CHUNK_SPACE+content.remaining()); |
153 nc.put(_content); | 153 nc.clear(); |
154 nc.put(HttpTokens.CRLF); | 154 nc.putQ(_content); |
155 nc.putQ(HttpTokens.CRLF); | |
155 BufferUtil.putHexInt(nc, content.remaining()); | 156 BufferUtil.putHexInt(nc, content.remaining()); |
156 nc.put(HttpTokens.CRLF); | 157 nc.putQ(HttpTokens.CRLF); |
157 nc.put(content); | 158 nc.putQ(content); |
158 content=nc; | 159 nc.flip(); |
160 content = nc; | |
159 } | 161 } |
160 else | 162 else |
161 { | 163 { |
162 JBuffer nc = _buffers.getBuffer(_content.remaining()+content.remaining()); | 164 JBuffer nc = _buffers.getBuffer(_content.remaining()+content.remaining()); |
163 nc.put(_content); | 165 nc.clear(); |
164 nc.put(content); | 166 nc.putQ(_content); |
165 content=nc; | 167 nc.putQ(content); |
168 nc.flip(); | |
169 content = nc; | |
166 } | 170 } |
167 } | 171 } |
168 } | 172 } |
169 | 173 |
170 _content = content; | 174 _content = content; |
243 throw new IllegalArgumentException("!1xx"); | 247 throw new IllegalArgumentException("!1xx"); |
244 Status status = __status[code]; | 248 Status status = __status[code]; |
245 if (status==null) | 249 if (status==null) |
246 throw new IllegalArgumentException(code+"?"); | 250 throw new IllegalArgumentException(code+"?"); |
247 | 251 |
248 // get a header buffer | 252 _header.putQ(status._responseLine); |
249 if (_header == null) | 253 _header.putQ(HttpTokens.CRLF); |
250 _header = _buffers.getHeader(); | |
251 | |
252 _header.put(status._responseLine); | |
253 _header.put(HttpTokens.CRLF); | |
254 | 254 |
255 try | 255 try |
256 { | 256 { |
257 // nasty semi busy flush! | 257 // nasty semi busy flush! |
258 _header.flip(); | |
258 while(_header.remaining()>0) | 259 while(_header.remaining()>0) |
259 { | 260 { |
260 int len = _endp.flush(_header); | 261 int len = _endp.flush(_header); |
261 if (len<0) | 262 if (len<0) |
262 throw new EofException(); | 263 throw new EofException(); |
282 | 283 |
283 if (_last && !allContentAdded) | 284 if (_last && !allContentAdded) |
284 throw new IllegalStateException("last?"); | 285 throw new IllegalStateException("last?"); |
285 _last = _last | allContentAdded; | 286 _last = _last | allContentAdded; |
286 | 287 |
287 // get a header buffer | |
288 if (_header == null) | |
289 _header = _buffers.getHeader(); | |
290 | |
291 boolean has_server = false; | 288 boolean has_server = false; |
292 | 289 |
293 try | 290 try |
294 { | 291 { |
295 // Responses | 292 // Responses |
308 // add response line | 305 // add response line |
309 Status status = _status<__status.length?__status[_status]:null; | 306 Status status = _status<__status.length?__status[_status]:null; |
310 | 307 |
311 if (status==null) | 308 if (status==null) |
312 { | 309 { |
313 _header.put(HttpVersions.HTTP_1_1_BYTES); | 310 _header.putQ(HttpVersions.HTTP_1_1_BYTES); |
314 _header.put((byte) ' '); | 311 _header.putQ((byte) ' '); |
315 _header.put((byte) ('0' + _status / 100)); | 312 _header.putQ((byte) ('0' + _status / 100)); |
316 _header.put((byte) ('0' + (_status % 100) / 10)); | 313 _header.putQ((byte) ('0' + (_status % 100) / 10)); |
317 _header.put((byte) ('0' + (_status % 10))); | 314 _header.putQ((byte) ('0' + (_status % 10))); |
318 _header.put((byte) ' '); | 315 _header.putQ((byte) ' '); |
319 if (_reason==null) | 316 if (_reason==null) |
320 { | 317 { |
321 _header.put((byte) ('0' + _status / 100)); | 318 _header.putQ((byte) ('0' + _status / 100)); |
322 _header.put((byte) ('0' + (_status % 100) / 10)); | 319 _header.putQ((byte) ('0' + (_status % 100) / 10)); |
323 _header.put((byte) ('0' + (_status % 10))); | 320 _header.putQ((byte) ('0' + (_status % 10))); |
324 } | 321 } |
325 else | 322 else |
326 _header.put(_reason); | 323 _header.putQ(_reason); |
327 _header.put(HttpTokens.CRLF); | 324 _header.putQ(HttpTokens.CRLF); |
328 } | 325 } |
329 else | 326 else |
330 { | 327 { |
331 if (_reason==null) | 328 if (_reason==null) |
332 _header.put(status._responseLine); | 329 _header.putQ(status._responseLine); |
333 else | 330 else |
334 { | 331 { |
335 _header.put(status._schemeCode); | 332 _header.putQ(status._schemeCode); |
336 _header.put(_reason); | 333 _header.putQ(_reason); |
337 _header.put(HttpTokens.CRLF); | 334 _header.putQ(HttpTokens.CRLF); |
338 } | 335 } |
339 } | 336 } |
340 | 337 |
341 if (_status<200 && _status>=100 ) | 338 if (_status<200 && _status>=100 ) |
342 { | 339 { |
346 _buffer.clearJ(); | 343 _buffer.clearJ(); |
347 // end the header. | 344 // end the header. |
348 | 345 |
349 if (_status!=101 ) | 346 if (_status!=101 ) |
350 { | 347 { |
351 _header.put(HttpTokens.CRLF); | 348 _header.putQ(HttpTokens.CRLF); |
352 _state = STATE_CONTENT; | 349 _state = STATE_CONTENT; |
353 return; | 350 return; |
354 } | 351 } |
355 } | 352 } |
356 else if (_status==204 || _status==304) | 353 else if (_status==204 || _status==304) |
530 // we have seen all the _content there is | 527 // we have seen all the _content there is |
531 _contentLength = _contentWritten; | 528 _contentLength = _contentWritten; |
532 if (content_length == null && !_noContent) | 529 if (content_length == null && !_noContent) |
533 { | 530 { |
534 // known length but not actually set. | 531 // known length but not actually set. |
535 _header.put(HttpHeaders.CONTENT_LENGTH_BYTES); | 532 _header.putQ(HttpHeaders.CONTENT_LENGTH_BYTES); |
536 _header.put(HttpTokens.COLON); | 533 _header.putQ(HttpTokens.COLON); |
537 _header.put((byte) ' '); | 534 _header.putQ((byte) ' '); |
538 BufferUtil.putDecLong(_header, _contentLength); | 535 BufferUtil.putDecLong(_header, _contentLength); |
539 _header.put(HttpTokens.CRLF); | 536 _header.putQ(HttpTokens.CRLF); |
540 } | 537 } |
541 } | 538 } |
542 else | 539 else |
543 { | 540 { |
544 // No idea, so we must assume that a body is coming | 541 // No idea, so we must assume that a body is coming |
546 } | 543 } |
547 break; | 544 break; |
548 | 545 |
549 case HttpTokens.NO_CONTENT: | 546 case HttpTokens.NO_CONTENT: |
550 if (content_length == null && _status >= 200 && _status != 204 && _status != 304) | 547 if (content_length == null && _status >= 200 && _status != 204 && _status != 304) |
551 _header.put(CONTENT_LENGTH_0); | 548 _header.putQ(CONTENT_LENGTH_0); |
552 break; | 549 break; |
553 | 550 |
554 case HttpTokens.EOF_CONTENT: | 551 case HttpTokens.EOF_CONTENT: |
555 _persistent = false; | 552 _persistent = false; |
556 break; | 553 break; |
574 transfer_encoding.putTo(_header); | 571 transfer_encoding.putTo(_header); |
575 else | 572 else |
576 throw new IllegalArgumentException("BAD TE"); | 573 throw new IllegalArgumentException("BAD TE"); |
577 } | 574 } |
578 else | 575 else |
579 _header.put(TRANSFER_ENCODING_CHUNKED); | 576 _header.putQ(TRANSFER_ENCODING_CHUNKED); |
580 } | 577 } |
581 | 578 |
582 // Handle connection if need be | 579 // Handle connection if need be |
583 if (_contentLength==HttpTokens.EOF_CONTENT) | 580 if (_contentLength==HttpTokens.EOF_CONTENT) |
584 { | 581 { |
586 _persistent=false; | 583 _persistent=false; |
587 } | 584 } |
588 | 585 |
589 if (!_persistent && (close || _version > HttpVersions.HTTP_1_0_ORDINAL)) | 586 if (!_persistent && (close || _version > HttpVersions.HTTP_1_0_ORDINAL)) |
590 { | 587 { |
591 _header.put(CONNECTION_CLOSE); | 588 _header.putQ(CONNECTION_CLOSE); |
592 if (connection!=null) | 589 if (connection!=null) |
593 { | 590 { |
594 _header.setPutIndex(_header.putIndex()-2); | 591 _header.position(_header.position()-2); |
595 _header.put((byte)','); | 592 _header.putQ((byte)','); |
596 _header.put(connection.toString().getBytes()); | 593 _header.putQ(connection.toString().getBytes()); |
597 _header.put(CRLF); | 594 _header.putQ(CRLF); |
598 } | 595 } |
599 } | 596 } |
600 else if (keep_alive) | 597 else if (keep_alive) |
601 { | 598 { |
602 _header.put(CONNECTION_KEEP_ALIVE); | 599 _header.putQ(CONNECTION_KEEP_ALIVE); |
603 if (connection!=null) | 600 if (connection!=null) |
604 { | 601 { |
605 _header.setPutIndex(_header.putIndex()-2); | 602 _header.position(_header.position()-2); |
606 _header.put((byte)','); | 603 _header.putQ((byte)','); |
607 _header.put(connection.toString().getBytes()); | 604 _header.putQ(connection.toString().getBytes()); |
608 _header.put(CRLF); | 605 _header.putQ(CRLF); |
609 } | 606 } |
610 } | 607 } |
611 else if (connection!=null) | 608 else if (connection!=null) |
612 { | 609 { |
613 _header.put(CONNECTION_); | 610 _header.putQ(CONNECTION_); |
614 _header.put(connection.toString().getBytes()); | 611 _header.putQ(connection.toString().getBytes()); |
615 _header.put(CRLF); | 612 _header.putQ(CRLF); |
616 } | 613 } |
617 | 614 |
618 if (!has_server && _status>199) | 615 if (!has_server && _status>199) |
619 _header.put(SERVER); | 616 _header.putQ(SERVER); |
620 | 617 |
621 // end the header. | 618 // end the header. |
622 _header.put(HttpTokens.CRLF); | 619 _header.putQ(HttpTokens.CRLF); |
623 _state = STATE_CONTENT; | 620 _state = STATE_CONTENT; |
624 | 621 |
625 } | 622 } |
626 catch(ArrayIndexOutOfBoundsException e) | 623 catch(ArrayIndexOutOfBoundsException e) |
627 { | 624 { |
628 throw new RuntimeException("Header>"+_header.capacity(),e); | 625 throw new RuntimeException("Header>"+_header.remaining(),e); |
629 } | 626 } |
630 } | 627 } |
631 | 628 |
632 /* ------------------------------------------------------------ */ | 629 /* ------------------------------------------------------------ */ |
633 /** | 630 /** |
671 do | 668 do |
672 { | 669 { |
673 last_flush = to_flush; | 670 last_flush = to_flush; |
674 switch (to_flush) | 671 switch (to_flush) |
675 { | 672 { |
673 //qqq | |
676 case 7: | 674 case 7: |
677 throw new IllegalStateException(); // should never happen! | 675 throw new IllegalStateException(); // should never happen! |
678 case 6: | 676 case 6: |
677 _header.flip(); | |
679 len = _endp.flush(_header, _buffer, null); | 678 len = _endp.flush(_header, _buffer, null); |
679 _header.compact(); | |
680 break; | 680 break; |
681 case 5: | 681 case 5: |
682 _header.flip(); | |
682 len = _endp.flush(_header, _content, null); | 683 len = _endp.flush(_header, _content, null); |
684 _header.compact(); | |
683 break; | 685 break; |
684 case 4: | 686 case 4: |
687 _header.flip(); | |
685 len = _endp.flush(_header); | 688 len = _endp.flush(_header); |
689 _header.compact(); | |
686 break; | 690 break; |
687 case 3: | 691 case 3: |
688 len = _endp.flush(_buffer, _content, null); | 692 len = _endp.flush(_buffer, _content, null); |
689 break; | 693 break; |
690 case 2: | 694 case 2: |
695 break; | 699 break; |
696 case 0: | 700 case 0: |
697 { | 701 { |
698 len=0; | 702 len=0; |
699 // Nothing more we can write now. | 703 // Nothing more we can write now. |
700 if (_header != null) | 704 _header.clear(); |
701 _header.clearJ(); | |
702 | 705 |
703 _bypass = false; | 706 _bypass = false; |
704 _bufferChunked = false; | 707 _bufferChunked = false; |
705 | 708 |
706 if (_buffer != null) | 709 if (_buffer != null) |
752 } | 755 } |
753 } | 756 } |
754 | 757 |
755 private int flushMask() | 758 private int flushMask() |
756 { | 759 { |
757 return ((_header != null && _header.remaining() > 0)?4:0) | 760 return ((_header.position() > 0)?4:0) |
758 | ((_buffer != null && _buffer.remaining() > 0)?2:0) | 761 | ((_buffer != null && _buffer.remaining() > 0)?2:0) |
759 | ((_bypass && _content != null && _content.remaining() > 0)?1:0); | 762 | ((_bypass && _content != null && _content.remaining() > 0)?1:0); |
760 } | 763 } |
761 | 764 |
762 private void prepareBuffers() | 765 private void prepareBuffers() |
780 { | 783 { |
781 // this is a bypass write | 784 // this is a bypass write |
782 int size = _content.remaining(); | 785 int size = _content.remaining(); |
783 _bufferChunked = true; | 786 _bufferChunked = true; |
784 | 787 |
785 if (_header == null) | |
786 _header = _buffers.getHeader(); | |
787 | |
788 // if we need CRLF add this to header | 788 // if we need CRLF add this to header |
789 if (_needCRLF) | 789 if (_needCRLF) |
790 { | 790 { |
791 if (_header.remaining() > 0) throw new IllegalStateException("EOC"); | 791 if (_header.position() > 0) throw new IllegalStateException("EOC"); |
792 _header.put(HttpTokens.CRLF); | 792 _header.putQ(HttpTokens.CRLF); |
793 _needCRLF = false; | 793 _needCRLF = false; |
794 } | 794 } |
795 // Add the chunk size to the header | 795 // Add the chunk size to the header |
796 BufferUtil.putHexInt(_header, size); | 796 BufferUtil.putHexInt(_header, size); |
797 _header.put(HttpTokens.CRLF); | 797 _header.putQ(HttpTokens.CRLF); |
798 | 798 |
799 // Need a CRLF after the content | 799 // Need a CRLF after the content |
800 _needCRLF = true; | 800 _needCRLF = true; |
801 } | 801 } |
802 else if (_buffer!=null) | 802 else if (_buffer!=null) |
805 if (size > 0) | 805 if (size > 0) |
806 { | 806 { |
807 // Prepare a chunk! | 807 // Prepare a chunk! |
808 _bufferChunked = true; | 808 _bufferChunked = true; |
809 | 809 |
810 if (_header == null) | |
811 _header = _buffers.getHeader(); | |
812 | |
813 if (_needCRLF) | 810 if (_needCRLF) |
814 { | 811 { |
815 if (_header.remaining() > 0) throw new IllegalStateException("EOC"); | 812 if (_header.position() > 0) throw new IllegalStateException("EOC"); |
816 _header.put(HttpTokens.CRLF); | 813 _header.putQ(HttpTokens.CRLF); |
817 _needCRLF = false; | 814 _needCRLF = false; |
818 } | 815 } |
819 BufferUtil.putHexInt(_header, size); | 816 BufferUtil.putHexInt(_header, size); |
820 _header.put(HttpTokens.CRLF); | 817 _header.putQ(HttpTokens.CRLF); |
821 | 818 |
822 // Add end chunk trailer. | 819 // Add end chunk trailer. |
823 if (_buffer.space() >= 2) | 820 if (_buffer.space() >= 2) |
824 _buffer.put(HttpTokens.CRLF); | 821 _buffer.put(HttpTokens.CRLF); |
825 else | 822 else |
828 } | 825 } |
829 | 826 |
830 // If we need EOC and everything written | 827 // If we need EOC and everything written |
831 if (_needEOC && (_content == null || _content.remaining() == 0)) | 828 if (_needEOC && (_content == null || _content.remaining() == 0)) |
832 { | 829 { |
833 if (_header == null && _buffer == null) | |
834 _header = _buffers.getHeader(); | |
835 | |
836 if (_needCRLF) | 830 if (_needCRLF) |
837 { | 831 { |
838 if (_buffer == null && _header != null && _header.space() >= HttpTokens.CRLF.length) | 832 if (_buffer == null && _header.remaining() >= HttpTokens.CRLF.length) |
839 { | 833 { |
840 _header.put(HttpTokens.CRLF); | 834 _header.putQ(HttpTokens.CRLF); |
841 _needCRLF = false; | 835 _needCRLF = false; |
842 } | 836 } |
843 else if (_buffer!=null && _buffer.space() >= HttpTokens.CRLF.length) | 837 else if (_buffer!=null && _buffer.space() >= HttpTokens.CRLF.length) |
844 { | 838 { |
845 _buffer.put(HttpTokens.CRLF); | 839 _buffer.put(HttpTokens.CRLF); |
847 } | 841 } |
848 } | 842 } |
849 | 843 |
850 if (!_needCRLF && _needEOC) | 844 if (!_needCRLF && _needEOC) |
851 { | 845 { |
852 if (_buffer == null && _header != null && _header.space() >= LAST_CHUNK.length) | 846 if (_buffer == null && _header.remaining() >= LAST_CHUNK.length) |
853 { | 847 { |
854 if (!_head) | 848 if (!_head) |
855 { | 849 { |
856 _header.put(LAST_CHUNK); | 850 _header.putQ(LAST_CHUNK); |
857 _bufferChunked=true; | 851 _bufferChunked=true; |
858 } | 852 } |
859 _needEOC = false; | 853 _needEOC = false; |
860 } | 854 } |
861 else if (_buffer!=null && _buffer.space() >= LAST_CHUNK.length) | 855 else if (_buffer!=null && _buffer.space() >= LAST_CHUNK.length) |
878 } | 872 } |
879 | 873 |
880 @Override | 874 @Override |
881 public String toString() | 875 public String toString() |
882 { | 876 { |
883 JBuffer header=_header; | 877 JBuffer header = _header; |
884 JBuffer buffer=_buffer; | 878 JBuffer buffer=_buffer; |
885 JBuffer content=_content; | 879 JBuffer content=_content; |
886 return String.format("%s{s=%d,h=%d,b=%d,c=%d}", | 880 return String.format("%s{s=%d,h=%d,b=%d,c=%d}", |
887 getClass().getSimpleName(), | 881 getClass().getSimpleName(), |
888 _state, | 882 _state, |
889 header == null ? -1 : header.remaining(), | 883 header == null ? -1 : header.position(), |
890 buffer == null ? -1 : buffer.remaining(), | 884 buffer == null ? -1 : buffer.remaining(), |
891 content == null ? -1 : content.remaining()); | 885 content == null ? -1 : content.remaining()); |
892 } | 886 } |
893 | 887 |
894 | 888 |
929 private boolean _last = false; | 923 private boolean _last = false; |
930 private boolean _head = false; | 924 private boolean _head = false; |
931 private boolean _noContent = false; | 925 private boolean _noContent = false; |
932 private Boolean _persistent = null; | 926 private Boolean _persistent = null; |
933 | 927 |
934 private JBuffer _header; // JBuffer for HTTP header (and maybe small _content) | 928 private final JBuffer _header; // JBuffer for HTTP header (and maybe small _content) |
935 private JBuffer _buffer; // JBuffer for copy of passed _content | 929 private JBuffer _buffer; // JBuffer for copy of passed _content |
936 private JBuffer _content; // JBuffer passed to addContent | 930 private JBuffer _content; // JBuffer passed to addContent |
937 | 931 |
938 | 932 |
939 public HttpGenerator(Buffers buffers, EndPoint io) | 933 public HttpGenerator(Buffers buffers, EndPoint io) |
940 { | 934 { |
941 this._buffers = buffers; | 935 this._buffers = buffers; |
942 this._endp = io; | 936 this._endp = io; |
937 _header = _buffers.getHeader(); | |
938 _header.clear(); | |
943 } | 939 } |
944 | 940 |
945 public final boolean isOpen() | 941 public final boolean isOpen() |
946 { | 942 { |
947 return _endp.isOpen(); | 943 return _endp.isOpen(); |