RedenormalizePath undoes path normalization done by some browsers and revers proxies. Also trims leading slash if it is present.
(path string)
| 40 | // RedenormalizePath undoes path normalization done by some browsers and revers proxies. |
| 41 | // Also trims leading slash if it is present. |
| 42 | func RedenormalizePath(path string) string { |
| 43 | // Split path into options and plain URL parts |
| 44 | var ( |
| 45 | options, plainURL string |
| 46 | hasPlain bool |
| 47 | ) |
| 48 | if strings.HasPrefix(path, "plain/") { |
| 49 | // If the path starts with `plain/`, it means that there are no options |
| 50 | // and the entire path is a plain URL |
| 51 | options = "" |
| 52 | plainURL = path[6:] |
| 53 | hasPlain = true |
| 54 | } else { |
| 55 | options, plainURL, hasPlain = strings.Cut(path, "/plain/") |
| 56 | } |
| 57 | |
| 58 | // Some proxies/CDNs may encode `:` in options as `%3A`, so we need to unescape it first |
| 59 | path = strings.ReplaceAll(options, "%3A", ":") |
| 60 | |
| 61 | if !hasPlain { |
| 62 | return strings.TrimPrefix(path, "/") |
| 63 | } |
| 64 | |
| 65 | // Some proxies/CDNs may "normalize" URLs by replacing `scheme://` with `scheme:/` |
| 66 | // in the plain URL part, so we need to fix it back. |
| 67 | if match := fixPathRe.FindStringSubmatch(plainURL); match != nil { |
| 68 | repl := fmt.Sprintf("%s://", match[1]) |
| 69 | if match[1] == "local" { |
| 70 | repl += "/" |
| 71 | } |
| 72 | repl += match[2] |
| 73 | plainURL = strings.Replace(plainURL, match[0], repl, 1) |
| 74 | } |
| 75 | |
| 76 | return strings.TrimPrefix(path+"/plain/"+plainURL, "/") |
| 77 | } |
no outgoing calls