HTTP-прокси "человек посередине" в python3 - PullRequest
0 голосов
/ 10 ноября 2019

Я пытаюсь реализовать упрощенный прокси-сервер типа «человек посередине», работающий на 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()

1 Ответ

0 голосов
/ 15 ноября 2019

См .: https://blog.scrapinghub.com/python-requests-proxy

import requests

proxies = {
 “http”: “http://10.10.10.10:8000”,
 “https”: “http://10.10.10.10:8000”,
}
r = requests.get(“http://toscrape.com”, proxies=proxies)
...