如何创建Uri实例分析与GenericUriParserOptions.DontCom pressPath [英] How to create a Uri instance parsed with GenericUriParserOptions.DontCompressPath

查看:209
本文介绍了如何创建Uri实例分析与GenericUriParserOptions.DontCom pressPath的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在.NET 的System.Uri 类解析字符串,它执行了一些规范化的输入,如低套管的方案和主机名。它还剪裁每个路段尾随句点。后者的特点是致命的OpenID的应用程序,因为一些的OpenID(像那些从雅虎发行)包括Base64 EN codeD路径段可以用一个句点结束。

如何禁用Uri类此期间修整行为?

注册使用 UriParser.Register GenericUriParserOptions.DontCom pressPath 初始化一个解析器避免自己的计划期间修剪,以及一些其他的操作,同时也是不希望的OpenID的。但我不能像HTTP和HTTPS现有的方案,这是我必须做的OpenID注册一个新的解析器。

我试着注册了自己的新方案,并编写自定义解析器来改变计划回标准的HTTP(S)方案作为分析的一部分,另一种方法:

 公共类MyUriParser:GenericUriParser
{
    私人字符串actualScheme;

    公共MyUriParser(字符串actualScheme)
        :基地(GenericUriParserOptions.DontCom pressPath)
    {
        this.actualScheme = actualScheme.ToLowerInvariant();
    }

    保护覆盖字符串GetComponents(URI URI,UriComponents组件,UriFormat格式)
    {
        字符串结果= base.GetComponents(URI,组件,格式);

        //替换我们实际需要的方案在字符串中,如果它在那里。
        如果((组件和放大器;!UriComponents.Scheme)= 0)
        {
            字符串registeredScheme = base.GetComponents(URI,UriComponents.Scheme,格式);
            结果= this.actualScheme + result.Substring(registeredScheme.Length);
        }

        返回结果;
    }
}

类节目
{
    静态无效的主要(字串[] args)
    {
        UriParser.Register(新MyUriParser(HTTP),httpx,80);
        UriParser.Register(新MyUriParser(https开头),httpsx,443);
        乌里Z =新的URI(httpsx://me.yahoo.com/b./c.#adf);
        VAR REQ =(HttpWebRequest的)WebRequest.Create(Z);
        req.GetResponse();
    }
}
 

这实际上的几乎的工作。该乌里实例报告HTTPS而不是httpsx无处不在 - 除了Uri.Scheme财产本身。这是一个问题,当你通过这个乌里实例给的HttpWebRequest 来发送一个请求到这个地址。显然,它会检查计划性,不承认它的https,因为它只是明文发送到443端口而不是SSL。

我很高兴的任何解决方案:

  1. preserves尾随路径段时期的 Uri.Path
  2. 在包括这一时间,传出HTTP请求。​​
  3. 在理想的情况下与工作在ASP.NET中等信任(但不是绝对必要的)。
解决方案

微软称,这将是固定在.NET 4.0中(虽然它似乎从它尚未确定的评论)

<一个href="https://connect.microsoft.com/VisualStudio/feedback/details/386695/system-uri-incorrectly-strips-trailing-dots?wa=wsignin1.0#tabs" rel="nofollow">https://connect.microsoft.com/VisualStudio/feedback/details/386695/system-uri-incorrectly-strips-trailing-dots?wa=wsignin1.0#tabs

然而,有是页面上的解决方法。它涉及到使用反射来,虽然改变的选项,所以它可能无法满足中等信任要求。只需滚动至底部,然后单击解决方法选项卡上。

由于jxdavis和谷歌对于这样的回答:

<一个href="http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/5206beca-071f-485d-a2bd-657d635239c9" rel="nofollow">http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/5206beca-071f-485d-a2bd-657d635239c9

When the .NET System.Uri class parses strings it performs some normalization on the input, such as lower-casing the scheme and hostname. It also trims trailing periods from each path segment. This latter feature is fatal to OpenID applications because some OpenIDs (like those issued from Yahoo) include base64 encoded path segments which may end with a period.

How can I disable this period-trimming behavior of the Uri class?

Registering my own scheme using UriParser.Register with a parser initialized with GenericUriParserOptions.DontCompressPath avoids the period trimming, and some other operations that are also undesirable for OpenID. But I cannot register a new parser for existing schemes like HTTP and HTTPS, which I must do for OpenIDs.

Another approach I tried was registering my own new scheme, and programming the custom parser to change the scheme back to the standard HTTP(s) schemes as part of parsing:

public class MyUriParser : GenericUriParser
{
    private string actualScheme;

    public MyUriParser(string actualScheme)
        : base(GenericUriParserOptions.DontCompressPath)
    {
        this.actualScheme = actualScheme.ToLowerInvariant();
    }

    protected override string GetComponents(Uri uri, UriComponents components, UriFormat format)
    {
        string result = base.GetComponents(uri, components, format);

        // Substitute our actual desired scheme in the string if it's in there.
        if ((components & UriComponents.Scheme) != 0)
        {
            string registeredScheme = base.GetComponents(uri, UriComponents.Scheme, format);
            result = this.actualScheme + result.Substring(registeredScheme.Length);
        }

        return result;
    }
}

class Program
{
    static void Main(string[] args)
    {
        UriParser.Register(new MyUriParser("http"), "httpx", 80);
        UriParser.Register(new MyUriParser("https"), "httpsx", 443);
        Uri z = new Uri("httpsx://me.yahoo.com/b./c.#adf");
        var req = (HttpWebRequest)WebRequest.Create(z);
        req.GetResponse();
    }
}

This actually almost works. The Uri instance reports https instead of httpsx everywhere -- except the Uri.Scheme property itself. That's a problem when you pass this Uri instance to the HttpWebRequest to send a request to this address. Apparently it checks the Scheme property and doesn't recognize it as 'https' because it just sends plaintext to the 443 port instead of SSL.

I'm happy for any solution that:

  1. Preserves trailing periods in path segments in Uri.Path
  2. Includes these periods in outgoing HTTP requests.
  3. Ideally works with under ASP.NET medium trust (but not absolutely necessary).

解决方案

Microsoft says it will be fixed in .NET 4.0 (though it appears from the comments that it has not been fixed yet)

https://connect.microsoft.com/VisualStudio/feedback/details/386695/system-uri-incorrectly-strips-trailing-dots?wa=wsignin1.0#tabs

There is a workaround on that page, however. It involves using reflection to change the options though, so it may not meet the medium trust requirement. Just scroll to the bottom and click on the "Workarounds" tab.

Thanks to jxdavis and Google for this answer:

http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/5206beca-071f-485d-a2bd-657d635239c9

这篇关于如何创建Uri实例分析与GenericUriParserOptions.DontCom pressPath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