Я пытаюсь реализовать упрощенный прокси-сервер типа «человек посередине», работающий на localhost: 44116, такой, что если я указываю моему браузеру на https://localhost:44116/foo, то прокси-сервер возвращает результаты, извлеченные из https://HOSTNAME/foo. Моя первая попытка цитируется ниже, в настоящее время настроено для HOSTNAME = www.bbc.co.uk
Прокси ужасно ненадежен. На HOSTNAME = www.bbc.co.uk он будет ретранслировать некоторый контент, но затем аварийно завершит работу в ответ на другие запросы ресурсов. На HOSTNAME = сайте github он просто зависает (и я подтвердил, что браузер только пытается получить GET, и ничего более). На HOSTNAME = stackoverflow.com кажется, что он работает нормально.
Конечная цель заключается в том, чтобы я мог изменять некоторые ресурсы, возвращаемые реальным сервером: фактически, некоторый Javascript для простого приложения, размещенного на github.com. (подробности не имеют значения).
Я не буду перечислять отдельные ошибки, с которыми я столкнулся, так как подозреваю, что проблема в том, что я просто неверно подхожу к этому. Какие-либо предложения по способам кодирования простого, надежного и понятного прокси-сервера , который может изменять ответы GET, но который позволяет всем остальным методам проходить беспрепятственно? Спасибо.
#!/usr/bin/env python3
HOSTNAME = 'www.bbc.co.uk'
from http.client import HTTPSConnection
from http.server import BaseHTTPRequestHandler, HTTPServer
import ssl
remote = HTTPSConnection(HOSTNAME,443)
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# shut up!
def log_message(self, format, *args):
return
# GET
def do_GET(self):
# relay C->S request
remote.putrequest(self.command,self.path,skip_host=True,skip_accept_encoding=True)
# relay C->S headers
for k,v in self.headers.items():
if v.startswith('localhost'):
v = HOSTNAME
remote.putheader(k,v)
remote.endheaders()
# get server response
response = remote.getresponse()
# relay S->C status
self.send_response(response.status)
# relay S->C headers
for k,v in response.msg.items():
self.send_header(k,v)
self.end_headers()
# relay S->C data
sc_data = response.read()
print('want',response.msg['Content-Length'],'got',len(sc_data))
self.wfile.write(sc_data)
self.wfile.flush()
return
server_address = ('localhost', 44116)
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket,server_side=True,certfile='server.pem')
httpd.serve_forever()