Mercurial Hosting > luan
comparison src/org/eclipse/jetty/http/HttpGenerator.java @ 1070:a44fc6b53757
fix use of HttpGenerator._buffer
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 10 Nov 2016 01:23:37 -0700 |
parents | 7dd6ec499000 |
children | b4ba8a4d5a16 |
comparison
equal
deleted
inserted
replaced
1069:7dd6ec499000 | 1070:a44fc6b53757 |
---|---|
176 if (_head) | 176 if (_head) |
177 { | 177 { |
178 // content.clear(); | 178 // content.clear(); |
179 _content = null; | 179 _content = null; |
180 } | 180 } |
181 else if ((_buffer==null || _buffer.remaining()==0) && _content.hasRemaining() && (_last || isCommitted() && _content.remaining()>1024)) | 181 else if ((_buffer.position()==0) && _content.hasRemaining() && (_last || isCommitted() && _content.remaining()>1024)) |
182 { | 182 { |
183 _bypass = true; | 183 _bypass = true; |
184 } | 184 } |
185 else if (!_bufferChunked) | 185 else if (!_bufferChunked) |
186 { | 186 { |
187 //System.out.println("qqqqqqqqqqqqqqqqqqq c"); | 187 //System.out.println("qqqqqqqqqqqqqqqqqqq c"); |
188 // Copy _content to buffer; | 188 // Copy _content to buffer; |
189 int len = _buffer.put(_content); | 189 _buffer.putQ(_content); |
190 _content.skip(len); | |
191 if (!_content.hasRemaining()) | 190 if (!_content.hasRemaining()) |
192 _content = null; | 191 _content = null; |
193 } | 192 } |
194 } | 193 } |
195 | 194 |
215 flushBuffer(); | 214 flushBuffer(); |
216 if (_content != null && _content.hasRemaining() || _bufferChunked) | 215 if (_content != null && _content.hasRemaining() || _bufferChunked) |
217 throw new IllegalStateException("FULL"); | 216 throw new IllegalStateException("FULL"); |
218 } | 217 } |
219 | 218 |
220 _contentWritten -= _buffer.remaining(); | 219 _contentWritten -= _buffer.position(); |
221 /* | 220 /* |
222 // Handle the _content | 221 // Handle the _content |
223 if (_head) | 222 if (_head) |
224 return Integer.MAX_VALUE; | 223 return Integer.MAX_VALUE; |
225 | 224 |
228 } | 227 } |
229 | 228 |
230 public boolean isBufferFull() | 229 public boolean isBufferFull() |
231 { | 230 { |
232 // Should we flush the buffers? | 231 // Should we flush the buffers? |
233 return isBufferFull2() || _bufferChunked || _bypass /* || (_contentLength == HttpTokens.CHUNKED_CONTENT && _buffer != null && _buffer.space() < CHUNK_SPACE)*/; | 232 return isBufferFull2() || _bufferChunked || _bypass /* || (_contentLength == HttpTokens.CHUNKED_CONTENT && _buffer.remaining() < CHUNK_SPACE)*/; |
234 } | 233 } |
235 | 234 |
236 public void send1xx(int code) throws IOException | 235 public void send1xx(int code) throws IOException |
237 { | 236 { |
238 if (_state != STATE_HEADER) | 237 if (_state != STATE_HEADER) |
332 | 331 |
333 if (_status<200 && _status>=100 ) | 332 if (_status<200 && _status>=100 ) |
334 { | 333 { |
335 _noContent = true; | 334 _noContent = true; |
336 _content = null; | 335 _content = null; |
337 if (_buffer!=null) | 336 _buffer.clear(); |
338 _buffer.clearJ(); | |
339 // end the header. | 337 // end the header. |
340 | 338 |
341 if (_status!=101 ) | 339 if (_status!=101 ) |
342 { | 340 { |
343 _header.putQ(HttpTokens.CRLF); | 341 _header.putQ(HttpTokens.CRLF); |
347 } | 345 } |
348 else if (_status==204 || _status==304) | 346 else if (_status==204 || _status==304) |
349 { | 347 { |
350 _noContent = true; | 348 _noContent = true; |
351 _content = null; | 349 _content = null; |
352 if (_buffer!=null) | 350 _buffer.clear(); |
353 _buffer.clearJ(); | |
354 } | 351 } |
355 } | 352 } |
356 | 353 |
357 // key field values | 354 // key field values |
358 HttpFields.Field content_length = null; | 355 HttpFields.Field content_length = null; |
668 //qqq | 665 //qqq |
669 case 7: | 666 case 7: |
670 throw new IllegalStateException(); // should never happen! | 667 throw new IllegalStateException(); // should never happen! |
671 case 6: | 668 case 6: |
672 _header.flip(); | 669 _header.flip(); |
670 _buffer.flip(); | |
673 len = _endp.flush(_header, _buffer, null); | 671 len = _endp.flush(_header, _buffer, null); |
674 _header.compact(); | 672 _header.compact(); |
673 _buffer.compact(); | |
675 break; | 674 break; |
676 case 5: | 675 case 5: |
677 _header.flip(); | 676 _header.flip(); |
678 len = _endp.flush(_header, _content, null); | 677 len = _endp.flush(_header, _content, null); |
679 _header.compact(); | 678 _header.compact(); |
682 _header.flip(); | 681 _header.flip(); |
683 len = _endp.flush(_header); | 682 len = _endp.flush(_header); |
684 _header.compact(); | 683 _header.compact(); |
685 break; | 684 break; |
686 case 3: | 685 case 3: |
686 _buffer.flip(); | |
687 len = _endp.flush(_buffer, _content, null); | 687 len = _endp.flush(_buffer, _content, null); |
688 _buffer.compact(); | |
688 break; | 689 break; |
689 case 2: | 690 case 2: |
691 _buffer.flip(); | |
690 len = _endp.flush(_buffer); | 692 len = _endp.flush(_buffer); |
693 _buffer.compact(); | |
691 break; | 694 break; |
692 case 1: | 695 case 1: |
693 len = _endp.flush(_content); | 696 len = _endp.flush(_content); |
694 break; | 697 break; |
695 case 0: | 698 case 0: |
696 { | 699 { |
697 len=0; | 700 len = 0; |
698 // Nothing more we can write now. | 701 // Nothing more we can write now. |
699 _header.clear(); | 702 _header.clear(); |
700 | 703 |
701 _bypass = false; | 704 _bypass = false; |
702 _bufferChunked = false; | 705 _bufferChunked = false; |
703 | 706 |
704 if (_buffer != null) | 707 _buffer.clear(); // ? |
708 if (_contentLength == HttpTokens.CHUNKED_CONTENT) | |
705 { | 709 { |
706 _buffer.clearJ(); | 710 // Special case handling for small left over buffer from |
707 if (_contentLength == HttpTokens.CHUNKED_CONTENT) | 711 // an addContent that caused a buffer flush. |
712 if (_content != null && _content.remaining() < _buffer.remaining() && _state != STATE_FLUSHING) | |
708 { | 713 { |
709 // Special case handling for small left over buffer from | 714 _buffer.putQ(_content); |
710 // an addContent that caused a buffer flush. | 715 _content = null; |
711 if (_content != null && _content.remaining() < _buffer.space() && _state != STATE_FLUSHING) | |
712 { | |
713 _buffer.put(_content); | |
714 _content = null; | |
715 } | |
716 } | 716 } |
717 } | 717 } |
718 | 718 |
719 // Are we completely finished for now? | 719 // Are we completely finished for now? |
720 if (!_needCRLF && !_needEOC && (_content==null || !_content.hasRemaining())) | 720 if (!_needCRLF && !_needEOC && (_content==null || !_content.hasRemaining())) |
743 return total; | 743 return total; |
744 } | 744 } |
745 catch (IOException e) | 745 catch (IOException e) |
746 { | 746 { |
747 LOG.trace("",e); | 747 LOG.trace("",e); |
748 throw (e instanceof EofException) ? e:new EofException(e); | 748 throw (e instanceof EofException) ? e : new EofException(e); |
749 } | 749 } |
750 } | 750 } |
751 | 751 |
752 private int flushMask() | 752 private int flushMask() |
753 { | 753 { |
754 return ((_header.position() > 0)?4:0) | 754 return ((_header.position() > 0)?4:0) |
755 | ((_buffer != null && _buffer.remaining() > 0)?2:0) | 755 | ((_buffer.position() > 0)?2:0) |
756 | ((_bypass && _content != null && _content.hasRemaining())?1:0); | 756 | ((_bypass && _content != null && _content.hasRemaining())?1:0); |
757 } | 757 } |
758 | 758 |
759 private void prepareBuffers() | 759 private void prepareBuffers() |
760 { | 760 { |
761 // if we are not flushing an existing chunk | 761 // if we are not flushing an existing chunk |
762 if (!_bufferChunked) | 762 if (!_bufferChunked) |
763 { | 763 { |
764 // Refill buffer if possible | 764 // Refill buffer if possible |
765 if (!_bypass && _content != null && _content.hasRemaining() && _buffer != null && _buffer.space() > 0) | 765 if (!_bypass && _content != null && _content.hasRemaining() && _buffer.hasRemaining()) |
766 { | 766 { |
767 int len = _buffer.put(_content); | 767 _buffer.putQ(_content); |
768 _content.skip(len); | |
769 if (!_content.hasRemaining()) | 768 if (!_content.hasRemaining()) |
770 _content = null; | 769 _content = null; |
771 } | 770 } |
772 | 771 |
773 // Chunk buffer if need be | 772 // Chunk buffer if need be |
774 if (_contentLength == HttpTokens.CHUNKED_CONTENT) | 773 if (_contentLength == HttpTokens.CHUNKED_CONTENT) |
775 { | 774 { |
776 if (_bypass && (_buffer==null||_buffer.remaining()==0) && _content!=null) | 775 if (_bypass && _buffer.position()==0 && _content!=null) |
777 { | 776 { |
778 // this is a bypass write | 777 // this is a bypass write |
779 int size = _content.remaining(); | 778 int size = _content.remaining(); |
780 _bufferChunked = true; | 779 _bufferChunked = true; |
781 | 780 |
791 _header.putQ(HttpTokens.CRLF); | 790 _header.putQ(HttpTokens.CRLF); |
792 | 791 |
793 // Need a CRLF after the content | 792 // Need a CRLF after the content |
794 _needCRLF = true; | 793 _needCRLF = true; |
795 } | 794 } |
796 else if (_buffer!=null) | 795 else |
797 { | 796 { |
798 int size = _buffer.remaining(); | 797 int size = _buffer.position(); |
799 if (size > 0) | 798 if (size > 0) |
800 { | 799 { |
801 // Prepare a chunk! | 800 // Prepare a chunk! |
802 _bufferChunked = true; | 801 _bufferChunked = true; |
803 | 802 |
809 } | 808 } |
810 BufferUtil.putHexInt(_header, size); | 809 BufferUtil.putHexInt(_header, size); |
811 _header.putQ(HttpTokens.CRLF); | 810 _header.putQ(HttpTokens.CRLF); |
812 | 811 |
813 // Add end chunk trailer. | 812 // Add end chunk trailer. |
814 if (_buffer.space() >= 2) | 813 if (_buffer.remaining() >= 2) |
815 _buffer.put(HttpTokens.CRLF); | 814 _buffer.putQ(HttpTokens.CRLF); |
816 else | 815 else |
817 _needCRLF = true; | 816 _needCRLF = true; |
818 } | 817 } |
819 } | 818 } |
820 | 819 |
821 // If we need EOC and everything written | 820 // If we need EOC and everything written |
822 if (_needEOC && (_content == null || !_content.hasRemaining())) | 821 if (_needEOC && (_content == null || !_content.hasRemaining())) |
823 { | 822 { |
824 if (_needCRLF) | 823 if (_needCRLF && _buffer.remaining() >= HttpTokens.CRLF.length) { |
825 { | 824 _buffer.putQ(HttpTokens.CRLF); |
826 if (_buffer == null && _header.remaining() >= HttpTokens.CRLF.length) | 825 _needCRLF = false; |
826 } | |
827 | |
828 if (!_needCRLF && _needEOC && _buffer.remaining() >= LAST_CHUNK.length) { | |
829 if (!_head) | |
827 { | 830 { |
828 _header.putQ(HttpTokens.CRLF); | 831 _buffer.putQ(LAST_CHUNK); |
829 _needCRLF = false; | 832 _bufferChunked = true; |
830 } | 833 } |
831 else if (_buffer!=null && _buffer.space() >= HttpTokens.CRLF.length) | 834 _needEOC = false; |
832 { | |
833 _buffer.put(HttpTokens.CRLF); | |
834 _needCRLF = false; | |
835 } | |
836 } | |
837 | |
838 if (!_needCRLF && _needEOC) | |
839 { | |
840 if (_buffer == null && _header.remaining() >= LAST_CHUNK.length) | |
841 { | |
842 if (!_head) | |
843 { | |
844 _header.putQ(LAST_CHUNK); | |
845 _bufferChunked=true; | |
846 } | |
847 _needEOC = false; | |
848 } | |
849 else if (_buffer!=null && _buffer.space() >= LAST_CHUNK.length) | |
850 { | |
851 if (!_head) | |
852 { | |
853 _buffer.put(LAST_CHUNK); | |
854 _bufferChunked=true; | |
855 } | |
856 _needEOC = false; | |
857 } | |
858 } | 835 } |
859 } | 836 } |
860 } | 837 } |
861 } | 838 } |
862 | 839 |
867 | 844 |
868 @Override | 845 @Override |
869 public String toString() | 846 public String toString() |
870 { | 847 { |
871 JBuffer header = _header; | 848 JBuffer header = _header; |
872 JBuffer buffer=_buffer; | 849 JBuffer buffer = _buffer; |
873 JBuffer content = _content; | 850 JBuffer content = _content; |
874 return String.format("%s{s=%d,h=%d,b=%d,c=%d}", | 851 return String.format("%s{s=%d,h=%d,b=%d,c=%d}", |
875 getClass().getSimpleName(), | 852 getClass().getSimpleName(), |
876 _state, | 853 _state, |
877 header == null ? -1 : header.position(), | 854 header == null ? -1 : header.position(), |
878 buffer == null ? -1 : buffer.remaining(), | 855 buffer == null ? -1 : buffer.position(), |
879 content == null ? -1 : content.remaining()); | 856 content == null ? -1 : content.remaining()); |
880 } | 857 } |
881 | 858 |
882 | 859 |
883 | 860 |
928 { | 905 { |
929 this._buffers = buffers; | 906 this._buffers = buffers; |
930 this._endp = io; | 907 this._endp = io; |
931 _header = _buffers.getHeader(); | 908 _header = _buffers.getHeader(); |
932 _buffer = _buffers.getBuffer(); | 909 _buffer = _buffers.getBuffer(); |
933 _buffer.limit(0); | |
934 } | 910 } |
935 | 911 |
936 public final boolean isOpen() | 912 public final boolean isOpen() |
937 { | 913 { |
938 return _endp.isOpen(); | 914 return _endp.isOpen(); |
946 _last = false; | 922 _last = false; |
947 _persistent = null; | 923 _persistent = null; |
948 _contentWritten = 0; | 924 _contentWritten = 0; |
949 _contentLength = HttpTokens.UNKNOWN_CONTENT; | 925 _contentLength = HttpTokens.UNKNOWN_CONTENT; |
950 _content = null; | 926 _content = null; |
951 if (_buffer!=null) | 927 _buffer.clear(); |
952 _buffer.clearJ(); | |
953 } | 928 } |
954 | 929 |
955 /* ------------------------------------------------------------ */ | 930 /* ------------------------------------------------------------ */ |
956 /** | 931 /** |
957 * @return Returns the contentBufferSize. | 932 * @return Returns the contentBufferSize. |
1050 } | 1025 } |
1051 } | 1026 } |
1052 | 1027 |
1053 public final void completeUncheckedAddContent() | 1028 public final void completeUncheckedAddContent() |
1054 { | 1029 { |
1055 _contentWritten += _buffer.remaining(); | 1030 _contentWritten += _buffer.position(); |
1056 if (_head) | 1031 if (_head) |
1057 _buffer.clearJ(); | 1032 _buffer.clear(); |
1058 } | 1033 } |
1059 | 1034 |
1060 private boolean isBufferFull2() | 1035 private boolean isBufferFull2() |
1061 { | 1036 { |
1062 if (_buffer != null && _buffer.space()==0) | 1037 return !_buffer.hasRemaining() || _content!=null && _content.remaining()>0; |
1063 { | |
1064 if (_buffer.remaining()==0) | |
1065 _buffer.limit(0); | |
1066 return _buffer.space()==0; | |
1067 } | |
1068 | |
1069 return _content!=null && _content.remaining()>0; | |
1070 } | 1038 } |
1071 | 1039 |
1072 public final boolean isWritten() | 1040 public final boolean isWritten() |
1073 { | 1041 { |
1074 return _contentWritten>0; | 1042 return _contentWritten>0; |
1097 | 1065 |
1098 | 1066 |
1099 public final void flush(long maxIdleTime) throws IOException | 1067 public final void flush(long maxIdleTime) throws IOException |
1100 { | 1068 { |
1101 // block until everything is flushed | 1069 // block until everything is flushed |
1102 long now=System.currentTimeMillis(); | 1070 long now = System.currentTimeMillis(); |
1103 long end=now+maxIdleTime; | 1071 long end = now+maxIdleTime; |
1104 JBuffer content = _content; | 1072 JBuffer content = _content; |
1105 JBuffer buffer = _buffer; | 1073 JBuffer buffer = _buffer; |
1106 if (content!=null && content.remaining()>0 || buffer!=null && buffer.remaining()>0 || isBufferFull()) | 1074 if (content!=null && content.remaining()>0 || buffer.position()>0 || isBufferFull()) |
1107 { | 1075 { |
1108 flushBuffer(); | 1076 flushBuffer(); |
1109 | 1077 |
1110 while (now<end && (content!=null && content.remaining()>0 ||buffer!=null && buffer.remaining()>0) && _endp.isOpen()&& !_endp.isOutputShutdown()) | 1078 while (now<end && (content!=null && content.remaining()>0 || buffer.position()>0) && _endp.isOpen()&& !_endp.isOutputShutdown()) |
1111 { | 1079 { |
1112 blockForOutput(end-now); | 1080 blockForOutput(end-now); |
1113 now=System.currentTimeMillis(); | 1081 now = System.currentTimeMillis(); |
1114 } | 1082 } |
1115 } | 1083 } |
1116 } | 1084 } |
1117 | 1085 |
1118 /* ------------------------------------------------------------ */ | 1086 /* ------------------------------------------------------------ */ |