Over the weekend I got a message from Chris on the message board. He ran into problems with my Credit Class processing classes for .NET that I posted some time ago. Basically what happens is this:
You connect to a secure site with WebRequest and the first request works perfectly fine. Then a second request is done quickly thereafter and the second request will always fail. A typical exception in this scenario might be:
A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll
Additional information: Cannot access a disposed object.
Now this is happening even though a completely new instance of a WebRequest object is created for each Http request. Http after all is stateless right <s>...
Lest you think this is just my scrappy code (I have a high level wwHTTP wrapper around WebRequest) <s>- I've run into this same situation with Web Service Proxies. Anything that uses WebRequest under the covers is possibly prone to this issue.
I've seen this issues with various servers but it seems to occur mostly with SSL transactions and more often than not when running through some sort of proxy server. For example I can make this fail by hooking up to Fiddler and running two requests. The second request will always fail.
The problem is that WebRequest uses a ServicePoint under the covers with a global ServicePointManager that is responsible for caching and dishing HTTP connections. Now https: requests are often chached agressively because SSL connections are fairly expensive to set up because there's a fair amount of back and forth messaging that occurs for the SSL handshakes. So ServicePointManager holds on to connections and tries to dish another one if you hit the same server in quick succession.
I've never run into this problem with non-SSL requests but I've seen this on a few occasions myself with HTTPS requests and always in scenarios where requests are repeated in quick succession with new instances of WebRequest objects (in this case for unrelated requests - ie. it's not a loop, but successive Credit Card Processing requests).
In any case, regardless of what the problem is you might run into this and when you do there's a fairly easy fix which is to turn of Http Keep-Alives for the http request. If you're making a single server request it's very easy to just tell WebRequest to close the connection:
HttpWebRequest request = HttpWebRequest.Create("https://gateway.merchantplus.com/...");
request.KeepAlive = false;
WebResponse response = request.GetResponse();
This takes care of the problem. You'll want to be careful not to use this code though on everything - if you make multiple server calls you certainly will want to take advantage of keep alives on SSL calls if possible. I suspect the problem is that the server might be forcing the connection closed even though the client asks for keep-alives (which is often done by proxies) and that's what actually causes the problem with the ServicePointManager.
On a slightly different topic - Chris sent me a complete network trace of his request which was a great help in tracking this down. The amount of information available on these traces is a tremendous help. You can find out how to set up a network trace in this MSDN article.
Other Posts you might also like