2
2
3
3
import h11
4
4
import pytest
5
-
6
- from tests .response import Response
7
5
from uvicorn .config import Config
8
6
from uvicorn .main import ServerState
9
7
from uvicorn .protocols .http .h11_impl import H11Protocol
10
- from uvicorn .protocols .http .httptools_impl import HttpToolsProtocol
11
8
from uvicorn .protocols .websockets .wsproto_impl import WSProtocol
12
9
10
+ from tests .response import Response
11
+
12
+ try :
13
+ from uvicorn .protocols .http .httptools_impl import HttpToolsProtocol
14
+ except ImportError :
15
+ HttpToolsProtocol = None
16
+
17
+
18
+ HTTP_PROTOCOLS = [p for p in [H11Protocol , HttpToolsProtocol ] if p is not None ]
19
+
13
20
SIMPLE_GET_REQUEST = b"\r \n " .join ([b"GET / HTTP/1.1" , b"Host: example.org" , b"" , b"" ])
14
21
15
22
SIMPLE_HEAD_REQUEST = b"\r \n " .join ([b"HEAD / HTTP/1.1" , b"Host: example.org" , b"" , b"" ])
@@ -144,7 +151,7 @@ def get_connected_protocol(app, protocol_cls, **kwargs):
144
151
return protocol
145
152
146
153
147
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
154
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
148
155
def test_get_request (protocol_cls ):
149
156
def app (scope ):
150
157
return Response ("Hello, world" , media_type = "text/plain" )
@@ -156,7 +163,7 @@ def app(scope):
156
163
assert b"Hello, world" in protocol .transport .buffer
157
164
158
165
159
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
166
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
160
167
def test_head_request (protocol_cls ):
161
168
def app (scope ):
162
169
return Response ("Hello, world" , media_type = "text/plain" )
@@ -168,7 +175,7 @@ def app(scope):
168
175
assert b"Hello, world" not in protocol .transport .buffer
169
176
170
177
171
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
178
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
172
179
def test_post_request (protocol_cls ):
173
180
class App :
174
181
def __init__ (self , scope ):
@@ -191,7 +198,7 @@ async def __call__(self, receive, send):
191
198
assert b'Body: {"hello": "world"}' in protocol .transport .buffer
192
199
193
200
194
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
201
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
195
202
def test_keepalive (protocol_cls ):
196
203
def app (scope ):
197
204
return Response (b"" , status_code = 204 )
@@ -204,7 +211,7 @@ def app(scope):
204
211
assert not protocol .transport .is_closing ()
205
212
206
213
207
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
214
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
208
215
def test_keepalive_timeout (protocol_cls ):
209
216
def app (scope ):
210
217
return Response (b"" , status_code = 204 )
@@ -223,7 +230,7 @@ def app(scope):
223
230
assert protocol .transport .is_closing ()
224
231
225
232
226
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
233
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
227
234
def test_close (protocol_cls ):
228
235
def app (scope ):
229
236
return Response (b"" , status_code = 204 , headers = {"connection" : "close" })
@@ -235,7 +242,7 @@ def app(scope):
235
242
assert protocol .transport .is_closing ()
236
243
237
244
238
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
245
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
239
246
def test_chunked_encoding (protocol_cls ):
240
247
def app (scope ):
241
248
return Response (
@@ -250,7 +257,7 @@ def app(scope):
250
257
assert not protocol .transport .is_closing ()
251
258
252
259
253
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
260
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
254
261
def test_chunked_encoding_empty_body (protocol_cls ):
255
262
def app (scope ):
256
263
return Response (
@@ -265,7 +272,7 @@ def app(scope):
265
272
assert not protocol .transport .is_closing ()
266
273
267
274
268
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
275
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
269
276
def test_chunked_encoding_head_request (protocol_cls ):
270
277
def app (scope ):
271
278
return Response (
@@ -279,7 +286,7 @@ def app(scope):
279
286
assert not protocol .transport .is_closing ()
280
287
281
288
282
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
289
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
283
290
def test_pipelined_requests (protocol_cls ):
284
291
def app (scope ):
285
292
return Response ("Hello, world" , media_type = "text/plain" )
@@ -305,7 +312,7 @@ def app(scope):
305
312
protocol .transport .clear_buffer ()
306
313
307
314
308
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
315
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
309
316
def test_undersized_request (protocol_cls ):
310
317
def app (scope ):
311
318
return Response (b"xxx" , headers = {"content-length" : "10" })
@@ -316,7 +323,7 @@ def app(scope):
316
323
assert protocol .transport .is_closing ()
317
324
318
325
319
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
326
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
320
327
def test_oversized_request (protocol_cls ):
321
328
def app (scope ):
322
329
return Response (b"xxx" * 20 , headers = {"content-length" : "10" })
@@ -327,7 +334,7 @@ def app(scope):
327
334
assert protocol .transport .is_closing ()
328
335
329
336
330
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
337
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
331
338
def test_large_post_request (protocol_cls ):
332
339
def app (scope ):
333
340
return Response ("Hello, world" , media_type = "text/plain" )
@@ -339,15 +346,15 @@ def app(scope):
339
346
assert not protocol .transport .read_paused
340
347
341
348
342
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
349
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
343
350
def test_invalid_http (protocol_cls ):
344
351
app = lambda scope : None
345
352
protocol = get_connected_protocol (app , protocol_cls )
346
353
protocol .data_received (b"x" * 100000 )
347
354
assert protocol .transport .is_closing ()
348
355
349
356
350
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
357
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
351
358
def test_app_exception (protocol_cls ):
352
359
class App :
353
360
def __init__ (self , scope ):
@@ -363,7 +370,7 @@ async def __call__(self, receive, send):
363
370
assert protocol .transport .is_closing ()
364
371
365
372
366
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
373
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
367
374
def test_app_init_exception (protocol_cls ):
368
375
def app (scope ):
369
376
raise Exception ()
@@ -375,7 +382,7 @@ def app(scope):
375
382
assert protocol .transport .is_closing ()
376
383
377
384
378
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
385
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
379
386
def test_exception_during_response (protocol_cls ):
380
387
class App :
381
388
def __init__ (self , scope ):
@@ -393,7 +400,7 @@ async def __call__(self, receive, send):
393
400
assert protocol .transport .is_closing ()
394
401
395
402
396
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
403
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
397
404
def test_no_response_returned (protocol_cls ):
398
405
class App :
399
406
def __init__ (self , scope ):
@@ -409,7 +416,7 @@ async def __call__(self, receive, send):
409
416
assert protocol .transport .is_closing ()
410
417
411
418
412
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
419
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
413
420
def test_partial_response_returned (protocol_cls ):
414
421
class App :
415
422
def __init__ (self , scope ):
@@ -425,7 +432,7 @@ async def __call__(self, receive, send):
425
432
assert protocol .transport .is_closing ()
426
433
427
434
428
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
435
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
429
436
def test_duplicate_start_message (protocol_cls ):
430
437
class App :
431
438
def __init__ (self , scope ):
@@ -442,7 +449,7 @@ async def __call__(self, receive, send):
442
449
assert protocol .transport .is_closing ()
443
450
444
451
445
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
452
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
446
453
def test_missing_start_message (protocol_cls ):
447
454
class App :
448
455
def __init__ (self , scope ):
@@ -458,7 +465,7 @@ async def __call__(self, receive, send):
458
465
assert protocol .transport .is_closing ()
459
466
460
467
461
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
468
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
462
469
def test_message_after_body_complete (protocol_cls ):
463
470
class App :
464
471
def __init__ (self , scope ):
@@ -476,7 +483,7 @@ async def __call__(self, receive, send):
476
483
assert protocol .transport .is_closing ()
477
484
478
485
479
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
486
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
480
487
def test_value_returned (protocol_cls ):
481
488
class App :
482
489
def __init__ (self , scope ):
@@ -494,7 +501,7 @@ async def __call__(self, receive, send):
494
501
assert protocol .transport .is_closing ()
495
502
496
503
497
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
504
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
498
505
def test_early_disconnect (protocol_cls ):
499
506
got_disconnect_event = False
500
507
@@ -520,7 +527,7 @@ async def __call__(self, receive, send):
520
527
assert got_disconnect_event
521
528
522
529
523
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
530
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
524
531
def test_early_response (protocol_cls ):
525
532
def app (scope ):
526
533
return Response ("Hello, world" , media_type = "text/plain" )
@@ -533,7 +540,7 @@ def app(scope):
533
540
assert not protocol .transport .is_closing ()
534
541
535
542
536
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
543
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
537
544
def test_read_after_response (protocol_cls ):
538
545
message_after_response = None
539
546
@@ -555,7 +562,7 @@ async def __call__(self, receive, send):
555
562
assert message_after_response == {"type" : "http.disconnect" }
556
563
557
564
558
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
565
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
559
566
def test_http10_request (protocol_cls ):
560
567
def app (scope ):
561
568
content = "Version: %s" % scope ["http_version" ]
@@ -568,7 +575,7 @@ def app(scope):
568
575
assert b"Version: 1.0" in protocol .transport .buffer
569
576
570
577
571
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
578
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
572
579
def test_root_path (protocol_cls ):
573
580
def app (scope ):
574
581
path = scope .get ("root_path" , "" ) + scope ["path" ]
@@ -581,7 +588,7 @@ def app(scope):
581
588
assert b"Path: /app/" in protocol .transport .buffer
582
589
583
590
584
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
591
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
585
592
def test_max_concurrency (protocol_cls ):
586
593
app = lambda scope : None
587
594
protocol = get_connected_protocol (app , protocol_cls , limit_concurrency = 1 )
@@ -590,7 +597,7 @@ def test_max_concurrency(protocol_cls):
590
597
assert b"HTTP/1.1 503 Service Unavailable" in protocol .transport .buffer
591
598
592
599
593
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
600
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
594
601
def test_shutdown_during_request (protocol_cls ):
595
602
def app (scope ):
596
603
return Response (b"" , status_code = 204 )
@@ -603,7 +610,7 @@ def app(scope):
603
610
assert protocol .transport .is_closing ()
604
611
605
612
606
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
613
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
607
614
def test_shutdown_during_idle (protocol_cls ):
608
615
app = lambda scope : None
609
616
protocol = get_connected_protocol (app , protocol_cls )
@@ -612,7 +619,7 @@ def test_shutdown_during_idle(protocol_cls):
612
619
assert protocol .transport .is_closing ()
613
620
614
621
615
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
622
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
616
623
def test_100_continue_sent_when_body_consumed (protocol_cls ):
617
624
class App :
618
625
def __init__ (self , scope ):
@@ -647,7 +654,7 @@ async def __call__(self, receive, send):
647
654
assert b'Body: {"hello": "world"}' in protocol .transport .buffer
648
655
649
656
650
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
657
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
651
658
def test_100_continue_not_sent_when_body_not_consumed (protocol_cls ):
652
659
def app (scope ):
653
660
return Response (b"" , status_code = 204 )
@@ -670,7 +677,7 @@ def app(scope):
670
677
assert b"HTTP/1.1 204 No Content" in protocol .transport .buffer
671
678
672
679
673
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
680
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
674
681
def test_unsupported_upgrade_request (protocol_cls ):
675
682
def app (scope ):
676
683
pass # pragma: no cover
@@ -681,7 +688,7 @@ def app(scope):
681
688
assert b"Unsupported upgrade request." in protocol .transport .buffer
682
689
683
690
684
- @pytest .mark .parametrize ("protocol_cls" , [ HttpToolsProtocol , H11Protocol ] )
691
+ @pytest .mark .parametrize ("protocol_cls" , HTTP_PROTOCOLS )
685
692
def test_supported_upgrade_request (protocol_cls ):
686
693
def app (scope ):
687
694
pass # pragma: no cover
0 commit comments