Uri 规范化压缩 FTP 方案

Uri canonicalization compacting FTP scheme

https://msdn.microsoft.com/en-us/library/system.uri(v=vs.110).aspx

根据上面的参考,当指定 ftp url 时,uri class 不应压缩 url。比如下面的ftpurl:

Uri uri = new Uri("ftp://myUrl/%2E%2E/%2E%2E");
Console.WriteLine(uri.AbsoluteUri);
Console.WriteLine(uri.PathAndQuery);

应该导致:

AbsoluteUri: "ftp://myUrl/%2E%2E/%2E%2E"

路径和查询:“/%2E%2E/%2E%2E

但是,这不是我所看到的。当我使用 .NET Framework 4.5.1 执行上述代码时,我看到:

AbsoluteUri:“ftp://myUrl/

路径和查询:“/

另外,加到我的app.config好像没有效果:

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

由于几个人已经能够重现该问题,我已经与 Microsoft 一起创建了一个错误报告。欢迎投票:

https://connect.microsoft.com/VisualStudio/feedback/details/2046491/uri-canonicalization-compacting-ftp-scheme

与 Microsoft 一起创建了错误报告: https://connect.microsoft.com/VisualStudio/Feedback/Details/2046491

目前,我正在通过(通过反射进行黑客攻击)从 Uri class:

中的 UriParser 对象中删除两个标志来解决这个问题

我在应用程序实例化时调用了一次下面的方法。实例化后,每个 FTP Uri 对象将在解析时使用新的标志组合。

// CompressPath = 0x800000, // For an authority based Uri remove/compress /./ /../ in the path
// UnEscapeDotsAndSlashes = 0x2000000, // additionally unescape dots and slashes before doing path compression

/// <summary>
/// http://referencesource.microsoft.com/#System/net/System/_UriSyntax.cs
/// </summary>
public static void LeaveDotsAndSlashesEscaped() {
    Uri uri = new Uri("ftp://myUrl/%2E%2E/%2E%2E/");
    if (uri == null) {
        throw new ArgumentNullException("uri");
    }
    FieldInfo fieldInfo = uri.GetType().GetField("m_Syntax", BindingFlags.Instance | BindingFlags.NonPublic);
    if (fieldInfo == null) {
        throw new MissingFieldException("'m_Syntax' field not found");
    }
    object uriParser = fieldInfo.GetValue(uri);
    fieldInfo = typeof(UriParser).GetField("m_Flags", BindingFlags.Instance | BindingFlags.NonPublic);
    if (fieldInfo == null) {
        throw new MissingFieldException("'m_Flags' field not found");
    }
    object uriSyntaxFlags = fieldInfo.GetValue(uriParser);
    // Clear the flags that we don't want
    uriSyntaxFlags = (int)uriSyntaxFlags & ~0x2000000 & ~0x800000;
    fieldInfo.SetValue(uriParser, uriSyntaxFlags);
}