none
REST call timeout, Microsoft.Http.HttpStageProcessingException

    Question

  • I'm using the HttpClient from the WCF-REST Starter Kit to call a REST service (build with Java, hosted in Jetty7).
    The client is POSTing text messages to the service, which returns 204 (No Content) responses.

    A POST request looks like this:
     --------
     POST http://myhost:9090/svc/publish HTTP/1.1
     Content-Type: text/plain
     Host: myhost:9090
     Content-Length: 22

     2222222222222222222222
     ---------

    The response looks like this:
     ---------
     HTTP/1.1 204 No Content
     Server: Jetty(7.2.0.v20101020)

     ---------
     
    Problem: The first POST seems to work fine, the client gets the correct response. However the second POST hangs for 100 seconds and then 'returns' with a HttpStageProcessingException (see the stacktrace below). 

    Interesting: The problem disappears under certain conditions:
    1. If the service and the client are running on the same machine, the problem is gone (even though the Uri for the call is still using the machine name and not 'localhost').
    2. If I use Fiddler (on the client machine) to capture the traffic, the problem is gone. As soon as I close Fiddler (or stop traffic capture) and try some more POSTs it happens again.
    3. I changed the service to return a 200 (OK) instead of the 204 response, and the problem was gone. When I checked the corresponding response, I found that it contained a "Content-Length: 0" header. If I change the service to explicitly add this header to the 204 response, the problem is gone too.

    The last observation (with the Content-Length header) caused me to do another test: I changed the service to return a 200 (OK) with chunked encoding (therefore no Content-Length header, see below). This leads to the same problem again. 

     ---------
     HTTP/1.1 200 OK
     Content-Type: text/plain
     Transfer-Encoding: chunked
     Server: Jetty(7.2.0.v20101020)

     16
     2222222222222222222222
     0
     ---------

    So I think the HttpClient has a general problem with all 2xx (Successful) responses that don't have a Content-Length header.

    Question: Is there anything that I could do (on the client side) to handle those responses correctly ?


    Unhandled Exception: Microsoft.Http.HttpStageProcessingException: The operation has timed out ---> System.Net.WebException: The operation has timed out
       at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
       at System.Net.HttpWebRequest.GetRequestStream()
       at Microsoft.Http.HttpWebRequestTransportStage.HttpTransportAsyncResult..ctor(Boolean preferSync, HttpRequestMessage request, HttpWebRequestTransportSettings settings, AsyncCallback callback, Object state) in e:\bt\3781\HttpClient\Microsoft.Http\HttpWebRequestTransportStage.cs:line 296
       at Microsoft.Http.HttpWebRequestTransportStage.ProcessRequestAndTryGetResponse(HttpRequestMessage request, HttpResponseMessage& response, Object& state) in e:\bt\3781\HttpClient\Microsoft.Http\HttpWebRequestTransportStage.cs:line 48
       at Microsoft.Http.HttpStageProcessingAsyncResult.NextRequest(HttpStageProcessingAsyncResult self) in e:\bt\3781\HttpClient\Microsoft.Http\HttpStageProcessingAsyncResult.cs:line 113
       --- End of inner exception stack trace ---
       at Microsoft.Http.HttpStageProcessingAsyncResult.Complete(HttpStage stage, Exception e) in e:\bt\3781\HttpClient\Microsoft.Http\HttpStageProcessingAsyncResult.cs:line 45
       at Microsoft.Http.HttpStageProcessingAsyncResult.NextRequest(HttpStageProcessingAsyncResult self) in e:\bt\3781\HttpClient\Microsoft.Http\HttpStageProcessingAsyncResult.cs:line 130
       at Microsoft.Http.HttpClient.Send(HttpRequestMessage request) in e:\bt\3781\HttpClient\Microsoft.Http\HttpClient.cs:line 291
       at Microsoft.Http.HttpClient.Send(HttpMethod method, Uri uri, RequestHeaders headers, HttpContent content) in e:\bt\3781\HttpClient\Microsoft.Http\HttpClient.cs:line 497
       at Microsoft.Http.HttpMethodExtensions.Method(HttpClient client, HttpMethod method, Uri uri, HttpContent body) in e:\bt\3781\HttpClient\Microsoft.Http\HttpMethodExtensions.cs:line 118
       at Microsoft.Http.HttpMethodExtensions.Method(HttpClient client, HttpMethod method, String uri, HttpContent body) in e:\bt\3781\HttpClient\Microsoft.Http\HttpMethodExtensions.cs:line 110
       at Microsoft.Http.HttpMethodExtensions.Post(HttpClient client, String uri, HttpContent body) in e:\bt\3781\HttpClient\Microsoft.Http\HttpMethodExtensions.cs:line 61
       at simpleTest.Program.Main(String[] args) in D:\Work\mule\external\notifications\mercurius\mercuriusCsharpChatter\simpleTest\Program.cs:line 43

    Tuesday, November 23, 2010 10:22 AM

All replies

  • Hello according to HTTP standard:

    14.13 Content-Length

    Applications SHOULD use this field to indicate the transfer-length of the message-body, unless this is prohibited by the rules in section 4.4.

    In HTTP, it SHOULD be sent whenever the message's length can be determined prior to being transferred, unless this is prohibited by the rules in section 4.4.

    The exceptions are:

    3.If a Content-Length header field (section 14.13) is present, its decimal value in OCTETs represents both the entity-length and the transfer-length. The Content-Length header field MUST NOT be sent if these two lengths are different

    Messages MUST NOT include both a Content-Length header field and a non-identity transfer-coding. If the message does include a non- identity transfer-coding, the Content-Length MUST be ignored.

     

    So I think in most cases, you should include Content-Length in service response. Can you add a Content-Length in the 204 response?


    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
    Wednesday, November 24, 2010 3:54 AM
  • Thanks for your reply.

    >> Applications SHOULD use this field to indicate the transfer-length of the message-body, unless this is prohibited by the rules in section 4.4

    From section 4.4:

    1.Any response message which "MUST NOT" include a message-body (such as the 1xx, 204, and 304 responses and any response to a HEAD request) is always terminated by the first empty line after the header fields, regardless of the entity-header fields present in the message.

    3.If a Content-Length header field (section 14.13) is present, its decimal value in OCTETs represents both the entity-length and the transfer-length. The Content-Length header field MUST NOT be sent if these two lengths are different (i.e., if a Transfer-Encoding header field is present).

    I agree that it leaves some room for interpretation, whether a Content-Length should be added to a 204 response - I would say no, because - as the message-body is prohibited - a Content-Length doesn't make any sense.

    However when using Transfer-Encoding chunked, there is no room for interpretation.

    And yes, I can modify our service to add the Content-Length to the 204 response. I'm afraid though that there are other REST services out there, that I cannot change - and cannot use with the WCF HttpClient, because of this issue.

    Wednesday, November 24, 2010 8:25 AM