11using System ;
22using System . Globalization ;
33using System . IO ;
4+ using System . Threading ;
45using System . Threading . Tasks ;
56using Titanium . Web . Proxy . Exceptions ;
6- using Titanium . Web . Proxy . Helpers ;
77using Titanium . Web . Proxy . StreamExtended . BufferPool ;
88using Titanium . Web . Proxy . StreamExtended . Network ;
99
@@ -51,11 +51,22 @@ private void getNextChunk()
5151 {
5252 // read the chunk trail of the previous chunk
5353 string ? s = baseReader . ReadLineAsync ( ) . Result ;
54+ if ( s == null )
55+ {
56+ bytesRemaining = - 1 ;
57+ return ;
58+ }
5459 }
5560
5661 readChunkTrail = true ;
5762
58- string ? chunkHead = baseReader . ReadLineAsync ( ) . Result ! ;
63+ string ? chunkHead = baseReader . ReadLineAsync ( ) . Result ;
64+ if ( chunkHead == null )
65+ {
66+ bytesRemaining = - 1 ;
67+ return ;
68+ }
69+
5970 int idx = chunkHead . IndexOf ( ";" , StringComparison . Ordinal ) ;
6071 if ( idx >= 0 )
6172 {
@@ -80,6 +91,50 @@ private void getNextChunk()
8091 }
8192 }
8293
94+ private async Task getNextChunkAsync ( )
95+ {
96+ if ( readChunkTrail )
97+ {
98+ // read the chunk trail of the previous chunk
99+ string ? s = await baseReader . ReadLineAsync ( ) ;
100+ if ( s == null )
101+ {
102+ bytesRemaining = - 1 ;
103+ return ;
104+ }
105+ }
106+
107+ readChunkTrail = true ;
108+
109+ string ? chunkHead = await baseReader . ReadLineAsync ( ) ;
110+ if ( chunkHead == null )
111+ {
112+ bytesRemaining = - 1 ;
113+ return ;
114+ }
115+
116+ int idx = chunkHead . IndexOf ( ";" , StringComparison . Ordinal ) ;
117+ if ( idx >= 0 )
118+ {
119+ chunkHead = chunkHead . Substring ( 0 , idx ) ;
120+ }
121+
122+ if ( ! int . TryParse ( chunkHead , NumberStyles . HexNumber , null , out int chunkSize ) )
123+ {
124+ throw new ProxyHttpException ( $ "Invalid chunk length: '{ chunkHead } '", null , null ) ;
125+ }
126+
127+ bytesRemaining = chunkSize ;
128+
129+ if ( chunkSize == 0 )
130+ {
131+ bytesRemaining = - 1 ;
132+
133+ // chunk trail
134+ await baseReader . ReadLineAsync ( ) ;
135+ }
136+ }
137+
83138 public override void Flush ( )
84139 {
85140 throw new NotSupportedException ( ) ;
@@ -131,6 +186,42 @@ public override int Read(byte[] buffer, int offset, int count)
131186 return res ;
132187 }
133188
189+ public override async Task < int > ReadAsync ( byte [ ] buffer , int offset , int count , CancellationToken cancellationToken )
190+ {
191+ if ( bytesRemaining == - 1 )
192+ {
193+ return 0 ;
194+ }
195+
196+ if ( bytesRemaining == 0 )
197+ {
198+ if ( isChunked )
199+ {
200+ await getNextChunkAsync ( ) ;
201+ }
202+ else
203+ {
204+ bytesRemaining = - 1 ;
205+ }
206+ }
207+
208+ if ( bytesRemaining == - 1 )
209+ {
210+ return 0 ;
211+ }
212+
213+ int toRead = ( int ) Math . Min ( count , bytesRemaining ) ;
214+ int res = await baseReader . ReadAsync ( buffer , offset , toRead , cancellationToken ) ;
215+ bytesRemaining -= res ;
216+
217+ if ( res == 0 )
218+ {
219+ bytesRemaining = - 1 ;
220+ }
221+
222+ return res ;
223+ }
224+
134225 public async Task Finish ( )
135226 {
136227 if ( bytesRemaining != - 1 )
0 commit comments