Wcf: NRE when response has Content-Type but empty body

Created on 5 Jul 2018  路  6Comments  路  Source: dotnet/wcf

When a SOAP service returns no content but has a Content-Type set, WCF throws a NullReferenceException in HttpResponseMessageHelper. Leaving off Content-Type works fine.

Example HTTP response that reproduces the issue

HTTP/1.1 500
Content-Length: 0
Content-Type: text/xml; charset=UTF-8
Date: Thu, 05 Jul 2018 21:10:34 GMT
Connection: close

Expected Result

System.ServiceModel.CommunicationException : The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error."

Actual Result

System.NullReferenceException : Object reference not set to an instance of an object.

The NRE happens due to inputStream being null in HttpResponseMessageHelper.DecodeBufferedMessageAsync when it attempts to dispose it in the finally block.

The root cause however looks to be in ValidateContentTypeAsync. It doesn't properly handle this situation. It returns true (last line in the method) if the content type has a value and content length is 0, when it should be returning false. Its return value is saved in a hasContent variable in ParseIncomingResponse, so it definitely looks like it should be returning false if there's no content.

Backlog bug

All 6 comments

Thanks for reporting this @IGx89 we'll have someone take a look next week.

Would it be possible to fix this bug anytime soon? Since it is a very trivial fix and we'd like to avoid using our own custom build. The patch for the fix is below.

diff --git a/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/HttpResponseMessageHelper.cs b/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/HttpResponseMessageHelper.cs
index 0c580539..f8407996 100644
--- a/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/HttpResponseMessageHelper.cs
+++ b/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/HttpResponseMessageHelper.cs
@@ -42,6 +42,7 @@ namespace System.ServiceModel.Channels
             bool hasContent = await ValidateContentTypeAsync();
             Message message = null;

+
             if (!hasContent)
             {
                 if (_encoder.MessageVersion == MessageVersion.None)
@@ -136,6 +137,11 @@ namespace System.ServiceModel.Channels
                 _contentLength = content.Headers.ContentLength.HasValue ? content.Headers.ContentLength.Value : -1;
             }

+            if (content == null || _contentLength == 0)
+            {
+                return false;
+            }
+
             if (string.IsNullOrEmpty(_contentType))
             {
                 Stream contentStream = await GetStreamAsync();

@Lxiamail, when is this likely to be addressed? (I've just tested with the 4.7.0 version as I've seen the code has been changed and it seems to be working, so perhaps this one is not even an issue)

@mconnew did this issue get fixed as a side-effect of PR #3709?

@StephenBonikowsky, unfortunately no.

This looks like it would be a simple fix.
We should consider it for 5.0.

Was this page helpful?
0 / 5 - 0 ratings