1

I want to call a webpage by its IP address by adding custom values to request header for "host". "
" Code:

 HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://1.1.1.1");
        request.Headers["Host"] = "xyz.net";
 WebResponse response = request.GetResponse();

But it gives an error:

ArgumentException: restricted header

It seems that some headers cannot be modified in .net 2.0 so is there any way that I can change the host or change the .net version in unity to higher version?

Programmer
  • 121,791
  • 22
  • 236
  • 328
Sonali Chalke
  • 149
  • 2
  • 15
  • Possible duplicate of [How to set custom "Host" header in HttpWebRequest?](https://stackoverflow.com/questions/1450937/how-to-set-custom-host-header-in-httpwebrequest) – joreldraw Oct 10 '17 at 12:22
  • @joreldraw This is Unity. None of those should work since it uses reflection – Programmer Oct 10 '17 at 12:26
  • Possible duplicate of [Cannot set some HTTP headers when using System.Net.WebRequest](https://stackoverflow.com/questions/239725/cannot-set-some-http-headers-when-using-system-net-webrequest) – Foggzie Oct 10 '17 at 15:29
  • ^ Explaination is in the answer to that question. TL;DR, just set the `Host` property on the `HttpWebRequest` object itself instead of using the `Headers` property. (https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.host(v=vs.110).aspx) – Foggzie Oct 10 '17 at 15:31

1 Answers1

2

You can do this with reflection. Unfortunately, none of the C# answers from similar questions works because Unity is using Mono and their variable names are totally different making GetField unable to find the variable that's holding the headers.

Dump all the headers in the HttpWebRequest class with HttpWebRequest.GetType().GetFields then look for the name of the field that holds the headers. In my test, the field name is "webHeaders" and is a type of WebHeaderCollection.

Below is an extension method that modifies that "webHeaders" from reflection:

public static class ExtensionMethods
{
    public static void changeSysTemHeader(this HttpWebRequest request, string key, string value)
    {
        WebHeaderCollection wHeader = new WebHeaderCollection();
        wHeader[key] = value;


        FieldInfo fildInfo = request.GetType().GetField("webHeaders",
                                                System.Reflection.BindingFlags.NonPublic
                                                   | System.Reflection.BindingFlags.Instance
                                                   | System.Reflection.BindingFlags.GetField);

        fildInfo.SetValue(request, wHeader);
    }

    public static void changeReflectionField(this HttpWebRequest request, string fieldName, object value)
    {
        FieldInfo fildInfo = request.GetType().GetField(fieldName, System.Reflection.BindingFlags.NonPublic
                                                   | System.Reflection.BindingFlags.Instance
                                                   | System.Reflection.BindingFlags.GetField);

        fildInfo.SetValue(request, value);
    }
}

USAGE:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://1.1.1.1");

//Change Host header
request.changeSysTemHeader("Host", "xyz.net");

request.changeReflectionField("hostChanged", true);

WebResponse response = request.GetResponse();

This should work for any restricted header like User-Agent. Tested with Unity 2017.2. Mentioned the Unity version and how I found the field name so that when the variable name changes in the future, anyone can simply fix it.

Programmer
  • 121,791
  • 22
  • 236
  • 328