ASP.NET规范化反斜杠以转发斜杠

时间:2012-11-29 11:07:42

标签: c# asp.net asp.net-mvc-4

ASP.NET正在“规范化”请求路径中的反斜杠以转发斜杠,我需要它们作为反斜杠(它用于在数据库中执行查找)。我不介意转义为正斜面的转义是否与未转义一致,与this question不同。

config.Routes.MapHttpRoute(
    name: "TransactionsApi",
    routeTemplate: "api/transactions/{*transaction}",
    defaults: new { controller = "transactions", transaction = RouteParameter.Optional }
);

请注意,我已设置事务以匹配路径的其余部分。

我尝试了以下网址(来自浏览器和Fiddler):

  • api/transactions/mscorlib.pdb\DFA83312EAB84F67BD225058B188F22B1\mscorlib.pdb
  • api/transactions/mscorlib.pdb\\DFA83312EAB84F67BD225058B188F22B1\\mscorlib.pdb
  • api/transactions/mscorlib.pdb%5CDFA83312EAB84F67BD225058B188F22B1%5Cmscorlib.pdb
  • api/transactions/mscorlib.pdb%5C%5CDFA83312EAB84F67BD225058B188F22B1%5C%5Cmscorlib.pdb

当他们点击我的Web API方法时,他们都是mscorlib.pdb/DFA83312EAB84F67BD225058B188F22B1/mscorlib.pdb。我检查了当前的HttpContext,看起来ASP.NET正在进行这种规范化(而不是MVC4)。

可能的解决方案:

  • 当插入事务时,将'\'标准化为'/',这样无论ASP.NET通过什么,查找都会成功。 看起来有点臭
  • Base64 {*transaction}部分,如果它包含反斜杠。 不是真正的地址栏黑客

关于如何让ASP.NET 的任何想法都能做到这种规范化吗?

2 个答案:

答案 0 :(得分:3)

简短回答

您无法阻止此行为,因为它已被硬编码到IIS中。

研究

我想通过反编译运行时和遵循代码来研究这个问题。这样做总是很好:您了解运行时的工作原理,有时您会发现问题。让我们开始旅程......

作为一个起点,我从HttpRuntime类开始用ILSpy反编译System.Web。浏览public static void ProcessRequest(HttpWorkerRequest wr)ProcessRequestNoDemandProcessRequestNowProcessRequestInternal ......

这里我想研究以下几行:
httpContext = new HttpContext(wr, false);
httpContext.Response.InitResponseWriter();
httpAsyncHandler.BeginProcessRequest(httpContext, this._handlerCompletionCallback, httpContext);

HttpContext.HttpContext(HttpWorkerRequest wr, bool initResponseWriter)许多事情可能会导致这种情况:
this.Init(request, response)
new HttpRequest(wr, this)

更准确地说HttpContext.GetEurl()(看起来很可疑),
Request.InternalRewritePath(VirtualPath.Create(virtualPath), null, true)(安全),
VirtualPath.Create(virtualPath)(看起来非常可疑),
virtualPath = UrlPath.FixVirtualPathSlashes(virtualPath);(臭名昭着!)。

让我们写下让我们来到这里的堆栈跟踪:

  • HttpRuntime.ProcessRequest...(多种方法)
  • new HttpContext(wr, false)
  • this.Init(new HttpRequest(wr, this), new HttpResponse(wr, this));
  • if (!string.IsNullOrEmpty(eurl))(我们可以阻止输入if吗?)
  • this.Request.InternalRewritePath(VirtualPath.Create(virtualPath), null, true);
  • VirtualPath Create(string virtualPath)
  • unsafe static VirtualPath Create(string virtualPath, VirtualPathOptions options)

这最后(不安全)方法正在对路径做些什么。首先,每个角色都有一个循环。如果字符在'以下,则与' /'不同。等于' \',然后flag = true。在循环后,if (flag)src),然后可能会抛出异常,并virtualPath = UrlPath.FixVirtualPathSlashes(virtualPath);src)。

现在似乎没有什么可以帮助我们避免去那里(也许是欧元的东西?)。

string FixVirtualPathSlashes(string virtualPath)src)将反斜杠替换为斜杠,如果删除重复的斜杠。羞。

GetEurl方法怎么样?当您阅读src时,您会发现这对您没有帮助。

结论

http运行时正在杀死反斜杠,原因没有记录。您无法禁用此行为。

解决方法#1

现在,必须有办法。 This guy引用this page有一种解决方法。似乎使用重写模块,您可以将原始URL放回管道中。我不太喜欢这个解决方案,因为我不知道究竟发生了什么。我有另一个想法......

我还没有测试过这个东西。你能吗?

搜索变通方法#2(未找到)

如果存在原始请求路径的位置怎么办?

搜索HttpRequest时,Url.OriginalStringRawUrlPathServerVariables都不包含所需的值。甚至不是_filePath_path_queryStringText_rawUrl_rewrittenUrl_url私有字段。

搜索IIS7WorkerRequest,该值已在运行时更改。我怀疑IIS在将请求推送到ASP.NET运行时之前正在做之前的事情。看起来似乎没有希望。

答案 1 :(得分:0)

您是否尝试在发出请求之前将UrlEncode()应用于路径?