7474import http
7575import io
7676import re
77+ import select
7778import socket
7879import sys
7980import collections .abc
@@ -321,15 +322,16 @@ def _read_status(self):
321322 raise BadStatusLine (line )
322323 return version , status , reason
323324
324- def begin (self ):
325+ def begin (self , ignore_100_continue = True ):
325326 if self .headers is not None :
326327 # we've already started reading the response
327328 return
328329
329330 # read until we get a non-100 response
331+ # (unless caller has requested return of 100 responses)
330332 while True :
331333 version , status , reason = self ._read_status ()
332- if status != CONTINUE :
334+ if not ( ignore_100_continue and status == CONTINUE ) :
333335 break
334336 # skip the header from the 100 response
335337 skipped_headers = _read_headers (self .fp )
@@ -865,13 +867,15 @@ def _get_content_length(body, method):
865867 return None
866868
867869 def __init__ (self , host , port = None , timeout = socket ._GLOBAL_DEFAULT_TIMEOUT ,
868- source_address = None , blocksize = 8192 ):
870+ source_address = None , blocksize = 8192 , continue_timeout = 2.5 ):
869871 self .timeout = timeout
872+ self .continue_timeout = continue_timeout
870873 self .source_address = source_address
871874 self .blocksize = blocksize
872875 self .sock = None
873876 self ._buffer = []
874877 self .__response = None
878+ self .__pending_response = None
875879 self .__state = _CS_IDLE
876880 self ._method = None
877881 self ._tunnel_host = None
@@ -883,9 +887,10 @@ def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
883887
884888 self ._validate_host (self .host )
885889
886- # This is stored as an instance variable to allow unit
887- # tests to replace it with a suitable mockup
890+ # These are stored as instance variables to allow unit
891+ # tests to replace them with a suitable mockup
888892 self ._create_connection = socket .create_connection
893+ self ._select = select .select
889894
890895 def set_tunnel (self , host , port = None , headers = None ):
891896 """Set up host and port for HTTP CONNECT tunnelling.
@@ -1021,6 +1026,10 @@ def close(self):
10211026 self .sock = None
10221027 sock .close () # close it manually... there may be other refs
10231028 finally :
1029+ pending_response = self .__pending_response
1030+ if pending_response :
1031+ self .__pending_response = None
1032+ pending_response .close ()
10241033 response = self .__response
10251034 if response :
10261035 self .__response = None
@@ -1081,7 +1090,8 @@ def _read_readable(self, readable):
10811090 datablock = datablock .encode ("iso-8859-1" )
10821091 yield datablock
10831092
1084- def _send_output (self , message_body = None , encode_chunked = False ):
1093+ def _send_output (self , message_body = None , encode_chunked = False ,
1094+ expect_continue = False ):
10851095 """Send the currently buffered request and clear the buffer.
10861096
10871097 Appends an extra \\ r\\ n to the buffer.
@@ -1093,6 +1103,23 @@ def _send_output(self, message_body=None, encode_chunked=False):
10931103 self .send (msg )
10941104
10951105 if message_body is not None :
1106+ if expect_continue and not self .__response :
1107+ read_ready , _ , _ = self ._select ([self .sock ], [], [],
1108+ self .continue_timeout )
1109+ if read_ready :
1110+ if self .debuglevel > 0 :
1111+ response = self .response_class (self .sock ,
1112+ self .debuglevel ,
1113+ method = self ._method )
1114+ else :
1115+ response = self .response_class (self .sock ,
1116+ method = self ._method )
1117+ response .begin (ignore_100_continue = False )
1118+ if response .code != CONTINUE :
1119+ # Break without sending the body
1120+ self .__pending_response = response
1121+ return
1122+ response .close ()
10961123
10971124 # create a consistent interface to message_body
10981125 if hasattr (message_body , 'read' ):
@@ -1319,7 +1346,8 @@ def putheader(self, header, *values):
13191346 header = header + b': ' + value
13201347 self ._output (header )
13211348
1322- def endheaders (self , message_body = None , * , encode_chunked = False ):
1349+ def endheaders (self , message_body = None , * , encode_chunked = False ,
1350+ expect_continue = False ):
13231351 """Indicate that the last header line has been sent to the server.
13241352
13251353 This method sends the request to the server. The optional message_body
@@ -1330,7 +1358,8 @@ def endheaders(self, message_body=None, *, encode_chunked=False):
13301358 self .__state = _CS_REQ_SENT
13311359 else :
13321360 raise CannotSendHeader ()
1333- self ._send_output (message_body , encode_chunked = encode_chunked )
1361+ self ._send_output (message_body , encode_chunked = encode_chunked ,
1362+ expect_continue = expect_continue )
13341363
13351364 def request (self , method , url , body = None , headers = {}, * ,
13361365 encode_chunked = False ):
@@ -1375,20 +1404,33 @@ def _send_request(self, method, url, body, headers, encode_chunked):
13751404 else :
13761405 encode_chunked = False
13771406
1407+ # If the Expect: 100-continue header is set, we will try to honor it
1408+ # (if possible). We can only do so if 1) the request has a body, and
1409+ # 2) there is no current incomplete response (since we need to read
1410+ # the response stream to check if the code is 100 or not)
1411+ expect_continue = (
1412+ body and not self .__response
1413+ and 'expect' in header_names
1414+ and '100-continue' in {v .lower () for k , v in headers .items ()
1415+ if k .lower () == 'expect' }
1416+ )
1417+
13781418 for hdr , value in headers .items ():
13791419 self .putheader (hdr , value )
13801420 if isinstance (body , str ):
13811421 # RFC 2616 Section 3.7.1 says that text default has a
13821422 # default charset of iso-8859-1.
13831423 body = _encode (body , 'body' )
1384- self .endheaders (body , encode_chunked = encode_chunked )
1424+ self .endheaders (body , encode_chunked = encode_chunked ,
1425+ expect_continue = expect_continue )
13851426
1386- def getresponse (self ):
1427+ def getresponse (self , ignore_100_continue = True ):
13871428 """Get the response from the server.
13881429
13891430 If the HTTPConnection is in the correct state, returns an
1390- instance of HTTPResponse or of whatever object is returned by
1391- the response_class variable.
1431+ instance of HTTPResponse or of whatever object is returned by the
1432+ response_class variable. The connection will wait for a response other
1433+ than code 100 ('Continue') unless ignore_100_continue is set to False.
13921434
13931435 If a request has not been sent or if a previous response has
13941436 not be handled, ResponseNotReady is raised. If the HTTP
@@ -1419,27 +1461,32 @@ def getresponse(self):
14191461 if self .__state != _CS_REQ_SENT or self .__response :
14201462 raise ResponseNotReady (self .__state )
14211463
1422- if self .debuglevel > 0 :
1464+ if self .__pending_response :
1465+ response = self .__pending_response
1466+ self .__pending_response = None
1467+ elif self .debuglevel > 0 :
14231468 response = self .response_class (self .sock , self .debuglevel ,
14241469 method = self ._method )
14251470 else :
14261471 response = self .response_class (self .sock , method = self ._method )
14271472
14281473 try :
14291474 try :
1430- response .begin ()
1475+ response .begin (ignore_100_continue = ignore_100_continue )
14311476 except ConnectionError :
14321477 self .close ()
14331478 raise
14341479 assert response .will_close != _UNKNOWN
1435- self .__state = _CS_IDLE
1480+ if response .code != 100 :
1481+ # Code 100 is effectively 'not a response' for this purpose
1482+ self .__state = _CS_IDLE
14361483
1437- if response .will_close :
1438- # this effectively passes the connection to the response
1439- self .close ()
1440- else :
1441- # remember this, so we can tell when it is complete
1442- self .__response = response
1484+ if response .will_close :
1485+ # this effectively passes the connection to the response
1486+ self .close ()
1487+ else :
1488+ # remember this, so we can tell when it is complete
1489+ self .__response = response
14431490
14441491 return response
14451492 except :
0 commit comments