@@ -118,7 +118,7 @@ def raw_items(self):
118118
119119def normalize_and_validate (headers , _parsed = False ):
120120 new_headers = []
121- saw_content_length = False
121+ seen_content_length = None
122122 saw_transfer_encoding = False
123123 for name , value in headers :
124124 # For headers coming out of the parser, we can safely skip some steps,
@@ -132,11 +132,17 @@ def normalize_and_validate(headers, _parsed=False):
132132 raw_name = name
133133 name = name .lower ()
134134 if name == b"content-length" :
135- if saw_content_length :
136- raise LocalProtocolError ("multiple Content-Length headers" )
135+ lengths = set (length .strip () for length in value .split (b"," ))
136+ if len (lengths ) != 1 :
137+ raise LocalProtocolError ("conflicting Content-Length headers" )
138+ value = lengths .pop ()
137139 validate (_content_length_re , value , "bad Content-Length" )
138- saw_content_length = True
139- if name == b"transfer-encoding" :
140+ if seen_content_length is None :
141+ seen_content_length = value
142+ new_headers .append ((raw_name , name , value ))
143+ elif seen_content_length != value :
144+ raise LocalProtocolError ("conflicting Content-Length headers" )
145+ elif name == b"transfer-encoding" :
140146 # "A server that receives a request message with a transfer coding
141147 # it does not understand SHOULD respond with 501 (Not
142148 # Implemented)."
@@ -154,7 +160,9 @@ def normalize_and_validate(headers, _parsed=False):
154160 error_status_hint = 501 ,
155161 )
156162 saw_transfer_encoding = True
157- new_headers .append ((raw_name , name , value ))
163+ new_headers .append ((raw_name , name , value ))
164+ else :
165+ new_headers .append ((raw_name , name , value ))
158166 return Headers (new_headers )
159167
160168
0 commit comments