I’m testing with firefox at the moment. The server receives an HTTP request from firefox as a string, and now I’m uncertain of what to do with it. Do I need to connect to port 8080 and send out the request as a string? Then listen on port 8080 for a response? If so, what will the response come as? I’m not sure what type of content to expect. A string of HTML? Which I then send back to firefox, also as a string?
Also, fyi, from other reading I’ve gotten the idea that there are lots of different kinds of proxies– I don’t know anything about that yet. My proxy just needs to serve as a middleman between the client and the actual internet, doing nothing else.
The rules for proxying HTTP are actually quite complex. But you can probably get away with ignoring most of them, especially if you don’t care about performance.
First, you’ll have to listen on some port. You’ll need to parse the query you receive. It will consist of some number of lines, each followed by a CRLF pair. You’ll know the end of the query headers by two CRLF pairs. There can be a query body (if this is a POST) and you don’t want to have to parse that because it’s complicated. So here’s how you’ll fake it:
Check the query for any
Connectionheaders. If you get any, remove them.Make a connection to the server on the other end.
After you send the request and the request headers, but before the second CRLF that marks the end of the request headers, add a
Connection: closeheader. Then send the second CRLF.Now proxy in both directions. You can use an additional process or additional thread if you’re too lazy to use
selectorpoll. Make sure to correctly proxy a half-closed connection. (The browser may shut down sending when it finishes its query — it’s still listening for the reply.)The browser should not attempt to re-use the connection. If HTTP/1.0, it will need specific permission to do that, which it will not get. If HTTP/1.1, the server should accept its
Connection: closerequest and respond with aConnection: closeheader of its own.Note that HTTPS is actually simpler. You’ll have to parse
CONNECTrequests if you need to support that too. But then you just connection to the other side, report success or failure, and go into bidirectional proxy mode.