Browse Source

[search engine] re-factoring of code

adaptive-webui-19844
DoumanAsh 10 years ago
parent
commit
2fc1487603
  1. 44
      src/searchengine/nova/nova2dl.py
  2. 67
      src/searchengine/nova/novaprinter.py
  3. 650
      src/searchengine/nova/socks.py
  4. 44
      src/searchengine/nova3/nova2dl.py
  5. 66
      src/searchengine/nova3/novaprinter.py
  6. 650
      src/searchengine/nova3/socks.py

44
src/searchengine/nova/nova2dl.py

@ -25,7 +25,7 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
#VERSION: 1.10 #VERSION: 1.20
# Author: # Author:
# Christophe DUMEZ (chris@qbittorrent.org) # Christophe DUMEZ (chris@qbittorrent.org)
@ -39,26 +39,26 @@ supported_engines = dict()
engines = glob.glob(os.path.join(os.path.dirname(__file__), 'engines','*.py')) engines = glob.glob(os.path.join(os.path.dirname(__file__), 'engines','*.py'))
for engine in engines: for engine in engines:
e = engine.split(os.sep)[-1][:-3] e = engine.split(os.sep)[-1][:-3]
if len(e.strip()) == 0: continue if len(e.strip()) == 0: continue
if e.startswith('_'): continue if e.startswith('_'): continue
try: try:
exec "from engines.%s import %s"%(e,e) exec("from engines.%s import %s"%(e,e))
exec "engine_url = %s.url"%e exec("engine_url = %s.url"%e)
supported_engines[engine_url] = e supported_engines[engine_url] = e
except: except:
pass pass
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) < 3: if len(sys.argv) < 3:
raise SystemExit('./nova2dl.py engine_url download_parameter') raise SystemExit('./nova2dl.py engine_url download_parameter')
engine_url = sys.argv[1].strip() engine_url = sys.argv[1].strip()
download_param = sys.argv[2].strip() download_param = sys.argv[2].strip()
if engine_url not in supported_engines.keys(): if engine_url not in list(supported_engines.keys()):
raise SystemExit('./nova2dl.py: this engine_url was not recognized') raise SystemExit('./nova2dl.py: this engine_url was not recognized')
exec "engine = %s()"%supported_engines[engine_url] exec("engine = %s()"%supported_engines[engine_url])
if hasattr(engine, 'download_torrent'): if hasattr(engine, 'download_torrent'):
engine.download_torrent(download_param) engine.download_torrent(download_param)
else: else:
print download_file(download_param) print(download_file(download_param))
sys.exit(0) sys.exit(0)

67
src/searchengine/nova/novaprinter.py

@ -25,45 +25,44 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
import sys, codecs import sys, codecs
from io import open
# Force UTF-8 printing # Force UTF-8 printing
sys.stdout = codecs.getwriter('utf-8')(sys.stdout) sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
def prettyPrinter(dictionary): def prettyPrinter(dictionary):
# Convert everything to unicode for safe printing dictionary['size'] = anySizeToBytes(dictionary['size'])
for key,value in dictionary.items(): outtext = "|".join((dictionary["link"], dictionary["name"].replace("|", " "), str(dictionary["size"]), str(dictionary["seeds"]), str(dictionary["leech"]), dictionary["engine_url"]))
if isinstance(dictionary[key], str): if 'desc_link' in dictionary:
dictionary[key] = unicode(dictionary[key], 'utf-8') outtext = "|".join((outtext, dictionary["desc_link"]))
dictionary['size'] = anySizeToBytes(dictionary['size'])
if dictionary.has_key('desc_link'): with open(1, 'w', encoding='utf-8', closefd=False) as utf8_stdout:
print u"%s|%s|%s|%s|%s|%s|%s"%(dictionary['link'],dictionary['name'].replace('|',' '),dictionary['size'],dictionary['seeds'],dictionary['leech'],dictionary['engine_url'],dictionary['desc_link']) utf8_stdout.write("".join((outtext, "\n")))
else:
print u"%s|%s|%s|%s|%s|%s"%(dictionary['link'],dictionary['name'].replace('|',' '),dictionary['size'],dictionary['seeds'],dictionary['leech'],dictionary['engine_url'])
def anySizeToBytes(size_string): def anySizeToBytes(size_string):
""" """
Convert a string like '1 KB' to '1024' (bytes) Convert a string like '1 KB' to '1024' (bytes)
""" """
# separate integer from unit # separate integer from unit
try: try:
size, unit = size_string.split() size, unit = size_string.split()
except: except:
try: try:
size = size_string.strip() size = size_string.strip()
unit = ''.join([c for c in size if c.isalpha()]) unit = ''.join([c for c in size if c.isalpha()])
if len(unit) > 0: if len(unit) > 0:
size = size[:-len(unit)] size = size[:-len(unit)]
except: except:
return -1 return -1
if len(size) == 0: if len(size) == 0:
return -1 return -1
size = float(size) size = float(size)
if len(unit) == 0: if len(unit) == 0:
return int(size) return int(size)
short_unit = unit.upper()[0] short_unit = unit.upper()[0]
# convert # convert
units_dict = { 'T': 40, 'G': 30, 'M': 20, 'K': 10 } units_dict = {'T': 40, 'G': 30, 'M': 20, 'K': 10}
if units_dict.has_key( short_unit ): if units_dict.has_key(short_unit):
size = size * 2**units_dict[short_unit] size = size * 2**units_dict[short_unit]
return int(size) return int(size)

650
src/searchengine/nova/socks.py

