.net - 将 header 添加到机器上的所有* HTTP 请求

标签 .net http

我需要能够附加由离开 PC 的大多数 HTTP 请求发送的 HTTP header (或修改用户代理字符串)。

大多数情况下,我指的是 Internet Explorer 中的任何内容,以及来自 .NET 应用程序的任何内容。

我已经通过编写 BHO 完成了 Internet Explorer 方面的工作,但是 BHO 不会拦截加载到 IE 中的 ClickOnce 控件发出的请求,这是另一个要求。

在我的案例中,.NET 应用程序都使用 WebRequest.Create 来发出它们的请求。

这可能吗?我希望我能在某个地方向 System.Net 堆栈中注入(inject)一些代码。

代理是一种可能性,但事实证明很难创建一个性能不尽如人意的代理。 HTTPS 流量是另一个问题。

最佳答案

好的。我想通了。

我创建了一个自定义 Web 请求模块,它在 WebRequest.Create 工厂返回之前显式设置 HttpWebRequest 的用户代理。

首先,创建一个实现了 IWebRequestCreate 的类:

public class CustomHttpRequestCreator : IWebRequestCreate
{
    public CustomHttpRequestCreator(){}

    public WebRequest Create(Uri uri)
    {
        HttpWebRequest webRequest = Activator.CreateInstance(typeof(HttpWebRequest),
                                        BindingFlags.CreateInstance | BindingFlags.Public |
                                        BindingFlags.NonPublic | BindingFlags.Instance,
                                        null, new object[] { uri, null }, null) as HttpWebRequest;

        webRequest.UserAgent = "OMG IT WORKED!";
        return webRequest;
    }
}

您需要签署此程序集并将其添加到 GAC。

现在在您机器上的 machine.config 中,添加以下配置部分:

<system.net>
    <webRequestModules>
        <remove prefix="http:"/>
        <remove prefix="https:"/>
        <add prefix="http:" type="HttpWebRequestTest.CustomHttpRequestCreator, HttpWebRequestTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4ba7a6b9db5020b7" />
        <add prefix="https:" type="HttpWebRequestTest.CustomHttpRequestCreator, HttpWebRequestTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4ba7a6b9db5020b7" />
    </webRequestModules>
</system.net>   

现在无论何时有人调用 WebRequest.Create,他们都会得到一个已经设置了用户代理字符串的 HttpWebRequest。


我还尝试创建一个继承自 HttpWebRequest 的自定义类,但这很棘手,因为没有默认的公共(public)构造函数。唯一的公共(public)构造函数是 ISerializable 的过时实现。

我成功地让派生类与 ISerializable 构造函数一起使用,但生成的“伪水合”对象未处于有效状态,这可能是因为 ISerializable 实现已过时且未得到维护由微软。

不过,如果他们更详细地调查使用它时遇到的错误,那么人们还是有可能使这项工作成功的。具体来说,与 ServicePoint 相关的访问存在问题。使用反射,也许可以使事情正常进行。这是我的实现供引用:

public class CustomHttpWebRequest : HttpWebRequest
{
    public CustomHttpWebRequest(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }

    internal CustomHttpWebRequest(Uri uri) : base(BuildSerializationInfo(uri), new StreamingContext())
    {
        this.UserAgent = "OMG IT WORKED! (Constructor)";
    }

    private static SerializationInfo BuildSerializationInfo(Uri uri)
    {
        HttpWebRequest webRequest = Activator.CreateInstance(typeof(HttpWebRequest),
                                        BindingFlags.CreateInstance | BindingFlags.Public |
                                        BindingFlags.NonPublic | BindingFlags.Instance,
                                        null, new object[] { uri, null }, null) as HttpWebRequest;

        var serializationInfo = new SerializationInfo(typeof(HttpWebRequest), new System.Runtime.Serialization.FormatterConverter());
        ((ISerializable)webRequest).GetObjectData(serializationInfo, new StreamingContext());
        return serializationInfo;
    }

    public override WebResponse GetResponse()
    {
        this.UserAgent = "OMG IT WORKED!";
        return base.GetResponse();
    }

    public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state)
    {
        this.UserAgent = "OMG IT WORKED ASYNC!";
        return base.BeginGetResponse(callback, state);
    }
}

关于.net - 将 header 添加到机器上的所有* HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9217595/

相关文章:

c - 使用 winHttpApi 或套接字发送大文件是否明智?

c# - 检测是否在 NavigationContext 中调用了 GoBack()

.net - 将 XmlNode 从一个 XmlDocument 移动到另一个的直观方法是什么?

c# - 如何模拟Windows关机进行调试?

c# - EF有时可以在成功写入后重试吗?

php - 使用 PHP 获取我必须登录才能到达的 URL 的源代码

Ruby 通过代理打开 uri 下载

c# - 使用前确保 App.config 存在

api - 如何构建 REST API XML 响应

c++ - 网络爬虫在 read() 中下载网页的 recv 缓冲区应该有多大?