使用url编码的斜杠获取URL

Ras*_*ber 35 .net c# base64 http url-encoding

我想发送一个HTTP GET http://example.com/%2F.我的第一个猜测是这样的:

using (WebClient webClient = new WebClient())
{
  webClient.DownloadData("http://example.com/%2F");
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,我可以看到实际上在线上发送的是:

GET // HTTP/1.1
Host: example.com
Connection: Keep-Alive
Run Code Online (Sandbox Code Playgroud)

因此http://example.com/%2F在传输之前会被翻译成http://example.com //.

有没有办法实际发送此GET请求?

当使用OCSP over HTTP/GET时,OCSP协议要求发送base-64编码的url编码,因此必须发送实际的%2F而不是'/'才能兼容.

编辑:

以下是OCSP协议标准(RFC 2560附录A.1.1)的相关部分:

使用GET方法的OCSP请求构造如下:

GET {url}/{对OCSPRequest的DER编码的base-64编码的url编码}

我对其他读物非常开放,但我看不出还有什么意思.

Ras*_*ber 48

这是一个可怕的黑客,必然与框架的未来版本等不兼容.

但它的确有效!

(在我的机器上......)

Uri uri = new Uri("http://example.com/%2F");
ForceCanonicalPathAndQuery(uri);
using (WebClient webClient = new WebClient())
{
  webClient.DownloadData(uri);
}

void ForceCanonicalPathAndQuery(Uri uri){
  string paq = uri.PathAndQuery; // need to access PathAndQuery
  FieldInfo flagsFieldInfo = typeof(Uri).GetField("m_Flags", BindingFlags.Instance | BindingFlags.NonPublic);
  ulong flags = (ulong) flagsFieldInfo.GetValue(uri);
  flags &= ~((ulong) 0x30); // Flags.PathNotCanonical|Flags.QueryNotCanonical
  flagsFieldInfo.SetValue(uri, flags);
}
Run Code Online (Sandbox Code Playgroud)

  • 对于阿特伍德的爱,这个答案为我节省了几个小时。谢谢! (2认同)

Bra*_*ger 27

默认情况下,Uri该类不允许URI中的转义/字符(%2f)(尽管在我阅读RFC 3986时这似乎是合法的).

Uri uri = new Uri("http://example.com/%2F");
Console.WriteLine(uri.AbsoluteUri); // prints: http://example.com//
Run Code Online (Sandbox Code Playgroud)

(注意:不要使用Uri.ToString来打印URI.)

根据Microsoft Connect上此问题错误报告,此行为是设计使然,但您可以通过将以下内容添加到app.config或web.config文件来解决此问题:

<uri>
  <schemeSettings>
    <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
  </schemeSettings>
</uri>
Run Code Online (Sandbox Code Playgroud)

(转自/sf/answers/729083771/,因为这是避免此错误而不使用反射来修改私有字段的"官方"方法.)

编辑: Connect错误报告不再可见,但文档<schemeSettings>推荐此方法以允许/URI中的转义字符.请注意(根据该文章),对于未正确处理转义斜杠的组件可能存在安全隐患.

  • 如果您要调用的URL是HTTPS,请确保使用name =“ https”。 (2认同)

Gle*_*ock 13

更新:看起来Uri类的默认行为实际上已在.NET 4.5中更改,现在您可以使用转义斜杠,它们将不会被触及.

我在.NET 3.5,.NET 4.0,.NET 4.5/4.5.1中运行以下代码

static void Main(string[] args)
{
    var uri = new Uri("http://www.yahooo.com/%2F");
    var client = new WebClient();
    client.DownloadString(uri);
}
Run Code Online (Sandbox Code Playgroud)

在.NET 3.5/4.0中,跟踪显示%2F实际上未按预期转义.

提琴手痕迹

但是,在.NET 4.5/4.5.1中,您可以看到%2F未转义(请注意GET /%2F)

提琴手痕迹

你甚至可以在Uri上使用ToString(),你会得到相同的结果.

总而言之,如果您使用的是.NET> = .NET 4.5,那么事情的行为就像它们应该与RFC一致.

我刚刚尝试了尝试在Mono上使用相同的方法.我在这里的方法上发布了我的问题:在单声道上获取带有逃逸斜线的Uri