I have downloaded Privoxy few weeks ago and for the fun I was curious to know how a simple version of it can be done.
I understand that I need to configure the browser (client) to send request to the proxy. The proxy send the request to the web (let say it's a http proxy). The proxy will receive the answer... but how can the proxy send back the request to the browser (client)?
I have search on the web for C# and http proxy but haven't found something that let me understand how it works behind the scene correctly. (I believe I do not want a reverse proxy but I am not sure).
Does any of you have some explication or some information that will let me continue this small project?
Update
This is what I understand (see graphic below).
Step 1 I configure the client (browser) for all request to be send to 127.0.0.1 at the port the Proxy listen. This way, request will be not sent to the Internet directly but will be processed by the proxy.
Step2 The proxy see a new connection, read the HTTP header and see the request he must executes. He executes the request.
Step3 The proxy receive an answer from the request. Now he must send the answer from the web to the client but how???
Useful link
Mentalis Proxy : I have found this project that is a proxy (but more that I would like). I might check the source but I really wanted something basic to understand more the concept.
ASP Proxy : I might be able to get some information over here too.
Request reflector : This is a simple example.
Here is a Git Hub Repository with a Simple Http Proxy.
Agree to dr evil if you use HTTPListener you will have many problems, you have to parse requests and will be engaged to headers and ...
you see you dont need to even know what is in the browser request and parse it, only get the target site address from the first line first line usually likes this GET http://google.com HTTP1.1 or CONNECT facebook.com:443 (this is for ssl requests)
You can build one with the
HttpListener
class to listen for incoming requests and theHttpWebRequest
class to relay the requests.Socks4 is a very simple protocol to implement. You listen for the initial connection, connect to the host/port that was requested by the client, send the success code to the client then forward the outgoing and incoming streams across sockets.
If you go with HTTP you'll have to read and possibly set/remove some HTTP headers so that's a little more work.
If I remember correctly, SSL will work across HTTP and Socks proxies. For a HTTP proxy you implement the CONNECT verb, which works much like the socks4 as described above, then the client opens the SSL connection across the proxied tcp stream.
Proxy can work in the following way.
Step1, configure client to use proxyHost:proxyPort.
Proxy is a TCP server that is listening on proxyHost:proxyPort. Browser opens connection with Proxy and sends Http request. Proxy parses this request and tries to detect "Host" header. This header will tell Proxy where to open connection.
Step 2: Proxy opens connection to the address specified in the "Host" header. Then it sends HTTP request to that remote server. Reads response.
Step 3: After response is read from remote HTTP server, Proxy sends the response through an earlier opened TCP connection with browser.
Schematically it will look like this:
I wouldn't use HttpListener or something like that, in that way you'll come across so many issues.
Most importantly it'll be a huge pain to support:
What you need to do is:
I wrote 2 different HTTP proxies in .NET with different requirements and I can tell you that this is the best way to do it.
Mentalis doing this, but their code is "delegate spaghetti", worse than GoTo :)
I have recently written a light weight proxy in c# .net using TcpListener and TcpClient.
https://github.com/titanium007/Titanium-Web-Proxy
It supports secure HTTP the correct way, client machine needs to trust root certificate used by the proxy. Also supports WebSockets relay. All features of HTTP 1.1 are supported except pipelining. Pipelining is not used by most modern browsers anyway. Also supports windows authentication (plain, digest).
You can hook up your application by referencing the project and then see and modify all traffic. (Request and response).
As far as performance, I have tested it on my machine and works without any noticeable delay.