Sync to version 0.7.0 of httplib2
diff --git a/httplib2/socks.py b/httplib2/socks.py
index b65fb38..a458e1c 100644
--- a/httplib2/socks.py
+++ b/httplib2/socks.py
@@ -3,8 +3,8 @@
 
 Copyright 2006 Dan-Haim. All rights reserved.
 
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
 1. Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright notice,
@@ -13,7 +13,7 @@
 3. Neither the name of Dan Haim nor the names of his contributors may be used
    to endorse or promote products derived from this software without specific
    prior written permission.
-
+   
 THIS SOFTWARE IS PROVIDED BY DAN HAIM "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
@@ -22,7 +22,7 @@
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA
 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMANGE.
 
 
 This module provides a standard socket-like interface for Python
@@ -41,95 +41,57 @@
 """
 
 import socket
+import struct
+import sys
 
 if getattr(socket, 'socket', None) is None:
     raise ImportError('socket.socket missing, proxy support unusable')
 
-import struct
-import sys
-
 PROXY_TYPE_SOCKS4 = 1
 PROXY_TYPE_SOCKS5 = 2
 PROXY_TYPE_HTTP = 3
 
 _defaultproxy = None
+_orgsocket = socket.socket
 
-# Small hack for Python 2.x
-if sys.version_info[0] <= 2:
-    def bytes(obj, enc=None):
-        return obj
-
-class ProxyError(Exception):
-    def __init__(self, value):
-        self.value = value
-    def __str__(self):
-        return repr(self.value)
-
-class GeneralProxyError(ProxyError):
-    def __init__(self, value):
-        self.value = value
-    def __str__(self):
-        return repr(self.value)
-
-class Socks5AuthError(ProxyError):
-    def __init__(self, value):
-        self.value = value
-    def __str__(self):
-        return repr(self.value)
-
-class Socks5Error(ProxyError):
-    def __init__(self, value):
-        self.value = value
-    def __str__(self):
-        return repr(self.value)
-
-class Socks4Error(ProxyError):
-    def __init__(self, value):
-        self.value = value
-    def __str__(self):
-        return repr(self.value)
-
-class HTTPError(ProxyError):
-    def __init__(self, value):
-        self.value = value
-    def __str__(self):
-        return repr(self.value)
+class ProxyError(Exception): pass
+class GeneralProxyError(ProxyError): pass
+class Socks5AuthError(ProxyError): pass
+class Socks5Error(ProxyError): pass
+class Socks4Error(ProxyError): pass
+class HTTPError(ProxyError): pass
 
 _generalerrors = ("success",
-                  "invalid data",
-                  "not connected",
-                  "not available",
-                  "bad proxy type",
-                  "bad input")
+    "invalid data",
+    "not connected",
+    "not available",
+    "bad proxy type",
+    "bad input")
 
 _socks5errors = ("succeeded",
-                 "general SOCKS server failure",
-                 "connection not allowed by ruleset",
-                 "Network unreachable",
-                 "Host unreachable",
-                 "Connection refused",
-                 "TTL expired",
-                 "Command not supported",
-                 "Address type not supported",
-                 "Unknown error")
+    "general SOCKS server failure",
+    "connection not allowed by ruleset",
+    "Network unreachable",
+    "Host unreachable",
+    "Connection refused",
+    "TTL expired",
+    "Command not supported",
+    "Address type not supported",
+    "Unknown error")
 
 _socks5autherrors = ("succeeded",
-                     "authentication is required",
-                     "all offered authentication methods were rejected",
-                     "unknown username or invalid password",
-                     "unknown error")
+    "authentication is required",
+    "all offered authentication methods were rejected",
+    "unknown username or invalid password",
+    "unknown error")
 
 _socks4errors = ("request granted",
-                 "request rejected or failed",
-                 ("request rejected because SOCKS server cannot connect to "
-                  "identd on the client"),
-                 ("request rejected because the client program and identd"
-                  " report different user-ids"),
-                 "unknown error")
+    "request rejected or failed",
+    "request rejected because SOCKS server cannot connect to identd on the client",
+    "request rejected because the client program and identd report different user-ids",
+    "unknown error")
 
-
-def setdefaultproxy(proxytype=None, addr=None, port=None, rdns=True,
-                    username=None, password=None):
+def setdefaultproxy(proxytype=None, addr=None, port=None, rdns=True, username=None, password=None):
     """setdefaultproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
     Sets a default proxy which all further socksocket objects will use,
     unless explicitly changed.
@@ -137,18 +99,27 @@
     global _defaultproxy
     _defaultproxy = (proxytype, addr, port, rdns, username, password)
 
