[英]Why does HttpWorkerRequest fail during HttpRuntime.ProcessRequest after a .NET 2.0 to .NET 4.0 upgrade?
我正在升级我们的应用程序,它有一个内部Web服务器,从.NET 2.0到.NET 4.0。
我正在使用对象HttpListenerWorkerRequest
处理请求,该对象扩展了HttpWorkerRequest
类,并创建了一个请求, GetRawUrl()
以http://localhost:82/Default.aspx
的格式返回一个Url。
在.NET 2.0中,将此发送到HttpRuntime.ProcessRequest(httpListenerWorkerRequest)
可以正常工作,但是在.NET 4.0中,我得到的网页上只有文本“Bad Request”。
破解打开HttpRuntime
,我可以看到从ProcessRequestInternal(HttpWorkerRequest wr)
抛出Bad Requests,这是一个尝试构建HttpContext的私有方法。
我自己尝试过:
try
{
//what's going on?
hcontext = new HttpContext(workerRequest);
}
catch(Exception e)
{
//Debugging break point here
}
预更新(.NET 2.0),它构建良好,更新后(.NET 4.0),我得到一个System.ArgumentException说明
The relative virtual path 'http:/localhost:82/Default.aspx' is not allowed here
,抛出
at System.Web.VirtualPath.Create(String virtualPath, VirtualPathOptions options)
at System.Web.HttpRequest.get_ClientFilePath()
at System.Web.Security.CookielessHelperClass.RemoveCookielessValuesFromPath()
at System.Web.HttpContext.Init(HttpRequest request, HttpResponse response)
at System.Web.HttpContext..ctor(HttpWorkerRequest wr)
at Talcasoft.Web.Hosting.HttpWorkerThread.Run(Object request) in
C:\[OurLibrary].Web\Hosting\HttpWorkerThread.cs:line 51
在.NET中发生了什么变化导致了这一点,我该怎么做才能解决它?
编辑我刚刚注意到,不允许的http:后跟一个斜杠,而不是一个斜杠,尽管请求中的GetRawUrl()肯定会返回一个double。
我不是100%肯定这是'确切的答案',但看起来非常接近我 - 还有更多要写...
VirtualPath
类中的类似似乎有一个breaking change
- 并且证实了它们如何检查illegal characters
。 (顺便说一句,你可以谷歌的'VirtualPath源'看起来似乎是它的.NET 4版本)。
在VirtualPath.Create
内部,为“非法虚拟路径字符”调用检查。
它首先进入注册表(“ HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ ASP.NET ”,“ VerificationCompatibility ”) - 以查看是否应该使用compatibility
模式“非法字符”。
基于此 - 我猜测(我现在没有办法检查这个) - 如果你将上面的注册表值(int)设置为
1
- 你应该让你的方法the old way
工作并且没有任何额外的努力。 注意: 可能需要重新启动 IIS(或主机进程),如其中一个链接所示
然后基于该注册表标志,它使用这两个中的任何一个......
':', '?', '*', '\0' // .NET 4.0 - the default
'\0' // the 'compatibility' mode
这似乎实际上很好地描述了你的故事,因为根据新的默认值,你的“端口”指定路径实际上是illegal
的。
(根据评论和解决方案的解决方案进行更新)
这是我对内部情况的理解:
1).NET 4.0之前的解决方案是VerificationCompatibility
键(见上文)。
2)使用.NET 4.0,内部处理和URL路径的修复变得更加健壮。 在大多数情况下工作正常。 简而言之, 在进入 VirtualPath.Create
之前 , 所有路径都是固定和规范化的 - 并且您的http://...
成为预期的绝对路径/Default.aspx
。
但是,当您提供HttpWorkerRequest
(而不是请求/响应等)时 - raw Url
直接从worker
- 并且提供正确和规范化路径的责任由您的工作人员请求决定 。 (这仍然有点不确定,看起来像一个错误或内部处理不好)。
要重现此问题:
internal class MyRequest : SimpleWorkerRequest
{
public MyRequest() : base("", "", String.Empty, String.Empty, null) { }
public override String GetRawUrl() { return "http://localhost:82/Default.aspx"; }
}
// ...
var wr = new MyRequest();
var context1 = new HttpContext(wr);
给出错误The relative virtual path 'http:/localhost:82/Default.aspx' is not allowed here.
FIX:
public override String GetRawUrl()
{ return new Uri(url, UriKind.RelativeOrAbsolute).AbsolutePath; }
VerificationCompatibility
关键字,这似乎是它的关键。
这是微软的一个类似的东西 - 但似乎是'2.0'的'修补程序',即不适用于你 - 但只是将它作为官方的一行附加。
FIX:.NET Framework 1.1中的“HTTP 400 - 错误请求”错误消息
当您尝试访问基于ASP.NET 2.0的网页时FIX:错误消息:“HttpException(0x80004005):'/ HandlerTest / WebForm1.aspx / a:b'不是有效的虚拟路径”
ASP.NET 2.0 x64 - 如KB 932552或826437中所述,您可能会收到HTTP 400错误请求或错误
HKEY_LOCAL_MACHINE \\ SOFTWARE \\微软\\ ASP.NET
DWord值名称:VerificationCompatibility值数据:1
这是我的看法。 它仍然包含一些猜测,但我会包括一个测试,你可以用它来证明或反驳这个假设。
堆栈跟踪将ClientFilePath.get
显示为异常的来源。 它看起来像这样:
if (this._clientFilePath == null)
{
string rawUrl = this.RawUrl;
int index = rawUrl.IndexOf('?');
if (index > -1)
{
rawUrl = rawUrl.Substring(0, index);
}
this._clientFilePath
= VirtualPath.Create(rawUrl, VirtualPathOptions.AllowAbsolutePath); //here!
}
return this._clientFilePath;
它创建一个VirtualPath
并仅允许绝对值。 http://localhost:82/Default.aspx
是一个相对路径,因为它不以斜杠开头。 它不是此上下文中的URL,因为它没有被解释为这样。
所以VirtualPath.Create
理解地否认了这条道路。 我不知道为什么.NET 2.0允许这样做,但.NET 4.0需要一个绝对路径,根据代码,这是不可配置的。
实际上,我以前从未见过HttpRequest.RawUrl
返回一个URL。 根据我的经验,它应该返回一个像/Default.aspx
这样的绝对路径。 如果要设置主机和端口,则必须找到其他方法。
所以解决方法是不使用http://localhost:82/Default.aspx
而是使用/Default.aspx
。 这对你有用吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.