为什么HttpClient会为Staples.com带来时间?

时间:2018-05-25 16:47:20

标签: c# .net .net-core

我正在为.NET Core 2.0控制台应用程序中的域尝试一个非常简单的GET请求:

curl https://www.staples.com

每次超时都会引发网络异常。

我可以在我的网络浏览器中访问网站https://www.staples.com或在邮递员中执行GET请求而不会出现问题,并返回< 1秒。

我甚至可以在域上做一个简单的curl请求,它运行正常:

message.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
  "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36");
message.Headers.Add("Accept-Language", "en-US,en;q=0.8");
message.Headers.Add("Cache-Control", "no-cache");
message.Headers.Add("Pragma", "no-cache");
message.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;" +
  "q=0.9,image/webp,image/apng,*/*;q=0.8");

我发现同样问题的另一个域是https://www.safeco.com/

我甚至尝试添加一些标题,使其看起来像Chrome浏览器请求,但没有任何区别:

.data
address   dd 82C028D1h, 81C0276Ah 
mask      dd FFFC0000h
reference dd 82C0B685h

.code
proc filter
    push bp
    mov bp, sp
    ; stack              

    ; bp+0  ==> old bp

    ; bp+2  ==> return address 
    ; bp+4  ==> return value
    ; bp+6  ==> offset mask
    ; bp+8  ==> offset address
    ; bp+10 ==> low reference
    ; bp+12 ==> high reference
    ....
    pop bp
    ret
    endp

我在这些域上尝试过的任何其他网址似乎都运行良好。为什么这两个域超时HttpClient请求?

2 个答案:

答案 0 :(得分:1)

几乎可以肯定,它们会在某种程度上进行某种连接过滤以防止刮擦,但只有他们的IT部门才能确认这一点。您可以通过模仿浏览器并发送正确的标头来使其正常工作。看来这个网站至少需要:

Connection: keep-alive
Accept-Encoding: gzip
Accept-Language: xxx

例如:

static async Task<string> MainAsync()
{
    //Added this to decompress the gzip encoded response
    HttpClientHandler handler = new HttpClientHandler();
    handler.AutomaticDecompression = System.Net.DecompressionMethods.GZip;

    var client = new HttpClient(handler);
    var request = new HttpRequestMessage()
    {
        Method = HttpMethod.Get, 
        RequestUri = new Uri("https://www.staples.com"),
        Version = new Version(1, 1)
    };

    request.Headers.Connection.Add("keep-alive");
    request.Headers.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("en-GB"));

    var response = await client.SendAsync(request);
    return await response.Content.ReadAsStringAsync();
}

答案 1 :(得分:0)

不是答案,但也不适合评论 - 也许您可以通过将此添加到您的配置中来收集网络跟踪中的内容。只需将initializeData的值更改为可写位置,发出请求,然后查看输出。它不是很漂亮但可能有线索。

  <system.diagnostics>
    <sources>
      <source name="System.Net" maxdatasize="102400" tracemode="includehex">
        <listeners>
          <add name="System.Net" />
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="System.Net" value="Verbose" />
    </switches>
    <sharedListeners>
      <add name="System.Net" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\somewhere...\networkErr.log" />
    </sharedListeners>
  </system.diagnostics>