path.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package processing
  2. import (
  3. "fmt"
  4. "net/http"
  5. "regexp"
  6. "strings"
  7. "github.com/imgproxy/imgproxy/v3/ierrors"
  8. )
  9. // fixPathRe is used in path re-denormalization
  10. var fixPathRe = regexp.MustCompile(`/plain/(\S+)\:/([^/])`)
  11. // splitPathSignature splits signature and path components from the request URI
  12. func splitPathSignature(r *http.Request, config *Config) (string, string, error) {
  13. uri := r.RequestURI
  14. // cut query params
  15. uri, _, _ = strings.Cut(uri, "?")
  16. // cut path prefix
  17. if len(config.PathPrefix) > 0 {
  18. uri = strings.TrimPrefix(uri, config.PathPrefix)
  19. }
  20. // cut leading slash
  21. uri = strings.TrimPrefix(uri, "/")
  22. signature, path, _ := strings.Cut(uri, "/")
  23. if len(signature) == 0 || len(path) == 0 {
  24. return "", "", ierrors.Wrap(
  25. newInvalidURLErrorf(http.StatusNotFound, "Invalid path: %s", path), 0,
  26. ierrors.WithCategory(categoryPathParsing),
  27. )
  28. }
  29. // restore broken slashes in the path
  30. path = redenormalizePath(path)
  31. return path, signature, nil
  32. }
  33. // redenormalizePath undoes path normalization done by some browsers and revers proxies
  34. func redenormalizePath(path string) string {
  35. for _, match := range fixPathRe.FindAllStringSubmatch(path, -1) {
  36. repl := fmt.Sprintf("/plain/%s://", match[1])
  37. if match[1] == "local" {
  38. repl += "/"
  39. }
  40. repl += match[2]
  41. path = strings.Replace(path, match[0], repl, 1)
  42. }
  43. return path
  44. }