2017-05-09 1 views
1

Ich habe ein Problem mit den HTTP-Headern, die das Modul Requests zurückgibt.Anforderungen HTTP-Header

Ich verwende den folgenden Code:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
import requests 

response = requests.get("http://www.google.co.il",proxies={'http': '','https':''}) 

data = response.text 
# response.text returns the appropriate html code 
# (<!doctype html><html dir="rtl" itemscope=""....) 

if response.status_code == requests.codes.ok: 
    # How do I send those headers to the conn (browser) 
    print "HEADERS: " + str(response.headers) 
    conn.send(data) 

Ich versuche, eine GET-Anfrage zu senden, www.google.co.il und die Antwort an den Browser (am Beispiel I genannt schicken es "conn"). Das Problem ist, dass der Browser den empfangenen HTML-Code nicht anzeigt und stattdessen ERR_EMPTY_RESPONSE empfängt. Die Header in der Antwort sind:

HEADERS: {'Content-Length': '5451', 'X-XSS-Protection': '1; mode=block', 'Content-Encoding': 'gzip', 'Set-Cookie': 'NID=103=RJzu4RTCNxkh-75dvKBHx-_jen9M8iPes_AdOIQqzBVZ0VPTz1PlQaAVLpwYOmxZlTKmcogiDb1VoY__Es0HqSNwlkmHl3SuBZC8_8XUfqh1PzdWTjrXRnB4S738M1lm; expires=Wed, 08-Nov-2017 10:05:46 GMT; path=/; domain=.google.co.il; HttpOnly', 'Expires': '-1', 'Server': 'gws', 'Cache-Control': 'private, max-age=0', 'Date': 'Tue, 09 May 2017 10:05:46 GMT', 'P3P': 'CP="This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info."', 'Content-Type': 'text/html; charset=windows-1255', 'X-Frame-Options': 'SAMEORIGIN'} 

Jemand sagte mir, dass das Problem ist, dass ich keinen Header an den Browser sendet bin. Ist das wirklich das Problem? Irgendwelche anderen Vorschläge ? und wenn es das Problem ist, wie sende ich die entsprechenden Überschriften an den Browser?

Edit: Ich habe vergessen zu erwähnen, dass die Verbindung über einen Proxy-Server ist.

Jede Hilfe wäre großartig!

Vielen Dank, Yahli.

+1

Was ist der 'conn'? Steckdose ? –

+0

Ja, 'conn' ist eine Buchse. –

+1

Etwas wie ein abfangender Proxy richtig? Sie müssen eine vollständige HTTP-Antwort an den Browser senden, nicht nur den Text. Wenn Sie Sockets verwenden, können Sie 'Requests' überspringen und die HTTP-Anfrage mit' socket' senden. Wenn Sie darauf bestehen, 'Anfragen' zu verwenden, müssen Sie den Header aus dem' response' Objekt konstruieren. –

Antwort

2

ich nichts über geting die rohe HTTP-Antwort (nicht response.raw) in requests Dokumentation finden kann, so schrieb ich eine Funktion:

def http_response(response): 
    return 'HTTP/1.1 {} {}\r\n{}\r\n\r\n{}'.format(
     response.status_code, response.reason , 
     '\r\n'.join(k + ': ' + v for k, v in response.headers.items()), 
     response.content 
    ) 

ich es getestet von Firefox HTTP-Proxy localhost Einstellung: Port (mit eine hörende Buchse am Port), und es funktioniert gut.

Alternativ können Sie den Host von conn.recv abrufen, einen neuen Socket für diesen Host öffnen und die Daten senden. Beispiel:

data = conn.recv(1024) 
host = [ l.split(':')[1].strip() for l in data.splitlines() if l.startswith('Host:') ] 
if len(host) : 
    cli = socket.socket() 
    cli.connect((host[0], 80)) 
    cli.send(data) 
    response = '' 
    while True : 
     data = cli.recv(1024) 
     if not data.strip() : 
      break 
     response += data 
    conn.send(response) 
    cli.close() 

Wo conn die Verbindung zum Web-Browser ist. Dies ist nur ein kurzes Beispiel, vorausgesetzt, Sie haben nur HTTP-Anfragen (Port 80). Es gibt Raum für viel Optimierung

+0

Wenn ich versuche, eine Verbindung zu 'www.google.com' herzustellen, erhalte ich diesen Fehler im Browser: ERR_TUNNEL_CONNECTION_FAILED (identisch mit anderen HTTP/s) und wird nicht angezeigt die richtige Website. Ich bekomme den richtigen HTML-Dump tho. Irgendwelche Ideen, warum das passiert? (Ich werde Sie nur in 5 Stunden, ich habe meine max Vote Nummer überschritten haben lol) –

+1

Ich kann nicht sicher sein, es sei denn, ich sehe Ihren Code, aber wenn Sie einen interzeptierenden Proxy erstellen, ist es ein SSL-Problem. Google verwendet nur HTTPS, Sie sollten Ihren Socket sslwrap (erstellen Sie ein Zertifikat, fügen Sie es zu vertrauenswürdigen Autoritäten usw.). Versuchen Sie, eine Verbindung zu stackoverflow auf Port 80 herzustellen und lassen Sie mich wissen, was passiert –

+0

Das ist mein vollständiger Code: [Pastebin] (https://pastebin.com/TtmaDLAs). Wenn Sie mir helfen würden, dieses spezifische Problem zu lösen, wäre ich dankbar! Der Code stammt aus der Klasse Server in der Funktion _https. In Bezug auf das, was Sie gesagt haben, dachte ich, dass das Modul Anfragen diese bereits behandelt, sollte ich dann eine Anfrage-Sitzung erstellen? –