HttpClient使用’HttpCompletionOption.ResponseHeadersRead’时,响应存储在哪里?

huangapple go评论69阅读模式
英文:

Even with 'HttpCompletionOption.ResponseHeadersRead', where does HttpClient store the response?

问题

Even with using HttpCompletionOption.ResponseHeadersRead like this:

var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://myserver.com");

var request = new HttpRequestMessage(HttpMethod.Get, "huge_file.bin");
var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

As soon as SendAsync is called, HttpClient issues a GET request. This can be seen with Fiddler.

Under the hood, where does the underlying HttpClient actually store the the request response? Is it in memory? If it's in memory, what if the response is really huge, couldn't that be problem? In my tests, it does not seem to be in memory.
Is it maybe in non-user memory, like in the kernel memory? I'm not familiar how does the network things work internally when downloading data.

Note that I'm not asking about consuming the response content by calling for example response.Content.ReadAsStringAsync(). I'm asking how does HttpClient reads and stores the response internally, before I start to consume it by calling response.Content.ReadAsStringAsync() for example.

英文:

Even with using HttpCompletionOption.ResponseHeadersRead like this:

var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://myserver.com");

var request = new HttpRequestMessage(HttpMethod.Get, "huge_file.bin");
var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

As soon as SendAsync is called, HttpClient issues a GET request. This can be seen with Fiddler.

Under the hood, where does the underlying HttpClient actually store the the request response? Is it in memory? If it's in memory, what if the response is really huge, couldn't that be problem? In my tests, it does not seem to be in memory.
Is it maybe in non-user memory, like in the kernel memory? I'm not familiar how does the network things work internally when downloading data.

Note that I'm not asking about consuming the response content by calling for example response.Content.ReadAsStringAsync(). I'm asking how does HttpClient reads and stores the response internally, before I start to consume it by calling response.Content.ReadAsStringAsync() for example.

答案1

得分: 2

不使用ResponseHeadersRead时,它不会将响应存储在任何地方。只有在调用ReadAs...之后,服务器才完全发送响应。

至于在Fiddler中查看请求:是的,请求已发出,但它实际上是否显示了响应中接收的所有字节?

无论如何,Fiddler是一个透明代理,可能会完全缓存请求和响应以解析它们。尝试使用Wireshark并观察实际的网络数据包,您将看到响应流在调用ReadAsStream并实际从流中读取字节之前并没有完全读取。

这就是TCP的工作原理(HTTP运行在TCP套接字上):它在发送一定量的数据后等待ACK。不过,它可能不仅仅是头部,因为TCP通常会在等待ACK之前推送多个数据包。

如果您在足够长的时间内不读取数据,服务器将中断连接。

英文:

It doesn't store it anywhere if you use ResponseHeadersRead. The response hasn't been fully sent by the server until you call ReadAs....

As far as seeing the request in Fiddler: yes the request is issued, but is it actually showing all the bytes being received in the response?

In any case, Fiddler is a transparent proxy, which is probably going to fully cache requests and responses in order to parse them. Try using Wireshark and watch the actual network packets, and you will see that the response stream is not fully read until you call ReadAsStream and actually read the bytes off the stream.

That's just how TCP works (HTTP runs on TCP sockets): it waits for an ACK after a certain amount of data. It might be more than just the headers though, as TCP commonly pushes through more than one packet before waiting for an ACK.

If you don't read the data after a long enough amount of time, the server will just break the connection.

huangapple
  • 本文由 发表于 2023年6月12日 00:47:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76451520.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定