+def wrapmodule(module):
+    """wrapmodule(module)
+    Attempts to replace a module's socket library with a SOCKS socket. Must set
+    a default proxy using setdefaultproxy(...) first.
+    This will only work on modules that import socket directly into the namespace;
+    most of the Python Standard Library falls into this category.
+    """
+    if _defaultproxy != None:
+        module.socket.socket = socksocket
+    else:
+        raise GeneralProxyError((4, "no proxy specified"))
 
 class socksocket(socket.socket):
     """socksocket([family[, type[, proto]]]) -> socket object
-
     Open a SOCKS enabled socket. The parameters are the same as
     those of the standard socket init. In order for SOCKS to work,
     you must specify family=AF_INET, type=SOCK_STREAM and proto=0.
     """
 
-    def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM,
-                 proto=0, _sock=None):
-        socket.socket.__init__(self, family, type, proto, _sock)
+    def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None):
+        _orgsocket.__init__(self, family, type, proto, _sock)
         if _defaultproxy != None:
             self.__proxy = _defaultproxy
         else:
@@ -156,41 +127,19 @@
         self.__proxysockname = None
         self.__proxypeername = None
 
-    def __decode(self, bytes):
-        if getattr(bytes, 'decode', False):
-            try:
-                bytes = bytes.decode()
-            except Exception:
-                pass
-        return bytes
-
-    def __encode(self, bytes):
-        if getattr(bytes, 'encode', False):
-            try:
-                bytes = bytes.encode()
-            except Exception:
-                pass
-        return bytes
-
     def __recvall(self, count):
         """__recvall(count) -> data
         Receive EXACTLY the number of bytes requested from the socket.
         Blocks until the required number of bytes have been received.
         """
-        data = bytes("")
+        data = self.recv(count)
         while len(data) < count:
-            d = self.recv(count - len(data))
-            if not d:
-                raise GeneralProxyError(
-                    (0, "connection closed unexpectedly"))
-            data = data + self.__decode(d)
+            d = self.recv(count-len(data))
+            if not d: raise GeneralProxyError((0, "connection closed unexpectedly"))
+            data = data + d
         return data
 
-    def sendall(self, bytes):
-        socket.socket.sendall(self, self.__encode(bytes))
-
-    def setproxy(self, proxytype=None, addr=None, port=None, rdns=True,
-                 username=None, password=None):
+    def setproxy(self, proxytype=None, addr=None, port=None, rdns=True, username=None, password=None):
         """setproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
         Sets the proxy to be used.
         proxytype -    The type of the proxy to be used. Three types
@@ -214,36 +163,35 @@
         Negotiates a connection through a SOCKS5 server.
         """
         # First we'll send the authentication packages we support.
-        if (self.__proxy[4] != None) and (self.__proxy[5] != None):
+        if (self.__proxy[4]!=None) and (self.__proxy[5]!=None):
             # The username/password details were supplied to the
             # setproxy method so we support the USERNAME/PASSWORD
             # authentication (in addition to the standard none).
-            self.sendall("\x05\x02\x00\x02")
+            self.sendall(struct.pack('BBBB', 0x05, 0x02, 0x00, 0x02))
         else:
             # No username/password were entered, therefore we
             # only support connections with no authentication.
-            self.sendall("\x05\x01\x00")
+            self.sendall(struct.pack('BBB', 0x05, 0x01, 0x00))
         # We'll receive the server's response to determine which
         # method was selected
         chosenauth = self.__recvall(2)
-        if chosenauth[0] != "\x05":
+        if chosenauth[0:1] != chr(0x05).encode():
             self.close()
             raise GeneralProxyError((1, _generalerrors[1]))
         # Check the chosen authentication method
-        if chosenauth[1] == "\x00":
+        if chosenauth[1:2] == chr(0x00).encode():
             # No authentication is required
             pass
-        elif chosenauth[1] == "\x02":
+        elif chosenauth[1:2] == chr(0x02).encode():
             # Okay, we need to perform a basic username/password
             # authentication.
-            self.sendall("\x01" + chr(len(self.__proxy[4])) + self.__proxy[4] +
-                         chr(len(self.__proxy[5])) + self.__proxy[5])
+            self.sendall(chr(0x01).encode() + chr(len(self.__proxy[4])) + self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5])
             authstat = self.__recvall(2)
-            if authstat[0] != "\x01":
+            if authstat[0:1] != chr(0x01).encode():
                 # Bad response
                 self.close()
                 raise GeneralProxyError((1, _generalerrors[1]))
-            if authstat[1] != "\x00":
+            if authstat[1:2] != chr(0x00).encode():
                 # Authentication failed
                 self.close()
                 raise Socks5AuthError((3, _socks5autherrors[3]))
@@ -251,52 +199,52 @@
         else:
             # Reaching here is always bad
             self.close()
