IIS把双恩codeD正斜杠在不同的网址上比它在后续请求的第一个请求 [英] IIS treats double-encoded forward slashes in URLs differently on the first request than it does on subsequent requests
问题描述
最近我的团队被要求实施的HttpModule一个ASP.NET MVC应用程序处理的双恩codeD网址上的IIS 7和.NET 3.5。下面是问题的症结所在:
我们有时会说有一个看上去像这样的双烯codeD斜线网址:
http://www.example.com/%252fbar%5cbaz/foo
有其他的格式,我们必须处理为好,但他们都有一个共同点,他们有一个双连接codeD斜杠。
要解决这个问题,我们写了一个HTTP模块时,一个URL有双重连接codeD斜杠,只有行动,我们重定向到一个理智的URL。的细节并不重要,但有两个位,其
- 我们无法控制的事实,这些URL具有双恩codeD斜杠
- 在我们还没有ugpraded到.NET 4.0然而,也不是在眼前的地平线上。
下面的问题:
在IIS启动的第一个请求显示不同的URL比第二个请求呢。
如果我们从上面的例子中使用的URL,第一个请求到IIS看起来像:
http://www.example.com/bar/baz/foo
和第二个请求将如下所示:
http://www.example.com/%252fbar%5cbaz/foo
这是通过检查 Application.Request.Url.AbsolutePath
属性在调试完成。
下面是应该重现该问题的最小的code例子(创建一个新的MVC应用程序,并注册了以下HTTP模块):
公共类ForwardSlashHttpModule:IHttpModule的
{
内部IHttpApplication申请{搞定;组; }
公共无效的Dispose()
{
应用= NULL;
}
公共无效的Init(HttpApplication的情况下)
{
初始化(新HttpApplicationAdapter(上下文));
}
内部空隙初始化(IHttpApplication上下文)
{
应用=背景;
context.BeginRequest + = context_BeginRequest;
}
内部空隙context_BeginRequest(对象发件人,EventArgs的)
{
VAR URL = Application.Request.Url.AbsolutePath; //< - 问题点
//做的东西与地址在这里。
}
}
然后,调用本地主机上的同一网址:
http://www.example.com/%252fbar%5c/foo
注:确保在
context_BeginRequest
使该行前插入Debugger.Launch()
叫你马上就能看到它第一次启动IIS
当你执行的第一个请求,你应该看到:
http://example.com/bar/foo
在后续的请求,你应该看到:
http://example.com//bar/foo
。
我的问题是:这是在IIS中的错误?为什么叫时,它提供了不同的网址 Application.Request.Url.AbsolutePath
的第一次,但没有任何后续请求?
另外:不要紧,第一个请求是否是一个双连接codeD URL或没有,第二个请求总是会适当由IIS(或至少处理,在适当的处理双恩codeD斜线即可)。这是第一个要求就是这个问题。
更新
我尝试了几种不同的属性,看看如果在第一次请求有不同的值:
首先请求 字符串U = Application.Request.Url.AbsoluteUri;
http://example.com/foo/baz/bar/
字符串x = Application.Request.Url.OriginalString;
http://example.com:80/foo/baz/bar
字符串Y = Application.Request.RawUrl;
/%2ffo /巴兹/条
布尔Z = Application.Request.Url.IsWellFormedOriginalString();
真正
唯一有趣的事情是, Application.Request.RawUrl
发出单一连接codeD正斜杠(%2F
),并将转换的EN codeD反斜杠(%5C
)到forwardslash(虽然一切人这么做过也一样)。
在 RawUrl
仍是部分连接codeD上的第一个请求。
字符串U = Application.Request.Url.AbsoluteUri;
http://example.com//foo/baz/bar
字符串x = Application.Request.Url.OriginalString;
http://example.com:80/%2ffoo/baz/bar
字符串Y = Application.Request.RawUrl;
/%2ffoo /巴兹/条
布尔Z = Application.Request.Url.IsWellFormedOriginalString();
假
这是第二个请求有趣的点:
-
IsWellFormedOriginalString()
是假
。在第一个要求是真
。 - 的RawUrl是相同的(可能有用)。
- 的
绝对URI
是不同的。在第二次请求,它有两个正斜杠。
更新
Application.Request.ServerVariables [网址] = /报价/ GC / V12 / CMX
Application.Request.ServerVariables [CACHE_URL] = http://example.com:80/%2ffoo/baz/bar
开放题
- 这似乎是在IIS或.NET的错误。是吗?
- 为第一个的请求后,由申请这只影响了
IISRESET
- 除了使用RawUrl(因为我们不得不担心很多其他的问题,如果我们分析的原始地址,而不是使用.NET提供了'安全'的网址),还有什么其他的方法有哪些让我们来处理这个?
请注意,该问题的物理冲击低:对于它是一个实际的问题,第一个请求从客户端的web服务器将必须是针对上述特定URL,这种事情发生的几率相对较低。
Request.Url可德$ C $早已CD - 我不相信它为你在做什么
请参阅内部细节处: <一href="http://stackoverflow.com/questions/3986736/querystring-with-url-en$c$cd-ampersand-$p$pmaturely-de$c$cd-within-request-url">Querystring与URL-EN codeD符号prematurely德$ C $内Request.Url
CD该解决方案是直接通过Request.RawUrl访问值
我知道你的概率与路径,但似乎同样的事情是怎么回事。请尝试RawUrl - 看看它是否适合你,而不是
Recently my team was asked to implement an HttpModule for an ASP.NET MVC application that handled double-encoded URLs on IIS 7 and .NET 3.5. Here's the crux of the problem:
We sometimes get URLs that have double-encoded forward slashes that look like so:
http://www.example.com/%252fbar%5cbaz/foo
There are other formats that we have to handle as well, but they all have something in common, they have a double-encoded forward slash.
To fix this, we wrote an HttpModule that only acts when a URL has a double encoded forward slash, and we redirect it to a sane URL. The details aren't important, but there are two bits that are:
- We can't control the fact that these URLs have double-encoded forward slashes
- And we have not ugpraded to .NET 4.0 yet, nor is it on the immediate horizon.
Here's the problem:
The first request after IIS starts up shows a different URL than the second request does.
If we used the URL from the above example, the first request to IIS would look like:
http://www.example.com/bar/baz/foo
and the second request would look like:
http://www.example.com/%252fbar%5cbaz/foo
This was done by inspecting the Application.Request.Url.AbsolutePath
property while debugging.
Here's the smallest code example that should reproduce the problem (create a new MVC application, and register the following HttpModule):
public class ForwardSlashHttpModule : IHttpModule
{
internal IHttpApplication Application { get; set; }
public void Dispose()
{
Application = null;
}
public void Init(HttpApplication context)
{
Initialize(new HttpApplicationAdapter(context));
}
internal void Initialize(IHttpApplication context)
{
Application = context;
context.BeginRequest += context_BeginRequest;
}
internal void context_BeginRequest(object sender, EventArgs e)
{
var url = Application.Request.Url.AbsolutePath; //<-- Problem point
//Do stuff with Url here.
}
}
Then, call the same URL on localhost:
http://www.example.com/%252fbar%5c/foo
NB: Make sure to insert a
Debugger.Launch()
call before the line incontext_BeginRequest
so that you'll be able to see it the first time IIS launches
When you execute the first request, you should see:
http://example.com/bar/foo
on subsequent requests, you should see:
http://example.com//bar/foo
.
My question is: Is this a bug in IIS? Why does it provide different URLs when calling Application.Request.Url.AbsolutePath
the first time, but not for any subsequent request?
Also: It doesn't matter whether the first request is for a double encoded URL or not, the second request will always be handled appropriately by IIS (or at least, as appropriate as handling double-encoded forward slashes can be). It's that very first request that is the problem.
Update
I tried a few different properties to see if one had different values on the first request:
First Requeststring u = Application.Request.Url.AbsoluteUri;
"http://example.com/foo/baz/bar/"
string x = Application.Request.Url.OriginalString;
"http://example.com:80/foo/baz/bar"
string y = Application.Request.RawUrl;
"/%2ffo/baz/bar"
bool z = Application.Request.Url.IsWellFormedOriginalString();
true
The only interesting thing is that the Application.Request.RawUrl
emits a single-encoded Forward slash (%2f
), and translates the encoded backslash (%5c
) to a forwardslash (although everything else does that as well).
The RawUrl
is still partially encoded on the first request.
string u = Application.Request.Url.AbsoluteUri;
"http://example.com//foo/baz/bar"
string x = Application.Request.Url.OriginalString;
"http://example.com:80/%2ffoo/baz/bar"
string y = Application.Request.RawUrl;
"/%2ffoo/baz/bar"
bool z = Application.Request.Url.IsWellFormedOriginalString();
false
Interesting points from the second request:
IsWellFormedOriginalString()
isfalse
. On the first request it wastrue
.- The RawUrl is the same (potentially helpful).
- The
AbsoluteUri
is different. On the second request, it has two forward slashes.
Update
Application.Request.ServerVariables["URL"] = /quotes/gc/v12/CMX
Application.Request.ServerVariables["CACHE_URL"] = http://example.com:80/%2ffoo/baz/bar
Open Questions
- This seems like a bug in either IIS or .NET. Is it?
- This only matters for the very first request made by an application after an
iisreset
- Besides using RawUrl (as we'd have to worry about a lot of other problems if we parsed the Raw Url instead of using the 'safe' URL provided by .NET), what other methods are there for us to handle this?
Keep in mind, the physical impact of this problem is low: For it to be an actual problem, the first request to the web server from a client would have to be for the above specific URL, and the chances of that happening are relatively low.
Request.Url can be decoded already - I wouldn't trust it for what you are doing.
See the internal details at: Querystring with url-encoded ampersand prematurely decoded within Request.Url
The solution is to access the values directly via Request.RawUrl.
I realize your prob is with the path, but it seems the same thing is going on. Try the RawUrl - see if it works for you instead.
这篇关于IIS把双恩codeD正斜杠在不同的网址上比它在后续请求的第一个请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!