composeRedirectURL resolves a redirect target relative to the current request URL while rejecting suspicious payloads (e.g. control characters) and restricting schemes to HTTP/S so caller-provided Location headers cannot trigger arbitrary transports.
(base string, location []byte, disablePathNormalizing bool)
| 352 | // restricting schemes to HTTP/S so caller-provided Location headers cannot |
| 353 | // trigger arbitrary transports. |
| 354 | func composeRedirectURL(base string, location []byte, disablePathNormalizing bool) (string, error) { |
| 355 | for _, b := range location { |
| 356 | if b < 0x20 || b == 0x7f { |
| 357 | return "", fasthttp.ErrorInvalidURI |
| 358 | } |
| 359 | } |
| 360 | |
| 361 | uri := fasthttp.AcquireURI() |
| 362 | defer fasthttp.ReleaseURI(uri) |
| 363 | |
| 364 | uri.Update(base) |
| 365 | uri.UpdateBytes(location) |
| 366 | uri.DisablePathNormalizing = disablePathNormalizing |
| 367 | |
| 368 | if scheme := uri.Scheme(); len(scheme) > 0 && !bytes.EqualFold(scheme, httpScheme) && !bytes.EqualFold(scheme, httpsScheme) { |
| 369 | return "", fasthttp.ErrorInvalidURI |
| 370 | } |
| 371 | |
| 372 | if len(uri.Scheme()) > 0 && len(uri.Host()) == 0 { |
| 373 | return "", fasthttp.ErrorInvalidURI |
| 374 | } |
| 375 | |
| 376 | return uri.String(), nil |
| 377 | } |
no test coverage detected