C# Bug in WebRequest

I have discovered what I think is a bug in the C# framework.

I have a simple code that sends a Http webdav request

  1. req = (HttpWebRequest)WebRequest.Create(url);
  2. req.Method = "PROPFIND";
  3. req.Headers = new WebHeaderCollection();
  4. // I dunno what's for, but Sharepoint throws error 404 if it is not set
  5. req.Headers.Set("translate", "f");
  6. req.Headers.Set("Depth", depth.ToString());
  7.  
  8. // encode en UTF8 le corp de message à transmettre
  9. byte[] bytes = Encoding.UTF8.GetBytes((string)query);
  10.  
  11. req.ContentType = "text/xml";
  12. req.ContentLength = bytes.LongLength;
  13.  
  14. RequestStream = req.GetRequestStream();
  15. RequestStream.Write(bytes, 0, bytes.Length);
  16. RequestStream.Close();
  17. HttpWebResponse webResp = (HttpWebResponse)req.GetResponse();
  18. // Note : C# has no constant for http status code WEBDAV_MULTI
  19. if (((int)webResp.StatusCode) == 207)
  20.     {
  21.  // handle web response
  22.      }

Everything works fine most of the time.

This is a typical http dump

PROPFIND /path/to/foo.bar HTTP/1.1
translate: f
Depth: 0
Content-Type: text/xml
Host: httpserver
Content-Length: 90
Expect: 100-continue
HTTP/1.1 100 Continue
< ?xml version="1.0" encoding="UTF-8"?><d:propfind xmlns:d='DAV:'><d:allprop /></d:propfind>HTTP/1.1 207 Multi-Status
Date: Mon, 27 Dec 2010 09:42:27 GMT
Server: IBM_HTTP_Server/2.0.47.1 Apache/2.0.47 (Unix) DAV/2
Transfer-Encoding: chunked
Content-Type: text/xml; charset="utf-8"

37b
< ?xml version="1.0" encoding="utf-8"?>
<d:multistatus xmlns: D="DAV:" xmlns:ns0="DAV:">
<d:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">
<d:href>/path/to/foo.bar</d:href>
<d:propstat>
<d:prop>
<lp1:resourcetype />
<lp1:creationdate>2010-12-21T15:07:41Z</lp1:creationdate>
<lp1:getcontentlength>2269</lp1:getcontentlength>
<lp1:getlastmodified>Tue, 21 Dec 2010 15:07:41 GMT</lp1:getlastmodified>
<lp1:getetag>"4cc6-8dd-ff786940"</lp1:getetag>
<lp2:executable>F</lp2:executable>
<d:supportedlock>
<d:lockentry>
<d:lockscope><d:exclusive /></d:lockscope>
<d:locktype><d:write /></d:locktype>
</d:lockentry>
<d:lockentry>
<d:lockscope><d:shared /></d:lockscope>
<d:locktype><d:write /></d:locktype>
</d:lockentry>
</d:supportedlock>
<d:lockdiscovery />
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
</d:multistatus>

Now, sometimes, C# hangs on

PROPFIND /path/to/foo.bar HTTP/1.1
translate: f
Depth: 0
Content-Type: text/xml
Host: httpserver
Content-Length: 90
Expect: 100-continue
HTTP/1.1 100 Continue

It is only 100 seconds afterwards that the IBM http server sends a timeout.

Why is the request never send? Mironelli gives a workaround

  1. req.ServicePoint.Expect100Continue = false;

That way, the request contains the full body from the beginning, instead of a check for the server capabilities.

  • I can send hundreds of request without problem. I think that once it has started to happen, every subsequent request hangs.

  • Conclusion: it is a known bug in HttpWebRequest: KB 969223 Race condition in HttpWebRequest leaves invalid connection in connection pool

  • And it should be fixed in C# Framework v4.0