33// See the LICENSE file in the project root for more information.
44
55using DevProxy . Abstractions . Proxy ;
6+ using DevProxy . Abstractions . Utils ;
67using DevProxy . Plugins . Models ;
78using DevProxy . Plugins . Utils ;
89using Microsoft . Extensions . Logging ;
@@ -116,27 +117,26 @@ [.. operationsFromRequests
116117 {
117118 logger . LogDebug ( "Checking server URL {ServerUrl}..." , server . Url ) ;
118119
119- if ( ! requestUrl . StartsWith ( server . Url , StringComparison . OrdinalIgnoreCase ) )
120+ if ( ! UrlMatchesServerUrl ( requestUrl , server . Url ) )
120121 {
121122 logger . LogDebug ( "Request URL {RequestUrl} does not match server URL {ServerUrl}" , requestUrl , server . Url ) ;
122123 continue ;
123124 }
124125
125- var serverUrl = new Uri ( server . Url ) ;
126- var serverPath = serverUrl . AbsolutePath . TrimEnd ( '/' ) ;
127126 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 ) ;
129128
130129 foreach ( var path in openApiDocument . Paths )
131130 {
132131 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 ) ;
134134
135135 // check if path contains parameters. If it does,
136136 // replace them with regex
137- if ( urlPathFromSpec . Contains ( '{' , StringComparison . OrdinalIgnoreCase ) )
137+ if ( absolutePathFromSpec . Contains ( '{' , StringComparison . OrdinalIgnoreCase ) )
138138 {
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 ) ;
140140
141141 // force replace all parameters with regex
142142 // this is more robust than replacing parameters by name
@@ -147,24 +147,24 @@ [.. operationsFromRequests
147147 // we also escape the path to make sure that regex special
148148 // characters are not interpreted so that we won't fail
149149 // on matching URLs that contain ()
150- urlPathFromSpec = Regex . Replace ( Regex . Escape ( urlPathFromSpec ) , @"\\\{[^}]+\}" , $ "([^/]+)") ;
150+ absolutePathFromSpec = Regex . Replace ( Regex . Escape ( absolutePathFromSpec ) , @"\\\{[^}]+\}" , $ "([^/]+)") ;
151151
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 ) )
155155 {
156- logger . LogDebug ( "Regex matches {RequestUrl}" , urlPathFromRequest ) ;
156+ logger . LogDebug ( "Regex matches {RequestUrl}" , absoluteUrlPathFromRequest ) ;
157157
158158 return path ;
159159 }
160160
161- logger . LogDebug ( "Regex does not match {RequestUrl}" , urlPathFromRequest ) ;
161+ logger . LogDebug ( "Regex does not match {RequestUrl}" , absoluteUrlPathFromRequest ) ;
162162 }
163163 else
164164 {
165- if ( urlPathFromRequest . Equals ( urlPathFromSpec , StringComparison . OrdinalIgnoreCase ) )
165+ if ( absoluteUrlPathFromRequest . Equals ( absolutePathFromSpec , StringComparison . OrdinalIgnoreCase ) )
166166 {
167- logger . LogDebug ( "{RequestUrl} matches {UrlPath}" , requestUrl , urlPathFromSpec ) ;
167+ logger . LogDebug ( "{RequestUrl} matches {UrlPath}" , requestUrl , absolutePathFromSpec ) ;
168168 return path ;
169169 }
170170
@@ -216,4 +216,21 @@ public static OpenApiSecurityScheme[] GetOAuth2Schemes(this OpenApiDocument open
216216 . Where ( s => s . Value . Type == SecuritySchemeType . OAuth2 )
217217 . Select ( s => s . Value ) ] ;
218218 }
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+ }
219236}
0 commit comments