You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If you access HttpContent.Headers.ContentLength directly, we will attempt to use the content's TryComputeLength to construct a content length header.
However, if you access HttpContent.Headers via its enumerator or a method like TryGetValues, we won't construct the content length header.
This means that just accessing the ContentLength property will change the results of header enumeration. For example:
varcontent=new StringContent("hello world");foreach(var kvp in content.Headers){}// Content-Length not presentvarignore= content.Headers.ContentLength;foreach(var kvp in content.Headers){}// Content-Length present
Similarly, if you try to remove the header using the Remove method, it's not actually removed:
varcontent=new StringContent("hello world");
content.Headers.Remove("Content-Length");
Assert.Equal(null, content.Headers.ContentLength);// fails; returns value from TryComputeLength
The easiest fix here is probably just to try to compute the length when the content object is constructed. This assumes that TryComputeLength is always cheap, which seems reasonable, but is slightly different than how it's used today. Also, it seems like LoadIntoBufferAsync changes the Content-Length, but probably this is fine.
Unfortunately, fixing this will cause SocketsHttpHandler to behave incorrectly. Currently, if you set TransferEncodingChunked = true, then SocketsHttpHandler will never access the ContentLength property directly, and thus it won't get populated and won't get sent on the wire. Fixing the above behavior will cause the ContentLength to get populated, and thus sent on the wire, which is not correct behavior, per RFC. So this will need to get fixed somehow. (Note that this problem exists today, it's just harder to hit it -- you would need to either set Content-Length explicitly, or force population of the header by accessing it.)
(edited because I'm an idiot and can't read the RFC properly)
The text was updated successfully, but these errors were encountered:
This also affects MultipartContent in a similar way to SocketsHttpHandler. If you access Content-Length on one of the content parts, it will end up getting serialized in that part's headers, which is probably not what you want.
I've submitted a PR for the SocketsHttpHandler fix. That's the most pressing issue here.
I suppose we can continue to live with the current behavior. That said, this is the sort of thing that causes subtle bugs, as demonstrated by the SocketsHttpHandler issue.
If you access HttpContent.Headers.ContentLength directly, we will attempt to use the content's TryComputeLength to construct a content length header.
However, if you access HttpContent.Headers via its enumerator or a method like TryGetValues, we won't construct the content length header.
This means that just accessing the ContentLength property will change the results of header enumeration. For example:
Similarly, if you try to remove the header using the Remove method, it's not actually removed:
The easiest fix here is probably just to try to compute the length when the content object is constructed. This assumes that TryComputeLength is always cheap, which seems reasonable, but is slightly different than how it's used today. Also, it seems like LoadIntoBufferAsync changes the Content-Length, but probably this is fine.
Unfortunately, fixing this will cause SocketsHttpHandler to behave incorrectly. Currently, if you set TransferEncodingChunked = true, then SocketsHttpHandler will never access the ContentLength property directly, and thus it won't get populated and won't get sent on the wire. Fixing the above behavior will cause the ContentLength to get populated, and thus sent on the wire, which is not correct behavior, per RFC. So this will need to get fixed somehow. (Note that this problem exists today, it's just harder to hit it -- you would need to either set Content-Length explicitly, or force population of the header by accessing it.)
(edited because I'm an idiot and can't read the RFC properly)
The text was updated successfully, but these errors were encountered: