@@ -209,22 +209,24 @@ def getallmatchingheaders(self, name):
209209 lst .append (line )
210210 return lst
211211
212- def _read_headers (fp ):
212+ def _read_headers (fp , max_headers ):
213213 """Reads potential header lines into a list from a file pointer.
214214
215215 Length of line is limited by _MAXLINE, and number of
216- headers is limited by _MAXHEADERS .
216+ headers is limited by max_headers .
217217 """
218218 headers = []
219+ if max_headers is None :
220+ max_headers = _MAXHEADERS
219221 while True :
220222 line = fp .readline (_MAXLINE + 1 )
221223 if len (line ) > _MAXLINE :
222224 raise LineTooLong ("header line" )
223- headers .append (line )
224- if len (headers ) > _MAXHEADERS :
225- raise HTTPException ("got more than %d headers" % _MAXHEADERS )
226225 if line in (b'\r \n ' , b'\n ' , b'' ):
227226 break
227+ headers .append (line )
228+ if len (headers ) > max_headers :
229+ raise HTTPException (f"got more than { max_headers } headers" )
228230 return headers
229231
230232def _parse_header_lines (header_lines , _class = HTTPMessage ):
@@ -241,10 +243,10 @@ def _parse_header_lines(header_lines, _class=HTTPMessage):
241243 hstring = b'' .join (header_lines ).decode ('iso-8859-1' )
242244 return email .parser .Parser (_class = _class ).parsestr (hstring )
243245
244- def parse_headers (fp , _class = HTTPMessage ):
246+ def parse_headers (fp , _class = HTTPMessage , * , _max_headers = None ):
245247 """Parses only RFC2822 headers from a file pointer."""
246248
247- headers = _read_headers (fp )
249+ headers = _read_headers (fp , _max_headers )
248250 return _parse_header_lines (headers , _class )
249251
250252
@@ -320,7 +322,7 @@ def _read_status(self):
320322 raise BadStatusLine (line )
321323 return version , status , reason
322324
323- def begin (self ):
325+ def begin (self , * , _max_headers = None ):
324326 if self .headers is not None :
325327 # we've already started reading the response
326328 return
@@ -331,7 +333,7 @@ def begin(self):
331333 if status != CONTINUE :
332334 break
333335 # skip the header from the 100 response
334- skipped_headers = _read_headers (self .fp )
336+ skipped_headers = _read_headers (self .fp , _max_headers )
335337 if self .debuglevel > 0 :
336338 print ("headers:" , skipped_headers )
337339 del skipped_headers
@@ -346,7 +348,9 @@ def begin(self):
346348 else :
347349 raise UnknownProtocol (version )
348350
349- self .headers = self .msg = parse_headers (self .fp )
351+ self .headers = self .msg = parse_headers (
352+ self .fp , _max_headers = _max_headers
353+ )
350354
351355 if self .debuglevel > 0 :
352356 for hdr , val in self .headers .items ():
@@ -864,7 +868,7 @@ def _get_content_length(body, method):
864868 return None
865869
866870 def __init__ (self , host , port = None , timeout = socket ._GLOBAL_DEFAULT_TIMEOUT ,
867- source_address = None , blocksize = 8192 ):
871+ source_address = None , blocksize = 8192 , * , max_response_headers = None ):
868872 self .timeout = timeout
869873 self .source_address = source_address
870874 self .blocksize = blocksize
@@ -877,6 +881,7 @@ def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
877881 self ._tunnel_port = None
878882 self ._tunnel_headers = {}
879883 self ._raw_proxy_headers = None
884+ self .max_response_headers = max_response_headers
880885
881886 (self .host , self .port ) = self ._get_hostport (host , port )
882887
@@ -969,7 +974,7 @@ def _tunnel(self):
969974 try :
970975 (version , code , message ) = response ._read_status ()
971976
972- self ._raw_proxy_headers = _read_headers (response .fp )
977+ self ._raw_proxy_headers = _read_headers (response .fp , self . max_response_headers )
973978
974979 if self .debuglevel > 0 :
975980 for header in self ._raw_proxy_headers :
@@ -1426,7 +1431,10 @@ def getresponse(self):
14261431
14271432 try :
14281433 try :
1429- response .begin ()
1434+ if self .max_response_headers is None :
1435+ response .begin ()
1436+ else :
1437+ response .begin (_max_headers = self .max_response_headers )
14301438 except ConnectionError :
14311439 self .close ()
14321440 raise
@@ -1457,10 +1465,12 @@ class HTTPSConnection(HTTPConnection):
14571465
14581466 def __init__ (self , host , port = None ,
14591467 * , timeout = socket ._GLOBAL_DEFAULT_TIMEOUT ,
1460- source_address = None , context = None , blocksize = 8192 ):
1468+ source_address = None , context = None , blocksize = 8192 ,
1469+ max_response_headers = None ):
14611470 super (HTTPSConnection , self ).__init__ (host , port , timeout ,
14621471 source_address ,
1463- blocksize = blocksize )
1472+ blocksize = blocksize ,
1473+ max_response_headers = max_response_headers )
14641474 if context is None :
14651475 context = _create_https_context (self ._http_vsn )
14661476 self ._context = context
0 commit comments