Augie Fackler committed c86239e

proxy support: degrade gracefully when socket.socket is unavailable

This should allow httplib2 to continue to work even on platforms like
appengine where the socket module exists but has no socket attribute.

  • Participants
  • Parent commits 402bd71

Comments (0)

Files changed (4)

File python2/httplib2/

 from gettext import gettext as _
 import socket
-from httplib2 import socks
+    from httplib2 import socks
+except ImportError:
+    socks = None
 # Build the appropriate socket wrapper for ssl
 __all__ = ['Http', 'Response', 'ProxyInfo', 'HttpLib2Error',
   'RedirectMissingLocation', 'RedirectLimit', 'FailedToDecompressContent',
   'UnimplementedDigestAuthOptionError', 'UnimplementedHmacDigestAuthOptionError',
-  'debuglevel']
+  'debuglevel', 'ProxiesUnavailableError']
 # The httplib debug level, set to a non-zero value to get debug output
 class RelativeURIError(HttpLib2Error): pass
 class ServerNotFoundError(HttpLib2Error): pass
+class ProxiesUnavailableError(HttpLib2Error): pass
 # Open Items:
 # -----------
     def connect(self):
         """Connect to the host and port specified in __init__."""
         # Mostly verbatim from
+        if self.proxy_info and socks is None:
+            raise ProxiesUnavailableError(
+                'Proxy support missing but proxy use was requested!')
         msg = "getaddrinfo returns an empty list"
         for res in socket.getaddrinfo(, self.port, 0,

File python2/httplib2/

 import socket
+if getattr(socket, 'socket', None) is None:
+    raise ImportError('socket.socket missing, proxy support unusable')
 import struct
 import sys

File python2/httplib2/test/brokensocket/

+from realsocket import gaierror, error, getaddrinfo, SOCK_STREAM

File python2/httplib2/test/

+"""Tests for httplib2 when the socket module is missing.
+This helps ensure compatibility with environments such as AppEngine.
+import os
+import sys
+import unittest
+import httplib2
+class MissingSocketTest(unittest.TestCase):
+    def setUp(self):
+        self._oldsocks = httplib2.socks
+        httplib2.socks = None
+    def tearDown(self):
+        httplib2.socks = self._oldsocks
+    def testProxyDisabled(self):
+        proxy_info = httplib2.ProxyInfo('blah',
+                                        'localhost', 0)
+        client = httplib2.Http(proxy_info=proxy_info)
+        self.assertRaises(httplib2.ProxiesUnavailableError,
+                          client.request, 'http://localhost:-1/')