How to connect a client to a server through an HTTP proxy in Python?
<p>I'm really new to coding using sockets.</p>

<p>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.</p>

<p>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). 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.</p>

<p>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.</p>

<pre><code>import socket
from _thread import *

def sender(server,h):
    b=input("&lt;&lt;--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("--&gt;&gt;{}".format(a.decode()))
    except KeyboardInterrupt:
        break
    except:
        pass

server.close()
</code></pre>

<p>I already tried the CONNECT method which works perfectly, but it's not allowed in my campus network proxy.
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..</p>

<p>Here's what I get on the client that sends a request to the proxy:</p>

<pre><code>~#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
</code></pre>

<p>Nothing is received after this..</p>

<pre><code>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
</code></pre>

<p>The body of your HTTP response consists of 7 bytes not 5 as you've stated in your <code>Content-length</code>. The <code>\r\n</code> after the 5 byte still belong to the response body. Giving the wrong size might mixup request handling, i.e. the proxy is expecting a new request but is actually getting <code>\r\n</code>, i.e. the 2 bytes after your 5 bytes <code>Content-length</code>.</p>

<p>Apart from that both path and <code>Host</code> header must include the name of the target from the perspective of the proxy. Using 127.0.0.1. like in your example would mean that you try to access a server at the same host of the proxy, i.e. localhost from the view of the proxy. This is probably not what you've intended.</p>

<pre><code>...
X-Transformed-From: HTTP/0.9
</code></pre>

<p>This header in the response of the proxy indicates that your server does not properly speak 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. With HTTP 0.9 the response will always end only at the end of the TCP connection. This means that you cannot have multiple requests within the same TCP connection.</p>

<blockquote>
  <p>I'm really new to coding using sockets.</p>
</blockquote>

<p>The problem is not caused by the wrong use of sockets but due the wrong implementation of the application protocol, i.e. the data send over the socket. If you really need to implement HTTP please study the standards, i.e. <a href="https://tools.ietf.org/html/rfc7230" rel="nofollow">RFC 7230</a> and following. If you don't want to do this use existing and tested HTTP libraries instead of writing your own.</p>

python sockets proxy server client