(path string, r *http.Request, repl *caddy.Replacer)
| 305 | } |
| 306 | |
| 307 | func escapePathPlaceholders(path string, r *http.Request, repl *caddy.Replacer) string { |
| 308 | // Replace path-valued placeholders in escaped form before the URI is parsed, |
| 309 | // otherwise literal '?' and '%' bytes from the path can be interpreted as URI |
| 310 | // delimiters or percent-escape sequences during the rewrite. |
| 311 | pathPlaceholder := "{http.request.uri.path}" |
| 312 | if strings.Contains(path, pathPlaceholder) { |
| 313 | path = strings.ReplaceAll(path, pathPlaceholder, r.URL.EscapedPath()) |
| 314 | } |
| 315 | |
| 316 | fileMatchRelativePlaceholder := "{http.matchers.file.relative}" |
| 317 | if strings.Contains(path, fileMatchRelativePlaceholder) { |
| 318 | if val, ok := repl.Get("http.matchers.file.relative"); ok { |
| 319 | if relativePath, ok := val.(string); ok { |
| 320 | path = strings.ReplaceAll(path, fileMatchRelativePlaceholder, escapePathPreservingSlashes(relativePath)) |
| 321 | } |
| 322 | } |
| 323 | } |
| 324 | |
| 325 | return path |
| 326 | } |
| 327 | |
| 328 | func escapePathPreservingSlashes(path string) string { |
| 329 | return strings.ReplaceAll(url.PathEscape(path), "%2F", "/") |
no test coverage detected