NullReferenceException parsing response of One-Way operation
- Dominant language
- C#
- Stars
- 1.8k
- Forks
- 576
- Avg merge
- 6d 9h
- Merged PRs (30d)
- 2
Description
I'm trying to migrate an existing SOAP/WCF client from .NET Framework to .NET 6. I haven't changed the actual client code (which used to work) at all. It's calling an endpoint that's not under my control so it's difficult to pinpoint exactly where it goes wrong, but here's what I'm observing. First the stack trace:
```
at async Task> System.ServiceModel.Channels.MessageEncoder.BufferMessageStreamAsync(Stream stream, BufferManager bufferManager, int maxBufferSize, CancellationToken cancellationToken)
at async Task System.ServiceModel.Channels.MessageEncoder.ReadMessageAsync(Stream stream, BufferManager bufferManager, int maxBufferSize, string contentType, CancellationToken cancellationToken)
at async Task System.ServiceModel.Channels.HttpResponseMessageHelper.ReadChunkedBufferedMessageAsync(Task inputStreamTask, TimeoutHelper timeoutHelper)
at async Task System.ServiceModel.Channels.HttpResponseMessageHelper.ParseIncomingResponse(TimeoutHelper timeoutHelper)
at async Task System.ServiceModel.Channels.HttpChannelFactory+HttpClientRequestChannel+HttpClientChannelAsyncRequest.ReceiveReplyAsync(TimeoutHelper timeoutHelper)
at async Task System.ServiceModel.Channels.RequestChannel.RequestAsync(Message message, TimeSpan timeout)
at async Task System.ServiceModel.Channels.RequestChannel.RequestAsyncInternal(Message message, TimeSpan timeout)
at Message System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at void System.ServiceModel.Dispatcher.RequestChannelBinder.Send(Message message, TimeSpan timeout)
at object System.ServiceModel.Channels.ServiceChannel.Call(string action, bool oneway, ProxyOperationRuntime operation, object[] ins, object[] outs, TimeSpan timeout)
at object System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(MethodCall methodCall, ProxyOperationRuntime operation)
at object System.ServiceModel.Channels.ServiceChannelProxy.Invoke(MethodInfo targetMethod, object[] args)
```
This is a One-Way operation so I'm already a bit surprised that it tries to read the response content at all, but this is what I'm getting from the response while debugging:
```
{StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
X-Backside-Transport: OK OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Date: Mon, 09 May 2022 06:00:28 GMT
Server: Apache/2.4.6 (CentOS)
X-ORACLE-DMS-ECID: 9a9cf930-e8af-4996-99cb-56ff8ddda4aa-00003fdd
X-ORACLE-DMS-RID: 0
X-Global-Transaction-ID: 8b42c99e6278adfc066011d1
Content-Type: text/xml; charset=utf-8
}, Trailing Headers:
{
}}
```
So I see that [HttpResponseMessageHelper.GetStreamAsync](https://github.com/dotnet/wcf/blob/main/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/HttpResponseMessageHelper.cs#L316) finds no Content-Length header (because of chunked encoding), then tries to read the first byte of the contentStream but finds it empty.
It then returns a _null_ contentStream.
This null stream is then passed onto MessageEncoder.ReadMessageAsync, which throws a NullReferenceException trying to read it.
I don't know if it's a bug or if the way that I have it set up is simply not supported, but does anyone know what is supposed to happen here? The way this path is handled doesn't seem very robust to me. I would have expected it to either ignore the response (because it's one-way), or to return some kind of empty response.
_.NET 6
System.ServiceModel 4.9.0_
Contributor guide
Assessment
This issue has not been assessed yet.