/
GenericUriParser.cs
144 lines (116 loc) · 6.07 KB
/
GenericUriParser.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace System
{
//
// This enum specifies the public options used to customize a hierarchical built-in parser.
//
[Flags]
public enum GenericUriParserOptions
{
// A hierarchical URI, allows a userinfo, non empty Inet-based authority, path, query and fragment
// The URI path gets aggressively compressed means dots, slashes and backslashes are unescaped,
// backslashesare converted, and then it compresses the path. It also removes trailing dots,
// empty segments and dots-only segments
Default = 0x0,
// Allows a free style authority that would terminate with '/'
GenericAuthority = 0x1,
// Allows an empty authority foo:///
AllowEmptyAuthority = 0x2,
// Disables a user info component, it implied in the case of GenericAuthority flag
NoUserInfo = 0x4,
// Disables a port component, it is implied in the case of GenericAuthority flag
NoPort = 0x8,
// Disables a query. A ? char is considered as part of the path and is escaped
NoQuery = 0x10,
// Disables a fragment. A # char is considered as part of the path or query and is escaped
NoFragment = 0x20,
// if false then converta \ to /, otherwise does this conversion for the Path component.
DontConvertPathBackslashes = 0x40,
// if false, then a/./b or a/.../b becomes a/b and /a/../b becomes /b
DontCompressPath = 0x80,
// if false then a/%2e./b becomes a/../b and then usually compressed
DontUnescapePathDotsAndSlashes= 0x100,
// IDN hosts supported. if true then unicode hostname is converted to IDN host
// and vice versa
Idn = 0x200,
// Iri strict parsing flag. Makes sense for Unicode. If true then string is
// normalized, bidi control characters are removed, unicode char limits are checked
IriParsing = 0x400
}
public class GenericUriParser: UriParser
{
public GenericUriParser(GenericUriParserOptions options) : base(MapGenericParserOptions(options))
{
}
private static UriSyntaxFlags MapGenericParserOptions(GenericUriParserOptions options)
{
//
// Here we map public flags to internal ones
// Note an instacne of this parser is always a "simple parser" since the class is sealed.
//
UriSyntaxFlags flags = DefaultGenericUriParserFlags;
if ((options & GenericUriParserOptions.GenericAuthority) != 0)
{
// Disable some options that are not compatible with generic authority
flags &= ~(UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowAnInternetHost);
flags |= UriSyntaxFlags.AllowAnyOtherHost;
}
if ((options & GenericUriParserOptions.AllowEmptyAuthority) != 0)
{
flags |= UriSyntaxFlags.AllowEmptyHost;
}
if ((options & GenericUriParserOptions.NoUserInfo) != 0)
{
flags &= ~UriSyntaxFlags.MayHaveUserInfo;
}
if ((options & GenericUriParserOptions.NoPort) != 0)
{
flags &= ~UriSyntaxFlags.MayHavePort;
}
if ((options & GenericUriParserOptions.NoQuery) != 0)
{
flags &= ~UriSyntaxFlags.MayHaveQuery;
}
if ((options & GenericUriParserOptions.NoFragment) != 0)
{
flags &= ~UriSyntaxFlags.MayHaveFragment;
}
if ((options & GenericUriParserOptions.DontConvertPathBackslashes) != 0)
{
flags &= ~UriSyntaxFlags.ConvertPathSlashes;
}
if ((options & GenericUriParserOptions.DontCompressPath) != 0)
{
flags &= ~(UriSyntaxFlags.CompressPath | UriSyntaxFlags.CanonicalizeAsFilePath);
}
if ((options & GenericUriParserOptions.DontUnescapePathDotsAndSlashes) != 0)
{
flags &= ~UriSyntaxFlags.UnEscapeDotsAndSlashes;
}
if ((options & GenericUriParserOptions.Idn) != 0)
{
flags |= UriSyntaxFlags.AllowIdn;
}
if ((options & GenericUriParserOptions.IriParsing) != 0)
{
flags |= UriSyntaxFlags.AllowIriParsing;
}
return flags;
}
private const UriSyntaxFlags DefaultGenericUriParserFlags =
UriSyntaxFlags.MustHaveAuthority |
UriSyntaxFlags.MayHaveUserInfo |
UriSyntaxFlags.MayHavePort |
UriSyntaxFlags.MayHavePath |
UriSyntaxFlags.MayHaveQuery |
UriSyntaxFlags.MayHaveFragment |
UriSyntaxFlags.AllowUncHost |
UriSyntaxFlags.AllowAnInternetHost |
UriSyntaxFlags.PathIsRooted |
UriSyntaxFlags.ConvertPathSlashes |
UriSyntaxFlags.CompressPath |
UriSyntaxFlags.CanonicalizeAsFilePath |
UriSyntaxFlags.UnEscapeDotsAndSlashes;
}
}