简体   繁体   English

如何在Python中通过HTTP代理将客户端连接到服务器?

[英]How to connect a client to a server through an HTTP proxy in Python?

I'm really new to coding using sockets. 我真的是使用套接字编码的新手。

I like the socket library, I get to understand a big part of what's happening in my program, so i you don't mind i would like to stick with it. 我喜欢套接字库,我了解了程序中发生的大部分情况,所以我不介意我坚持使用它。

So as the title says, I have a socket based client and server and I would like to exchange content through an HTTP proxy(I'm using a Squid proxy). 因此,正如标题所述,我有一个基于套接字的客户端和服务器,我想通过HTTP代理交换内容(我正在使用Squid代理)。 This little piece of code is supposed to bypass the proxy in my campus to simulate a chat over the campus network. 这小段代码应该绕过我校园中的代理,以模拟校园网络上的聊天。 This is totally legal since I asked the IT guys that work there. 这是完全合法的,因为我问在那里工作的IT人员。

Here's the deal, I am able to send a POST request through the proxy to my server which receives it and sends it back to client 1, but when I try to send more requests to the proxy none of them gets to the server so I think to my self the connection died but here's the thing, when I send messages from client 2 which is connected directly to the server, the server AND client 1 receive them. 这是交易,我能够通过代理将POST请求发送到我的服务器,该服务器接收该请求并将其发送回客户端1,但是当我尝试向代理发送更多请求时,它们都没有到达服务器,因此我认为就我自己而言,连接已终止,但问题是,当我从直接连接到服务器的客户端2发送消息时,服务器和客户端1接收到它们。

import socket
from _thread import *

def sender(server,h):
    b=input("<<--Send--")
    b=h
    server.send(b.encode())

PROXY_IP="127.0.0.1"
PROXY_PORT=3128
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.settimeout(0.05)
server.connect((PROXY_IP,PROXY_PORT))

header="""POST http://127.0.0.1:3001 HTTP/1.1\r\n
Host: 127.0.0.1:3001\r\n
Proxy-Connection: keep-alive\r\n
Content-Length: 5 \r\n\r\n
hello\r\n"""

server.send(header.encode())

while 1:
    try:
        start_new_thread(sender,(server,header))
        a=server.recv(1024)
        print("-->>{}".format(a.decode()))
    except KeyboardInterrupt:
        break
    except:
        pass

server.close()

I already tried the CONNECT method which works perfectly, but it's not allowed in my campus network proxy. 我已经尝试了CONNECT方法,该方法非常有效,但是在我的校园网络代理中是不允许的。 What am I doing wrong ? 我究竟做错了什么 ? Is there something I should know about how to re-send content through a proxy ? 关于如何通过代理重新发送内容,我应该知道些什么吗? Thank you for your time and please bear with me.. 谢谢您的宝贵时间,请多多包涵。

Here's what I get on the client that sends a request to the proxy: 这是我在将请求发送到代理的客户端上得到的:

~#Sent : POST http://127.0.0.1:3001 HTTP/1.1
Host: 127.0.0.1:3001
Proxy-Connection: keep-alive
Content-Length: 5 

hello

#Received : HTTP/1.1 200 OK
Server: squid/3.5.19
Mime-Version: 1.0
Date: Mon, 10 Oct 2016 00:46:39 GMT
X-Transformed-From: HTTP/0.9
X-Cache: MISS from kali
X-Cache-Lookup: MISS from kali:3128
Transfer-Encoding: chunked
Via: 1.1 kali (squid/3.5.19)
Connection: keep-alive


#Received : B2
POST / HTTP/1.1
Content-Length: 5
Host: 127.0.0.1:3001
Via: 1.1 kali (squid/3.5.19)
X-Forwarded-For: 127.0.0.1
Cache-Control: max-age=259200
Connection: keep-alive

hello


#Sent : POST http://127.0.0.1:3001 HTTP/1.1
Host: 127.0.0.1:3001
Proxy-Connection: keep-alive
Content-Length: 5 

hello

Nothing is received after this.. 此后什么也没收到。

POST http://127.0.0.1:3001 HTTP/1.1\r\n
Host: 127.0.0.1:3001\r\n
Proxy-Connection: keep-alive\r\n
Content-Length: 5 \r\n\r\n
hello\r\n

The body of your HTTP response consists of 7 bytes not 5 as you've stated in your Content-length . HTTP响应的主体由7个字节组成,而不是Content-length所述的5个字节。 The \\r\\n after the 5 byte still belong to the response body. 5个字节后的\\r\\n仍属于响应主体。 Giving the wrong size might mixup request handling, ie the proxy is expecting a new request but is actually getting \\r\\n , ie the 2 bytes after your 5 bytes Content-length . 设置错误的大小可能会混淆请求处理,即代理期望一个新请求,但实际上是\\r\\n ,即5字节Content-length之后的2字节。

Apart from that both path and Host header must include the name of the target from the perspective of the proxy. 除此之外,从代理的角度来看,路径和Host头都必须包括目标的名称。 Using 127.0.0.1. 使用127.0.0.1。 like in your example would mean that you try to access a server at the same host of the proxy, ie localhost from the view of the proxy. 就像在您的示例中一样,意味着您尝试访问代理服务器相同主机(即从代理服务器角度来看的本地主机)上的服务器。 This is probably not what you've intended. 这可能不是您想要的。

...
X-Transformed-From: HTTP/0.9

This header in the response of the proxy indicates that your server does not properly speak HTTP/1.x. 代理响应中的此标头表示您的服务器未正确说出HTTP / 1.x。 Instead of sending HTTP header and body it just sends the payload back without any HTTP header, like done in the HTTP 0.9 protocol which was obsoleted 20 years ago. 而不是发送HTTP标头和正文,它只是将有效载荷发送回去而没有任何HTTP标头,就像在20年前废弃的HTTP 0.9协议中所做的那样。 With HTTP 0.9 the response will always end only at the end of the TCP connection. 使用HTTP 0.9时,响应将始终仅在TCP连接结束时结束。 This means that you cannot have multiple requests within the same TCP connection. 这意味着在同一TCP连接中不能有多个请求。

I'm really new to coding using sockets. 我真的是使用套接字编码的新手。

The problem is not caused by the wrong use of sockets but due the wrong implementation of the application protocol, ie the data send over the socket. 问题不是由套接字的错误使用引起的,而是由于应用程序协议的错误实现,即,通过套接字发送的数据。 If you really need to implement HTTP please study the standards, ie RFC 7230 and following. 如果您确实需要实现HTTP,请研究这些标准,即RFC 7230及以下。 If you don't want to do this use existing and tested HTTP libraries instead of writing your own. 如果您不想这样做,请使用现有的和经过测试的HTTP库,而不要编写自己的库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM