2014-04-29 3 views
5

Ich entwickle einen einfachen HTTPS-Proxy (geschrieben in Python), der POST/GET-Anfragen/Antworten empfängt, eine Transformation anwendet und das Ergebnis schließlich an den Empfänger weiterleitet. Ich muss chunked-codierte Anfragen/Antworten in einer "Streaming" -Methode behandeln, was bedeutet, dass der Proxy, sobald ein Chunk empfangen wird, diesen transformiert und an den Empfänger weiterleitet.HTTPS-Proxy mit Unterstützung für chunked-codierte Anfragen

Bevor Sie sich für chunked-codierte Anfragen entschieden haben, habe ich mitmproxy http://mitmproxy.org/ verwendet und es hat perfekt funktioniert. Leider habe ich bemerkt, dass es wartet, bis der gesamte Körper empfangen wird, bevor ich die Antwort/Anfrage behandeln darf.

Wie kann ich einen Proxy implementieren, der chunked-codierte Anfragen/Antworten unterstützt? Hat jemand von euch jemals so etwas getan?

Dank

EDIT: MEHR INFO ON MY USE CASE

Ich brauche POST-Anfragen zu behandeln und Antworten.

In der POST-Anfrage Ich erhalte ein JSON-Objekt und ich muss einige seiner Werte verschlüsseln.

In der GET Antwort Ich erhalte ein JSON-Objekt und ich muss einige seiner Werte entschlüsseln.

Bis jetzt der folgende Code hat perfekt funktioniert:

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 

Wie kann ich das gleiche tun mit einzelnen Brocken?

EDIT: AKTUELL

Nach verschiedenen Lösungen bewerten, entschied ich mich für Squid (Proxy) + ICAP (Content Adaptation) zu gehen.

Ich habe Squid erfolgreich konfiguriert und die Leistung ist einfach großartig. Leider kann ich keinen geeigneten ICAP-Server finden (in Python, wenn möglich), um die Anpassung des Inhalts vorzunehmen (Modifikation). Ich dachte, dass diese https://github.com/netom/pyicap könnte die Arbeit tun, aber sieht aus wie es liest nicht den Körper von myPOST Anfragen.

Kennen Sie einen Python ICAP-Server, den ich zusammen mit Squid verwenden kann?

Danke

Antwort

1

Die folgende Antwort ist veraltet. Sie können nun --stream an mitmproxy übergeben, dessen Verhalten in der mitmproxy documentation erklärt wird.

mitmproxy Entwickler hier. Dies ist definitiv ein Merkmal, das wir auch für Mitstrafer brauchen, aber es ist nicht so trivial und wahrscheinlich nicht sehr bald kommen. Wenn Sie wirklich, dass selbst implementieren wollen, kann ich zwei Dinge empfehlen:

  1. Wenn Sie einen sehr speziellen Anwendungsfall haben, können Sie libmproxy.protocol.http.HTTPRequest.from_stream zum Parsen der Header und machen den Körper selbst die Verarbeitung verwenden können.
  2. Wenn Sie den Anfrage-/Antworttext nicht ändern möchten, reicht es möglicherweise aus, mitmproxy selbst zu ändern. Kurz gesagt, müssten Sie die Anfrage/Antwort ohne Inhalt lesen (siehe 1.), sie an Ihre Bedürfnisse anpassen, an den Server übergeben und dann die Kontrolle an die Datei libmproxy.protocol.tcp delegieren (siehe https://github.com/mitmproxy/mitmproxy/blob/master/libmproxy/proxy/server.py#L169)

Wenn Sie weitere Fragen haben, zögern Sie nicht hier oder auf dem IRC-Kanal von mitmproxy zu fragen.


Re Kommentar # 1:

Sie können nicht zu viel, um aus mitmproxy, aber zumindest erhalten Sie die Header delegieren Parsen & Verarbeitung.

# ...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 

Das ist gesagt, das ist ein ziemlich komplexes Thema. Schließlich ist es besser, das direkt in libmproxy.protocol.http.HTTPHandler zu hacken.

Eine weitere Option, je nach Anwendungsfall: Verwenden Sie mitmproxy, setzen Sie den Conntype auf tcp und leiten Sie den Datenverkehr unverändert weiter und verwenden Sie regex replacements für den Inhalt in libmproxy.protocol.tcp. Wahrscheinlich der einfachste Weg, aber der hackigste. Wenn Sie einen Kontext bereitstellen können, kann ich Sie weiter in die richtige Richtung führen.


Re Kommentar # 2:

Bevor wir zum Hauptteil bekommen: JSON ist eine wirklich schlechte Wahl für das Streaming/Chunking, solange Sie nicht das vollständige JSON-Objekt verschlüsseln wollen und behandeln es als eine einzelne Zeichenfolge. Wenn Sie nur Teile verschlüsseln wollen, sollten Sie auf jeden Fall so etwas wie T-Strings in Betracht ziehen.

Abgesehen davon funktioniert das Einhängen in read_chunk, aber zuerst müssen Sie den Punkt erreichen, an dem Sie tatsächlich Stücke über die Linie erhalten können. Dann ist es so einfach, die einzelnen Chunks zu lesen, sie zu verschlüsseln und weiterzuleiten.

+0

Hallo mhils, danke für deine Antwort und deinen Rat. Ich habe beide Optionen nicht so gut bekommen, aber die Option # 1 ist wahrscheinlich die beste für mich (ich möchte vermeiden, mitmproxy zu modifizieren). Wie kann ich https://github.com/mitmproxy/mitmproxy/blob/master/libmproxy/protocol/http.py verwenden, um einzelne Chunks zu verarbeiten? Könnten Sie bitte etwas genauer sein oder mir ein Beispiel geben? Danke – pAkY88

+0

Siehe bearbeiten oben. :-) –

+0

Hi mhils, ich habe gerade die Antwort bearbeitet und weitere Details zu meinem Anwendungsfall hinzugefügt. Wenn ich mich nicht irre, denke ich, wäre es schön, meinem Skript etwas wie "handle_chunk (self, r, chunk)" hinzuzufügen und diese Funktion von https://github.com/mitmproxy/netlib/blob/master aufzurufen /netlib/http.py#L98. Was denken Sie? – pAkY88