CacheCow: Crash when deserializing a HttpResponseMessage on .NET Core
On .NET Core (I’ve tested 2.0 and 2.1) calling DeserializeToResponseAsync
on MessageContentHttpMessageSerializer
will crash with certain http responses. (google.com being one of them)
I’ve tested this on 4.7.1 and the crash does not occur. I’m guessing this may be a framework issue, but I’m not 100% sure.
I’ve attached a project that reproduces the problem
Exception backtrace
System.InvalidOperationException: Error parsing HTTP message header byte 697 of message System.Byte[].
at System.Net.Http.HttpContentMessageExtensions.ReadAsHttpResponseMessageAsyncCore(HttpContent content, Int32 bufferSize, Int32 maxHeaderSize, CancellationToken cancellationToken)
at CacheCow.Client.MessageContentHttpMessageSerializer.DeserializeToResponseAsync(Stream stream)
at CacheCowCrashRepro.TestCacheStore.AddOrUpdateAsync(CacheKey key, HttpResponseMessage response) in C:\Users\james\Documents\Projects\CacheCowCrashRepro\CacheCowCrashRepro\Program.cs:line 45
at CacheCow.Client.CachingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at CacheCowCrashRepro.Program.Main(String[] args) in C:\Users\james\Documents\Projects\CacheCowCrashRepro\CacheCowCrashRepro\Program.cs:line 19} System.Exception {System.InvalidOperationException
Thanks
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 1
- Comments: 23 (12 by maintainers)
Well even .NET Core 3.0 does not seem to fix it so I have got back to them now 😦
It might help for the rest who have a similar issue. I found a way to bypass this Expires header issue, provided that in your case, it is totally ok to ignore that header.
And then you can wrap your original FileStore or memoryStore with:
That worked for me. Thanks for the great library!
I’ve run into a similar issue when the ETag is not well formed.
The Http spec says that the ETag header should be quoted and in my case I have a resource that is returning an ETag without quotes.
Putting aside the fact that the server should be returning a well-formed ETag, the root problem here as I see it is that the serialisation and deserialisation are not being done by the same library/code and essentially the deserialisation is less tolerant of malformed headers than the normal code path that creates a HttpResponse from the network stream. When reading from the network stream, the headers are added using “response.Content!.Headers.TryAddWithoutValidation(descriptor, headerValue);”, but when deserialised it uses “headers.Add(text, value)”.
There are likely to be other ways to trigger this failure with other malformed headers too.
Ironically, the internal class “InternetMessageFormatHeaderParser” that is doing the deserialisation currently has an overload that takes a parameter in the constructor to “ignoreHeaderValidation”, but there is nowhere to set that further up the call chain.
I think to fix this, the library needs to take control of the deserialisation rather than delegating to the extension method in the “System.Net.Http.Formatting” library (which I think is legacy anyway?). I’m going to have a look at implementing my own FileStore that uses a new “MessageContentHttpMessageSerializer” that does not depend on the “System.Net.Http.Formatting” library. If I get somewhere I am happy with I’ll create a pull request.
Hi, I’m just hit the same issue in my app on asp.net core 3.1. @aliostad, is there any update on this?
Thanks.
Thanks 😃 And thanks for the great library