56 lines
1.7 KiB
Python
56 lines
1.7 KiB
Python
from http_parser.http import HttpStream
|
|
from http_parser.reader import SocketReader
|
|
import requests
|
|
import socketserver
|
|
import re
|
|
import argparse
|
|
|
|
def response2http(resp):
|
|
body = resp.raw.read()
|
|
resp.close()
|
|
|
|
s = f'HTTP/1.1 {resp.status_code} {resp.reason}\r\n'
|
|
for key in resp.headers:
|
|
s = s + f'{key}: {resp.headers[key]}\r\n'
|
|
s = s + f'Content-Length: {len(body)}\r\n'
|
|
s = s + '\r\n'
|
|
|
|
return bytes(s, encoding='utf-8') + body
|
|
|
|
class ProxyHandler(socketserver.BaseRequestHandler):
|
|
def handle(self):
|
|
reader = SocketReader(self.request)
|
|
stream = HttpStream(reader)
|
|
|
|
url = stream.url()
|
|
if not url.startswith("http"):
|
|
url = "https://" + url
|
|
else:
|
|
url = re.sub(r"^http", "https", stream.url(), count=1)
|
|
|
|
print(url)
|
|
# Disable compression by default, because some HTTP clients do
|
|
# not support compression.
|
|
headers = stream.headers()
|
|
if 'Accept-Encoding' not in headers:
|
|
headers['Accept-Encoding'] = 'identity'
|
|
|
|
r = requests.get(url, headers=headers, stream=True)
|
|
|
|
respBytes = response2http(r)
|
|
|
|
sent = 0
|
|
while sent < len(respBytes):
|
|
sent += self.request.send(respBytes[sent:])
|
|
if sent == 0:
|
|
break
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("-l", "--listen", help="Listen IP", action="store", default="0.0.0.0")
|
|
parser.add_argument("-p", "--port", help="Proxy Port", action="store", type=int, default=8080)
|
|
args = parser.parse_args()
|
|
|
|
with socketserver.ForkingTCPServer((args.listen, args.port), ProxyHandler) as server:
|
|
server.serve_forever()
|