I have written a SOCKS proxy which works with both HTTP and HTTPS traffic if chaining is turned off.
If chaining is turned on and the forwarding host and port belong to a filtering HTTP proxy then only HTTP traffic can flow. HTTPS traffic does not flow and reports an SSL error.
Note that the HTTP proxy does handle HTTPS traffic when the request is coming direct from the browser and not from the SOCKS server.
As an example if I make a request to https://www.google.com the following occurs:
1) Client sends a SOCKS 5 greeting to let us know which auth methods are acceptable.
2) Server responds with NO_AUTH
3) Client sends a connection request (which includes the intended destination host and port).
4) The server creates and connects a socket to the HTTP proxy server and responds to the client with GRANTED
5) The SOCKS server then receives the following request (the invisible/control characters have all been replaced with their character codes so you can see what's going on):
\u0016\u0003\u0001\u0000Ñ\u0001\u0000\u0000Í\u0003\u0003áp¥@Ia¹\u0001„Ä\u0006 É;š‰‰4\u001dýà•J>Ü6¢Þ\fö\u001c%\u0000\u0000(À+À/\u0000žÌ\u0014Ì\u0013À\nÀ\tÀ\u0013À\u0014À\u0007À\u0011\u00003\u00002\u00009\u0000œ\u0000/\u00005\u0000\n\u0000\u0005\u0000\u0004\u0001\u0000\u0000|\u0000\u0000\u0000\u0013\u0000\u0011\u0000\u0000\u000ewww.google.comÿ\u0001\u0000\u0001\u0000\u0000\n\u0000\b\u0000\u0006\u0000\u0017\u0000\u0018\u0000\u0019\u0000\u000b\u0000\u0002\u0001\u0000\u0000#\u0000\u00003t\u0000\u0000\u0000\u0010\u0000\u001b\u0000\u0019\u0006spdy/3\bspdy/3.1\bhttp/1.1uP\u0000\u0000\u0000\u0005\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0000\u0012\u0000\u0000\u0000\r\u0000\u0012\u0000\u0010\u0004\u0001\u0005\u0001\u0002\u0001\u0004\u0003\u0005\u0003\u0002\u0003\u0004\u0002\u0002\u0002
As you can see, its completely unreadable, but we already know where the user intends to go from the initial SOCKS connection message (step 3) so we can create and issue the following connect request:
CONNECT www.google.com:443 HTTP/1.1\r\nUser-Agent: MySocksServer\r\nProxy-Connection: keep-alive\r\nHost: www.google.com\r\n\r\n
6) This newly constructed CONNECT is sent to the HTTP proxy that we are chaining to, this proxy checks against its filter rules and responds with:
HTTP/1.1 200 Connection Established\r\nVia: 1.1 HTTPserverName\r\nX-WebMarshal-RequestID: AN_ID_STRING\r\n\r\n
7) This is received in our SOCKS server and is forwarded (unmodified) to the client. In my debugging I am monitoring the sockets directly before the send request and can see that the client socket is connected.
8) The next event raised is an error, with the error, SOCKET_NOT_CONNECTED, running another check on the sockets confirms that the client socket is indeed no longer connected.
Why would my Socket be getting closed between steps 7 and 8 here? Have I not followed the protocol correctly? I can't see what I am missing. I guess I am handling the CONNECT method wrong in some way?
If I do not modify the request received by the SOCKS server (i.e. convert it into a CONNECT request) and instead forward on the unreadable data direct to the HTTP proxy then the Logs for the HTTP proxy show either:
Badly formated request: \u0016\u0003\u001
Bad request received.
OR
Failed to read request: Client closed connection. (0)
1Request took 0 ms + 23 ms idle time