le serveur proxy n’envoie pas toutes les données python

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:

  1. Acceptez la connexion d’un client et recevez une requête HTTP.
  2. Analyser la demande et extraire sa destination.
  3. Transférer les demandes et les réponses.
  4. (éventuellement) Support 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:

  1. Les chances sont, vous obtiendrez plusieurs requêtes GET dans un seul 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.
  2. La demande peut différer pour les types POST, HEAD, PUT, DELETE et autres. Les parsingr en conséquence.
  3. Les navigateurs et les serveurs utilisent généralement une connexion TCP en définissant l’option 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).
  4. bind , listen , accept , recv , send , sendall , getaddrinfo , select – toutes ces fonctions peuvent getaddrinfo exceptions. Il vaut mieux les attraper et agir en conséquence.
  5. Le code actuellement serveur un client à la fois.