The other day our WCF services (over HTTP) stopped working; with the following exception:
System.ServiceModel.CommunicationException:
An error occurred while receiving the HTTP response to http://x.y.z/service.
This could be due to the service endpoint binding not using the HTTP protocol.
This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down).
See server logs for more details.
---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive.
---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
After several hours of searching for the reason, and a lot of frustration,
it turned out that our friendly IT dept. installed an Internet proxy server without letting anybody know.
But, even so, MSDN documentation seems to suggest that WCF should use any configuration settings defined in Internet Options
(and Internet Explorer would connect - no problems). So, why the failure?
One suggestion that came up on was to use this in the program's .config file:
<configuration>
... (other settings)
<system.net>
<defaultProxy>
<proxy usesystemdefault="true" />
</defaultProxy>
</system.net>
</configuration>
usesystemdefault
"Specifies whether to use Internet Explorer proxy settings." (even though WCF over HTTP is supposed to do that already?)
Anyway, we tried this setting and the application started working here again; so, we deployed this solution to some of our clients.
Unfortunately, we then started to get some strange errors from several users
(for instance, that the server name could not be resolved even though it could be resolved, without any problems, outside of our program).
Well it turns out that usesystemdefault will use IE proxy settings, but will also disable auto-configuration (PAC) scripts.
So, on systems configured thus (as it is in most larger companies, I would guess) this solution is just bad.
(There's another setting in the defaultProxy tag - scriptLocation - but, even if it worked, it wouldn't really solve the problem;
scriptLocation can be different on different computers and we didn't want to end up managing .config files for each user....)
More documentation on this can be found here:
"usesystemdefault controls whether the static proxy settings (proxy address, bypass list, and bypass on local) should be read from the Internet Explorer proxy settings for the user." and,
more importantly: "This value must also be set to "false" or not set for adaptive proxies to be enabled".
Ok, fine, but going back to our original connectivity issue - how do we fix it, using a single .config file, so that it works everywhere?
Well, I couldn't find anything relevant on the net;
so, I ended up installing Wireshark to see what exactly is going on.
The analysis quickly gave me this:
...
HTTP/1.0
417 Expectation Failed
Server: squid/3.1.8
...
X-Squid-Error: ERR_INVALID_REQ
...
Ah, that, at least, pointed me to searching for WCF problems with the Squid proxy server, and gave the error number.
And that finally lead me to the follow two blog entries (thanks!):
So, I tried the solution described there and added this entry: <servicePointManager expect100Continue="false" />
to our application's .config file:
<configuration>
... (other settings)
<system.net>
<settings>
... (other settings)
<servicePointManager expect100Continue="false" />
</settings>
</system.net>
</configuration>
And that finally worked; here, and, more importantly, for our clients... Yay!
So, why did usesystemdefault work for us as well?
Apparently,
MS decided not to use expect100Continue in IE (hence, IE worked in our network without any issues).
Then, when setting usesystemdefault to true, WCF 'inherits' this setting from IE (but, again, blocks auto-configuration scripts).
Oh, and BTW, there were no such problems with using HttpWebRequest with that proxy server...
HTH
Top
|