sunny boy, 2009-01-01
I was writing an HTTP proxy during last weeks. I need to address the origin server with a custom IP address, but I should keep the "Host" header.
I googled about "HttpWebRequest set server IP", "WebRequest modify Host", etc. I read through several posts, and realized:
My purpose is: make HttpWebRequest send its request to a custom IP address, but leave the Request-Line as "GET / HTTP/1.1".
After hours of Reflector, I found the solution:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://blogs.msdn.com");//url and Host header
FieldInfo field_ServicePoint_ProxyServicePoint = (typeof(ServicePoint))
.GetField("m_ProxyServicePoint", BindingFlags.NonPublic | BindingFlags.Instance);
req.Proxy = new WebProxy("www.google.com:80");//server IP and port
field_ServicePoint_ProxyServicePoint.SetValue(req.ServicePoint, false);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
When the above code is executed, I can see the following request in Wireshark:
GET / HTTP/1.1 Host: blogs.msdn.com Connection: Keep-Alive
And, the request is sent to 64.233.189.99:80, a www.google.com server.
DOWNLOAD: C# code & Wireshark capture
ServicePoint class provides connection management for HTTP connections. A ServicePoint instance is created for each "host:port" combination, and reused across several requests. ServicePoint.m_ProxyServicePoint determines whether this ServicePoint connects to a proxy. When m_ProxyServicePoint is set to false, HttpWebRequest don't think it's a proxy, so the Request-Line becomes "GET / HTTP/1.1".
However, m_ProxyServicePoint is a private property of ServicePoint, so I have to use Reflection to change it.
2010-05-31 update: As of .Net Framework 4.0, you can use HttpWebRequest.Host property to set Host header independent from the request URI.
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://www.google.com");//url path and actual server
req.Host = "blogs.msdn.com");//Host header
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Author: sunny boy
Note: to help international users, this article is written in English.