我正在python中创建一个HTTP代理,但我遇到麻烦,因为我的代理只会接受Web服务器响应,并且会完全忽略浏览器的下一个请求,并且数据传输就会停止。这是代码:
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)`
对于代码感到抱歉这只是一个试用版,我将非常感谢帮助,因为我只有14岁并且需要学习: - )
答案 0 :(得分:1)
不幸的是,我并没有真正看到你的代码应该如何工作,所以我在这里想到了一个简单的HTTP代理应该是怎样的。 那么基本代理服务器应该做什么:
Connection: keep-alive
。让我们一步一步地写一些非常简化的代码。
代理如何接受客户端。应创建套接字并将其移至被动模式:
import socket, select
sock = socket.socket()
sock.bind((your_ip, port))
sock.listen()
while True:
client_sock = sock.accept()
do_stuff(client_sock)
建立TCP连接后,时间会收到请求。我们假设我们会得到这样的东西:
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
在TCP中,不保留消息边界,因此我们应该等到至少前两行(对于GET请求)才能知道以后要做什么:
def do_stuff(sock):
data = receive_two_lines(sock)
remote_host = parse_request(data)
获得远程主机名后,是时候转发请求和响应了:
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))
请注意select
- 这就是我们知道远程对等方是否向我们发送数据的方式。我没有运行并测试过这段代码,还有一件事要做:
client_sock.recv(1024)
调用中获得多个GET请求,因为在TCP中不会保留消息边界。可能每次收到数据时都要查看其他获取请求。Connection: keep-alive
选项来使用一个TCP连接,但他们也可能决定放弃它。准备好检测远程对等体关闭的断开连接和套接字(为简单起见,这在代码中称为while it_makes_sense()
。)bind
,listen
,accept
,recv
,send
,sendall
,getaddrinfo
,select
- 所有这些函数都可以抛出异常。抓住它们并采取相应的行动会更好。