Je crée un proxy HTTP en Python mais j’ai du mal à accepter le fait que mon proxy n’acceptera que la réponse des serveurs Web et ignorera complètement la prochaine requête du navigateur et le transfert des données s’arrête. Voici le code:
import socket s = socket.socket() s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) bhost = '192.168.1.115' port = 8080 s.bind((bhost, port)) s.listen(5) def server(sock, data, host): p = socket.socket(socket.AF_INET, socket.SOCK_STREAM) p.connect((host, 80)) p.send(data) rdata = p.recv(1024) print(rdata) sock.send(rdata) while True: sock, addr = s.accept() data = sock.recv(1024) host = data.splitlines()[1][6:] server(sock, data, host)`
Désolé pour le code, il ne s’agit que d’une version d’essai et l’aide sera très appréciée car je n’ai que 14 ans et j’ai beaucoup à apprendre 🙂
Malheureusement, je ne vois pas vraiment comment votre code devrait fonctionner, alors je pense ici à la manière dont un simple proxy HTTP devrait ressembler. Alors, que doit faire un serveur proxy de base:
Connection: keep-alive
. Allons-y pas à pas et écrivons du code très simplifié.
Comment proxy accepte un client. Un socket doit être créé et déplacé en mode passif:
import socket, select sock = socket.socket() sock.bind((your_ip, port)) sock.listen() while True: client_sock = sock.accept() do_stuff(client_sock)
Une fois la connexion TCP établie, il est temps de recevoir une requête . Supposons que nous allons obtenir quelque chose comme ceci:
GET /?a=1&b=2 HTTP/1.1 Host: localhost User-Agent: my browser details Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-gb,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive
Dans TCP, les bordures des messages ne sont pas conservées, nous devons donc attendre d’avoir au moins les deux premières lignes (pour la requête GET) afin de savoir quoi faire plus tard:
def do_stuff(sock): data = receive_two_lines(sock) remote_host = parse_request(data)
Après avoir obtenu le nom d’hôte distant, il est temps de transférer les demandes et les réponses:
def do_stuff(client_sock): data = receive_two_lines(client_sock) remote_host = parse_request(data) remote_ip = socket.getaddrinfo(remote_host) # see the docs for exact use webserver = socket.socket() webserver.connect((remote_ip, 80)) webserver.sendall(data) while it_makes_sense(): client_ready = select.select([client_sock], [], [])[0] web_ready = select.select([webserver], [], [])[0] if client_ready: webserver.sendall(client_sock.recv(1024)) if web_ready: client_sock.sendall(webserver.recv(1024))
S’il vous plaît noter select
– c’est comment nous soaps si un pair distant nous a envoyé des données. Je n’ai pas exécuté et testé ce code et il rest quelque chose à faire:
client_sock.recv(1024)
, car encore une fois, les bordures de message ne sont pas conservées dans TCP. Probablement, recherchez des requêtes de téléchargement supplémentaires chaque fois que vous recevez des données. Connection: keep-alive
dans les en-têtes, mais ils peuvent également décider de la supprimer. Soyez prêt à détecter les déconnexions et les sockets fermés par un pair distant (pour simplifier, cela s’appelle while it_makes_sense()
dans le code). bind
, listen
, accept
, recv
, send
, sendall
, getaddrinfo
, select
– toutes ces fonctions peuvent getaddrinfo
exceptions. Il vaut mieux les attraper et agir en conséquence.