Merge branch 'changes9' into 'master'
Changes9 See merge request mserneels/ppf!10
This commit is contained in:
86
comboparse.py
Normal file
86
comboparse.py
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
from ConfigParser import SafeConfigParser, NoOptionError
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class _Dummy():
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ComboParser(object):
|
||||||
|
def __init__(self, ini):
|
||||||
|
self.items = []
|
||||||
|
self.cparser = SafeConfigParser()
|
||||||
|
self.aparser = ArgumentParser()
|
||||||
|
self.ini = ini
|
||||||
|
self.items = []
|
||||||
|
self.loaded = False
|
||||||
|
|
||||||
|
def add_item(self, section, name, type, default, desc, required):
|
||||||
|
self.items.append({
|
||||||
|
'section':section,
|
||||||
|
'name':name,
|
||||||
|
'type':type,
|
||||||
|
'default':default,
|
||||||
|
'required':required,
|
||||||
|
})
|
||||||
|
self.aparser.add_argument(
|
||||||
|
'--%s.%s'%(section, name),
|
||||||
|
help='%s, default: (%s)'%(desc, str(default)),
|
||||||
|
type=type,
|
||||||
|
default=None,
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
def load(self):
|
||||||
|
if self.loaded: return
|
||||||
|
self.loaded = True
|
||||||
|
|
||||||
|
try: self.cparser.read(self.ini)
|
||||||
|
except: pass
|
||||||
|
args = self.aparser.parse_args()
|
||||||
|
for item in self.items:
|
||||||
|
try:
|
||||||
|
obj = getattr(self, item['section'])
|
||||||
|
except AttributeError:
|
||||||
|
setattr(self, item['section'], _Dummy())
|
||||||
|
obj = getattr(self, item['section'])
|
||||||
|
|
||||||
|
setattr(obj, item['name'], item['default'])
|
||||||
|
inner = getattr(obj, item['name'])
|
||||||
|
|
||||||
|
item['found'] = True
|
||||||
|
try:
|
||||||
|
if item['type'] is bool : inner = self.cparser.getboolean(item['section'], item['name'])
|
||||||
|
elif item['type'] is float: inner = self.cparser.getfloat(item['section'], item['name'])
|
||||||
|
elif item['type'] is int : inner = self.cparser.getint(item['section'], item['name'])
|
||||||
|
elif item['type'] is str : inner = self.cparser.get(item['section'], item['name'])
|
||||||
|
except NoOptionError:
|
||||||
|
item['found'] = False
|
||||||
|
try:
|
||||||
|
arg = getattr(args, '%s.%s'%(item['section'], item['name']))
|
||||||
|
if arg is not None:
|
||||||
|
inner = arg
|
||||||
|
item['found'] = True
|
||||||
|
except: pass
|
||||||
|
if not item['found']:
|
||||||
|
if item['required']:
|
||||||
|
sys.stderr.write('error: required config item "%s" not found in section "%s" of "%s"!\n'%(item['name'], item['section'], self.ini))
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
sys.stderr.write('warning: assigned default value of "%s" to "%s.%s"\n'%(str(item['default']), item['section'], item['name']))
|
||||||
|
setattr(obj, item['name'], inner)
|
||||||
|
|
||||||
|
|
||||||
|
# TEST CODE
|
||||||
|
def _main():
|
||||||
|
config = ComboParser('config.ini')
|
||||||
|
config.add_item('watchd', 'debug', bool, False, 'turn additional debug info on', False)
|
||||||
|
config.add_item('watchd', 'float', float, 0.1, 'a float test', True)
|
||||||
|
config.add_item('watchd', 'strupp', str, "sup", 'a str test', False)
|
||||||
|
config.add_item('common', 'tor_host', str, '127.0.0.1:9050', 'address of tor proxy', True)
|
||||||
|
config.load()
|
||||||
|
print config.watchd.debug
|
||||||
|
print config.watchd.float
|
||||||
|
print config.watchd.strupp
|
||||||
|
print config.common.tor_host
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
_main()
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
[global]
|
[common]
|
||||||
tor_host = 127.0.0.1:9050
|
tor_hosts = 127.0.0.1:9050
|
||||||
database = proxylist.sqlite
|
database = proxylist.sqlite
|
||||||
|
|
||||||
[watcherd]
|
[watchd]
|
||||||
proxy_file = false
|
|
||||||
max_fail = 5
|
max_fail = 5
|
||||||
threads = 10
|
threads = 10
|
||||||
timeout = 15
|
timeout = 15
|
||||||
@@ -11,10 +10,10 @@ submit_after = 200
|
|||||||
use_ssl = false
|
use_ssl = false
|
||||||
debug = false
|
debug = false
|
||||||
|
|
||||||
[proxyfind]
|
[ppf]
|
||||||
search = true
|
search = true
|
||||||
timeout = 30
|
timeout = 30
|
||||||
threads = 3
|
http_retries = 1
|
||||||
checktime = 3600
|
checktime = 3600
|
||||||
perfail_checktime = 3600
|
perfail_checktime = 3600
|
||||||
|
|
||||||
|
|||||||
67
config.py
67
config.py
@@ -1,48 +1,25 @@
|
|||||||
from ConfigParser import SafeConfigParser
|
from comboparse import ComboParser
|
||||||
|
|
||||||
_loaded = False
|
class Config(ComboParser):
|
||||||
|
def load(self):
|
||||||
|
super(Config, self).load()
|
||||||
|
self.torhosts = [ str(i).strip() for i in self.common.tor_hosts.split(',') ]
|
||||||
|
with open('servers.txt', 'r') as handle:
|
||||||
|
self.servers = [x.strip() for x in handle.readlines() if len(x.strip()) > 0]
|
||||||
|
def __init__(self):
|
||||||
|
super(Config, self).__init__('config.ini')
|
||||||
|
self.add_item('common', 'tor_hosts', str, '127.0.0.1:9050', 'comma-separated list of tor proxy address(es)', True)
|
||||||
|
self.add_item('common', 'database', str, 'proxylist.sqlite', 'filename of database', True)
|
||||||
|
|
||||||
class phantom():
|
self.add_item('watchd', 'max_fail', int, 5, 'number of fails after which a proxy is considered dead', False)
|
||||||
def __init__(self): pass
|
self.add_item('watchd', 'threads', int, 10, 'number of threads watchd uses to check proxies', True)
|
||||||
|
self.add_item('watchd', 'timeout', int, 15, 'timeout for blocking operations (connect/recv/...) for proxy checks in seconds', False)
|
||||||
|
self.add_item('watchd', 'submit_after', int, 200, 'min. number of tested proxies for DB write', False)
|
||||||
|
self.add_item('watchd', 'debug', bool, False, 'whether to print additional debug info', False)
|
||||||
|
self.add_item('watchd', 'use_ssl', bool, False, 'whether to use SSL and port 6697 to connect to targets (slower)', False)
|
||||||
|
|
||||||
def load():
|
self.add_item('ppf', 'search', bool, True, 'whether to use searx search engine to find new proxy lists', False)
|
||||||
if _loaded: return
|
self.add_item('ppf', 'timeout', float, 15, 'timeout for blocking operations (connect/recv/...) for proxy checks in seconds', False)
|
||||||
global database, maxfail, search, torhosts, watchd_threads, checktime, timeout, read_timeout, submit_after, use_ssl, url_checktime, url_perfail_checktime
|
self.add_item('ppf', 'http_retries', int, 1, 'number of retries for http connects', False)
|
||||||
|
self.add_item('ppf', 'checktime', int, 3600, 'base checking interval for urls in db in seconds', False)
|
||||||
## read the config files
|
self.add_item('ppf', 'perfail_checktime', int, 3600, 'additional checking interval for urls in db in seconds per experienced failure', False)
|
||||||
parser = SafeConfigParser()
|
|
||||||
parser.read('config.ini')
|
|
||||||
|
|
||||||
database = parser.get('global', 'database')
|
|
||||||
#maxfail = parser.getint('global', 'proxy_max_fail')
|
|
||||||
torhosts = [ str(i).strip() for i in parser.get('global', 'tor_host').split(',') ]
|
|
||||||
|
|
||||||
global _watchd
|
|
||||||
_watchd = phantom()
|
|
||||||
_watchd.threads = parser.getint('watcherd', 'threads')
|
|
||||||
_watchd.timeout = parser.getint('watcherd', 'timeout')
|
|
||||||
_watchd.submit_after = parser.getint('watcherd', 'submit_after')
|
|
||||||
_watchd.use_ssl = parser.getboolean('watcherd', 'use_ssl')
|
|
||||||
_watchd.debug = parser.getboolean('watcherd', 'debug')
|
|
||||||
_watchd.maxfail = parser.getint('watcherd', 'max_fail')
|
|
||||||
|
|
||||||
global _leechd
|
|
||||||
_leechd = phantom()
|
|
||||||
_leechd.checktime = parser.get('proxyfind', 'checktime')
|
|
||||||
_leechd.perfail_checktime = parser.get('proxyfind', 'perfail_checktime')
|
|
||||||
_leechd.search = parser.getboolean('proxyfind', 'search')
|
|
||||||
|
|
||||||
global watchd_debug
|
|
||||||
watchd_debug = parser.getboolean('watcherd', 'debug')
|
|
||||||
|
|
||||||
# allow overriding select items from the commandline
|
|
||||||
import argparse
|
|
||||||
aparse = argparse.ArgumentParser()
|
|
||||||
aparse.add_argument('--watchd_threads', help="how many proxy checker threads to spin up, 0==none, default: 10", type=int, default=_watchd.threads, required=False)
|
|
||||||
args = aparse.parse_args()
|
|
||||||
|
|
||||||
_watchd.threads = args.watchd_threads
|
|
||||||
|
|
||||||
global servers
|
|
||||||
with open('servers.txt', 'r') as handle:
|
|
||||||
servers = [x.strip() for x in handle.readlines() if len(x.strip()) > 0]
|
|
||||||
|
|||||||
16
http2.py
16
http2.py
@@ -75,7 +75,10 @@ def _is_textual_content_type(ct):
|
|||||||
return ct in TEXTUAL_CONTENT_TYPES_LIST
|
return ct in TEXTUAL_CONTENT_TYPES_LIST
|
||||||
|
|
||||||
class RsHttp():
|
class RsHttp():
|
||||||
def __init__(self, host, port=80, ssl=False, follow_redirects=False, auto_set_cookies=False, keep_alive=False, timeout=60, user_agent=None, proxies=None, max_tries=10, **kwargs):
|
def __init__(self, host, port=80, ssl=False, follow_redirects=False, \
|
||||||
|
auto_set_cookies=False, keep_alive=False, timeout=60, \
|
||||||
|
user_agent=None, proxies=None, max_tries=10, log_errors=True, \
|
||||||
|
**kwargs):
|
||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
self.use_ssl = ssl
|
self.use_ssl = ssl
|
||||||
@@ -88,10 +91,16 @@ class RsHttp():
|
|||||||
self.proxies = proxies
|
self.proxies = proxies
|
||||||
self.cookies = dict()
|
self.cookies = dict()
|
||||||
self.max_tries = max_tries
|
self.max_tries = max_tries
|
||||||
|
self.log_errors = log_errors
|
||||||
|
self.last_rs_exception = None
|
||||||
self.headers = []
|
self.headers = []
|
||||||
|
|
||||||
|
def get_last_rocksock_exception(self):
|
||||||
|
return self.last_rs_exception
|
||||||
|
|
||||||
def _err_log(self, s):
|
def _err_log(self, s):
|
||||||
sys.stderr.write(s + '\n')
|
if self.log_errors:
|
||||||
|
sys.stderr.write(s + '\n')
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
return self.reconnect()
|
return self.reconnect()
|
||||||
@@ -242,6 +251,7 @@ class RsHttp():
|
|||||||
self.conn.connect()
|
self.conn.connect()
|
||||||
return True
|
return True
|
||||||
except RocksockException as e:
|
except RocksockException as e:
|
||||||
|
self.last_rs_exception = e
|
||||||
if e.errortype == rocksock.RS_ET_GAI and e.error==-2:
|
if e.errortype == rocksock.RS_ET_GAI and e.error==-2:
|
||||||
# -2: Name does not resolve
|
# -2: Name does not resolve
|
||||||
self.conn.disconnect()
|
self.conn.disconnect()
|
||||||
@@ -277,6 +287,7 @@ class RsHttp():
|
|||||||
try:
|
try:
|
||||||
return func(*args)
|
return func(*args)
|
||||||
except RocksockException as e:
|
except RocksockException as e:
|
||||||
|
self.last_rs_exception = e
|
||||||
self.conn.disconnect()
|
self.conn.disconnect()
|
||||||
if not self.reconnect(): return failret
|
if not self.reconnect(): return failret
|
||||||
except IOError:
|
except IOError:
|
||||||
@@ -310,6 +321,7 @@ class RsHttp():
|
|||||||
self.use_ssl = use_ssl
|
self.use_ssl = use_ssl
|
||||||
self.conn.disconnect()
|
self.conn.disconnect()
|
||||||
self.conn = None
|
self.conn = None
|
||||||
|
self.reconnect()
|
||||||
return self.get(url, extras)
|
return self.get(url, extras)
|
||||||
|
|
||||||
return hdr, res
|
return hdr, res
|
||||||
|
|||||||
60
ppf.py
60
ppf.py
@@ -8,10 +8,12 @@ import mysqlite
|
|||||||
import proxywatchd
|
import proxywatchd
|
||||||
from misc import _log
|
from misc import _log
|
||||||
from soup_parser import soupify
|
from soup_parser import soupify
|
||||||
import config
|
from config import Config
|
||||||
from http2 import RsHttp, _parse_url
|
from http2 import RsHttp, _parse_url
|
||||||
import rocksock
|
import rocksock
|
||||||
|
|
||||||
|
config = Config()
|
||||||
|
|
||||||
base_header = {
|
base_header = {
|
||||||
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||||
}
|
}
|
||||||
@@ -32,7 +34,7 @@ def import_from_file(fn, sqlite):
|
|||||||
exists = [ i[0] for i in sqlite.execute('SELECT url FROM uris WHERE url=?',(u,)).fetchall() ]
|
exists = [ i[0] for i in sqlite.execute('SELECT url FROM uris WHERE url=?',(u,)).fetchall() ]
|
||||||
if exists: continue
|
if exists: continue
|
||||||
print('adding "%s"' % u)
|
print('adding "%s"' % u)
|
||||||
sqlite.execute('INSERT INTO uris (added,url,check_time,error) VALUES (?,?,?,?)', (time.time(),u,0,1))
|
sqlite.execute('INSERT INTO uris (added,url,check_time,error) VALUES (?,?,?,?)', (int(time.time()),u,0,1))
|
||||||
sqlite.commit()
|
sqlite.commit()
|
||||||
|
|
||||||
def fetch_contents(url):
|
def fetch_contents(url):
|
||||||
@@ -41,9 +43,25 @@ def fetch_contents(url):
|
|||||||
'Accept-Language: en-US,en;q=0.8',
|
'Accept-Language: en-US,en;q=0.8',
|
||||||
'Cache-Control: max-age=0',
|
'Cache-Control: max-age=0',
|
||||||
]
|
]
|
||||||
proxies = [rocksock.RocksockProxyFromURL('socks4://%s' % random.choice( config.torhosts ))]
|
while True:
|
||||||
http = RsHttp(host,ssl=ssl,port=port, keep_alive=True, timeout=15, max_tries=1, follow_redirects=True, auto_set_cookies=True, proxies=proxies, user_agent='Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0')
|
proxies = [rocksock.RocksockProxyFromURL('socks4://%s' % random.choice( config.torhosts ))]
|
||||||
if not http.connect(): return ''
|
http = RsHttp(host,ssl=ssl,port=port, keep_alive=True, timeout=config.ppf.timeout, max_tries=config.ppf.http_retries, follow_redirects=True, auto_set_cookies=True, proxies=proxies, user_agent='Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0')
|
||||||
|
if not http.connect():
|
||||||
|
_log("failed to connect to %s"%url, "ppf")
|
||||||
|
e = http.get_last_rocksock_exception()
|
||||||
|
if not e:
|
||||||
|
return ''
|
||||||
|
et = e.get_errortype()
|
||||||
|
ee = e.get_error()
|
||||||
|
ef = e.get_failedproxy()
|
||||||
|
if et == rocksock.RS_ET_OWN and \
|
||||||
|
ee == rocksock.RS_E_TARGET_CONN_REFUSED \
|
||||||
|
and ef == 0:
|
||||||
|
_log("could not connect to proxy 0 - check your connection", "error")
|
||||||
|
time.sleep(5)
|
||||||
|
continue
|
||||||
|
return ''
|
||||||
|
break
|
||||||
hdr, res = http.get(uri, headers)
|
hdr, res = http.get(uri, headers)
|
||||||
res = res.encode('utf-8') if isinstance(res, unicode) else res
|
res = res.encode('utf-8') if isinstance(res, unicode) else res
|
||||||
for retry_message in retry_messages:
|
for retry_message in retry_messages:
|
||||||
@@ -51,6 +69,11 @@ def fetch_contents(url):
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def valid_port(proxy):
|
||||||
|
ip, port = proxy.split(':')
|
||||||
|
port = int(port)
|
||||||
|
return port > 0 and port < 65535
|
||||||
|
|
||||||
_known_proxies = {}
|
_known_proxies = {}
|
||||||
def insert_proxies(proxies, uri, sqlite, timestamp):
|
def insert_proxies(proxies, uri, sqlite, timestamp):
|
||||||
global _known_proxies
|
global _known_proxies
|
||||||
@@ -59,9 +82,12 @@ def insert_proxies(proxies, uri, sqlite, timestamp):
|
|||||||
for k in known:
|
for k in known:
|
||||||
_known_proxies[k[0]] = True
|
_known_proxies[k[0]] = True
|
||||||
|
|
||||||
new = [ (timestamp,i,3,0,0,0) for i in proxies if not i in _known_proxies ]
|
new = []
|
||||||
for i in new:
|
for p in proxies:
|
||||||
_known_proxies[i[1]] = True
|
if not p in _known_proxies:
|
||||||
|
if not valid_port(p): continue
|
||||||
|
new.append((timestamp,p,3,0,0,0))
|
||||||
|
_known_proxies[p] = True
|
||||||
|
|
||||||
if len(new):
|
if len(new):
|
||||||
sqlite.executemany('INSERT INTO proxylist (added,proxy,failed,tested,success_count,total_duration) VALUES (?,?,?,?,?,?)', new)
|
sqlite.executemany('INSERT INTO proxylist (added,proxy,failed,tested,success_count,total_duration) VALUES (?,?,?,?,?,?)', new)
|
||||||
@@ -69,7 +95,7 @@ def insert_proxies(proxies, uri, sqlite, timestamp):
|
|||||||
_log('+%d item(s) from %s' % (len(new), uri), 'added')
|
_log('+%d item(s) from %s' % (len(new), uri), 'added')
|
||||||
|
|
||||||
def proxyfind(sqlite = None):
|
def proxyfind(sqlite = None):
|
||||||
if not sqlite: sqlite = mysqlite.mysqlite(config.database,str)
|
if not sqlite: sqlite = mysqlite.mysqlite(config.common.database,str)
|
||||||
choice = random.choice(searx_instances)
|
choice = random.choice(searx_instances)
|
||||||
urls = []
|
urls = []
|
||||||
|
|
||||||
@@ -91,7 +117,7 @@ def proxyfind(sqlite = None):
|
|||||||
if len(urls):
|
if len(urls):
|
||||||
query = [ 'url=?' for u in urls ]
|
query = [ 'url=?' for u in urls ]
|
||||||
known = [ i[0] for i in sqlite.execute('SELECT url FROM uris WHERE %s' % ' OR '.join(query),urls).fetchall() ]
|
known = [ i[0] for i in sqlite.execute('SELECT url FROM uris WHERE %s' % ' OR '.join(query),urls).fetchall() ]
|
||||||
time_now = time.time()
|
time_now = int(time.time())
|
||||||
new = [ (time_now,i,0,5,0) for i in urls if not i in known ]
|
new = [ (time_now,i,0,5,0) for i in urls if not i in known ]
|
||||||
if len(new):
|
if len(new):
|
||||||
sqlite.executemany('INSERT INTO uris (added,url,check_time,error,driver) values(?,?,?,?,?)', new)
|
sqlite.executemany('INSERT INTO uris (added,url,check_time,error,driver) values(?,?,?,?,?)', new)
|
||||||
@@ -135,13 +161,13 @@ def proxyleech(sqlite, rows):
|
|||||||
else: row[2] = 0
|
else: row[2] = 0
|
||||||
|
|
||||||
#check_time = (time.time() + 3600 + (3600 * row[2]))
|
#check_time = (time.time() + 3600 + (3600 * row[2]))
|
||||||
sqlite.execute('UPDATE uris SET error=?,hash=?,check_time=? where url=?', (row[2],hash, time.time(),row[0]))
|
sqlite.execute('UPDATE uris SET error=?,hash=?,check_time=? where url=?', (row[2],hash, int(time.time()),row[0]))
|
||||||
sqlite.commit()
|
sqlite.commit()
|
||||||
|
|
||||||
if not row[1] or row[2] > 0: return
|
if not row[1] or row[2] > 0: return
|
||||||
|
|
||||||
add = []
|
add = []
|
||||||
time_now = time.time()
|
time_now = int(time.time())
|
||||||
for i in uniques:
|
for i in uniques:
|
||||||
add.append(i)
|
add.append(i)
|
||||||
if len(add) > 500:
|
if len(add) > 500:
|
||||||
@@ -155,14 +181,14 @@ if __name__ == '__main__':
|
|||||||
config.load()
|
config.load()
|
||||||
proxies={'http':'socks4://%s' % random.choice(config.torhosts),'https':'socks4://%s' % random.choice(config.torhosts)}
|
proxies={'http':'socks4://%s' % random.choice(config.torhosts),'https':'socks4://%s' % random.choice(config.torhosts)}
|
||||||
|
|
||||||
sqlite = mysqlite.mysqlite(config.database, str)
|
sqlite = mysqlite.mysqlite(config.common.database, str)
|
||||||
## create dbs if required
|
## create dbs if required
|
||||||
sqlite.execute('CREATE TABLE IF NOT EXISTS uris (added INT, url TEXT, check_time INT, error INT, driver INT, hash TEXT)')
|
sqlite.execute('CREATE TABLE IF NOT EXISTS uris (added INT, url TEXT, check_time INT, error INT, driver INT, hash TEXT)')
|
||||||
sqlite.execute('CREATE TABLE IF NOT EXISTS proxylist (proxy BLOB, country BLOB, added INT, failed INT, tested INT, dronebl INT, proto TEXT, success_count INT, total_duration INT)')
|
sqlite.execute('CREATE TABLE IF NOT EXISTS proxylist (proxy BLOB, country BLOB, added INT, failed INT, tested INT, dronebl INT, proto TEXT, success_count INT, total_duration INT)')
|
||||||
sqlite.commit()
|
sqlite.commit()
|
||||||
import_from_file('import.txt', sqlite)
|
import_from_file('import.txt', sqlite)
|
||||||
|
|
||||||
if config._leechd.search:
|
if config.ppf.search:
|
||||||
## load search terms
|
## load search terms
|
||||||
with open('search_terms.txt', 'r') as f:
|
with open('search_terms.txt', 'r') as f:
|
||||||
search_terms = [ i.strip() for i in f.read().split('\n') if len(i.strip()) ]
|
search_terms = [ i.strip() for i in f.read().split('\n') if len(i.strip()) ]
|
||||||
@@ -173,7 +199,7 @@ if __name__ == '__main__':
|
|||||||
empty = [ urignore.append(i.split('/')[2]) for i in searx_instances ]
|
empty = [ urignore.append(i.split('/')[2]) for i in searx_instances ]
|
||||||
|
|
||||||
# start proxy watcher
|
# start proxy watcher
|
||||||
if config._watchd.threads > 0:
|
if config.watchd.threads > 0:
|
||||||
watcherd = proxywatchd.Proxywatchd()
|
watcherd = proxywatchd.Proxywatchd()
|
||||||
watcherd.start()
|
watcherd.start()
|
||||||
else:
|
else:
|
||||||
@@ -183,11 +209,11 @@ if __name__ == '__main__':
|
|||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
## any site that needs to be checked ?
|
## any site that needs to be checked ?
|
||||||
rows = [ [i[0],i[1],i[2]] for i in sqlite.execute('SELECT url,hash,error FROM uris WHERE (check_time+?+(error*?) <?) ORDER BY RANDOM() LIMIT 25', (config._leechd.checktime, config._leechd.perfail_checktime, time.time())).fetchall() ]
|
rows = [ [i[0],i[1],i[2]] for i in sqlite.execute('SELECT url,hash,error FROM uris WHERE (check_time+?+(error*?) <?) ORDER BY RANDOM() LIMIT 25', (config.ppf.checktime, config.ppf.perfail_checktime, int(time.time()))).fetchall() ]
|
||||||
|
|
||||||
if len(rows): proxyleech(sqlite,rows)
|
if len(rows): proxyleech(sqlite,rows)
|
||||||
## search for new website during free time
|
## search for new website during free time
|
||||||
elif config._leechd.search: proxyfind(sqlite)
|
elif config.ppf.search: proxyfind(sqlite)
|
||||||
## sleep
|
## sleep
|
||||||
else: time.sleep(10)
|
else: time.sleep(10)
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ import threading
|
|||||||
import time, random, string, re, copy
|
import time, random, string, re, copy
|
||||||
#from geoip import geolite2
|
#from geoip import geolite2
|
||||||
|
|
||||||
import config
|
from config import Config
|
||||||
|
|
||||||
import mysqlite
|
import mysqlite
|
||||||
from misc import _log
|
from misc import _log
|
||||||
import rocksock
|
import rocksock
|
||||||
|
|
||||||
|
config = Config()
|
||||||
|
|
||||||
_run_standalone = False
|
_run_standalone = False
|
||||||
|
|
||||||
class WorkerJob():
|
class WorkerJob():
|
||||||
@@ -24,7 +26,7 @@ class WorkerJob():
|
|||||||
def connect_socket(self):
|
def connect_socket(self):
|
||||||
srv = random.choice(config.servers).strip()
|
srv = random.choice(config.servers).strip()
|
||||||
protos = ['http', 'socks5', 'socks4'] if self.proto is None else [self.proto]
|
protos = ['http', 'socks5', 'socks4'] if self.proto is None else [self.proto]
|
||||||
server_port = 6697 if config._watchd.use_ssl else 6667
|
server_port = 6697 if config.watchd.use_ssl else 6667
|
||||||
|
|
||||||
fail_inc = 1
|
fail_inc = 1
|
||||||
|
|
||||||
@@ -37,12 +39,12 @@ class WorkerJob():
|
|||||||
]
|
]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sock = rocksock.Rocksock(host=srv, port=server_port, ssl=config._watchd.use_ssl, proxies=proxies, timeout=config._watchd.timeout)
|
sock = rocksock.Rocksock(host=srv, port=server_port, ssl=config.watchd.use_ssl, proxies=proxies, timeout=config.watchd.timeout)
|
||||||
sock.connect()
|
sock.connect()
|
||||||
sock.send('%s\n' % random.choice(['NICK', 'USER', 'JOIN', 'MODE', 'PART', 'INVITE', 'KNOCK', 'WHOIS', 'WHO', 'NOTICE', 'PRIVMSG', 'PING', 'QUIT']))
|
sock.send('%s\n' % random.choice(['NICK', 'USER', 'JOIN', 'MODE', 'PART', 'INVITE', 'KNOCK', 'WHOIS', 'WHO', 'NOTICE', 'PRIVMSG', 'PING', 'QUIT']))
|
||||||
return sock, proto, duration, torhost, srv, 0
|
return sock, proto, duration, torhost, srv, 0
|
||||||
except rocksock.RocksockException as e:
|
except rocksock.RocksockException as e:
|
||||||
if config._watchd.debug:
|
if config.watchd.debug:
|
||||||
_log("proxy failed: %s://%s: %s"%(proto, self.proxy, e.get_errormessage()), 'debug')
|
_log("proxy failed: %s://%s: %s"%(proto, self.proxy, e.get_errormessage()), 'debug')
|
||||||
|
|
||||||
et = e.get_errortype()
|
et = e.get_errortype()
|
||||||
@@ -57,6 +59,12 @@ class WorkerJob():
|
|||||||
err == rocksock.RS_E_HIT_TIMEOUT:
|
err == rocksock.RS_E_HIT_TIMEOUT:
|
||||||
# proxy is not online, so don't waste time trying all possible protocols
|
# proxy is not online, so don't waste time trying all possible protocols
|
||||||
break
|
break
|
||||||
|
elif fp == 0 and \
|
||||||
|
err == rocksock.RS_E_TARGET_CONN_REFUSED:
|
||||||
|
fail_inc = 0
|
||||||
|
if random.randint(0, (config.watchd.threads-1)/2) == 0:
|
||||||
|
_log("could not connect to proxy 0, sleep 5s", "ERROR")
|
||||||
|
time.sleep(5)
|
||||||
elif et == rocksock.RS_ET_GAI:
|
elif et == rocksock.RS_ET_GAI:
|
||||||
fail_inc = 0
|
fail_inc = 0
|
||||||
_log("could not resolve connection target %s"%srv, "ERROR")
|
_log("could not resolve connection target %s"%srv, "ERROR")
|
||||||
@@ -64,7 +72,6 @@ class WorkerJob():
|
|||||||
|
|
||||||
except KeyboardInterrupt as e:
|
except KeyboardInterrupt as e:
|
||||||
raise(e)
|
raise(e)
|
||||||
except: sock.disconnect()
|
|
||||||
|
|
||||||
return None, None, None, None, None, fail_inc
|
return None, None, None, None, None, fail_inc
|
||||||
|
|
||||||
@@ -98,7 +105,7 @@ class WorkerJob():
|
|||||||
_log('%s://%s;%s d: %.2f sec(s);%s srv: %s; recv: %s' % (proto, self.proxy, cstats, duration, torstats, srv, recvstats), 'xxxxx')
|
_log('%s://%s;%s d: %.2f sec(s);%s srv: %s; recv: %s' % (proto, self.proxy, cstats, duration, torstats, srv, recvstats), 'xxxxx')
|
||||||
except KeyboardInterrupt as e:
|
except KeyboardInterrupt as e:
|
||||||
raise e
|
raise e
|
||||||
except:
|
except rocksock.RocksockException as e:
|
||||||
self.failcount += 1
|
self.failcount += 1
|
||||||
finally:
|
finally:
|
||||||
sock.disconnect()
|
sock.disconnect()
|
||||||
@@ -183,7 +190,7 @@ class Proxywatchd():
|
|||||||
while not self.stopped.is_set(): time.sleep(0.1)
|
while not self.stopped.is_set(): time.sleep(0.1)
|
||||||
|
|
||||||
def _prep_db(self):
|
def _prep_db(self):
|
||||||
self.mysqlite = mysqlite.mysqlite(config.database, str)
|
self.mysqlite = mysqlite.mysqlite(config.common.database, str)
|
||||||
def _close_db(self):
|
def _close_db(self):
|
||||||
if self.mysqlite:
|
if self.mysqlite:
|
||||||
self.mysqlite.close()
|
self.mysqlite.close()
|
||||||
@@ -201,14 +208,14 @@ class Proxywatchd():
|
|||||||
self.mysqlite.commit()
|
self.mysqlite.commit()
|
||||||
self._close_db()
|
self._close_db()
|
||||||
|
|
||||||
self.submit_after = config._watchd.submit_after # number of collected jobs before writing db
|
self.submit_after = config.watchd.submit_after # number of collected jobs before writing db
|
||||||
self.jobs = []
|
self.jobs = []
|
||||||
self.collected = []
|
self.collected = []
|
||||||
|
|
||||||
def prepare_jobs(self):
|
def prepare_jobs(self):
|
||||||
self._prep_db()
|
self._prep_db()
|
||||||
q = 'SELECT proxy,proto,failed,success_count,total_duration FROM proxylist WHERE failed<? and tested<? ORDER BY RANDOM()' # ' LIMIT ?'
|
q = 'SELECT proxy,proto,failed,success_count,total_duration FROM proxylist WHERE failed<? and tested<? ORDER BY RANDOM()' # ' LIMIT ?'
|
||||||
rows = self.mysqlite.execute(q, (config._watchd.maxfail, time.time())).fetchall()
|
rows = self.mysqlite.execute(q, (config.watchd.max_fail, time.time())).fetchall()
|
||||||
for row in rows:
|
for row in rows:
|
||||||
job = WorkerJob(row[0], row[1], row[2], row[3], row[4])
|
job = WorkerJob(row[0], row[1], row[2], row[3], row[4])
|
||||||
self.jobs.append(job)
|
self.jobs.append(job)
|
||||||
@@ -254,7 +261,7 @@ class Proxywatchd():
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
if config._watchd.threads == 1 and _run_standalone:
|
if config.watchd.threads == 1 and _run_standalone:
|
||||||
return self._run()
|
return self._run()
|
||||||
else:
|
else:
|
||||||
return self._run_background()
|
return self._run_background()
|
||||||
@@ -271,7 +278,7 @@ class Proxywatchd():
|
|||||||
def _run(self):
|
def _run(self):
|
||||||
_log('starting...', 'watchd')
|
_log('starting...', 'watchd')
|
||||||
|
|
||||||
for i in range(config._watchd.threads):
|
for i in range(config.watchd.threads):
|
||||||
threadid = ''.join( [ random.choice(string.letters) for x in range(5) ] )
|
threadid = ''.join( [ random.choice(string.letters) for x in range(5) ] )
|
||||||
wt = WorkerThread(threadid)
|
wt = WorkerThread(threadid)
|
||||||
if self.in_background:
|
if self.in_background:
|
||||||
|
|||||||
21
rocksock.py
21
rocksock.py
@@ -1,4 +1,4 @@
|
|||||||
import socket, ssl, select, copy
|
import socket, ssl, select, copy, errno
|
||||||
|
|
||||||
# rs_proxyType
|
# rs_proxyType
|
||||||
RS_PT_NONE = 0
|
RS_PT_NONE = 0
|
||||||
@@ -31,9 +31,13 @@ RS_E_HIT_READTIMEOUT = 14
|
|||||||
RS_E_HIT_WRITETIMEOUT = 15
|
RS_E_HIT_WRITETIMEOUT = 15
|
||||||
RS_E_HIT_CONNECTTIMEOUT = 16
|
RS_E_HIT_CONNECTTIMEOUT = 16
|
||||||
RS_E_PROXY_GENERAL_FAILURE = 17
|
RS_E_PROXY_GENERAL_FAILURE = 17
|
||||||
|
RS_E_TARGET_NET_UNREACHABLE = 18
|
||||||
RS_E_TARGETPROXY_NET_UNREACHABLE = 18
|
RS_E_TARGETPROXY_NET_UNREACHABLE = 18
|
||||||
|
RS_E_TARGET_HOST_UNREACHABLE = 19
|
||||||
RS_E_TARGETPROXY_HOST_UNREACHABLE = 19
|
RS_E_TARGETPROXY_HOST_UNREACHABLE = 19
|
||||||
|
RS_E_TARGET_CONN_REFUSED = 20
|
||||||
RS_E_TARGETPROXY_CONN_REFUSED = 20
|
RS_E_TARGETPROXY_CONN_REFUSED = 20
|
||||||
|
RS_E_TARGET_TTL_EXPIRED = 21
|
||||||
RS_E_TARGETPROXY_TTL_EXPIRED = 21
|
RS_E_TARGETPROXY_TTL_EXPIRED = 21
|
||||||
RS_E_PROXY_COMMAND_NOT_SUPPORTED = 22
|
RS_E_PROXY_COMMAND_NOT_SUPPORTED = 22
|
||||||
RS_E_PROXY_ADDRESSTYPE_NOT_SUPPORTED = 23
|
RS_E_PROXY_ADDRESSTYPE_NOT_SUPPORTED = 23
|
||||||
@@ -99,7 +103,6 @@ class RocksockException(Exception):
|
|||||||
RS_E_INVALID_PROXY_URL : "invalid proxy URL string"
|
RS_E_INVALID_PROXY_URL : "invalid proxy URL string"
|
||||||
}
|
}
|
||||||
if self.errortype == RS_ET_SYS:
|
if self.errortype == RS_ET_SYS:
|
||||||
import errno
|
|
||||||
if self.error in errno.errorcode:
|
if self.error in errno.errorcode:
|
||||||
msg = "ERRNO: " + errno.errorcode[self.error]
|
msg = "ERRNO: " + errno.errorcode[self.error]
|
||||||
else:
|
else:
|
||||||
@@ -117,6 +120,8 @@ class RocksockException(Exception):
|
|||||||
|
|
||||||
class RocksockHostinfo():
|
class RocksockHostinfo():
|
||||||
def __init__(self, host, port):
|
def __init__(self, host, port):
|
||||||
|
if port < 0 or port > 65535:
|
||||||
|
raise RocksockException(RS_E_INVALID_PROXY_URL, failedproxy=-1)
|
||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
|
|
||||||
@@ -166,6 +171,12 @@ class Rocksock():
|
|||||||
self.sock = None
|
self.sock = None
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
|
|
||||||
|
def _translate_socket_error(self, e, pnum):
|
||||||
|
fp = self._failed_proxy(pnum)
|
||||||
|
if e.errno == errno.ECONNREFUSED:
|
||||||
|
return RocksockException(RS_E_TARGET_CONN_REFUSED, failedproxy=fp)
|
||||||
|
return RocksockException(e.errno, errortype=RS_ET_SYS, failedproxy=fp)
|
||||||
|
|
||||||
def _failed_proxy(self, pnum):
|
def _failed_proxy(self, pnum):
|
||||||
if pnum < 0: return -1
|
if pnum < 0: return -1
|
||||||
if pnum >= len(self.proxychain)-1: return -1
|
if pnum >= len(self.proxychain)-1: return -1
|
||||||
@@ -189,7 +200,7 @@ class Rocksock():
|
|||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
raise RocksockException(RS_E_HIT_TIMEOUT, failedproxy=self._failed_proxy(0))
|
raise RocksockException(RS_E_HIT_TIMEOUT, failedproxy=self._failed_proxy(0))
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
raise RocksockException(e.errno, errortype=RS_ET_SYS, failedproxy=self._failed_proxy(0))
|
raise self._translate_socket_error(e, 0)
|
||||||
|
|
||||||
for pnum in xrange(1, len(self.proxychain)):
|
for pnum in xrange(1, len(self.proxychain)):
|
||||||
curr = self.proxychain[pnum]
|
curr = self.proxychain[pnum]
|
||||||
@@ -204,7 +215,7 @@ class Rocksock():
|
|||||||
#if hasattr(e, 'library'): subsystem = e.library
|
#if hasattr(e, 'library'): subsystem = e.library
|
||||||
raise RocksockException(RS_E_SSL_GENERIC, failedproxy=reason, errortype=RS_ET_SSL)
|
raise RocksockException(RS_E_SSL_GENERIC, failedproxy=reason, errortype=RS_ET_SSL)
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
raise RocksockException(e.errno, errortype=RS_ET_SYS)
|
raise self._translate_socket_error(e, -1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
"""
|
"""
|
||||||
@@ -252,6 +263,8 @@ class Rocksock():
|
|||||||
chunk = self.sock.recv(n)
|
chunk = self.sock.recv(n)
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
raise RocksockException(RS_E_HIT_TIMEOUT, failedproxy=self._failed_proxy(pnum))
|
raise RocksockException(RS_E_HIT_TIMEOUT, failedproxy=self._failed_proxy(pnum))
|
||||||
|
except socket.error as e:
|
||||||
|
raise self._translate_socket_error(e, pnum)
|
||||||
except ssl.SSLError as e:
|
except ssl.SSLError as e:
|
||||||
s = self._get_ssl_exception_reason(e)
|
s = self._get_ssl_exception_reason(e)
|
||||||
if s == 'The read operation timed out':
|
if s == 'The read operation timed out':
|
||||||
|
|||||||
Reference in New Issue
Block a user