-            if chosenauth[1] == "\xFF":
+            if chosenauth[1] == chr(0xFF).encode():
                 raise Socks5AuthError((2, _socks5autherrors[2]))
             else:
                 raise GeneralProxyError((1, _generalerrors[1]))
         # Now we can request the actual connection
-        req = "\x05\x01\x00"
+        req = struct.pack('BBB', 0x05, 0x01, 0x00)
         # If the given destination address is an IP address, we'll
         # use the IPv4 address request even if remote resolving was specified.
         try:
             ipaddr = socket.inet_aton(destaddr)
-            req = req + "\x01" + ipaddr
+            req = req + chr(0x01).encode() + ipaddr
         except socket.error:
             # Well it's not an IP number,  so it's probably a DNS name.
-            if self.__proxy[3] == True:
+            if self.__proxy[3]:
                 # Resolve remotely
                 ipaddr = None
-                req = req + "\x03" + chr(len(destaddr)) + destaddr
+                req = req + chr(0x03).encode() + chr(len(destaddr)).encode() + destaddr
             else:
                 # Resolve locally
                 ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
-                req = req + "\x01" + ipaddr
-        req = req + self.__decode(struct.pack(">H", destport))
+                req = req + chr(0x01).encode() + ipaddr
+        req = req + struct.pack(">H", destport)
         self.sendall(req)
         # Get the response
         resp = self.__recvall(4)
-        if resp[0] != "\x05":
+        if resp[0:1] != chr(0x05).encode():
             self.close()
             raise GeneralProxyError((1, _generalerrors[1]))
-        elif resp[1] != "\x00":
+        elif resp[1:2] != chr(0x00).encode():
             # Connection failed
             self.close()
-            if ord(resp[1]) <= 8:
-                raise Socks5Error((ord(resp[1]), _socks5errors[ord(resp[1])]))
+            if ord(resp[1:2])<=8:
+                raise Socks5Error((ord(resp[1:2]), _socks5errors[ord(resp[1:2])]))
             else:
                 raise Socks5Error((9, _socks5errors[9]))
         # Get the bound address/port
-        elif resp[3] == "\x01":
+        elif resp[3:4] == chr(0x01).encode():
             boundaddr = self.__recvall(4)
-        elif resp[3] == "\x03":
+        elif resp[3:4] == chr(0x03).encode():
             resp = resp + self.recv(1)
-            boundaddr = self.__recvall(ord(resp[4]))
+            boundaddr = self.__recvall(ord(resp[4:5]))
         else:
             self.close()
-            raise GeneralProxyError((1, _generalerrors[1]))
-        boundport = struct.unpack(">H", bytes(self.__recvall(2), 'utf8'))[0]
-        self.__proxysockname = boundaddr, boundport
+            raise GeneralProxyError((1,_generalerrors[1]))
+        boundport = struct.unpack(">H", self.__recvall(2))[0]
+        self.__proxysockname = (boundaddr, boundport)
         if ipaddr != None:
             self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)
         else:
@@ -312,7 +260,7 @@
         """getproxypeername() -> address info
         Returns the IP and port number of the proxy.
         """
-        return socket.socket.getpeername(self)
+        return _orgsocket.getpeername(self)
 
     def getpeername(self):
         """getpeername() -> address info
@@ -321,7 +269,7 @@
         """
         return self.__proxypeername
 
-    def __negotiatesocks4(self, destaddr, destport):
+    def __negotiatesocks4(self,destaddr,destport):
         """__negotiatesocks4(self,destaddr,destport)
         Negotiates a connection through a SOCKS4 server.
         """
@@ -331,41 +279,41 @@
             ipaddr = socket.inet_aton(destaddr)
         except socket.error:
             # It's a DNS name. Check where it should be resolved.
-            if self.__proxy[3] == True:
-                ipaddr = "\x00\x00\x00\x01"
+            if self.__proxy[3]:
+                ipaddr = struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01)
                 rmtrslv = True
             else:
                 ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
         # Construct the request packet
-        req = "\x04\x01" + self.__decode(struct.pack(">H", destport)) + ipaddr
+        req = struct.pack(">BBH", 0x04, 0x01, destport) + ipaddr
         # The username parameter is considered userid for SOCKS4
         if self.__proxy[4] != None:
             req = req + self.__proxy[4]
-        req = req + "\x00"
+        req = req + chr(0x00).encode()
         # DNS name if remote resolving is required
         # NOTE: This is actually an extension to the SOCKS4 protocol
         # called SOCKS4A and may not be supported in all cases.
-        if rmtrslv==True:
-            req = req + destaddr + "\x00"
+        if rmtrslv:
+            req = req + destaddr + chr(0x00).encode()
         self.sendall(req)
         # Get the response from the server
         resp = self.__recvall(8)
