[ChangeLog] Actualize
[youtube-dl] / youtube_dl / socks.py
index 0e3dd7893183759ea69d910d605f550f06f4e3e1..5d4adbe72de5d273a11f0fc2d66b7829c4bbfb37 100644 (file)
@@ -14,8 +14,8 @@ import socket
 
 from .compat import (
     compat_ord,
-    struct_pack,
-    struct_unpack,
+    compat_struct_pack,
+    compat_struct_unpack,
 )
 
 __author__ = 'Timo Schmid <coding@timoschmid.de>'
@@ -26,7 +26,7 @@ SOCKS4_REPLY_VERSION = 0x00
 # if the client cannot resolve the destination host's domain name to find its
 # IP address, it should set the first three bytes of DSTIP to NULL and the last
 # byte to a non-zero value.
-SOCKS4_DEFAULT_DSTIP = struct_pack('!BBBB', 0, 0, 0, 0xFF)
+SOCKS4_DEFAULT_DSTIP = compat_struct_pack('!BBBB', 0, 0, 0, 0xFF)
 
 SOCKS5_VERSION = 5
 SOCKS5_USER_AUTH_VERSION = 0x01
@@ -55,12 +55,12 @@ class Socks5AddressType(object):
     ATYP_IPV6 = 0x04
 
 
-class ProxyError(IOError):
+class ProxyError(socket.error):
     ERR_SUCCESS = 0x00
 
     def __init__(self, code=None, msg=None):
         if code is not None and msg is None:
-            msg = self.CODES.get(code) and 'unknown error'
+            msg = self.CODES.get(code) or 'unknown error'
         super(ProxyError, self).__init__(code, msg)
 
 
@@ -76,7 +76,7 @@ class Socks4Error(ProxyError):
 
     CODES = {
         91: 'request rejected or failed',
-        92: 'request rejected becasue SOCKS server cannot connect to identd on the client',
+        92: 'request rejected because SOCKS server cannot connect to identd on the client',
         93: 'request rejected because the client program and identd report different user-ids'
     }
 
@@ -103,6 +103,7 @@ class ProxyType(object):
     SOCKS4A = 1
     SOCKS5 = 2
 
+
 Proxy = collections.namedtuple('Proxy', (
     'type', 'host', 'port', 'username', 'password', 'remote_dns'))
 
@@ -122,17 +123,17 @@ class sockssocket(socket.socket):
         while len(data) < cnt:
             cur = self.recv(cnt - len(data))
             if not cur:
-                raise IOError('{0} bytes missing'.format(cnt - len(data)))
+                raise EOFError('{0} bytes missing'.format(cnt - len(data)))
             data += cur
         return data
 
     def _recv_bytes(self, cnt):
         data = self.recvall(cnt)
-        return struct_unpack('!{0}B'.format(cnt), data)
+        return compat_struct_unpack('!{0}B'.format(cnt), data)
 
     @staticmethod
     def _len_and_data(data):
-        return struct_pack('!B', len(data)) + data
+        return compat_struct_pack('!B', len(data)) + data
 
     def _check_response_version(self, expected_version, got_version):
         if got_version != expected_version:
@@ -153,7 +154,7 @@ class sockssocket(socket.socket):
 
         ipaddr = self._resolve_address(destaddr, SOCKS4_DEFAULT_DSTIP, use_remote_dns=is_4a)
 
-        packet = struct_pack('!BBH', SOCKS4_VERSION, Socks4Command.CMD_CONNECT, port) + ipaddr
+        packet = compat_struct_pack('!BBH', SOCKS4_VERSION, Socks4Command.CMD_CONNECT, port) + ipaddr
 
         username = (self._proxy.username or '').encode('utf-8')
         packet += username + b'\x00'
@@ -163,7 +164,7 @@ class sockssocket(socket.socket):
 
         self.sendall(packet)
 
