~ubuntu-branches/ubuntu/utopic/python-urllib3/utopic

« back to all changes in this revision

Viewing changes to urllib3/connectionpool.py

  • Committer: Package Import Robot
  • Author(s): Daniele Tricoli
  • Date: 2014-07-07 16:09:06 UTC
  • mfrom: (4.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20140707160906-hv2d4zrlg8u7rjby
Tags: 1.8.3-1
* New upstream release (Closes: #754090)
* debian/patches/01_do-not-use-embedded-python-six.patch
  - Refresh
* debian/patches/04_relax_nosetests_options.patch
  - Refresh

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
from socket import error as SocketError, timeout as SocketTimeout
12
12
import socket
13
13
 
14
 
try: # Python 3
 
14
try:  # Python 3
15
15
    from queue import LifoQueue, Empty, Full
16
16
except ImportError:
17
17
    from Queue import LifoQueue, Empty, Full
21
21
from .exceptions import (
22
22
    ClosedPoolError,
23
23
    ConnectionError,
24
 
    ConnectTimeoutError,
25
24
    EmptyPoolError,
26
25
    HostChangedError,
27
26
    LocationParseError,
54
53
 
55
54
_Default = object()
56
55
 
 
56
 
57
57
## Pool objects
58
 
 
59
58
class ConnectionPool(object):
60
59
    """
61
60
    Base class for all connection pools, such as
82
81
# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252
83
82
_blocking_errnos = set([errno.EAGAIN, errno.EWOULDBLOCK])
84
83
 
 
84
 
85
85
class HTTPConnectionPool(ConnectionPool, RequestMethods):
86
86
    """
87
87
    Thread-safe connection pool for one host.
133
133
    :param _proxy_headers:
134
134
        A dictionary with proxy headers, should not be used directly,
135
135
        instead, see :class:`urllib3.connectionpool.ProxyManager`"
 
136
 
 
137
    :param \**conn_kw:
 
138
        Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`,
 
139
        :class:`urllib3.connection.HTTPSConnection` instances.
136
140
    """
137
141
 
138
142
    scheme = 'http'
166
170
        # These are mostly for testing and debugging purposes.
167
171
        self.num_connections = 0
168
172
        self.num_requests = 0
169
 
 
170
 
        if sys.version_info < (2, 7):  # Python 2.6 and older
171
 
            conn_kw.pop('source_address', None)
172
173
        self.conn_kw = conn_kw
173
174
 
 
175
        if self.proxy:
 
176
            # Enable Nagle's algorithm for proxies, to avoid packet fragmentation.
 
177
            # We cannot know if the user has added default socket options, so we cannot replace the
 
178
            # list.
 
179
            self.conn_kw.setdefault('socket_options', [])
 
180
 
174
181
    def _new_conn(self):
175
182
        """
176
183
        Return a fresh :class:`HTTPConnection`.
182
189
        conn = self.ConnectionCls(host=self.host, port=self.port,
183
190
                                  timeout=self.timeout.connect_timeout,
184
191
                                  strict=self.strict, **self.conn_kw)
185
 
        if self.proxy is not None:
186
 
            # Enable Nagle's algorithm for proxies, to avoid packet
187
 
            # fragmentation.
188
 
            conn.tcp_nodelay = 0
189
192
        return conn
190
193
 
191
194
    def _get_conn(self, timeout=None):
204
207
        try:
205
208
            conn = self.pool.get(block=self.block, timeout=timeout)
206
209
 
207
 
        except AttributeError: # self.pool is None
 
210
        except AttributeError:  # self.pool is None
208
211
            raise ClosedPoolError(self, "Pool is closed.")
209
212
 
210
213
        except Empty:
218
221
        if conn and is_connection_dropped(conn):
219
222
            log.info("Resetting dropped connection: %s" % self.host)
220
223
            conn.close()
 
224
            if getattr(conn, 'auto_open', 1) == 0:
 
225
                # This is a proxied connection that has been mutated by
 
226
                # httplib._tunnel() and cannot be reused (since it would
 
227
                # attempt to bypass the proxy)
 
228
                conn = None
221
229
 
222
230
        return conn or self._new_conn()
223
231
 
237
245
        """
238
246
        try:
239
247
            self.pool.put(conn, block=False)
240
 
            return # Everything is dandy, done.
 
248
            return  # Everything is dandy, done.
241
249
        except AttributeError:
242
250
            # self.pool is None.
243
251
            pass
283
291
 
284
292
        timeout_obj = self._get_timeout(timeout)
285
293
 
286
 
        try:
287
 
            timeout_obj.start_connect()
288
 
            conn.timeout = timeout_obj.connect_timeout
289
 
            # conn.request() calls httplib.*.request, not the method in
290
 
            # urllib3.request. It also calls makefile (recv) on the socket.
291
 
            conn.request(method, url, **httplib_request_kw)
292
 
        except SocketTimeout:
293
 
            raise ConnectTimeoutError(
294
 
                self, "Connection to %s timed out. (connect timeout=%s)" %
295
 
                (self.host, timeout_obj.connect_timeout))
 
294
        timeout_obj.start_connect()
 
295
        conn.timeout = timeout_obj.connect_timeout
 
296
        # conn.request() calls httplib.*.request, not the method in
 
297
        # urllib3.request. It also calls makefile (recv) on the socket.
 
298
        conn.request(method, url, **httplib_request_kw)
296
299
 
297
300
        # Reset the timeout for the recv() on the socket
298
301
        read_timeout = timeout_obj.read_timeout
310
313
                    "Read timed out. (read timeout=%s)" % read_timeout)
311
314
            if read_timeout is Timeout.DEFAULT_TIMEOUT:
312
315
                conn.sock.settimeout(socket.getdefaulttimeout())
313
 
            else: # None or a value
 
316
            else:  # None or a value
314
317
                conn.sock.settimeout(read_timeout)
315
318
 
316
319
        # Receive the response from the server
317
320
        try:
318
 
            try: # Python 2.7+, use buffering of HTTP responses
 
321
            try:  # Python 2.7+, use buffering of HTTP responses
319
322
                httplib_response = conn.getresponse(buffering=True)
320
 
            except TypeError: # Python 2.6 and older
 
323
            except TypeError:  # Python 2.6 and older
321
324
                httplib_response = conn.getresponse()
322
325
        except SocketTimeout:
323
326
            raise ReadTimeoutError(
333
336
 
334
337
            raise
335
338
 
336
 
        except SocketError as e: # Platform-specific: Python 2
 
339
        except SocketError as e:  # Platform-specific: Python 2
337
340
            # See the above comment about EAGAIN in Python 3. In Python 2 we
338
341
            # have to specifically catch it and throw the timeout error
339
342
            if e.errno in _blocking_errnos:
364
367
                    conn.close()
365
368
 
366
369
        except Empty:
367
 
            pass # Done.
 
370
            pass  # Done.
368
371
 
369
372
    def is_same_host(self, url):
370
373
        """
607
610
                 assert_hostname=None, assert_fingerprint=None,
608
611
                 **conn_kw):
609
612
 
610
 
        if sys.version_info < (2, 7):  # Python 2.6 or older
611
 
            conn_kw.pop('source_address', None)
612
 
 
613
613
        HTTPConnectionPool.__init__(self, host, port, strict, timeout, maxsize,
614
 
                                    block, headers, _proxy, _proxy_headers, **conn_kw)
 
614
                                    block, headers, _proxy, _proxy_headers,
 
615
                                    **conn_kw)
615
616
        self.key_file = key_file
616
617
        self.cert_file = cert_file
617
618
        self.cert_reqs = cert_reqs
619
620
        self.ssl_version = ssl_version
620
621
        self.assert_hostname = assert_hostname
621
622
        self.assert_fingerprint = assert_fingerprint
622
 
        self.conn_kw = conn_kw
623
623
 
624
624
    def _prepare_conn(self, conn):
625
625
        """
635
635
                          assert_hostname=self.assert_hostname,
636
636
                          assert_fingerprint=self.assert_fingerprint)
637
637
            conn.ssl_version = self.ssl_version
638
 
            conn.conn_kw = self.conn_kw
639
638
 
640
639
        if self.proxy is not None:
641
640
            # Python 2.7+
643
642
                set_tunnel = conn.set_tunnel
644
643
            except AttributeError:  # Platform-specific: Python 2.6
645
644
                set_tunnel = conn._set_tunnel
646
 
            set_tunnel(self.host, self.port, self.proxy_headers)
 
645
                
 
646
            if sys.version_info <= (2, 6, 4) and not self.proxy_headers:   # Python 2.6.4 and older
 
647
                set_tunnel(self.host, self.port)
 
648
            else:
 
649
                set_tunnel(self.host, self.port, self.proxy_headers)
 
650
 
647
651
            # Establish tunnel connection early, because otherwise httplib
648
652
            # would improperly set Host: header to proxy's IP:port.
649
653
            conn.connect()
669
673
            actual_host = self.proxy.host
670
674
            actual_port = self.proxy.port
671
675
 
672
 
        extra_params = {}
673
 
        if not six.PY3:  # Python 2
674
 
            extra_params['strict'] = self.strict
675
 
        extra_params.update(self.conn_kw)
676
 
 
677
676
        conn = self.ConnectionCls(host=actual_host, port=actual_port,
678
677
                                  timeout=self.timeout.connect_timeout,
679
 
                                  **extra_params)
680
 
        if self.proxy is not None:
681
 
            # Enable Nagle's algorithm for proxies, to avoid packet
682
 
            # fragmentation.
683
 
            conn.tcp_nodelay = 0
 
678
                                  strict=self.strict, **self.conn_kw)
684
679
 
685
680
        return self._prepare_conn(conn)
686
681