Proxy HTTPS avec prise en charge des requêtes codées en blocs

Je développe un proxy HTTPS simple (écrit en Python) qui reçoit les requêtes / réponses POST / GET, applique certaines transformations et transmet le résultat au destinataire. Je dois gérer les demandes / réponses codées en blocs de manière “en continu”, ce qui signifie que dès qu’un bloc est reçu, le proxy le transforme et le transmet au destinataire.

Avant de décider de prendre en charge les demandes codées en blocs, j’utilisais mitmproxy http://mitmproxy.org/ et cela fonctionnait parfaitement. Malheureusement, j’ai remarqué qu’il attend que tout le corps soit reçu avant de me laisser traiter la réponse / demande.

Comment puis-je implémenter un proxy prenant en charge les demandes / réponses codées en blocs? Quelqu’un parmi vous a-t-il déjà fait quelque chose comme ça?

Merci

EDIT: PLUS D’INFO SUR MON CAS D’UTILISATION

Je dois gérer les requêtes POST et les réponses GET.

Dans la requête POST, je reçois un object JSON et je dois chiffrer certaines de ses valeurs.

Dans la réponse GET, je reçois un object JSON et je dois décrypter certaines de ses valeurs.

Jusqu’à présent, le code suivant a parfaitement fonctionné:

def handle_request(self, r): if(r.method=='POST'): // encryption of r.get_form_urlencoded() def handle_response(self, r): if(r.request.method=='GET'): // decryption of r.content 

Comment puis-je faire la même chose avec des morceaux simples?

EDIT: MISES A JOUR

Après avoir évalué différentes solutions, j’ai décidé de choisir Squid (proxy) + ICAP (adaptation de contenu).

J’ai configuré Squid avec succès et les performances sont excellentes. Malheureusement, je ne trouve pas de serveur ICAP approprié (en Python, si possible) pour faire de l’adaptation de contenu (modification). Je pensais que celui-ci https://github.com/netom/pyicap pourrait faire le travail mais il semble qu’il ne lise pas le corps des requêtes myPOST.

Connaissez-vous un serveur Python ICAP que je peux utiliser avec Squid?

Merci

La réponse ci-dessous est obsolète. Vous pouvez maintenant transmettre --stream à mitmproxy, dont le comportement est expliqué dans la documentation de mitmproxy .

développeur mitmproxy ici. C’est certainement une fonctionnalité que nous souhaitons également pour mitmproxy, mais ce n’est pas si simple et cela n’arrivera probablement pas très bientôt. Si vous voulez vraiment l’implémenter vous-même, je peux vous recommander deux choses:

  1. Si vous avez un cas d’utilisation très spécifique, vous pouvez utiliser libmproxy.protocol.http.HTTPRequest.from_stream pour parsingr l’ intégralité de l’en-tête et traiter vous-même le corps.
  2. Si vous ne souhaitez pas modifier le corps de la requête / réponse, vous pouvez trouver suffisant de modifier mitmproxy lui-même. En bref, vous devez lire la requête / réponse sans contenu (voir 1.), la modifier selon vos besoins, la transmettre au serveur puis déléguer le contrôle à libmproxy.protocol.tcp (voir https: // github .com / mitmproxy / mitmproxy / blob / master / libmproxy / proxy / server.py # L169 )

Si vous avez d’autres questions, n’hésitez pas à demander ici ou sur le canal IRC de mitmproxy.


Re commentaire n ° 1:

Vous ne pouvez pas prendre trop de mitmproxy, mais au moins vous obtenez déléguer l’parsing et le traitement de l’en-tête.

 # ...accept request, socket.makefile() etc... req = HTTPRequest.from_stream(client_conn.rfile, include_content=False) # manually forward to the server (req._assemble_head()) # manually receive response body chunk by chunk and forward it to the server, see # https://github.com/mitmproxy/netlib/blob/master/netlib/http.py#L98 resp = HTTPResponse.from_stream(server_conn.rfile, include_content=False) # manually forward headers # manually process body and forward 

Cela étant dit, il s’agit d’un sujet assez complexe. Finalement, il vaut mieux le pirater directement dans libmproxy.protocol.http.HTTPHandler.

Une autre option, en fonction de votre cas d’utilisation: Utilisez mitmproxy, définissez le type de connexion sur TCP et le trafic tel quel et utilisez des remplacements de regex sur le contenu de libmproxy.protocol.tcp. Probablement le moyen le plus facile, mais le plus pirate. Si vous pouvez fournir un contexte, je peux vous guider plus avant dans la bonne direction.


Re commentaire # 2:

Avant que nous arrivions à la partie principale: JSON est un très mauvais choix pour le streaming / morceau tant que vous ne voulez pas chiffrer l’object JSON complet et le traiter comme une chaîne unique. Vous devriez certainement envisager quelque chose comme tnetssortingngs si vous voulez seulement chiffrer des parties.

En dehors de cela, le raccordement à read_chunk fonctionne, mais vous devez d’abord atteindre le point où vous pouvez réellement recevoir des morceaux sur la ligne. Ensuite, il suffit de lire les éléments individuels, de les chiffrer et de les transférer.