@ -42,350 +42,350 @@ _defaultproxy = None
_orgsocket = socket.socket _orgsocket = socket.socket
class ProxyError(Exception): class ProxyError(Exception):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
class GeneralProxyError(ProxyError): class GeneralProxyError(ProxyError):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
class Socks5AuthError(ProxyError): class Socks5AuthError(ProxyError):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
class Socks5Error(ProxyError): class Socks5Error(ProxyError):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
class Socks4Error(ProxyError): class Socks4Error(ProxyError):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
class HTTPError(ProxyError): class HTTPError(ProxyError):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
_generalerrors = ("success", _generalerrors = ("success",
"invalid data", "invalid data",
"not connected", "not connected",
"not available", "not available",
"bad proxy type", "bad proxy type",
"bad input") "bad input")
_socks5errors = ("succeeded", _socks5errors = ("succeeded",
"general SOCKS server failure", "general SOCKS server failure",
"connection not allowed by ruleset", "connection not allowed by ruleset",
"Network unreachable", "Network unreachable",
"Host unreachable", "Host unreachable",
"Connection refused", "Connection refused",
"TTL expired", "TTL expired",
"Command not supported", "Command not supported",
"Address type not supported", "Address type not supported",
"Unknown error") "Unknown error")
_socks5autherrors = ("succeeded", _socks5autherrors = ("succeeded",
"authentication is required", "authentication is required",
"all offered authentication methods were rejected", "all offered authentication methods were rejected",
"unknown username or invalid password", "unknown username or invalid password",
"unknown error") "unknown error")
_socks4errors = ("request granted", _socks4errors = ("request granted",
"request rejected or failed", "request rejected or failed",
"request rejected because SOCKS server cannot connect to identd on the client", "request rejected because SOCKS server cannot connect to identd on the client",
"request rejected because the client program and identd report different user-ids", "request rejected because the client program and identd report different user-ids",
"unknown error") "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]]]]) """setdefaultproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
Sets a default proxy which all further socksocket objects will use, Sets a default proxy which all further socksocket objects will use,
unless explicitly changed. unless explicitly changed.
""" """
global _defaultproxy global _defaultproxy
_defaultproxy = (proxytype,addr,port,rdns,username,password) _defaultproxy = (proxytype,addr,port,rdns,username,password)
class socksocket(socket.socket): class socksocket(socket.socket):
"""socksocket([family[, type[, proto]]]) -> socket object """socksocket([family[, type[, proto]]]) -> socket object
Open a SOCKS enabled socket. The parameters are the same as Open a SOCKS enabled socket. The parameters are the same as
those of the standard socket init. In order for SOCKS to work, those of the standard socket init. In order for SOCKS to work,
you must specify family=AF_INET, type=SOCK_STREAM and proto=0. 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): def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None):
_orgsocket.__init__(self,family,type,proto,_sock) _orgsocket.__init__(self,family,type,proto,_sock)
if _defaultproxy != None: if _defaultproxy != None:
self.__proxy = _defaultproxy self.__proxy = _defaultproxy
else: else:
self.__proxy = (None, None, None, None, None, None) self.__proxy = (None, None, None, None, None, None)
self.__proxysockname = None self.__proxysockname = None
self.__proxypeername = None self.__proxypeername = None
def __recvall(self, bytes): def __recvall(self, bytes):
"""__recvall(bytes) -> data """__recvall(bytes) -> data
Receive EXACTLY the number of bytes requested from the socket. Receive EXACTLY the number of bytes requested from the socket.
Blocks until the required number of bytes have been received. Blocks until the required number of bytes have been received.
""" """
data = "" data = ""
while len(data) < bytes: while len(data) < bytes:
d = self.recv(bytes-len(data)) d = self.recv(bytes-len(data))
if not d: if not d:
raise GeneralProxyError("connection closed unexpectedly") raise GeneralProxyError("connection closed unexpectedly")
data = data + d data = data + d
return data return data
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]]]]) """setproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
Sets the proxy to be used. Sets the proxy to be used.
proxytype - The type of the proxy to be used. Three types proxytype - The type of the proxy to be used. Three types
are supported: PROXY_TYPE_SOCKS4 (including socks4a), are supported: PROXY_TYPE_SOCKS4 (including socks4a),
PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP
addr - The address of the server (IP or DNS). addr - The address of the server (IP or DNS).
port - The port of the server. Defaults to 1080 for SOCKS port - The port of the server. Defaults to 1080 for SOCKS
servers and 8080 for HTTP proxy servers. servers and 8080 for HTTP proxy servers.
rdns - Should DNS queries be preformed on the remote side rdns - Should DNS queries be preformed on the remote side
(rather than the local side). The default is True. (rather than the local side). The default is True.
Note: This has no effect with SOCKS4 servers. Note: This has no effect with SOCKS4 servers.
username - Username to authenticate with to the server. username - Username to authenticate with to the server.
The default is no authentication. The default is no authentication.
password - Password to authenticate with to the server. password - Password to authenticate with to the server.
Only relevant when username is also provided. Only relevant when username is also provided.
""" """
self.__proxy = (proxytype,addr,port,rdns,username,password) self.__proxy = (proxytype,addr,port,rdns,username,password)
def __negotiatesocks5(self,destaddr,destport): def __negotiatesocks5(self,destaddr,destport):
"""__negotiatesocks5(self,destaddr,destport) """__negotiatesocks5(self,destaddr,destport)
Negotiates a connection through a SOCKS5 server. Negotiates a connection through a SOCKS5 server.
""" """
# First we'll send the authentication packages we support. # 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 # The username/password details were supplied to the
# setproxy method so we support the USERNAME/PASSWORD # setproxy method so we support the USERNAME/PASSWORD
# authentication (in addition to the standard none). # authentication (in addition to the standard none).
self.sendall("\x05\x02\x00\x02") self.sendall("\x05\x02\x00\x02")
else: else:
# No username/password were entered, therefore we # No username/password were entered, therefore we
# only support connections with no authentication. # only support connections with no authentication.
self.sendall("\x05\x01\x00") self.sendall("\x05\x01\x00")
# We'll receive the server's response to determine which # We'll receive the server's response to determine which
# method was selected # method was selected
chosenauth = self.__recvall(2) chosenauth = self.__recvall(2)
if chosenauth[0] != "\x05": if chosenauth[0] != "\x05":
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
# Check the chosen authentication method # Check the chosen authentication method
if chosenauth[1] == "\x00": if chosenauth[1] == "\x00":
# No authentication is required # No authentication is required
pass pass
elif chosenauth[1] == "\x02": elif chosenauth[1] == "\x02":
# Okay, we need to perform a basic username/password # Okay, we need to perform a basic username/password
# authentication. # authentication.
self.sendall("\x01" + chr(len(self.__proxy[4])) + self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5]) self.sendall("\x01" + chr(len(self.__proxy[4])) + self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5])
authstat = self.__recvall(2) authstat = self.__recvall(2)
if authstat[0] != "\x01": if authstat[0] != "\x01":
# Bad response # Bad response
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
if authstat[1] != "\x00": if authstat[1] != "\x00":
# Authentication failed # Authentication failed
self.close() self.close()
raise Socks5AuthError,((3,_socks5autherrors[3])) raise Socks5AuthError,((3,_socks5autherrors[3]))
# Authentication succeeded # Authentication succeeded
else: else:
# Reaching here is always bad # Reaching here is always bad
self.close() self.close()
if chosenauth[1] == "\xFF": if chosenauth[1] == "\xFF":
raise Socks5AuthError((2,_socks5autherrors[2])) raise Socks5AuthError((2,_socks5autherrors[2]))
else: else:
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
# Now we can request the actual connection # Now we can request the actual connection
req = "\x05\x01\x00" req = "\x05\x01\x00"
# If the given destination address is an IP address, we'll # If the given destination address is an IP address, we'll
# use the IPv4 address request even if remote resolving was specified. # use the IPv4 address request even if remote resolving was specified.
try: try:
ipaddr = socket.inet_aton(destaddr) ipaddr = socket.inet_aton(destaddr)
req = req + "\x01" + ipaddr req = req + "\x01" + ipaddr
except socket.error: except socket.error:
# Well it's not an IP number, so it's probably a DNS name. # Well it's not an IP number, so it's probably a DNS name.
if self.__proxy[3]==True: if self.__proxy[3]==True:
# Resolve remotely # Resolve remotely
ipaddr = None ipaddr = None
req = req + "\x03" + chr(len(destaddr)) + destaddr req = req + "\x03" + chr(len(destaddr)) + destaddr
else: else:
# Resolve locally # Resolve locally
ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
req = req + "\x01" + ipaddr req = req + "\x01" + ipaddr
req = req + struct.pack(">H",destport) req = req + struct.pack(">H",destport)
self.sendall(req) self.sendall(req)
# Get the response # Get the response
resp = self.__recvall(4) resp = self.__recvall(4)
if resp[0] != "\x05": if resp[0] != "\x05":
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
elif resp[1] != "\x00": elif resp[1] != "\x00":
# Connection failed # Connection failed
self.close() self.close()
if ord(resp[1])<=8: if ord(resp[1])<=8:
raise Socks5Error((ord(resp[1]),_generalerrors[ord(resp[1])])) raise Socks5Error((ord(resp[1]),_generalerrors[ord(resp[1])]))
else: else:
raise Socks5Error((9,_generalerrors[9])) raise Socks5Error((9,_generalerrors[9]))
# Get the bound address/port # Get the bound address/port
elif resp[3] == "\x01": elif resp[3] == "\x01":
boundaddr = self.__recvall(4) boundaddr = self.__recvall(4)
elif resp[3] == "\x03": elif resp[3] == "\x03":
resp = resp + self.recv(1) resp = resp + self.recv(1)
boundaddr = self.__recvall(ord(resp[4])) boundaddr = self.__recvall(ord(resp[4]))
else: else:
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
boundport = struct.unpack(">H",self.__recvall(2))[0] boundport = struct.unpack(">H",self.__recvall(2))[0]
self.__proxysockname = (boundaddr,boundport) self.__proxysockname = (boundaddr,boundport)
if ipaddr != None: if ipaddr != None:
self.__proxypeername = (socket.inet_ntoa(ipaddr),destport) self.__proxypeername = (socket.inet_ntoa(ipaddr),destport)
else: else:
self.__proxypeername = (destaddr,destport) self.__proxypeername = (destaddr,destport)
def getproxysockname(self): def getproxysockname(self):
"""getsockname() -> address info """getsockname() -> address info
Returns the bound IP address and port number at the proxy. Returns the bound IP address and port number at the proxy.
""" """
return self.__proxysockname return self.__proxysockname
def getproxypeername(self): def getproxypeername(self):
"""getproxypeername() -> address info """getproxypeername() -> address info
Returns the IP and port number of the proxy. Returns the IP and port number of the proxy.
""" """
return _orgsocket.getpeername(self) return _orgsocket.getpeername(self)
def getpeername(self): def getpeername(self):
"""getpeername() -> address info """getpeername() -> address info
Returns the IP address and port number of the destination Returns the IP address and port number of the destination
machine (note: getproxypeername returns the proxy) machine (note: getproxypeername returns the proxy)
""" """
return self.__proxypeername return self.__proxypeername
def __negotiatesocks4(self,destaddr,destport): def __negotiatesocks4(self,destaddr,destport):
"""__negotiatesocks4(self,destaddr,destport) """__negotiatesocks4(self,destaddr,destport)
Negotiates a connection through a SOCKS4 server. Negotiates a connection through a SOCKS4 server.
""" """
# Check if the destination address provided is an IP address # Check if the destination address provided is an IP address
rmtrslv = False rmtrslv = False
try: try:
ipaddr = socket.inet_aton(destaddr) ipaddr = socket.inet_aton(destaddr)
except socket.error: except socket.error:
# It's a DNS name. Check where it should be resolved. # It's a DNS name. Check where it should be resolved.
if self.__proxy[3]==True: if self.__proxy[3]==True:
ipaddr = "\x00\x00\x00\x01" ipaddr = "\x00\x00\x00\x01"
rmtrslv = True rmtrslv = True
else: else:
ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
# Construct the request packet # Construct the request packet
req = "\x04\x01" + struct.pack(">H",destport) + ipaddr req = "\x04\x01" + struct.pack(">H",destport) + ipaddr
# The username parameter is considered userid for SOCKS4 # The username parameter is considered userid for SOCKS4
if self.__proxy[4] != None: if self.__proxy[4] != None:
req = req + self.__proxy[4] req = req + self.__proxy[4]
req = req + "\x00" req = req + "\x00"
# DNS name if remote resolving is required # DNS name if remote resolving is required
# NOTE: This is actually an extension to the SOCKS4 protocol # NOTE: This is actually an extension to the SOCKS4 protocol
# called SOCKS4A and may not be supported in all cases. # called SOCKS4A and may not be supported in all cases.
if rmtrslv==True: if rmtrslv==True:
req = req + destaddr + "\x00" req = req + destaddr + "\x00"
self.sendall(req) self.sendall(req)
# Get the response from the server # Get the response from the server
resp = self.__recvall(8) resp = self.__recvall(8)
if resp[0] != "\x00": if resp[0] != "\x00":
# Bad data # Bad data
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
if resp[1] != "\x5A": if resp[1] != "\x5A":
# Server returned an error # Server returned an error
self.close() self.close()
if ord(resp[1]) in (91,92,93): if ord(resp[1]) in (91,92,93):
self.close() self.close()
raise Socks4Error((ord(resp[1]),_socks4errors[ord(resp[1])-90])) raise Socks4Error((ord(resp[1]),_socks4errors[ord(resp[1])-90]))
else: else:
raise Socks4Error((94,_socks4errors[4])) raise Socks4Error((94,_socks4errors[4]))
# Get the bound address/port # Get the bound address/port
self.__proxysockname = (socket.inet_ntoa(resp[4:]),struct.unpack(">H",resp[2:4])[0]) self.__proxysockname = (socket.inet_ntoa(resp[4:]),struct.unpack(">H",resp[2:4])[0])
if rmtrslv != None: if rmtrslv != None:
self.__proxypeername = (socket.inet_ntoa(ipaddr),destport) self.__proxypeername = (socket.inet_ntoa(ipaddr),destport)
else: else:
self.__proxypeername = (destaddr,destport) self.__proxypeername = (destaddr,destport)
def __negotiatehttp(self,destaddr,destport): def __negotiatehttp(self,destaddr,destport):
"""__negotiatehttp(self,destaddr,destport) """__negotiatehttp(self,destaddr,destport)
Negotiates a connection through an HTTP server. Negotiates a connection through an HTTP server.
""" """
# If we need to resolve locally, we do this now # If we need to resolve locally, we do this now
if self.__proxy[3] == False: if self.__proxy[3] == False:
addr = socket.gethostbyname(destaddr) addr = socket.gethostbyname(destaddr)
else: else:
addr = destaddr addr = destaddr
self.sendall("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n") self.sendall("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n")
# We read the response until we get the string "\r\n\r\n" # We read the response until we get the string "\r\n\r\n"
resp = self.recv(1) resp = self.recv(1)
while resp.find("\r\n\r\n")==-1: while resp.find("\r\n\r\n")==-1:
resp = resp + self.recv(1) resp = resp + self.recv(1)
# We just need the first line to check if the connection # We just need the first line to check if the connection
# was successful # was successful
statusline = resp.splitlines()[0].split(" ",2) statusline = resp.splitlines()[0].split(" ",2)
if statusline[0] not in ("HTTP/1.0","HTTP/1.1"): if statusline[0] not in ("HTTP/1.0","HTTP/1.1"):
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
try: try:
statuscode = int(statusline[1]) statuscode = int(statusline[1])
except ValueError: except ValueError:
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
if statuscode != 200: if statuscode != 200:
self.close() self.close()
raise HTTPError((statuscode,statusline[2])) raise HTTPError((statuscode,statusline[2]))
self.__proxysockname = ("0.0.0.0",0) self.__proxysockname = ("0.0.0.0",0)
self.__proxypeername = (addr,destport) self.__proxypeername = (addr,destport)
def connect(self,destpair): def connect(self,destpair):
"""connect(self,despair) """connect(self,despair)
Connects to the specified destination through a proxy. Connects to the specified destination through a proxy.
destpar - A tuple of the IP/DNS address and the port number. destpar - A tuple of the IP/DNS address and the port number.
(identical to socket's connect). (identical to socket's connect).
To select the proxy server use setproxy(). To select the proxy server use setproxy().
""" """
# Do a minimal input check first # Do a minimal input check first
if (type(destpair) in (list,tuple)==False) or (len(destpair)<2) or (type(destpair[0])!=str) or (type(destpair[1])!=int): if (type(destpair) in (list,tuple)==False) or (len(destpair)<2) or (type(destpair[0])!=str) or (type(destpair[1])!=int):
raise GeneralProxyError((5,_generalerrors[5])) raise GeneralProxyError((5,_generalerrors[5]))
if self.__proxy[0] == PROXY_TYPE_SOCKS5: if self.__proxy[0] == PROXY_TYPE_SOCKS5:
if self.__proxy[2] != None: if self.__proxy[2] != None:
portnum = self.__proxy[2] portnum = self.__proxy[2]
else: else:
portnum = 1080 portnum = 1080
_orgsocket.connect(self,(self.__proxy[1],portnum)) _orgsocket.connect(self,(self.__proxy[1],portnum))
self.__negotiatesocks5(destpair[0],destpair[1]) self.__negotiatesocks5(destpair[0],destpair[1])
elif self.__proxy[0] == PROXY_TYPE_SOCKS4: elif self.__proxy[0] == PROXY_TYPE_SOCKS4:
if self.__proxy[2] != None: if self.__proxy[2] != None:
portnum = self.__proxy[2] portnum = self.__proxy[2]
else: else:
portnum = 1080 portnum = 1080
_orgsocket.connect(self,(self.__proxy[1],portnum)) _orgsocket.connect(self,(self.__proxy[1],portnum))
self.__negotiatesocks4(destpair[0],destpair[1]) self.__negotiatesocks4(destpair[0],destpair[1])
elif self.__proxy[0] == PROXY_TYPE_HTTP: elif self.__proxy[0] == PROXY_TYPE_HTTP:
if self.__proxy[2] != None: if self.__proxy[2] != None:
portnum = self.__proxy[2] portnum = self.__proxy[2]
else: else:
portnum = 8080 portnum = 8080
_orgsocket.connect(self,(self.__proxy[1],portnum)) _orgsocket.connect(self,(self.__proxy[1],portnum))
self.__negotiatehttp(destpair[0],destpair[1]) self.__negotiatehttp(destpair[0],destpair[1])
elif self.__proxy[0] == None: elif self.__proxy[0] == None:
_orgsocket.connect(self,(destpair[0],destpair[1])) _orgsocket.connect(self,(destpair[0],destpair[1]))
else: else:
raise GeneralProxyError((4,_generalerrors[4])) raise GeneralProxyError((4,_generalerrors[4]))

44
src/searchengine/nova3/nova2dl.py

@ -25,7 +25,7 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
#VERSION: 1.10 #VERSION: 1.20
# Author: # Author:
# Christophe DUMEZ (chris@qbittorrent.org) # Christophe DUMEZ (chris@qbittorrent.org)
@ -39,26 +39,26 @@ supported_engines = dict()
engines = glob.glob(os.path.join(os.path.dirname(__file__), 'engines','*.py')) engines = glob.glob(os.path.join(os.path.dirname(__file__), 'engines','*.py'))
for engine in engines: for engine in engines:
e = engine.split(os.sep)[-1][:-3] e = engine.split(os.sep)[-1][:-3]
if len(e.strip()) == 0: continue if len(e.strip()) == 0: continue
if e.startswith('_'): continue if e.startswith('_'): continue
try: try:
exec("from engines.%s import %s"%(e,e)) exec("from engines.%s import %s"%(e,e))
exec("engine_url = %s.url"%e) exec("engine_url = %s.url"%e)
supported_engines[engine_url] = e supported_engines[engine_url] = e
except: except:
pass pass
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) < 3: if len(sys.argv) < 3:
raise SystemExit('./nova2dl.py engine_url download_parameter') raise SystemExit('./nova2dl.py engine_url download_parameter')
engine_url = sys.argv[1].strip() engine_url = sys.argv[1].strip()
download_param = sys.argv[2].strip() download_param = sys.argv[2].strip()
if engine_url not in list(supported_engines.keys()): if engine_url not in list(supported_engines.keys()):
raise SystemExit('./nova2dl.py: this engine_url was not recognized') raise SystemExit('./nova2dl.py: this engine_url was not recognized')
exec("engine = %s()"%supported_engines[engine_url]) exec("engine = %s()"%supported_engines[engine_url])
if hasattr(engine, 'download_torrent'): if hasattr(engine, 'download_torrent'):
engine.download_torrent(download_param) engine.download_torrent(download_param)
else: else:
print(download_file(download_param)) print(download_file(download_param))
sys.exit(0) sys.exit(0)

66
src/searchengine/nova3/novaprinter.py

@ -26,41 +26,39 @@
def prettyPrinter(dictionary): def prettyPrinter(dictionary):
outtext = '' dictionary['size'] = anySizeToBytes(dictionary['size'])
dictionary['size'] = anySizeToBytes(dictionary['size']) outtext = "|".join((dictionary["link"], dictionary["name"].replace("|", " "), str(dictionary["size"]), str(dictionary["seeds"]), str(dictionary["leech"]), dictionary["engine_url"]))
if 'desc_link' in dictionary: if 'desc_link' in dictionary:
outtext = '%s|%s|%s|%s|%s|%s|%s'%(dictionary['link'],dictionary['name'].replace('|',' '),dictionary['size'],dictionary['seeds'],dictionary['leech'],dictionary['engine_url'],dictionary['desc_link']) outtext = "|".join((outtext, dictionary["desc_link"]))
else:
outtext = '%s|%s|%s|%s|%s|%s'%(dictionary['link'],dictionary['name'].replace('|',' '),dictionary['size'],dictionary['seeds'],dictionary['leech'],dictionary['engine_url'])
# fd 1 is stdout # fd 1 is stdout
with open(1, 'w', encoding='utf-8', closefd=False) as utf8stdout: with open(1, 'w', encoding='utf-8', closefd=False) as utf8stdout:
print(outtext, file=utf8stdout) print(outtext, file=utf8stdout)
def anySizeToBytes(size_string): def anySizeToBytes(size_string):
""" """
Convert a string like '1 KB' to '1024' (bytes) Convert a string like '1 KB' to '1024' (bytes)
""" """
# separate integer from unit # separate integer from unit
try: try:
size, unit = size_string.split() size, unit = size_string.split()
except: except:
try: try:
size = size_string.strip() size = size_string.strip()
unit = ''.join([c for c in size if c.isalpha()]) unit = ''.join([c for c in size if c.isalpha()])
if len(unit) > 0: if len(unit) > 0:
size = size[:-len(unit)] size = size[:-len(unit)]
except: except:
return -1 return -1
if len(size) == 0: if len(size) == 0:
return -1 return -1
size = float(size) size = float(size)
if len(unit) == 0: if len(unit) == 0:
return int(size) return int(size)
short_unit = unit.upper()[0] short_unit = unit.upper()[0]
# convert # convert
units_dict = { 'T': 40, 'G': 30, 'M': 20, 'K': 10 } units_dict = {'T': 40, 'G': 30, 'M': 20, 'K': 10}
if short_unit in units_dict: if short_unit in units_dict:
size = size * 2**units_dict[short_unit] size = size * 2**units_dict[short_unit]
return int(size) return int(size)

650
src/searchengine/nova3/socks.py

@ -42,350 +42,350 @@ _defaultproxy = None
_orgsocket = socket.socket _orgsocket = socket.socket
class ProxyError(Exception): class ProxyError(Exception):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
class GeneralProxyError(ProxyError): class GeneralProxyError(ProxyError):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
class Socks5AuthError(ProxyError): class Socks5AuthError(ProxyError):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
class Socks5Error(ProxyError): class Socks5Error(ProxyError):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
class Socks4Error(ProxyError): class Socks4Error(ProxyError):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
class HTTPError(ProxyError): class HTTPError(ProxyError):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
_generalerrors = ("success", _generalerrors = ("success",
"invalid data", "invalid data",
"not connected", "not connected",
"not available", "not available",
"bad proxy type", "bad proxy type",
"bad input") "bad input")
_socks5errors = ("succeeded", _socks5errors = ("succeeded",
"general SOCKS server failure", "general SOCKS server failure",
"connection not allowed by ruleset", "connection not allowed by ruleset",
"Network unreachable", "Network unreachable",
"Host unreachable", "Host unreachable",
"Connection refused", "Connection refused",
"TTL expired", "TTL expired",
"Command not supported", "Command not supported",
"Address type not supported", "Address type not supported",
"Unknown error") "Unknown error")
_socks5autherrors = ("succeeded", _socks5autherrors = ("succeeded",
"authentication is required", "authentication is required",
"all offered authentication methods were rejected", "all offered authentication methods were rejected",
"unknown username or invalid password", "unknown username or invalid password",
"unknown error") "unknown error")
_socks4errors = ("request granted", _socks4errors = ("request granted",
"request rejected or failed", "request rejected or failed",
"request rejected because SOCKS server cannot connect to identd on the client", "request rejected because SOCKS server cannot connect to identd on the client",
"request rejected because the client program and identd report different user-ids", "request rejected because the client program and identd report different user-ids",
"unknown error") "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]]]]) """setdefaultproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
Sets a default proxy which all further socksocket objects will use, Sets a default proxy which all further socksocket objects will use,
unless explicitly changed. unless explicitly changed.
""" """
global _defaultproxy global _defaultproxy
_defaultproxy = (proxytype,addr,port,rdns,username,password) _defaultproxy = (proxytype,addr,port,rdns,username,password)
class socksocket(socket.socket): class socksocket(socket.socket):
"""socksocket([family[, type[, proto]]]) -> socket object """socksocket([family[, type[, proto]]]) -> socket object
Open a SOCKS enabled socket. The parameters are the same as Open a SOCKS enabled socket. The parameters are the same as
those of the standard socket init. In order for SOCKS to work, those of the standard socket init. In order for SOCKS to work,
you must specify family=AF_INET, type=SOCK_STREAM and proto=0. 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): def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None):
_orgsocket.__init__(self,family,type,proto,_sock) _orgsocket.__init__(self,family,type,proto,_sock)
if _defaultproxy != None: if _defaultproxy != None:
self.__proxy = _defaultproxy self.__proxy = _defaultproxy
else: else:
self.__proxy = (None, None, None, None, None, None) self.__proxy = (None, None, None, None, None, None)
self.__proxysockname = None self.__proxysockname = None
self.__proxypeername = None self.__proxypeername = None
def __recvall(self, bytes): def __recvall(self, bytes):
"""__recvall(bytes) -> data """__recvall(bytes) -> data
Receive EXACTLY the number of bytes requested from the socket. Receive EXACTLY the number of bytes requested from the socket.
Blocks until the required number of bytes have been received. Blocks until the required number of bytes have been received.
""" """
data = "" data = ""
while len(data) < bytes: while len(data) < bytes:
d = self.recv(bytes-len(data)) d = self.recv(bytes-len(data))
if not d: if not d:
raise GeneralProxyError("connection closed unexpectedly") raise GeneralProxyError("connection closed unexpectedly")
data = data + d data = data + d
return data return data
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]]]]) """setproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
Sets the proxy to be used. Sets the proxy to be used.
proxytype - The type of the proxy to be used. Three types proxytype - The type of the proxy to be used. Three types
are supported: PROXY_TYPE_SOCKS4 (including socks4a), are supported: PROXY_TYPE_SOCKS4 (including socks4a),
PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP
addr - The address of the server (IP or DNS). addr - The address of the server (IP or DNS).
port - The port of the server. Defaults to 1080 for SOCKS port - The port of the server. Defaults to 1080 for SOCKS
servers and 8080 for HTTP proxy servers. servers and 8080 for HTTP proxy servers.
rdns - Should DNS queries be preformed on the remote side rdns - Should DNS queries be preformed on the remote side
(rather than the local side). The default is True. (rather than the local side). The default is True.
Note: This has no effect with SOCKS4 servers. Note: This has no effect with SOCKS4 servers.
username - Username to authenticate with to the server. username - Username to authenticate with to the server.
The default is no authentication. The default is no authentication.
password - Password to authenticate with to the server. password - Password to authenticate with to the server.
Only relevant when username is also provided. Only relevant when username is also provided.
""" """
self.__proxy = (proxytype,addr,port,rdns,username,password) self.__proxy = (proxytype,addr,port,rdns,username,password)
def __negotiatesocks5(self,destaddr,destport): def __negotiatesocks5(self,destaddr,destport):
"""__negotiatesocks5(self,destaddr,destport) """__negotiatesocks5(self,destaddr,destport)
Negotiates a connection through a SOCKS5 server. Negotiates a connection through a SOCKS5 server.
""" """
# First we'll send the authentication packages we support. # 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 # The username/password details were supplied to the
# setproxy method so we support the USERNAME/PASSWORD # setproxy method so we support the USERNAME/PASSWORD
# authentication (in addition to the standard none). # authentication (in addition to the standard none).
self.sendall("\x05\x02\x00\x02") self.sendall("\x05\x02\x00\x02")
else: else:
# No username/password were entered, therefore we # No username/password were entered, therefore we
# only support connections with no authentication. # only support connections with no authentication.
self.sendall("\x05\x01\x00") self.sendall("\x05\x01\x00")
# We'll receive the server's response to determine which # We'll receive the server's response to determine which
# method was selected # method was selected
chosenauth = self.__recvall(2) chosenauth = self.__recvall(2)
if chosenauth[0] != "\x05": if chosenauth[0] != "\x05":
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
# Check the chosen authentication method # Check the chosen authentication method
if chosenauth[1] == "\x00": if chosenauth[1] == "\x00":
# No authentication is required # No authentication is required
pass pass
elif chosenauth[1] == "\x02": elif chosenauth[1] == "\x02":
# Okay, we need to perform a basic username/password # Okay, we need to perform a basic username/password
# authentication. # authentication.
self.sendall("\x01" + chr(len(self.__proxy[4])) + self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5]) self.sendall("\x01" + chr(len(self.__proxy[4])) + self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5])
authstat = self.__recvall(2) authstat = self.__recvall(2)
if authstat[0] != "\x01": if authstat[0] != "\x01":
# Bad response # Bad response
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
if authstat[1] != "\x00": if authstat[1] != "\x00":
# Authentication failed # Authentication failed
self.close() self.close()
raise Socks5AuthError((3,_socks5autherrors[3])) raise Socks5AuthError((3,_socks5autherrors[3]))
# Authentication succeeded # Authentication succeeded
else: else:
# Reaching here is always bad # Reaching here is always bad
self.close() self.close()
if chosenauth[1] == "\xFF": if chosenauth[1] == "\xFF":
raise Socks5AuthError((2,_socks5autherrors[2])) raise Socks5AuthError((2,_socks5autherrors[2]))
else: else:
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
# Now we can request the actual connection # Now we can request the actual connection
req = "\x05\x01\x00" req = "\x05\x01\x00"
# If the given destination address is an IP address, we'll # If the given destination address is an IP address, we'll
# use the IPv4 address request even if remote resolving was specified. # use the IPv4 address request even if remote resolving was specified.
try: try:
ipaddr = socket.inet_aton(destaddr) ipaddr = socket.inet_aton(destaddr)
req = req + "\x01" + ipaddr req = req + "\x01" + ipaddr
except socket.error: except socket.error:
# Well it's not an IP number, so it's probably a DNS name. # Well it's not an IP number, so it's probably a DNS name.
if self.__proxy[3]==True: if self.__proxy[3]==True:
# Resolve remotely # Resolve remotely
ipaddr = None ipaddr = None
req = req + "\x03" + chr(len(destaddr)) + destaddr req = req + "\x03" + chr(len(destaddr)) + destaddr
else: else:
# Resolve locally # Resolve locally
ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
req = req + "\x01" + ipaddr req = req + "\x01" + ipaddr
req = req + struct.pack(">H",destport) req = req + struct.pack(">H",destport)
self.sendall(req) self.sendall(req)
# Get the response # Get the response
resp = self.__recvall(4) resp = self.__recvall(4)
if resp[0] != "\x05": if resp[0] != "\x05":
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
elif resp[1] != "\x00": elif resp[1] != "\x00":
# Connection failed # Connection failed
self.close() self.close()
if ord(resp[1])<=8: if ord(resp[1])<=8:
raise Socks5Error((ord(resp[1]),_generalerrors[ord(resp[1])])) raise Socks5Error((ord(resp[1]),_generalerrors[ord(resp[1])]))
else: else:
raise Socks5Error((9,_generalerrors[9])) raise Socks5Error((9,_generalerrors[9]))
# Get the bound address/port # Get the bound address/port
elif resp[3] == "\x01": elif resp[3] == "\x01":
boundaddr = self.__recvall(4) boundaddr = self.__recvall(4)
elif resp[3] == "\x03": elif resp[3] == "\x03":
resp = resp + self.recv(1) resp = resp + self.recv(1)
boundaddr = self.__recvall(ord(resp[4])) boundaddr = self.__recvall(ord(resp[4]))
else: else:
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
boundport = struct.unpack(">H",self.__recvall(2))[0] boundport = struct.unpack(">H",self.__recvall(2))[0]
self.__proxysockname = (boundaddr,boundport) self.__proxysockname = (boundaddr,boundport)
if ipaddr != None: if ipaddr != None:
self.__proxypeername = (socket.inet_ntoa(ipaddr),destport) self.__proxypeername = (socket.inet_ntoa(ipaddr),destport)
else: else:
self.__proxypeername = (destaddr,destport) self.__proxypeername = (destaddr,destport)
def getproxysockname(self): def getproxysockname(self):
"""getsockname() -> address info """getsockname() -> address info
Returns the bound IP address and port number at the proxy. Returns the bound IP address and port number at the proxy.
""" """
return self.__proxysockname return self.__proxysockname
def getproxypeername(self): def getproxypeername(self):
"""getproxypeername() -> address info """getproxypeername() -> address info
Returns the IP and port number of the proxy. Returns the IP and port number of the proxy.
""" """
return _orgsocket.getpeername(self) return _orgsocket.getpeername(self)
def getpeername(self): def getpeername(self):
"""getpeername() -> address info """getpeername() -> address info
Returns the IP address and port number of the destination Returns the IP address and port number of the destination
machine (note: getproxypeername returns the proxy) machine (note: getproxypeername returns the proxy)
""" """
return self.__proxypeername return self.__proxypeername
def __negotiatesocks4(self,destaddr,destport): def __negotiatesocks4(self,destaddr,destport):
"""__negotiatesocks4(self,destaddr,destport) """__negotiatesocks4(self,destaddr,destport)
Negotiates a connection through a SOCKS4 server. Negotiates a connection through a SOCKS4 server.
""" """
# Check if the destination address provided is an IP address # Check if the destination address provided is an IP address
rmtrslv = False rmtrslv = False
try: try:
ipaddr = socket.inet_aton(destaddr) ipaddr = socket.inet_aton(destaddr)
except socket.error: except socket.error:
# It's a DNS name. Check where it should be resolved. # It's a DNS name. Check where it should be resolved.
if self.__proxy[3]==True: if self.__proxy[3]==True:
ipaddr = "\x00\x00\x00\x01" ipaddr = "\x00\x00\x00\x01"
rmtrslv = True rmtrslv = True
else: else:
ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
# Construct the request packet # Construct the request packet
req = "\x04\x01" + struct.pack(">H",destport) + ipaddr req = "\x04\x01" + struct.pack(">H",destport) + ipaddr
# The username parameter is considered userid for SOCKS4 # The username parameter is considered userid for SOCKS4
if self.__proxy[4] != None: if self.__proxy[4] != None:
req = req + self.__proxy[4] req = req + self.__proxy[4]
req = req + "\x00" req = req + "\x00"
# DNS name if remote resolving is required # DNS name if remote resolving is required
# NOTE: This is actually an extension to the SOCKS4 protocol # NOTE: This is actually an extension to the SOCKS4 protocol
# called SOCKS4A and may not be supported in all cases. # called SOCKS4A and may not be supported in all cases.
if rmtrslv==True: if rmtrslv==True:
req = req + destaddr + "\x00" req = req + destaddr + "\x00"
self.sendall(req) self.sendall(req)
# Get the response from the server # Get the response from the server
resp = self.__recvall(8) resp = self.__recvall(8)
if resp[0] != "\x00": if resp[0] != "\x00":
# Bad data # Bad data
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
if resp[1] != "\x5A": if resp[1] != "\x5A":
# Server returned an error # Server returned an error
self.close() self.close()
if ord(resp[1]) in (91,92,93): if ord(resp[1]) in (91,92,93):
self.close() self.close()
raise Socks4Error((ord(resp[1]),_socks4errors[ord(resp[1])-90])) raise Socks4Error((ord(resp[1]),_socks4errors[ord(resp[1])-90]))
else: else:
raise Socks4Error((94,_socks4errors[4])) raise Socks4Error((94,_socks4errors[4]))
# Get the bound address/port # Get the bound address/port
self.__proxysockname = (socket.inet_ntoa(resp[4:]),struct.unpack(">H",resp[2:4])[0]) self.__proxysockname = (socket.inet_ntoa(resp[4:]),struct.unpack(">H",resp[2:4])[0])
if rmtrslv != None: if rmtrslv != None:
self.__proxypeername = (socket.inet_ntoa(ipaddr),destport) self.__proxypeername = (socket.inet_ntoa(ipaddr),destport)
else: else:
self.__proxypeername = (destaddr,destport) self.__proxypeername = (destaddr,destport)
def __negotiatehttp(self,destaddr,destport): def __negotiatehttp(self,destaddr,destport):
"""__negotiatehttp(self,destaddr,destport) """__negotiatehttp(self,destaddr,destport)
Negotiates a connection through an HTTP server. Negotiates a connection through an HTTP server.
""" """
# If we need to resolve locally, we do this now # If we need to resolve locally, we do this now
if self.__proxy[3] == False: if self.__proxy[3] == False:
addr = socket.gethostbyname(destaddr) addr = socket.gethostbyname(destaddr)
else: else:
addr = destaddr addr = destaddr
self.sendall("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n") self.sendall("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n")
# We read the response until we get the string "\r\n\r\n" # We read the response until we get the string "\r\n\r\n"
resp = self.recv(1) resp = self.recv(1)
while resp.find("\r\n\r\n")==-1: while resp.find("\r\n\r\n")==-1:
resp = resp + self.recv(1) resp = resp + self.recv(1)
# We just need the first line to check if the connection # We just need the first line to check if the connection
# was successful # was successful
statusline = resp.splitlines()[0].split(" ",2) statusline = resp.splitlines()[0].split(" ",2)
if statusline[0] not in ("HTTP/1.0","HTTP/1.1"): if statusline[0] not in ("HTTP/1.0","HTTP/1.1"):
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
try: try:
statuscode = int(statusline[1]) statuscode = int(statusline[1])
except ValueError: except ValueError:
self.close() self.close()
raise GeneralProxyError((1,_generalerrors[1])) raise GeneralProxyError((1,_generalerrors[1]))
if statuscode != 200: if statuscode != 200:
self.close() self.close()
raise HTTPError((statuscode,statusline[2])) raise HTTPError((statuscode,statusline[2]))
self.__proxysockname = ("0.0.0.0",0) self.__proxysockname = ("0.0.0.0",0)
self.__proxypeername = (addr,destport) self.__proxypeername = (addr,destport)
def connect(self,destpair): def connect(self,destpair):
"""connect(self,despair) """connect(self,despair)
Connects to the specified destination through a proxy. Connects to the specified destination through a proxy.
destpar - A tuple of the IP/DNS address and the port number. destpar - A tuple of the IP/DNS address and the port number.
(identical to socket's connect). (identical to socket's connect).
To select the proxy server use setproxy(). To select the proxy server use setproxy().
""" """
# Do a minimal input check first # Do a minimal input check first
if (type(destpair) in (list,tuple)==False) or (len(destpair)<2) or (type(destpair[0])!=str) or (type(destpair[1])!=int): if (type(destpair) in (list,tuple)==False) or (len(destpair)<2) or (type(destpair[0])!=str) or (type(destpair[1])!=int):
raise GeneralProxyError((5,_generalerrors[5])) raise GeneralProxyError((5,_generalerrors[5]))
if self.__proxy[0] == PROXY_TYPE_SOCKS5: if self.__proxy[0] == PROXY_TYPE_SOCKS5:
if self.__proxy[2] != None: if self.__proxy[2] != None:
portnum = self.__proxy[2] portnum = self.__proxy[2]
else: else:
portnum = 1080 portnum = 1080
_orgsocket.connect(self,(self.__proxy[1],portnum)) _orgsocket.connect(self,(self.__proxy[1],portnum))
self.__negotiatesocks5(destpair[0],destpair[1]) self.__negotiatesocks5(destpair[0],destpair[1])
elif self.__proxy[0] == PROXY_TYPE_SOCKS4: elif self.__proxy[0] == PROXY_TYPE_SOCKS4:
if self.__proxy[2] != None: if self.__proxy[2] != None:
portnum = self.__proxy[2] portnum = self.__proxy[2]
else: else:
portnum = 1080 portnum = 1080
_orgsocket.connect(self,(self.__proxy[1],portnum)) _orgsocket.connect(self,(self.__proxy[1],portnum))
self.__negotiatesocks4(destpair[0],destpair[1]) self.__negotiatesocks4(destpair[0],destpair[1])
elif self.__proxy[0] == PROXY_TYPE_HTTP: elif self.__proxy[0] == PROXY_TYPE_HTTP:
if self.__proxy[2] != None: if self.__proxy[2] != None:
portnum = self.__proxy[2] portnum = self.__proxy[2]
else: else:
portnum = 8080 portnum = 8080
_orgsocket.connect(self,(self.__proxy[1],portnum)) _orgsocket.connect(self,(self.__proxy[1],portnum))
self.__negotiatehttp(destpair[0],destpair[1]) self.__negotiatehttp(destpair[0],destpair[1])
elif self.__proxy[0] == None: elif self.__proxy[0] == None:
_orgsocket.connect(self,(destpair[0],destpair[1])) _orgsocket.connect(self,(destpair[0],destpair[1]))
else: else:
raise GeneralProxyError((4,_generalerrors[4])) raise GeneralProxyError((4,_generalerrors[4]))

Loading…
Cancel
Save