June 19, 2010 4 Comments
What is Expect 100 Continue and how does it change the behavior of HttpWebRequest?
In general and according to the HTTP/1.1 W3C RFC 2616 the purpose of the 100 (Continue) status is to allow a client that is sending a request message with a request body to determine if the origin server is willing to accept the request (based on the request headers) before the client sends the request body. In some cases, it might either be inappropriate or highly inefficient for the client to send the body if the server will reject the message without looking at the body. A client MUST NOT send an Expect request-header field with the “100-continue” expectation if it does not intend to send a request body.
Now, having ServicePointManager.Expect100Continue and ServicePoint.Expect100Continue; lets talk about the difference between the two versions of this property. ServicePointManager is the master object that controls the creation and lookup of ServicePoints. As a general rule, properties set on ServicePointManager apply to newly created ServicePoints from that point forward. If you set the property on ServicePointManager after a ServicePoint is created, it will not be propogated to the already existing ServicePoints.
This property simply tells the HttpWebRequest object whether or not to send the “Expect: 100-continue” header with the request . Meaning when this header is sent it tells the server that the client is going to delay sending the body of the request waiting for the server to give the client the OK (a 100 continue response) to upload the data. In current implementations, the HttpWebRequest object waits 350 milliseconds.
The “Expect 100-continue” header with the request is considered important since:
- The server could redirect the user to a different location, it could require authentication, the connection could have been dropped in between requests, thus avoiding the upload of unnecessary data.
- The client sets the HttpWebRequest.SendChunked property to true. This means that the client will not tell the server the upload size, but will send the data in chunks. At the beginning of each chunk is information on how big the chunk is and the client sends a zero length chunk to advise the server that there is no more data coming.
- And because HttpWebRequest keeps a pool of connections to any given server, the connection could be closed by the remote server without the client knowing that the connection has been dropped. And the client cannot safely retry the request if an error occurs beyond a certain point in the request process. If the client has sent even one byte of the upload body, then HttpWebRequest will fail if an error occurs in the connection. If Expect100Continue functionality is enabled, this gives a small window where upload requests can be retried safely. If it is disabled, then an error that occurs when sending the request will cause the entire request to fail.
During my work with different web services on different web servers, I have noticed that server web servers choke on the “Expect 100 Continue” and send be Error 417 “Expectation Failed”. Investigating the problem, I understood that the exception is raised when using ad-blocking proxies which does not know how to handle or HTTP/1.1 features.
In such cases, you need to disable the Expect 100 continue features by writing the following in your code:
ServicePointManager.Expect100Continue = false;