-        if resp[0] != "\x00":
+        if resp[0:1] != chr(0x00).encode():
             # Bad data
             self.close()
-            raise GeneralProxyError((1, _generalerrors[1]))
-        if resp[1] != "\x5A":
+            raise GeneralProxyError((1,_generalerrors[1]))
+        if resp[1:2] != chr(0x5A).encode():
             # Server returned an error
             self.close()
-            if ord(resp[1]) in (91,92,93):
+            if ord(resp[1:2]) in (91, 92, 93):
                 self.close()
-                raise Socks4Error((ord(resp[1]), _socks4errors[ord(resp[1])-90]))
+                raise Socks4Error((ord(resp[1:2]), _socks4errors[ord(resp[1:2]) - 90]))
             else:
-                raise Socks4Error((94,_socks4errors[4]))
+                raise Socks4Error((94, _socks4errors[4]))
         # Get the bound address/port
-        self.__proxysockname = (socket.inet_ntoa(resp[4:]),struct.unpack(">H",bytes(resp[2:4],'utf8'))[0])
+        self.__proxysockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0])
         if rmtrslv != None:
-            self.__proxypeername = (socket.inet_ntoa(ipaddr),destport)
+            self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)
         else:
             self.__proxypeername = (destaddr, destport)
 
@@ -374,20 +322,19 @@
         Negotiates a connection through an HTTP server.
         """
         # If we need to resolve locally, we do this now
-        if self.__proxy[3] == False:
+        if not self.__proxy[3]:
             addr = socket.gethostbyname(destaddr)
         else:
             addr = destaddr
-        self.sendall(("CONNECT %s:%s HTTP/1.1\r\n"
-                      "Host: %s\r\n\r\n") % (addr, destport, destaddr))
+        self.sendall(("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n").encode())
         # We read the response until we get the string "\r\n\r\n"
         resp = self.recv(1)
-        while resp.find("\r\n\r\n") == -1:
+        while resp.find("\r\n\r\n".encode()) == -1:
             resp = resp + self.recv(1)
         # We just need the first line to check if the connection
         # was successful
-        statusline = resp.splitlines()[0].split(" ", 2)
-        if statusline[0] not in ("HTTP/1.0", "HTTP/1.1"):
+        statusline = resp.splitlines()[0].split(" ".encode(), 2)
+        if statusline[0] not in ("HTTP/1.0".encode(), "HTTP/1.1".encode()):
             self.close()
             raise GeneralProxyError((1, _generalerrors[1]))
         try:
@@ -402,39 +349,37 @@
         self.__proxypeername = (addr, destport)
 
     def connect(self, destpair):
-        """connect(self,despair)
+        """connect(self, despair)
         Connects to the specified destination through a proxy.
         destpar - A tuple of the IP/DNS address and the port number.
         (identical to socket's connect).
         To select the proxy server use setproxy().
         """
         # Do a minimal input check first
-        # TODO(durin42): seriously? type checking? do we care?
-        if ((not isinstance(destpair, (list, tuple))) or len(destpair) < 2
-            or not isinstance(destpair[0], str) or not isinstance(destpair[1], int)):
+        if (not type(destpair) in (list,tuple)) or (len(destpair) < 2) or (type(destpair[0]) != type('')) or (type(destpair[1]) != int):
             raise GeneralProxyError((5, _generalerrors[5]))
         if self.__proxy[0] == PROXY_TYPE_SOCKS5:
             if self.__proxy[2] != None:
                 portnum = self.__proxy[2]
             else:
                 portnum = 1080
-            socket.socket.connect(self,(self.__proxy[1], portnum))
+            _orgsocket.connect(self, (self.__proxy[1], portnum))
             self.__negotiatesocks5(destpair[0], destpair[1])
         elif self.__proxy[0] == PROXY_TYPE_SOCKS4:
             if self.__proxy[2] != None:
                 portnum = self.__proxy[2]
             else:
                 portnum = 1080
-            socket.socket.connect(self, (self.__proxy[1], portnum))
+            _orgsocket.connect(self,(self.__proxy[1], portnum))
             self.__negotiatesocks4(destpair[0], destpair[1])
         elif self.__proxy[0] == PROXY_TYPE_HTTP:
             if self.__proxy[2] != None:
                 portnum = self.__proxy[2]
             else:
                 portnum = 8080
-            socket.socket.connect(self, (self.__proxy[1], portnum))
+            _orgsocket.connect(self,(self.__proxy[1], portnum))
             self.__negotiatehttp(destpair[0], destpair[1])
         elif self.__proxy[0] == None:
-            socket.socket.connect(self, (destpair[0], destpair[1]))
+            _orgsocket.connect(self, (destpair[0], destpair[1]))
         else:
             raise GeneralProxyError((4, _generalerrors[4]))