HttpWebRequest and Host Headers

A user posted on the newsgroups asking about how to set Host headers in HttpWebRequest.

HttpWebRequest does not allow the host header to be set by the user. It is set automatically from the URI supplied to HttpWebRequest constructor.

However, it turns out that there is a roundabout way to accomplish this. This is shown in the following reply to the original post:

https://groups-beta.google.com/group/microsoft.public.dotnet.framework/browse_thread/thread/17c5369520221c8/4e768c733ad2f451?q=HttpWebRequest+and+Host+Header&rnum=1#4e768c733ad2f451

This solution works, but there is a subtle difference in the request sent on the wire. To illustrate that, look at the following program:


using System;
using System.Net;

public class EP {
 public static void Main()
 {
  test("https://www.company.com/test.aspx");
  test("https://www.contoso.com/test.aspx");
  
 }

 public static void test(string uri)
 {
  WebRequest req = WebRequest.Create(uri);
  req.Proxy = new WebProxy("https://myserver", false);

  WebResponse resp = req.GetResponse();

  resp.Close();
 }
}


To get this program to work, you need to do the following:

  1. Have a server named "myserver" on which you get IIS/ASP.NET running. If you dont want to run ASP.NET that is fine as well.
  2. On the server, go into the IIS console, and create two websites. Set the host header on the first website to be www.company.com and the other to be www.contoso.com
  3. Compile and run the above program.

If you look at the request sent on the wire, you will notice that this program sends the following request to the server "myserver"

GET https://www.contoso.com/test.aspx HTTP/1.1
Host: https://www.contoso.com

Whereas the actual request you want sent is:

GET /test.aspx HTTP/1.1
Host: www.contoso.com

NOTE: Even though the request URI sent on the wire is an absolute URI, and is different from what should actually be sent if the client had control of the host header, it will still work on the server, because as per RFC/2616, a server is supposed to honor all requests which use an absolute URI instead of a relative URI to identify the resource.