3
3
// See the LICENSE file in the project root for more information.
4
4
5
5
using DevProxy . Abstractions . Proxy ;
6
+ using DevProxy . Abstractions . Utils ;
6
7
using DevProxy . Plugins . Models ;
7
8
using DevProxy . Plugins . Utils ;
8
9
using Microsoft . Extensions . Logging ;
@@ -116,27 +117,26 @@ [.. operationsFromRequests
116
117
{
117
118
logger . LogDebug ( "Checking server URL {ServerUrl}..." , server . Url ) ;
118
119
119
- if ( ! requestUrl . StartsWith ( server . Url , StringComparison . OrdinalIgnoreCase ) )
120
+ if ( ! UrlMatchesServerUrl ( requestUrl , server . Url ) )
120
121
{
121
122
logger . LogDebug ( "Request URL {RequestUrl} does not match server URL {ServerUrl}" , requestUrl , server . Url ) ;
122
123
continue ;
123
124
}
124
125
125
- var serverUrl = new Uri ( server . Url ) ;
126
- var serverPath = serverUrl . AbsolutePath . TrimEnd ( '/' ) ;
127
126
var requestUri = new Uri ( requestUrl ) ;
128
- var urlPathFromRequest = requestUri . GetLeftPart ( UriPartial . Path ) . Replace ( server . Url . TrimEnd ( '/' ) , "" , StringComparison . OrdinalIgnoreCase ) ;
127
+ var absoluteUrlPathFromRequest = requestUri . GetLeftPart ( UriPartial . Path ) ;
129
128
130
129
foreach ( var path in openApiDocument . Paths )
131
130
{
132
131
var urlPathFromSpec = path . Key ;
133
- logger . LogDebug ( "Checking path {UrlPath}..." , urlPathFromSpec ) ;
132
+ var absolutePathFromSpec = server . Url . TrimEnd ( '/' ) + urlPathFromSpec ;
133
+ logger . LogDebug ( "Checking path {UrlPath}..." , absolutePathFromSpec ) ;
134
134
135
135
// check if path contains parameters. If it does,
136
136
// replace them with regex
137
- if ( urlPathFromSpec . Contains ( '{' , StringComparison . OrdinalIgnoreCase ) )
137
+ if ( absolutePathFromSpec . Contains ( '{' , StringComparison . OrdinalIgnoreCase ) )
138
138
{
139
- logger . LogDebug ( "Path {UrlPath} contains parameters and will be converted to Regex" , urlPathFromSpec ) ;
139
+ logger . LogDebug ( "Path {UrlPath} contains parameters and will be converted to Regex" , absolutePathFromSpec ) ;
140
140
141
141
// force replace all parameters with regex
142
142
// this is more robust than replacing parameters by name
@@ -147,24 +147,24 @@ [.. operationsFromRequests
147
147
// we also escape the path to make sure that regex special
148
148
// characters are not interpreted so that we won't fail
149
149
// on matching URLs that contain ()
150
- urlPathFromSpec = Regex . Replace ( Regex . Escape ( urlPathFromSpec ) , @"\\\{[^}]+\}" , $ "([^/]+)") ;
150
+ absolutePathFromSpec = Regex . Replace ( Regex . Escape ( absolutePathFromSpec ) , @"\\\{[^}]+\}" , $ "([^/]+)") ;
151
151
152
- logger . LogDebug ( "Converted path to Regex: {UrlPath}" , urlPathFromSpec ) ;
153
- var regex = new Regex ( $ "^{ urlPathFromSpec } $") ;
154
- if ( regex . IsMatch ( urlPathFromRequest ) )
152
+ logger . LogDebug ( "Converted path to Regex: {UrlPath}" , absolutePathFromSpec ) ;
153
+ var regex = new Regex ( $ "^{ absolutePathFromSpec } $") ;
154
+ if ( regex . IsMatch ( absoluteUrlPathFromRequest ) )
155
155
{
156
- logger . LogDebug ( "Regex matches {RequestUrl}" , urlPathFromRequest ) ;
156
+ logger . LogDebug ( "Regex matches {RequestUrl}" , absoluteUrlPathFromRequest ) ;
157
157
158
158
return path ;
159
159
}
160
160
161
- logger . LogDebug ( "Regex does not match {RequestUrl}" , urlPathFromRequest ) ;
161
+ logger . LogDebug ( "Regex does not match {RequestUrl}" , absoluteUrlPathFromRequest ) ;
162
162
}
163
163
else
164
164
{
165
- if ( urlPathFromRequest . Equals ( urlPathFromSpec , StringComparison . OrdinalIgnoreCase ) )
165
+ if ( absoluteUrlPathFromRequest . Equals ( absolutePathFromSpec , StringComparison . OrdinalIgnoreCase ) )
166
166
{
167
- logger . LogDebug ( "{RequestUrl} matches {UrlPath}" , requestUrl , urlPathFromSpec ) ;
167
+ logger . LogDebug ( "{RequestUrl} matches {UrlPath}" , requestUrl , absolutePathFromSpec ) ;
168
168
return path ;
169
169
}
170
170
@@ -216,4 +216,21 @@ public static OpenApiSecurityScheme[] GetOAuth2Schemes(this OpenApiDocument open
216
216
. Where ( s => s . Value . Type == SecuritySchemeType . OAuth2 )
217
217
. Select ( s => s . Value ) ] ;
218
218
}
219
+
220
+ private static bool UrlMatchesServerUrl ( string absoluteUrl , string serverUrl )
221
+ {
222
+ if ( absoluteUrl . StartsWith ( serverUrl , StringComparison . OrdinalIgnoreCase ) )
223
+ {
224
+ return true ;
225
+ }
226
+
227
+ // If serverUrl contains parameters, use regex to compare it
228
+ if ( ! serverUrl . Contains ( '{' , StringComparison . Ordinal ) )
229
+ {
230
+ return false ;
231
+ }
232
+
233
+ var serverUrlPattern = ProxyUtils . UrlWithParametersToRegex ( serverUrl ) ;
234
+ return Regex . IsMatch ( absoluteUrl , serverUrlPattern , RegexOptions . IgnoreCase ) ;
235
+ }
219
236
}
0 commit comments