utils.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package dpcore
  2. import (
  3. "net/url"
  4. "strings"
  5. )
  6. // replaceLocationHost rewrite the backend server's location header to a new URL based on the given proxy rules
  7. // If you have issues with tailing slash, you can try to fix them here (and remember to PR :D )
  8. func replaceLocationHost(urlString string, rrr *ResponseRewriteRuleSet, useTLS bool) (string, error) {
  9. u, err := url.Parse(urlString)
  10. if err != nil {
  11. return "", err
  12. }
  13. //Update the schemetic if the proxying target is http
  14. //but exposed as https to the internet via Zoraxy
  15. if useTLS {
  16. u.Scheme = "https"
  17. } else {
  18. u.Scheme = "http"
  19. }
  20. //Issue #39: Check if it is location target match the proxying domain
  21. //E.g. Proxy config: blog.example.com -> example.com/blog
  22. //Check if it is actually redirecting to example.com instead of a new domain
  23. //like news.example.com.
  24. if rrr.ProxyDomain != u.Host {
  25. //New location domain not matching proxy target domain.
  26. //Do not modify location header
  27. return urlString, nil
  28. }
  29. u.Host = rrr.OriginalHost
  30. if strings.Contains(rrr.ProxyDomain, "/") {
  31. //The proxy domain itself seems contain subpath.
  32. //Trim it off from Location header to prevent URL segment duplicate
  33. //E.g. Proxy config: blog.example.com -> example.com/blog
  34. //Location Header: /blog/post?id=1
  35. //Expected Location Header send to client:
  36. // blog.example.com/post?id=1 instead of blog.example.com/blog/post?id=1
  37. ProxyDomainURL := "http://" + rrr.ProxyDomain
  38. if rrr.UseTLS {
  39. ProxyDomainURL = "https://" + rrr.ProxyDomain
  40. }
  41. ru, err := url.Parse(ProxyDomainURL)
  42. if err == nil {
  43. //Trim off the subpath
  44. u.Path = strings.TrimPrefix(u.Path, ru.Path)
  45. }
  46. }
  47. return u.String(), nil
  48. }
  49. // Debug functions
  50. func ReplaceLocationHost(urlString string, rrr *ResponseRewriteRuleSet, useTLS bool) (string, error) {
  51. return replaceLocationHost(urlString, rrr, useTLS)
  52. }