3333 b':authority' , u':authority' ,
3434 b':path' , u':path' ,
3535 b':status' , u':status' ,
36+ b':protocol' , u':protocol' ,
3637])
3738
3839
4748 b':scheme' , u':scheme' ,
4849 b':path' , u':path' ,
4950 b':authority' , u':authority' ,
50- b':method' , u':method'
51+ b':method' , u':method' ,
52+ b':protocol' , u':protocol' ,
5153])
5254
5355
5456_RESPONSE_ONLY_HEADERS = frozenset ([b':status' , u':status' ])
5557
5658
59+ # A Set of pseudo headers that are only valid if the method is
60+ # CONNECT, see RFC 8441 § 5
61+ _CONNECT_REQUEST_ONLY_HEADERS = frozenset ([b':protocol' , u':protocol' ])
62+
63+
5764if sys .version_info [0 ] == 2 : # Python 2.X
5865 _WHITESPACE = frozenset (whitespace )
5966else : # Python 3.3+
@@ -323,6 +330,7 @@ def _reject_pseudo_header_fields(headers, hdr_validation_flags):
323330 """
324331 seen_pseudo_header_fields = set ()
325332 seen_regular_header = False
333+ method = None
326334
327335 for header in headers :
328336 if _custom_startswith (header [0 ], b':' , u':' ):
@@ -344,18 +352,25 @@ def _reject_pseudo_header_fields(headers, hdr_validation_flags):
344352 "Received custom pseudo-header field %s" % header [0 ]
345353 )
346354
355+ if header [0 ] in (b':method' , u':method' ):
356+ if not isinstance (header [1 ], bytes ):
357+ method = header [1 ].encode ('utf-8' )
358+ else :
359+ method = header [1 ]
360+
347361 else :
348362 seen_regular_header = True
349363
350364 yield header
351365
352366 # Check the pseudo-headers we got to confirm they're acceptable.
353367 _check_pseudo_header_field_acceptability (
354- seen_pseudo_header_fields , hdr_validation_flags
368+ seen_pseudo_header_fields , method , hdr_validation_flags
355369 )
356370
357371
358372def _check_pseudo_header_field_acceptability (pseudo_headers ,
373+ method ,
359374 hdr_validation_flags ):
360375 """
361376 Given the set of pseudo-headers present in a header block and the
@@ -394,6 +409,13 @@ def _check_pseudo_header_field_acceptability(pseudo_headers,
394409 "Encountered response-only headers %s" %
395410 invalid_request_headers
396411 )
412+ if method != b'CONNECT' :
413+ invalid_headers = pseudo_headers & _CONNECT_REQUEST_ONLY_HEADERS
414+ if invalid_headers :
415+ raise ProtocolError (
416+ "Encountered connect-request-only headers %s" %
417+ invalid_headers
418+ )
397419
398420
399421def _validate_host_authority_header (headers ):
0 commit comments