@@ -25,7 +25,7 @@ internal CredentialCacheKey(Uri uriPrefix, string authenticationType)
25
25
AuthenticationType = authenticationType ;
26
26
}
27
27
28
- internal bool Match ( Uri uri , string authenticationType )
28
+ internal bool Match ( Uri uri , int prefixLen , string authenticationType )
29
29
{
30
30
if ( uri == null || authenticationType == null )
31
31
{
@@ -40,12 +40,12 @@ internal bool Match(Uri uri, string authenticationType)
40
40
41
41
if ( NetEventSource . Log . IsEnabled ( ) ) NetEventSource . Info ( this , $ "Match({ UriPrefix } & { uri } )") ;
42
42
43
- return IsPrefix ( uri , UriPrefix ) ;
43
+ return IsPrefix ( uri , prefixLen ) ;
44
44
}
45
45
46
46
// IsPrefix (Uri)
47
47
//
48
- // Determines whether <prefixUri > is a prefix of this URI. A prefix
48
+ // Determines whether <this > is a prefix of this URI. A prefix
49
49
// match is defined as:
50
50
//
51
51
// scheme match
@@ -55,23 +55,22 @@ internal bool Match(Uri uri, string authenticationType)
55
55
//
56
56
// Returns:
57
57
// True if <prefixUri> is a prefix of this URI
58
- private static bool IsPrefix ( Uri uri , Uri prefixUri )
58
+ private bool IsPrefix ( Uri uri , int prefixLen )
59
59
{
60
60
Debug . Assert ( uri != null ) ;
61
- Debug . Assert ( prefixUri != null ) ;
61
+ Uri uriPrefix = UriPrefix ;
62
62
63
- if ( prefixUri . Scheme != uri . Scheme || prefixUri . Host != uri . Host || prefixUri . Port != uri . Port )
63
+ if ( uriPrefix . Scheme != uri . Scheme || uriPrefix . Host != uri . Host || uriPrefix . Port != uri . Port )
64
64
{
65
65
return false ;
66
66
}
67
67
68
- int prefixLen = prefixUri . AbsolutePath . LastIndexOf ( '/' ) ;
69
- if ( prefixLen > uri . AbsolutePath . LastIndexOf ( '/' ) )
68
+ if ( UriPrefixLength > prefixLen )
70
69
{
71
70
return false ;
72
71
}
73
72
74
- return string . Compare ( uri . AbsolutePath , 0 , prefixUri . AbsolutePath , 0 , prefixLen , StringComparison . OrdinalIgnoreCase ) == 0 ;
73
+ return string . Compare ( uri . AbsolutePath , 0 , uriPrefix . AbsolutePath , 0 , UriPrefixLength , StringComparison . OrdinalIgnoreCase ) == 0 ;
75
74
}
76
75
77
76
public override int GetHashCode ( ) =>
@@ -108,21 +107,37 @@ public static bool TryGetCredential(Dictionary<CredentialCacheKey, NetworkCreden
108
107
mostSpecificMatch = null ;
109
108
mostSpecificMatchUri = null ;
110
109
111
- // Enumerate through every credential in the cache
110
+ if ( cache . Count == 0 )
111
+ {
112
+ return false ;
113
+ }
114
+
115
+ // precompute the length of the prefix
116
+ int uriPrefixLength = uriPrefix . AbsolutePath . LastIndexOf ( '/' ) ;
117
+
118
+ // Enumerate through every credential in the cache, get match with longest prefix
112
119
foreach ( ( CredentialCacheKey key , NetworkCredential value ) in cache )
113
120
{
121
+ int prefixLen = key . UriPrefixLength ;
122
+
123
+ if ( prefixLen <= longestMatchPrefix )
124
+ {
125
+ // this credential can't provide a longer prefix match
126
+ continue ;
127
+ }
128
+
114
129
// Determine if this credential is applicable to the current Uri/AuthType
115
- if ( key . Match ( uriPrefix , authType ) )
130
+ if ( key . Match ( uriPrefix , uriPrefixLength , authType ) )
116
131
{
117
- int prefixLen = key . UriPrefixLength ;
132
+ // update the information about currently preferred match
133
+ longestMatchPrefix = prefixLen ;
134
+ mostSpecificMatch = value ;
135
+ mostSpecificMatchUri = key . UriPrefix ;
118
136
119
- // Check if the match is better than the current-most-specific match
120
- if ( prefixLen > longestMatchPrefix )
137
+ if ( uriPrefixLength == prefixLen )
121
138
{
122
- // Yes: update the information about currently preferred match
123
- longestMatchPrefix = prefixLen ;
124
- mostSpecificMatch = value ;
125
- mostSpecificMatchUri = key . UriPrefix ;
139
+ // we can't get any better than this
140
+ break ;
126
141
}
127
142
}
128
143
}
0 commit comments