-        version, resp_code, dstport, dsthost = struct_unpack('!BBHI', self.recvall(8))
+        version, resp_code, dstport, dsthost = compat_struct_unpack('!BBHI', self.recvall(8))
 
         self._check_response_version(SOCKS4_REPLY_VERSION, version)
 
@@ -177,14 +178,14 @@ class sockssocket(socket.socket):
         self._setup_socks4(address, is_4a=True)
 
     def _socks5_auth(self):
-        packet = struct_pack('!B', SOCKS5_VERSION)
+        packet = compat_struct_pack('!B', SOCKS5_VERSION)
 
         auth_methods = [Socks5Auth.AUTH_NONE]
         if self._proxy.username and self._proxy.password:
             auth_methods.append(Socks5Auth.AUTH_USER_PASS)
 
-        packet += struct_pack('!B', len(auth_methods))
-        packet += struct_pack('!{0}B'.format(len(auth_methods)), *auth_methods)
+        packet += compat_struct_pack('!B', len(auth_methods))
+        packet += compat_struct_pack('!{0}B'.format(len(auth_methods)), *auth_methods)
 
         self.sendall(packet)
 
@@ -192,14 +193,15 @@ class sockssocket(socket.socket):
 
         self._check_response_version(SOCKS5_VERSION, version)
 
-        if method == Socks5Auth.AUTH_NO_ACCEPTABLE:
+        if method == Socks5Auth.AUTH_NO_ACCEPTABLE or (
+                method == Socks5Auth.AUTH_USER_PASS and (not self._proxy.username or not self._proxy.password)):
             self.close()
-            raise Socks5Error(method)
+            raise Socks5Error(Socks5Auth.AUTH_NO_ACCEPTABLE)
 
         if method == Socks5Auth.AUTH_USER_PASS:
             username = self._proxy.username.encode('utf-8')
             password = self._proxy.password.encode('utf-8')
-            packet = struct_pack('!B', SOCKS5_USER_AUTH_VERSION)
+            packet = compat_struct_pack('!B', SOCKS5_USER_AUTH_VERSION)
             packet += self._len_and_data(username) + self._len_and_data(password)
             self.sendall(packet)
 
@@ -210,8 +212,6 @@ class sockssocket(socket.socket):
             if status != SOCKS5_USER_AUTH_SUCCESS:
                 self.close()
                 raise Socks5Error(Socks5Error.ERR_GENERAL_FAILURE)
-        elif method == Socks5Auth.AUTH_NONE:
-            pass
 
     def _setup_socks5(self, address):
         destaddr, port = address
@@ -221,14 +221,14 @@ class sockssocket(socket.socket):
         self._socks5_auth()
 
         reserved = 0
-        packet = struct_pack('!BBB', SOCKS5_VERSION, Socks5Command.CMD_CONNECT, reserved)
+        packet = compat_struct_pack('!BBB', SOCKS5_VERSION, Socks5Command.CMD_CONNECT, reserved)
         if ipaddr is None:
             destaddr = destaddr.encode('utf-8')
-            packet += struct_pack('!B', Socks5AddressType.ATYP_DOMAINNAME)
+            packet += compat_struct_pack('!B', Socks5AddressType.ATYP_DOMAINNAME)
             packet += self._len_and_data(destaddr)
         else:
-            packet += struct_pack('!B', Socks5AddressType.ATYP_IPV4) + ipaddr
-        packet += struct_pack('!H', port)
+            packet += compat_struct_pack('!B', Socks5AddressType.ATYP_IPV4) + ipaddr
+        packet += compat_struct_pack('!H', port)
 
         self.sendall(packet)
 
@@ -247,7 +247,7 @@ class sockssocket(socket.socket):
             destaddr = self.recvall(alen)
         elif atype == Socks5AddressType.ATYP_IPV6:
             destaddr = self.recvall(16)
-        destport = struct_unpack('!H', self.recvall(2))[0]
+        destport = compat_struct_unpack('!H', self.recvall(2))[0]
 
         return (destaddr, destport)