1
- // Copyright (c) .NET Foundation. All rights reserved.
1
+ // Copyright (c) .NET Foundation. All rights reserved.
2
2
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3
3
4
4
using System ;
@@ -75,7 +75,7 @@ private async Task ProcessRequestsAsync()
75
75
private bool HandleRequests ( in ReadOnlySequence < byte > buffer , bool isCompleted )
76
76
{
77
77
var reader = new SequenceReader < byte > ( buffer ) ;
78
- var writer = GetWriter ( Writer ) ;
78
+ var writer = GetWriter ( Writer , sizeHint : 160 * 16 ) ; // 160*16 is for Plaintext, for Json 160 would be enough
79
79
80
80
while ( true )
81
81
{
@@ -112,18 +112,21 @@ private bool ParseHttpRequest(ref SequenceReader<byte> reader, bool isCompleted)
112
112
113
113
if ( state == State . StartLine )
114
114
{
115
- #if NETCOREAPP5_0
116
- var unconsumedSequence = reader . UnreadSequence ;
115
+ #if NETCOREAPP5_0 || NET5_0
116
+ if ( Parser . ParseRequestLine ( new ParsingAdapter ( this ) , ref reader ) )
117
+ {
118
+ state = State . Headers ;
119
+ }
117
120
#else
118
121
var unconsumedSequence = reader . Sequence . Slice ( reader . Position ) ;
119
- #endif
120
122
if ( Parser . ParseRequestLine ( new ParsingAdapter ( this ) , unconsumedSequence , out var consumed , out _ ) )
121
123
{
122
124
state = State . Headers ;
123
125
124
126
var parsedLength = unconsumedSequence . Slice ( reader . Position , consumed ) . Length ;
125
127
reader . Advance ( parsedLength ) ;
126
128
}
129
+ #endif
127
130
}
128
131
129
132
if ( state == State . Headers )
@@ -150,11 +153,17 @@ private async Task ProcessRequestsAsync()
150
153
while ( true )
151
154
{
152
155
var readResult = await Reader . ReadAsync ( ) ;
153
-
154
156
var buffer = readResult . Buffer ;
157
+ var isCompleted = readResult . IsCompleted ;
158
+
159
+ if ( buffer . IsEmpty && isCompleted )
160
+ {
161
+ return ;
162
+ }
163
+
155
164
while ( true )
156
165
{
157
- if ( ! ParseHttpRequest ( ref buffer , readResult . IsCompleted , out var examined ) )
166
+ if ( ! ParseHttpRequest ( ref buffer , isCompleted ) )
158
167
{
159
168
return ;
160
169
}
@@ -173,67 +182,71 @@ private async Task ProcessRequestsAsync()
173
182
}
174
183
175
184
// No more input or incomplete data, Advance the Reader
176
- Reader . AdvanceTo ( buffer . Start , examined ) ;
185
+ Reader . AdvanceTo ( buffer . Start , buffer . End ) ;
177
186
break ;
178
187
}
179
188
180
189
await Writer . FlushAsync ( ) ;
181
190
}
182
191
}
183
192
184
- private bool ParseHttpRequest ( ref ReadOnlySequence < byte > buffer , bool isCompleted , out SequencePosition examined )
193
+ private bool ParseHttpRequest ( ref ReadOnlySequence < byte > buffer , bool isCompleted )
185
194
{
186
- examined = buffer . End ;
195
+ var reader = new SequenceReader < byte > ( buffer ) ;
187
196
var state = _state ;
188
197
189
- if ( ! buffer . IsEmpty )
198
+ if ( state == State . StartLine )
190
199
{
191
- SequencePosition consumed ;
192
- if ( state == State . StartLine )
200
+ #if NETCOREAPP5_0 || NET5_0
201
+ if ( Parser . ParseRequestLine ( new ParsingAdapter ( this ) , ref reader ) )
193
202
{
194
- if ( Parser . ParseRequestLine ( new ParsingAdapter ( this ) , buffer , out consumed , out examined ) )
195
- {
196
- state = State . Headers ;
197
- }
198
-
199
- buffer = buffer . Slice ( consumed ) ;
203
+ state = State . Headers ;
200
204
}
201
-
202
- if ( state == State . Headers )
205
+ #else
206
+ var unconsumedSequence = reader . Sequence . Slice ( reader . Position ) ;
207
+ if ( Parser . ParseRequestLine ( new ParsingAdapter ( this ) , unconsumedSequence , out var consumed , out _ ) )
203
208
{
204
- var reader = new SequenceReader < byte > ( buffer ) ;
205
- var success = Parser . ParseHeaders ( new ParsingAdapter ( this ) , ref reader ) ;
206
-
207
- consumed = reader . Position ;
208
- if ( success )
209
- {
210
- examined = consumed ;
211
- state = State . Body ;
212
- }
213
- else
214
- {
215
- examined = buffer . End ;
216
- }
209
+ state = State . Headers ;
217
210
218
- buffer = buffer . Slice ( consumed ) ;
211
+ var parsedLength = unconsumedSequence . Slice ( reader . Position , consumed ) . Length ;
212
+ reader . Advance ( parsedLength ) ;
219
213
}
214
+ #endif
215
+ }
220
216
221
- if ( state != State . Body && isCompleted )
217
+ if ( state == State . Headers )
218
+ {
219
+ var success = Parser . ParseHeaders ( new ParsingAdapter ( this ) , ref reader ) ;
220
+
221
+ if ( success )
222
222
{
223
- ThrowUnexpectedEndOfData ( ) ;
223
+ state = State . Body ;
224
224
}
225
225
}
226
- else if ( isCompleted )
226
+
227
+ if ( state != State . Body && isCompleted )
227
228
{
228
- return false ;
229
+ ThrowUnexpectedEndOfData ( ) ;
229
230
}
230
231
231
232
_state = state ;
233
+
234
+ if ( state == State . Body )
235
+ {
236
+ // Complete request read, consumed and examined are the same (length 0)
237
+ buffer = buffer . Slice ( reader . Position , 0 ) ;
238
+ }
239
+ else
240
+ {
241
+ // In-complete request read, consumed is current position and examined is the remaining.
242
+ buffer = buffer . Slice ( reader . Position ) ;
243
+ }
244
+
232
245
return true ;
233
246
}
234
247
#endif
235
248
236
- #if NETCOREAPP5_0
249
+ #if NETCOREAPP5_0 || NET5_0
237
250
238
251
public void OnStaticIndexedHeader ( int index )
239
252
{
@@ -271,8 +284,8 @@ private enum State
271
284
}
272
285
273
286
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
274
- private static BufferWriter < WriterAdapter > GetWriter ( PipeWriter pipeWriter )
275
- => new BufferWriter < WriterAdapter > ( new WriterAdapter ( pipeWriter ) ) ;
287
+ private static BufferWriter < WriterAdapter > GetWriter ( PipeWriter pipeWriter , int sizeHint )
288
+ => new BufferWriter < WriterAdapter > ( new WriterAdapter ( pipeWriter ) , sizeHint ) ;
276
289
277
290
private struct WriterAdapter : IBufferWriter < byte >
278
291
{
@@ -298,7 +311,7 @@ private struct ParsingAdapter : IHttpRequestLineHandler, IHttpHeadersHandler
298
311
public ParsingAdapter ( BenchmarkApplication requestHandler )
299
312
=> RequestHandler = requestHandler ;
300
313
301
- #if NETCOREAPP5_0
314
+ #if NETCOREAPP5_0 || NET5_0
302
315
public void OnStaticIndexedHeader ( int index )
303
316
=> RequestHandler . OnStaticIndexedHeader ( index ) ;
304
317
@@ -310,15 +323,17 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)
310
323
311
324
public void OnHeadersComplete ( bool endStream )
312
325
=> RequestHandler . OnHeadersComplete ( endStream ) ;
326
+
327
+ public void OnStartLine ( HttpVersionAndMethod versionAndMethod , TargetOffsetPathLength targetPath , Span < byte > startLine )
328
+ => RequestHandler . OnStartLine ( versionAndMethod , targetPath , startLine ) ;
313
329
#else
314
330
public void OnHeader ( Span < byte > name , Span < byte > value )
315
331
=> RequestHandler . OnHeader ( name , value ) ;
316
332
public void OnHeadersComplete ( )
317
333
=> RequestHandler . OnHeadersComplete ( ) ;
318
- #endif
319
-
320
334
public void OnStartLine ( HttpMethod method , HttpVersion version , Span < byte > target , Span < byte > path , Span < byte > query , Span < byte > customMethod , bool pathEncoded )
321
335
=> RequestHandler . OnStartLine ( method , version , target , path , query , customMethod , pathEncoded ) ;
336
+ #endif
322
337
}
323
338
}
324
339
}
0 commit comments