Augie Fackler avatar 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.

Comments (0)

Files changed (4)


 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,


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


+from realsocket import gaierror, error, getaddrinfo, SOCK_STREAM


+"""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/')
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.