123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- package proxy
- import (
- "net/http"
- "net/http/httputil"
- "net/url"
- "nginx-ui/server/models"
- "strings"
- )
- type HttpProxy struct {
- *httputil.ReverseProxy
- data *Data
- }
- func NewSingleHostReverseProxy(target *url.URL, data *models.ProxyEntity) *HttpProxy {
- director := func(req *http.Request) {
- rewriteRequestURL(req, target, data)
- }
- return &HttpProxy{
- ReverseProxy: &httputil.ReverseProxy{Director: director},
- }
- }
- func rewriteRequestURL(req *http.Request, target *url.URL, data *models.ProxyEntity) {
- targetQuery := target.RawQuery
- req.URL.Scheme = target.Scheme
- req.URL.Host = target.Host
- req.URL.Path, req.URL.RawPath = joinURLPath(target, req.URL)
- if data.StripPrefix != "" {
- req.URL.Path = strings.TrimPrefix(req.URL.Path, data.StripPrefix)
- req.URL.RawPath = strings.TrimPrefix(req.URL.RawPath, data.StripPrefix)
- }
- if targetQuery == "" || req.URL.RawQuery == "" {
- req.URL.RawQuery = targetQuery + req.URL.RawQuery
- } else {
- req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
- }
- }
- func joinURLPath(a, b *url.URL) (path, rawpath string) {
- if a.RawPath == "" && b.RawPath == "" {
- return singleJoiningSlash(a.Path, b.Path), ""
- }
- // Same as singleJoiningSlash, but uses EscapedPath to determine
- // whether a slash should be added
- apath := a.EscapedPath()
- bpath := b.EscapedPath()
- aslash := strings.HasSuffix(apath, "/")
- bslash := strings.HasPrefix(bpath, "/")
- switch {
- case aslash && bslash:
- return a.Path + b.Path[1:], apath + bpath[1:]
- case !aslash && !bslash:
- return a.Path + "/" + b.Path, apath + "/" + bpath
- }
- return a.Path + b.Path, apath + bpath
- }
- func singleJoiningSlash(a, b string) string {
- aslash := strings.HasSuffix(a, "/")
- bslash := strings.HasPrefix(b, "/")
- switch {
- case aslash && bslash:
- return a + b[1:]
- case !aslash && !bslash:
- return a + "/" + b
- }
- return a + b
- }
|