'"NotSupportedException" when WebRequest is unable to find a creator for that prefix
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=4.0.0.0
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 HttpRequestCreator
to 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?
Details:
mono --version
Mono JIT compiler version 3.0.6 (Debian 3.0.6+dfsg-1~exp1~pre1)
Possibly related, unanswered question:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|