如何使用 HttpWebRequest 设置 SSL 请求的主机标头值
我正在尝试使用 System.Net.HttpWebRequest 类对我们在众多服务器上进行负载平衡的 Web 应用程序的特定 Web 服务器执行 HTTP GET 请求。 为了实现此目的,我需要能够设置请求的 Host 标头值,并且我已经能够通过使用 System.Net.WebProxy 类来实现此目的。
然而,当我尝试使用 SSL 执行 GET 时,这一切都崩溃了。 当我尝试执行此操作时,对 HttpWebRequest.GetResponse 的调用会引发 System.Net.WebException,HTTP 状态代码为 400(错误请求)。
我想要通过 HttpWebRequest 实现的目标是否可行,或者我应该寻找替代方法来执行我想要的操作?
这是我一直用来尝试让这一切正常工作的代码:-
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);
}
}
}
}
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);
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我之前使用过一种 hacky 方法 - 使用一个测试 exe 来修改我的“hosts”文件,将场名称的条目注入到特定服务器的地址(并发出
ipconfig /flushdns
)。 之后,请求应该被路由到正确的服务器,就好像它是那里唯一的服务器一样。显然,这需要管理员访问权限...我将其用作自动冒烟测试的一部分,就像它是单独的机器一样对农场进行测试。
您可能会尝试的另一件事是 NLB 上的某些内容,也许在 TCL 中(在 F5 的情况下) - 也许添加 NLB 可以理解的自定义标头? (假设它正在进行 SSL 重新签名)。
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).
在 .NET 4.0 中,Host 标头可以独立于请求将要发送到的 URL 进行设置,因此我建议您使用 HttpwebRequest.Host 来解决您的问题。 (我认为)这将作为 .NET 4.0 beta2 的一部分发布。 如果不实现您自己的 WebRequest 自定义子类,则无法将主机头重写为与以前版本的 .Net 不同的主机头(相信我,它已经被尝试过)。
In .NET 4.0 the Host header can be set independently of the URL that the request is going to so I would recommend that you use HttpwebRequest.Host to solve your problem. This (I think) will ship as part of .NET 4.0 beta2. There is NO way to re-write the host header to be different under previous versions of .Net without implementing your own custom subclass of WebRequest (believe me, it's been tried).