使用url编码的斜杠获取URL

时间:2009-04-23 10:51:47

标签: c# .net http base64 url-encoding

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

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

不幸的是,我可以看到实际发送的内容是:

GET // HTTP/1.1
Host: example.com
Connection: Keep-Alive

所以http://example.com/%2F在传输之前会被转换为http://example.com//

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

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

修改

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

  

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

     
    

获取{url} / {OCSPRequest的DER编码的base-64编码的url-encoding}

  

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

5 个答案:

答案 0 :(得分:46)

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

但它有效!

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

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);
}

答案 1 :(得分:25)

默认情况下,Uri课程不允许在URI中使用转义的/字符(%2f)(尽管在我阅读{{3}时这似乎是合法的})。

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

(注意:RFC 3986打印URI。)

根据Microsoft Connect上的don't use Uri.ToString,此行为是设计使然,但您可以通过将以下内容添加到app.config或web.config文件来解决此问题:

<uri>
  <schemeSettings>
    <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
  </schemeSettings>
</uri>

(转自bug report for this issue,因为这是避免此错误而不使用反射来修改私有字段的“官方”方法。)

修改:Connect错误报告不再可见,但https://stackoverflow.com/a/10415482建议采用此方法在URI中允许转义/个字符。请注意(根据该文章),对于未正确处理转义斜杠的组件可能存在安全隐患。

答案 2 :(得分:11)

对此进行更新:看起来Uri类的默认行为实际上是.NET 4.5中的changed,现在您可以使用转义斜杠并且不会触及它们。

我在.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);
}

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

Fiddler trace

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

Fiddler trace

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

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

我刚刚尝试了尝试在Mono上使用相同的方法。我在这里发布了关于方法的问题:Getting a Uri with escaped slashes on mono

答案 3 :(得分:0)

正如我对Ramus发布的答案的评论中所提到的那样,.Net Standard(可能还有.Net Framework的更高版本)需要以下各项才能使此hack正常工作:

<Grid
columns={["auto", "medium"]}
rows={["small", "auto"]}
gap="small"
areas={[
{ name: "navbar", start: [1, 0], end: [1, 0] },
{ name: "main", start: [0, 1], end: [0, 1] }
]}
>
<NavbarTop gridArea="navbar" handler={this.changeState} />
<Box
gridArea="main"

答案 4 :(得分:-7)

对其进行双重编码:%252F

但是,如果您使用HttpWebRequest,您实际上可以告诉不要对URL进行编码,无论它应该如何工作。

此外,如果WebClient接受URI,那么您可以创建一个新URI,并将其设置为不编码。