PageRenderTime 62ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/mercurial/httpclient/__init__.py

https://bitbucket.org/mirror/mercurial/
Python | 728 lines | 520 code | 42 blank | 166 comment | 103 complexity | 4000c213b3e4f8c9cf0112652770b3d7 MD5 | raw file
Possible License(s): GPL-2.0
  1. # Copyright 2010, Google Inc.
  2. # All rights reserved.
  3. #
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions are
  6. # met:
  7. #
  8. # * Redistributions of source code must retain the above copyright
  9. # notice, this list of conditions and the following disclaimer.
  10. # * Redistributions in binary form must reproduce the above
  11. # copyright notice, this list of conditions and the following disclaimer
  12. # in the documentation and/or other materials provided with the
  13. # distribution.
  14. # * Neither the name of Google Inc. nor the names of its
  15. # contributors may be used to endorse or promote products derived from
  16. # this software without specific prior written permission.
  17. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  20. # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  21. # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  22. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  23. # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. """Improved HTTP/1.1 client library
  29. This library contains an HTTPConnection which is similar to the one in
  30. httplib, but has several additional features:
  31. * supports keepalives natively
  32. * uses select() to block for incoming data
  33. * notices when the server responds early to a request
  34. * implements ssl inline instead of in a different class
  35. """
  36. # Many functions in this file have too many arguments.
  37. # pylint: disable=R0913
  38. import cStringIO
  39. import errno
  40. import httplib
  41. import logging
  42. import rfc822
  43. import select
  44. import socket
  45. import _readers
  46. import socketutil
  47. logger = logging.getLogger(__name__)
  48. __all__ = ['HTTPConnection', 'HTTPResponse']
  49. HTTP_VER_1_0 = 'HTTP/1.0'
  50. HTTP_VER_1_1 = 'HTTP/1.1'
  51. OUTGOING_BUFFER_SIZE = 1 << 15
  52. INCOMING_BUFFER_SIZE = 1 << 20
  53. HDR_ACCEPT_ENCODING = 'accept-encoding'
  54. HDR_CONNECTION_CTRL = 'connection'
  55. HDR_CONTENT_LENGTH = 'content-length'
  56. HDR_XFER_ENCODING = 'transfer-encoding'
  57. XFER_ENCODING_CHUNKED = 'chunked'
  58. CONNECTION_CLOSE = 'close'
  59. EOL = '\r\n'
  60. _END_HEADERS = EOL * 2
  61. # Based on some searching around, 1 second seems like a reasonable
  62. # default here.
  63. TIMEOUT_ASSUME_CONTINUE = 1
  64. TIMEOUT_DEFAULT = None
  65. class HTTPResponse(object):
  66. """Response from an HTTP server.
  67. The response will continue to load as available. If you need the
  68. complete response before continuing, check the .complete() method.
  69. """
  70. def __init__(self, sock, timeout, method):
  71. self.sock = sock
  72. self.method = method
  73. self.raw_response = ''
  74. self._headers_len = 0
  75. self.headers = None
  76. self.will_close = False
  77. self.status_line = ''
  78. self.status = None
  79. self.continued = False
  80. self.http_version = None
  81. self.reason = None
  82. self._reader = None
  83. self._read_location = 0
  84. self._eol = EOL
  85. self._timeout = timeout
  86. @property
  87. def _end_headers(self):
  88. return self._eol * 2
  89. def complete(self):
  90. """Returns true if this response is completely loaded.
  91. Note that if this is a connection where complete means the
  92. socket is closed, this will nearly always return False, even
  93. in cases where all the data has actually been loaded.
  94. """
  95. if self._reader:
  96. return self._reader.done()
  97. def _close(self):
  98. if self._reader is not None:
  99. # We're a friend of the reader class here.
  100. # pylint: disable=W0212
  101. self._reader._close()
  102. def readline(self):
  103. """Read a single line from the response body.
  104. This may block until either a line ending is found or the
  105. response is complete.
  106. """
  107. blocks = []
  108. while True:
  109. self._reader.readto('\n', blocks)
  110. if blocks and blocks[-1][-1] == '\n' or self.complete():
  111. break
  112. self._select()
  113. return ''.join(blocks)
  114. def read(self, length=None):
  115. """Read data from the response body."""
  116. # if length is None, unbounded read
  117. while (not self.complete() # never select on a finished read
  118. and (not length # unbounded, so we wait for complete()
  119. or length > self._reader.available_data)):
  120. self._select()
  121. if not length:
  122. length = self._reader.available_data
  123. r = self._reader.read(length)
  124. if self.complete() and self.will_close:
  125. self.sock.close()
  126. return r
  127. def _select(self):
  128. r, unused_write, unused_err = select.select(
  129. [self.sock], [], [], self._timeout)
  130. if not r:
  131. # socket was not readable. If the response is not
  132. # complete, raise a timeout.
  133. if not self.complete():
  134. logger.info('timed out with timeout of %s', self._timeout)
  135. raise HTTPTimeoutException('timeout reading data')
  136. try:
  137. data = self.sock.recv(INCOMING_BUFFER_SIZE)
  138. except socket.sslerror, e:
  139. if e.args[0] != socket.SSL_ERROR_WANT_READ:
  140. raise
  141. logger.debug('SSL_ERROR_WANT_READ in _select, should retry later')
  142. return True
  143. logger.debug('response read %d data during _select', len(data))
  144. # If the socket was readable and no data was read, that means
  145. # the socket was closed. Inform the reader (if any) so it can
  146. # raise an exception if this is an invalid situation.
  147. if not data:
  148. if self._reader:
  149. # We're a friend of the reader class here.
  150. # pylint: disable=W0212
  151. self._reader._close()
  152. return False
  153. else:
  154. self._load_response(data)
  155. return True
  156. # This method gets replaced by _load later, which confuses pylint.
  157. def _load_response(self, data): # pylint: disable=E0202
  158. # Being here implies we're not at the end of the headers yet,
  159. # since at the end of this method if headers were completely
  160. # loaded we replace this method with the load() method of the
  161. # reader we created.
  162. self.raw_response += data
  163. # This is a bogus server with bad line endings
  164. if self._eol not in self.raw_response:
  165. for bad_eol in ('\n', '\r'):
  166. if (bad_eol in self.raw_response
  167. # verify that bad_eol is not the end of the incoming data
  168. # as this could be a response line that just got
  169. # split between \r and \n.
  170. and (self.raw_response.index(bad_eol) <
  171. (len(self.raw_response) - 1))):
  172. logger.info('bogus line endings detected, '
  173. 'using %r for EOL', bad_eol)
  174. self._eol = bad_eol
  175. break
  176. # exit early if not at end of headers
  177. if self._end_headers not in self.raw_response or self.headers:
  178. return
  179. # handle 100-continue response
  180. hdrs, body = self.raw_response.split(self._end_headers, 1)
  181. unused_http_ver, status = hdrs.split(' ', 1)
  182. if status.startswith('100'):
  183. self.raw_response = body
  184. self.continued = True
  185. logger.debug('continue seen, setting body to %r', body)
  186. return
  187. # arriving here means we should parse response headers
  188. # as all headers have arrived completely
  189. hdrs, body = self.raw_response.split(self._end_headers, 1)
  190. del self.raw_response
  191. if self._eol in hdrs:
  192. self.status_line, hdrs = hdrs.split(self._eol, 1)
  193. else:
  194. self.status_line = hdrs
  195. hdrs = ''
  196. # TODO HTTP < 1.0 support
  197. (self.http_version, self.status,
  198. self.reason) = self.status_line.split(' ', 2)
  199. self.status = int(self.status)
  200. if self._eol != EOL:
  201. hdrs = hdrs.replace(self._eol, '\r\n')
  202. headers = rfc822.Message(cStringIO.StringIO(hdrs))
  203. content_len = None
  204. if HDR_CONTENT_LENGTH in headers:
  205. content_len = int(headers[HDR_CONTENT_LENGTH])
  206. if self.http_version == HTTP_VER_1_0:
  207. self.will_close = True
  208. elif HDR_CONNECTION_CTRL in headers:
  209. self.will_close = (
  210. headers[HDR_CONNECTION_CTRL].lower() == CONNECTION_CLOSE)
  211. if (HDR_XFER_ENCODING in headers
  212. and headers[HDR_XFER_ENCODING].lower() == XFER_ENCODING_CHUNKED):
  213. self._reader = _readers.ChunkedReader(self._eol)
  214. logger.debug('using a chunked reader')
  215. else:
  216. # HEAD responses are forbidden from returning a body, and
  217. # it's implausible for a CONNECT response to use
  218. # close-is-end logic for an OK response.
  219. if (self.method == 'HEAD' or
  220. (self.method == 'CONNECT' and content_len is None)):
  221. content_len = 0
  222. if content_len is not None:
  223. logger.debug('using a content-length reader with length %d',
  224. content_len)
  225. self._reader = _readers.ContentLengthReader(content_len)
  226. else:
  227. # Response body had no length specified and is not
  228. # chunked, so the end of the body will only be
  229. # identifiable by the termination of the socket by the
  230. # server. My interpretation of the spec means that we
  231. # are correct in hitting this case if
  232. # transfer-encoding, content-length, and
  233. # connection-control were left unspecified.
  234. self._reader = _readers.CloseIsEndReader()
  235. logger.debug('using a close-is-end reader')
  236. self.will_close = True
  237. if body:
  238. # We're a friend of the reader class here.
  239. # pylint: disable=W0212
  240. self._reader._load(body)
  241. logger.debug('headers complete')
  242. self.headers = headers
  243. # We're a friend of the reader class here.
  244. # pylint: disable=W0212
  245. self._load_response = self._reader._load
  246. class HTTPConnection(object):
  247. """Connection to a single http server.
  248. Supports 100-continue and keepalives natively. Uses select() for
  249. non-blocking socket operations.
  250. """
  251. http_version = HTTP_VER_1_1
  252. response_class = HTTPResponse
  253. def __init__(self, host, port=None, use_ssl=None, ssl_validator=None,
  254. timeout=TIMEOUT_DEFAULT,
  255. continue_timeout=TIMEOUT_ASSUME_CONTINUE,
  256. proxy_hostport=None, ssl_wrap_socket=None, **ssl_opts):
  257. """Create a new HTTPConnection.
  258. Args:
  259. host: The host to which we'll connect.
  260. port: Optional. The port over which we'll connect. Default 80 for
  261. non-ssl, 443 for ssl.
  262. use_ssl: Optional. Whether to use ssl. Defaults to False if port is
  263. not 443, true if port is 443.
  264. ssl_validator: a function(socket) to validate the ssl cert
  265. timeout: Optional. Connection timeout, default is TIMEOUT_DEFAULT.
  266. continue_timeout: Optional. Timeout for waiting on an expected
  267. "100 Continue" response. Default is TIMEOUT_ASSUME_CONTINUE.
  268. proxy_hostport: Optional. Tuple of (host, port) to use as an http
  269. proxy for the connection. Default is to not use a proxy.
  270. ssl_wrap_socket: Optional function to use for wrapping
  271. sockets. If unspecified, the one from the ssl module will
  272. be used if available, or something that's compatible with
  273. it if on a Python older than 2.6.
  274. Any extra keyword arguments to this function will be provided
  275. to the ssl_wrap_socket method. If no ssl
  276. """
  277. if port is None and host.count(':') == 1 or ']:' in host:
  278. host, port = host.rsplit(':', 1)
  279. port = int(port)
  280. if '[' in host:
  281. host = host[1:-1]
  282. if ssl_wrap_socket is not None:
  283. self._ssl_wrap_socket = ssl_wrap_socket
  284. else:
  285. self._ssl_wrap_socket = socketutil.wrap_socket
  286. if use_ssl is None and port is None:
  287. use_ssl = False
  288. port = 80
  289. elif use_ssl is None:
  290. use_ssl = (port == 443)
  291. elif port is None:
  292. port = (use_ssl and 443 or 80)
  293. self.port = port
  294. if use_ssl and not socketutil.have_ssl:
  295. raise Exception('ssl requested but unavailable on this Python')
  296. self.ssl = use_ssl
  297. self.ssl_opts = ssl_opts
  298. self._ssl_validator = ssl_validator
  299. self.host = host
  300. self.sock = None
  301. self._current_response = None
  302. self._current_response_taken = False
  303. if proxy_hostport is None:
  304. self._proxy_host = self._proxy_port = None
  305. else:
  306. self._proxy_host, self._proxy_port = proxy_hostport
  307. self.timeout = timeout
  308. self.continue_timeout = continue_timeout
  309. def _connect(self):
  310. """Connect to the host and port specified in __init__."""
  311. if self.sock:
  312. return
  313. if self._proxy_host is not None:
  314. logger.info('Connecting to http proxy %s:%s',
  315. self._proxy_host, self._proxy_port)
  316. sock = socketutil.create_connection((self._proxy_host,
  317. self._proxy_port))
  318. if self.ssl:
  319. # TODO proxy header support
  320. data = self._buildheaders('CONNECT', '%s:%d' % (self.host,
  321. self.port),
  322. {}, HTTP_VER_1_0)
  323. sock.send(data)
  324. sock.setblocking(0)
  325. r = self.response_class(sock, self.timeout, 'CONNECT')
  326. timeout_exc = HTTPTimeoutException(
  327. 'Timed out waiting for CONNECT response from proxy')
  328. while not r.complete():
  329. try:
  330. # We're a friend of the response class, so let
  331. # us use the private attribute.
  332. # pylint: disable=W0212
  333. if not r._select():
  334. if not r.complete():
  335. raise timeout_exc
  336. except HTTPTimeoutException:
  337. # This raise/except pattern looks goofy, but
  338. # _select can raise the timeout as well as the
  339. # loop body. I wish it wasn't this convoluted,
  340. # but I don't have a better solution
  341. # immediately handy.
  342. raise timeout_exc
  343. if r.status != 200:
  344. raise HTTPProxyConnectFailedException(
  345. 'Proxy connection failed: %d %s' % (r.status,
  346. r.read()))
  347. logger.info('CONNECT (for SSL) to %s:%s via proxy succeeded.',
  348. self.host, self.port)
  349. else:
  350. sock = socketutil.create_connection((self.host, self.port))
  351. if self.ssl:
  352. # This is the default, but in the case of proxied SSL
  353. # requests the proxy logic above will have cleared
  354. # blocking mode, so re-enable it just to be safe.
  355. sock.setblocking(1)
  356. logger.debug('wrapping socket for ssl with options %r',
  357. self.ssl_opts)
  358. sock = self._ssl_wrap_socket(sock, **self.ssl_opts)
  359. if self._ssl_validator:
  360. self._ssl_validator(sock)
  361. sock.setblocking(0)
  362. self.sock = sock
  363. def _buildheaders(self, method, path, headers, http_ver):
  364. if self.ssl and self.port == 443 or self.port == 80:
  365. # default port for protocol, so leave it out
  366. hdrhost = self.host
  367. else:
  368. # include nonstandard port in header
  369. if ':' in self.host: # must be IPv6
  370. hdrhost = '[%s]:%d' % (self.host, self.port)
  371. else:
  372. hdrhost = '%s:%d' % (self.host, self.port)
  373. if self._proxy_host and not self.ssl:
  374. # When talking to a regular http proxy we must send the
  375. # full URI, but in all other cases we must not (although
  376. # technically RFC 2616 says servers must accept our
  377. # request if we screw up, experimentally few do that
  378. # correctly.)
  379. assert path[0] == '/', 'path must start with a /'
  380. path = 'http://%s%s' % (hdrhost, path)
  381. outgoing = ['%s %s %s%s' % (method, path, http_ver, EOL)]
  382. headers['host'] = ('Host', hdrhost)
  383. headers[HDR_ACCEPT_ENCODING] = (HDR_ACCEPT_ENCODING, 'identity')
  384. for hdr, val in headers.itervalues():
  385. outgoing.append('%s: %s%s' % (hdr, val, EOL))
  386. outgoing.append(EOL)
  387. return ''.join(outgoing)
  388. def close(self):
  389. """Close the connection to the server.
  390. This is a no-op if the connection is already closed. The
  391. connection may automatically close if requested by the server
  392. or required by the nature of a response.
  393. """
  394. if self.sock is None:
  395. return
  396. self.sock.close()
  397. self.sock = None
  398. logger.info('closed connection to %s on %s', self.host, self.port)
  399. def busy(self):
  400. """Returns True if this connection object is currently in use.
  401. If a response is still pending, this will return True, even if
  402. the request has finished sending. In the future,
  403. HTTPConnection may transparently juggle multiple connections
  404. to the server, in which case this will be useful to detect if
  405. any of those connections is ready for use.
  406. """
  407. cr = self._current_response
  408. if cr is not None:
  409. if self._current_response_taken:
  410. if cr.will_close:
  411. self.sock = None
  412. self._current_response = None
  413. return False
  414. elif cr.complete():
  415. self._current_response = None
  416. return False
  417. return True
  418. return False
  419. def _reconnect(self, where):
  420. logger.info('reconnecting during %s', where)
  421. self.close()
  422. self._connect()
  423. def request(self, method, path, body=None, headers={},
  424. expect_continue=False):
  425. """Send a request to the server.
  426. For increased flexibility, this does not return the response
  427. object. Future versions of HTTPConnection that juggle multiple
  428. sockets will be able to send (for example) 5 requests all at
  429. once, and then let the requests arrive as data is
  430. available. Use the `getresponse()` method to retrieve the
  431. response.
  432. """
  433. if self.busy():
  434. raise httplib.CannotSendRequest(
  435. 'Can not send another request before '
  436. 'current response is read!')
  437. self._current_response_taken = False
  438. logger.info('sending %s request for %s to %s on port %s',
  439. method, path, self.host, self.port)
  440. hdrs = dict((k.lower(), (k, v)) for k, v in headers.iteritems())
  441. if hdrs.get('expect', ('', ''))[1].lower() == '100-continue':
  442. expect_continue = True
  443. elif expect_continue:
  444. hdrs['expect'] = ('Expect', '100-Continue')
  445. chunked = False
  446. if body and HDR_CONTENT_LENGTH not in hdrs:
  447. if getattr(body, '__len__', False):
  448. hdrs[HDR_CONTENT_LENGTH] = (HDR_CONTENT_LENGTH, len(body))
  449. elif getattr(body, 'read', False):
  450. hdrs[HDR_XFER_ENCODING] = (HDR_XFER_ENCODING,
  451. XFER_ENCODING_CHUNKED)
  452. chunked = True
  453. else:
  454. raise BadRequestData('body has no __len__() nor read()')
  455. # If we're reusing the underlying socket, there are some
  456. # conditions where we'll want to retry, so make a note of the
  457. # state of self.sock
  458. fresh_socket = self.sock is None
  459. self._connect()
  460. outgoing_headers = self._buildheaders(
  461. method, path, hdrs, self.http_version)
  462. response = None
  463. first = True
  464. while ((outgoing_headers or body)
  465. and not (response and response.complete())):
  466. select_timeout = self.timeout
  467. out = outgoing_headers or body
  468. blocking_on_continue = False
  469. if expect_continue and not outgoing_headers and not (
  470. response and (response.headers or response.continued)):
  471. logger.info(
  472. 'waiting up to %s seconds for'
  473. ' continue response from server',
  474. self.continue_timeout)
  475. select_timeout = self.continue_timeout
  476. blocking_on_continue = True
  477. out = False
  478. if out:
  479. w = [self.sock]
  480. else:
  481. w = []
  482. r, w, x = select.select([self.sock], w, [], select_timeout)
  483. # if we were expecting a 100 continue and it's been long
  484. # enough, just go ahead and assume it's ok. This is the
  485. # recommended behavior from the RFC.
  486. if r == w == x == []:
  487. if blocking_on_continue:
  488. expect_continue = False
  489. logger.info('no response to continue expectation from '
  490. 'server, optimistically sending request body')
  491. else:
  492. raise HTTPTimeoutException('timeout sending data')
  493. was_first = first
  494. # incoming data
  495. if r:
  496. try:
  497. try:
  498. data = r[0].recv(INCOMING_BUFFER_SIZE)
  499. except socket.sslerror, e:
  500. if e.args[0] != socket.SSL_ERROR_WANT_READ:
  501. raise
  502. logger.debug('SSL_ERROR_WANT_READ while sending '
  503. 'data, retrying...')
  504. continue
  505. if not data:
  506. logger.info('socket appears closed in read')
  507. self.sock = None
  508. self._current_response = None
  509. if response is not None:
  510. # We're a friend of the response class, so let
  511. # us use the private attribute.
  512. # pylint: disable=W0212
  513. response._close()
  514. # This if/elif ladder is a bit subtle,
  515. # comments in each branch should help.
  516. if response is not None and response.complete():
  517. # Server responded completely and then
  518. # closed the socket. We should just shut
  519. # things down and let the caller get their
  520. # response.
  521. logger.info('Got an early response, '
  522. 'aborting remaining request.')
  523. break
  524. elif was_first and response is None:
  525. # Most likely a keepalive that got killed
  526. # on the server's end. Commonly happens
  527. # after getting a really large response
  528. # from the server.
  529. logger.info(
  530. 'Connection appeared closed in read on first'
  531. ' request loop iteration, will retry.')
  532. self._reconnect('read')
  533. continue
  534. else:
  535. # We didn't just send the first data hunk,
  536. # and either have a partial response or no
  537. # response at all. There's really nothing
  538. # meaningful we can do here.
  539. raise HTTPStateError(
  540. 'Connection appears closed after '
  541. 'some request data was written, but the '
  542. 'response was missing or incomplete!')
  543. logger.debug('read %d bytes in request()', len(data))
  544. if response is None:
  545. response = self.response_class(
  546. r[0], self.timeout, method)
  547. # We're a friend of the response class, so let us
  548. # use the private attribute.
  549. # pylint: disable=W0212
  550. response._load_response(data)
  551. # Jump to the next select() call so we load more
  552. # data if the server is still sending us content.
  553. continue
  554. except socket.error, e:
  555. if e[0] != errno.EPIPE and not was_first:
  556. raise
  557. # outgoing data
  558. if w and out:
  559. try:
  560. if getattr(out, 'read', False):
  561. # pylint guesses the type of out incorrectly here
  562. # pylint: disable=E1103
  563. data = out.read(OUTGOING_BUFFER_SIZE)
  564. if not data:
  565. continue
  566. if len(data) < OUTGOING_BUFFER_SIZE:
  567. if chunked:
  568. body = '0' + EOL + EOL
  569. else:
  570. body = None
  571. if chunked:
  572. out = hex(len(data))[2:] + EOL + data + EOL
  573. else:
  574. out = data
  575. amt = w[0].send(out)
  576. except socket.error, e:
  577. if e[0] == socket.SSL_ERROR_WANT_WRITE and self.ssl:
  578. # This means that SSL hasn't flushed its buffer into
  579. # the socket yet.
  580. # TODO: find a way to block on ssl flushing its buffer
  581. # similar to selecting on a raw socket.
  582. continue
  583. if e[0] == errno.EWOULDBLOCK or e[0] == errno.EAGAIN:
  584. continue
  585. elif (e[0] not in (errno.ECONNRESET, errno.EPIPE)
  586. and not first):
  587. raise
  588. self._reconnect('write')
  589. amt = self.sock.send(out)
  590. logger.debug('sent %d', amt)
  591. first = False
  592. if out is body:
  593. body = out[amt:]
  594. else:
  595. outgoing_headers = out[amt:]
  596. # close if the server response said to or responded before eating
  597. # the whole request
  598. if response is None:
  599. response = self.response_class(self.sock, self.timeout, method)
  600. if not fresh_socket:
  601. if not response._select():
  602. # This means the response failed to get any response
  603. # data at all, and in all probability the socket was
  604. # closed before the server even saw our request. Try
  605. # the request again on a fresh socket.
  606. logging.debug('response._select() failed during request().'
  607. ' Assuming request needs to be retried.')
  608. self.sock = None
  609. # Call this method explicitly to re-try the
  610. # request. We don't use self.request() because
  611. # some tools (notably Mercurial) expect to be able
  612. # to subclass and redefine request(), and they
  613. # don't have the same argspec as we do.
  614. #
  615. # TODO restructure sending of requests to avoid
  616. # this recursion
  617. return HTTPConnection.request(
  618. self, method, path, body=body, headers=headers,
  619. expect_continue=expect_continue)
  620. data_left = bool(outgoing_headers or body)
  621. if data_left:
  622. logger.info('stopped sending request early, '
  623. 'will close the socket to be safe.')
  624. response.will_close = True
  625. if response.will_close:
  626. # The socket will be closed by the response, so we disown
  627. # the socket
  628. self.sock = None
  629. self._current_response = response
  630. def getresponse(self):
  631. """Returns the response to the most recent request."""
  632. if self._current_response is None:
  633. raise httplib.ResponseNotReady()
  634. r = self._current_response
  635. while r.headers is None:
  636. # We're a friend of the response class, so let us use the
  637. # private attribute.
  638. # pylint: disable=W0212
  639. if not r._select() and not r.complete():
  640. raise _readers.HTTPRemoteClosedError()
  641. if r.will_close:
  642. self.sock = None
  643. self._current_response = None
  644. elif r.complete():
  645. self._current_response = None
  646. else:
  647. self._current_response_taken = True
  648. return r
  649. class HTTPTimeoutException(httplib.HTTPException):
  650. """A timeout occurred while waiting on the server."""
  651. class BadRequestData(httplib.HTTPException):
  652. """Request body object has neither __len__ nor read."""
  653. class HTTPProxyConnectFailedException(httplib.HTTPException):
  654. """Connecting to the HTTP proxy failed."""
  655. class HTTPStateError(httplib.HTTPException):
  656. """Invalid internal state encountered."""
  657. # Forward this exception type from _readers since it needs to be part
  658. # of the public API.
  659. HTTPRemoteClosedError = _readers.HTTPRemoteClosedError
  660. # no-check-code