diff options
-rw-r--r-- | .gitattributes | 30 | ||||
-rw-r--r-- | server.py | 282 |
2 files changed, 171 insertions, 141 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ba03642 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,30 @@ +# Basic .gitattributes for a python repo. + +# Source files +# ============ +*.pxd text +*.py text +*.py3 text +*.pyw text +*.pyx text + +*.html text +*.xml text +*.xhtml text +*.htm text +*.css text +*.txt text + +# Binary files +# ============ +*.db binary +*.p binary +*.pkl binary +*.pyc binary +*.pyd binary +*.pyo binary + +# Note: .db, .p, and .pkl files are associated +# with the python modules ``pickle``, ``dbm.*``, +# ``shelve``, ``marshal``, ``anydbm``, & ``bsddb`` +# (among others).
\ No newline at end of file @@ -1,141 +1,141 @@ -from gevent import monkey
-monkey.patch_all()
-import gevent.socket
-
-from gevent.pywsgi import WSGIServer
-from youtube.youtube import youtube
-import urllib
-import socket
-import socks
-import subprocess
-import re
-
-ROUTE_TOR = True
-TOR_PATH = ***REMOVED***
-PORT_NUMBER=80
-ALLOW_FOREIGN_ADDRESSES=True
-
-BAN_FILE = "banned_addresses.txt"
-with open(BAN_FILE, 'r') as f:
- banned_addresses = f.read().splitlines()
-
-def ban_address(address):
- banned_addresses.append(address)
- with open(BAN_FILE, 'a') as f:
- f.write(address + "\n")
-
-
-def youtu_be(env, start_response):
- id = env['PATH_INFO'][1:]
- env['PATH_INFO'] = '/watch'
- env['QUERY_STRING'] = 'v=' + id
- return youtube(env, start_response)
-
-def proxy_site(env, start_response):
- headers = {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)',
- 'Accept': '*/*',
- }
- url = "https://" + env['SERVER_NAME'] + env['PATH_INFO']
- if env['QUERY_STRING']:
- url += '?' + env['QUERY_STRING']
- req = urllib.request.Request(url, headers=headers)
- response = urllib.request.urlopen(req, timeout = 10)
- start_response('200 OK', () )
- return response.read()
-
-site_handlers = {
- 'youtube.com':youtube,
- 'youtu.be':youtu_be,
- 'ytimg.com': proxy_site,
- 'yt3.ggpht.com': proxy_site,
- 'lh3.googleusercontent.com': proxy_site,
-
-}
-
-def split_url(url):
- ''' Split https://sub.example.com/foo/bar.html into ('sub.example.com', '/foo/bar.html')'''
- # XXX: Is this regex safe from REDOS?
- # python STILL doesn't have a proper regular expression engine like grep uses built in...
- match = re.match(r'(?:https?://)?([\w-]+(?:\.[\w-]+)+?)(/.*|$)', url)
- if match is None:
- raise ValueError('Invalid or unsupported url: ' + url)
-
- return match.group(1), match.group(2)
-
-
-
-def error_code(code, start_response):
- start_response(code, ())
- return code.encode()
-
-def site_dispatch(env, start_response):
- client_address = env['REMOTE_ADDR']
- try:
- method = env['REQUEST_METHOD']
- path = env['PATH_INFO']
- if client_address in banned_addresses:
- yield error_code('403 Fuck Off', start_response)
- return
- if method=="POST" and client_address not in ('127.0.0.1', '::1'):
- yield error_code('403 Forbidden', start_response)
- return
- if "phpmyadmin" in path or (path == "/" and method == "HEAD"):
- ban_address(client_address)
- start_response('403 Fuck Off', ())
- yield b'403 Fuck Off'
- return
-
- '''if env['QUERY_STRING']:
- path += '?' + env['QUERY_STRING']'''
- #path_parts = urllib.parse.urlparse(path)
- try:
- env['SERVER_NAME'], env['PATH_INFO'] = split_url(path[1:])
- except ValueError:
- yield error_code('404 Not Found', start_response)
- return
-
- base_name = ''
- for domain in reversed(env['SERVER_NAME'].split('.')):
- if base_name == '':
- base_name = domain
- else:
- base_name = domain + '.' + base_name
-
- try:
- handler = site_handlers[base_name]
- except KeyError:
- continue
- else:
- yield handler(env, start_response)
- break
- else: # did not break
- yield error_code('404 Not Found', start_response)
- return
-
-
- except (socket.error, ConnectionAbortedError) as e:
- start_response('500 Internal Server Error', ())
- print(str(e))
- yield b'500 Internal Server Error'
-
- except Exception:
- start_response('500 Internal Server Error', ())
- raise
- return
-
-
-
-
-if ROUTE_TOR:
- #subprocess.Popen(TOR_PATH)
- socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', 9150)
- socket.socket = socks.socksocket
- gevent.socket.socket = socks.socksocket
-
-if ALLOW_FOREIGN_ADDRESSES:
- server = WSGIServer(('0.0.0.0', PORT_NUMBER), site_dispatch)
-else:
- server = WSGIServer(('127.0.0.1', PORT_NUMBER), site_dispatch)
-print('Started httpserver on port ' , PORT_NUMBER)
-server.serve_forever()
+from gevent import monkey +monkey.patch_all() +import gevent.socket + +from gevent.pywsgi import WSGIServer +from youtube.youtube import youtube +import urllib +import socket +import socks +import subprocess +import re + +ROUTE_TOR = True +TOR_PATH = ***REMOVED*** +PORT_NUMBER=80 +ALLOW_FOREIGN_ADDRESSES=False + +BAN_FILE = "banned_addresses.txt" +with open(BAN_FILE, 'r') as f: + banned_addresses = f.read().splitlines() + +def ban_address(address): + banned_addresses.append(address) + with open(BAN_FILE, 'a') as f: + f.write(address + "\n") + + +def youtu_be(env, start_response): + id = env['PATH_INFO'][1:] + env['PATH_INFO'] = '/watch' + env['QUERY_STRING'] = 'v=' + id + return youtube(env, start_response) + +def proxy_site(env, start_response): + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)', + 'Accept': '*/*', + } + url = "https://" + env['SERVER_NAME'] + env['PATH_INFO'] + if env['QUERY_STRING']: + url += '?' + env['QUERY_STRING'] + req = urllib.request.Request(url, headers=headers) + response = urllib.request.urlopen(req, timeout = 10) + start_response('200 OK', () ) + return response.read() + +site_handlers = { + 'youtube.com':youtube, + 'youtu.be':youtu_be, + 'ytimg.com': proxy_site, + 'yt3.ggpht.com': proxy_site, + 'lh3.googleusercontent.com': proxy_site, + +} + +def split_url(url): + ''' Split https://sub.example.com/foo/bar.html into ('sub.example.com', '/foo/bar.html')''' + # XXX: Is this regex safe from REDOS? + # python STILL doesn't have a proper regular expression engine like grep uses built in... + match = re.match(r'(?:https?://)?([\w-]+(?:\.[\w-]+)+?)(/.*|$)', url) + if match is None: + raise ValueError('Invalid or unsupported url: ' + url) + + return match.group(1), match.group(2) + + + +def error_code(code, start_response): + start_response(code, ()) + return code.encode() + +def site_dispatch(env, start_response): + client_address = env['REMOTE_ADDR'] + try: + method = env['REQUEST_METHOD'] + path = env['PATH_INFO'] + if client_address in banned_addresses: + yield error_code('403 Fuck Off', start_response) + return + if method=="POST" and client_address not in ('127.0.0.1', '::1'): + yield error_code('403 Forbidden', start_response) + return + if "phpmyadmin" in path or (path == "/" and method == "HEAD"): + ban_address(client_address) + start_response('403 Fuck Off', ()) + yield b'403 Fuck Off' + return + + '''if env['QUERY_STRING']: + path += '?' + env['QUERY_STRING']''' + #path_parts = urllib.parse.urlparse(path) + try: + env['SERVER_NAME'], env['PATH_INFO'] = split_url(path[1:]) + except ValueError: + yield error_code('404 Not Found', start_response) + return + + base_name = '' + for domain in reversed(env['SERVER_NAME'].split('.')): + if base_name == '': + base_name = domain + else: + base_name = domain + '.' + base_name + + try: + handler = site_handlers[base_name] + except KeyError: + continue + else: + yield handler(env, start_response) + break + else: # did not break + yield error_code('404 Not Found', start_response) + return + + + except (socket.error, ConnectionAbortedError) as e: + start_response('500 Internal Server Error', ()) + print(str(e)) + yield b'500 Internal Server Error' + + except Exception: + start_response('500 Internal Server Error', ()) + raise + return + + + + +if ROUTE_TOR: + #subprocess.Popen(TOR_PATH) + socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', 9150) + socket.socket = socks.socksocket + gevent.socket.socket = socks.socksocket + +if ALLOW_FOREIGN_ADDRESSES: + server = WSGIServer(('0.0.0.0', PORT_NUMBER), site_dispatch) +else: + server = WSGIServer(('127.0.0.1', PORT_NUMBER), site_dispatch) +print('Started httpserver on port ' , PORT_NUMBER) +server.serve_forever() |