I have a really strange problem with
WebRequest in a
ServiceStack web application (hosted by XSP on Mono).
It seems that the registration of request modules works in a very strange way; I am using
WebRequest to create an HTTP request, and it is failing because it was not able to find a creator for that "prefix" (HTTP).
The exception I am seeing is
NotSupportedException, and I was able to track it to the fact that no creator is registered for the HTTP prefix (I am hitting https://github.com/mono/mono/blob/master/mcs/class/System/System.Net/WebRequest.cs, around line 479)
EDIT: more details:
NotSupportedException is thrown by
WebRequest.GetCreator, which uses the URL prefix as a key to choose which creator to return; in my case, a
HttpRequestCreator. The exception is thrown because there is no creator registered for the "HTTP" prefix (actually, there are no creators at all).
So I searched around a little bit, dug into Mono sources, and found that modules are (or should be) added to the
webRequestModules section of
system.web in one of the various *.config files.
I looked at my machine.config file, and there it is:
System.Net.HttpRequestCreator, System, Version=18.104.22.168
Looking at WebRequest Mono sources it seems that prefixes are added from configuration(s) inside the class static constructor (not a good choice, IMHO, but still.. it should work).
To test it, I tried to add an
system.net/webRequestModules in my
web.config; this is loaded by XSP/Mono and results in a duplicate key exception (which is expected since
HttpRequestCreator should be already loaded, as it is already present in machine.config).
Even stranger: if I add a mock handler for Http, like this:
bool res = System.Net.WebRequest.RegisterPrefix ("http", new MyHttpRequestCreator ()); Debug.Assert (res == false);
The assertion sometimes pass... sometimes not!
RegisterPrefix returns "false" if a creator for the same prefix is already registered; I expect it always to return false, but this is not the case! Again, it is completely random)
When the registration "fails" (i.e., returns false because an "HTTP" prefix is already registered), then the
WebRequest can create requests for HTTP. It is as if calling
RegisterPrefix "wakes up" the static constructor and let it run.
I am perplexed: it seems like a race condition in the execution of the static constructor of
WebRequest, but this does not make sense (the runtime protects static constructors with a lock, IIRC)
What am I missing? How could I solve or work around this problem? Is it my fault (misunderstanding or missing something), or does it look like a Mono bug, so should I submit it?
Mono JIT compiler version 3.0.6 (Debian 3.0.6+dfsg-1~exp1~pre1)
Possibly related, unanswered question: