Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set a Host header value for SSL requests using HttpWebRequest

I am trying to use the System.Net.HttpWebRequest class to perform a HTTP GET request to a specific web server for web applications we have load balanced over numerous servers. In order to achieve this, I need to be able to set the Host header value for the request, and I have been able to achieve this by using the System.Net.WebProxy class.

However, this all breaks down when I try to perform a GET using SSL. When I attempt to do this, the call to HttpWebRequest.GetResponse throws a System.Net.WebException, with a HTTP status code of 400 (Bad Request).

Is what I'm trying to achieve possible with HttpWebRequest, or should I be looking for an alternative way to perform what I want?

Here is the code I've been using to try and get this all to work :-

using System;
using System.Web;
using System.Net;
using System.IO;

namespace UrlPollTest
{
    class Program
    {
        private static int suffix = 1;
        static void Main(string[] args)
        {
            PerformRequest("http://www.microsoft.com/en/us/default.aspx", "www.microsoft.com");
            PerformRequest("https://www.microsoft.com/en/us/default.aspx", "");
            PerformRequest("https://www.microsoft.com/en/us/default.aspx", "www.microsoft.com");

            Console.WriteLine("Press any key to continue");
            Console.ReadKey();
        }

        static void PerformRequest(string AUrl, string AProxy)
        {
            Console.WriteLine("Fetching from {0}", AUrl);
            try
            {
                HttpWebRequest request = WebRequest.Create(AUrl) as HttpWebRequest;
                if (AProxy != "")
                {
                    Console.WriteLine("Proxy = {0}", AProxy);
                    request.Proxy = new WebProxy(AProxy);
                }

                WebResponse response = request.GetResponse();
                using (Stream httpStream = response.GetResponseStream())
                {
                    using (StreamReader reader = new StreamReader(httpStream))
                    {
                        string s = reader.ReadToEnd();
                        File.WriteAllText(string.Format("D:\\Temp\\Response{0}.html", suffix++), s);
                    }
                }
                Console.WriteLine("  Success");
            }
            catch (Exception e)
            {
                Console.WriteLine("  " + e.Message);
            }
        }
    }
}
like image 459
Cleggy Avatar asked Aug 06 '09 03:08

Cleggy


People also ask

What is the host header used for?

The HTTP host header is a request header that specifies the domain that a client (browser) wants to access. This header is necessary because it is pretty standard for servers to host websites and applications at the same IP address. However, they don't automatically know where to direct the request.

What is host header in Postman?

The Host request header specifies the host and port number of the server to which the request is being sent. If no port is included, the default port for the service requested is implied (e.g., 443 for an HTTPS URL, and 80 for an HTTP URL). A Host header field must be sent in all HTTP/1.1 request messages.

What is the use of HttpWebRequest in C#?

The HttpWebRequest class provides support for the properties and methods defined in WebRequest and for additional properties and methods that enable the user to interact directly with servers using HTTP.

What is HTTP host?

The HTTP Host represents the domain name of the server. It may also represent the Transmission Control Protocol (TCP) port number which the server uses. Defining the port number is optional, the default value is considered.


1 Answers

I've used a hacky approach before - of having a test exe that modifies my "hosts" file, injecting an entry for the farm name to the specific server's address (and issuing an ipconfig /flushdns). After that, requests should get routed to the right server as though it were the only one there.

Obviously this requires admin access... I use it as part of an automated smoke-test to hit the farm as though it were individual machines.

The other thing you might try is something on the NLB, perhaps in TCL (in the case of F5) - maybe add a custom header that the NLB understands? (assuming it is doing SSL re-signing).

like image 182
Marc Gravell Avatar answered Oct 04 '22 22:10

Marc Gravell