github.com/avenga/couper@v1.12.2/handler/producer/url.go (about) 1 package producer 2 3 import ( 4 "fmt" 5 "net/http" 6 "net/url" 7 "strings" 8 9 "github.com/hashicorp/hcl/v2" 10 "github.com/hashicorp/hcl/v2/hclsyntax" 11 "github.com/zclconf/go-cty/cty" 12 13 "github.com/avenga/couper/config/request" 14 "github.com/avenga/couper/eval" 15 "github.com/avenga/couper/utils" 16 ) 17 18 func NewURLFromAttribute(hclCtx *hcl.EvalContext, content *hclsyntax.Body, attrName string, req *http.Request) (*url.URL, error) { 19 urlVal, err := eval.ValueFromBodyAttribute(hclCtx, content, attrName) 20 if err != nil { 21 return nil, err 22 } 23 24 if urlVal.Type() == cty.NilType { // not set 25 return req.URL, nil 26 } 27 28 if urlVal.Type() != cty.String { 29 return nil, fmt.Errorf("url %q: not a string", attrName) 30 } 31 32 urlStr := urlVal.AsString() 33 if urlStr == "" { // no attr 34 return req.URL, nil 35 } 36 37 u, err := url.ParseRequestURI(urlStr) // method forces abs path 38 if err != nil { 39 return nil, err 40 } 41 42 pathMatch, wildcardEP := req.Context().Value(request.Wildcard).(string) 43 44 path := u.Path 45 46 if wildcardEP { 47 if strings.HasSuffix(u.Path, "/**") { 48 if strings.HasSuffix(req.URL.Path, "/") && !strings.HasSuffix(pathMatch, "/") { 49 pathMatch += "/" 50 } 51 52 path = utils.JoinPath("/", strings.ReplaceAll(u.Path, "/**", "/"), pathMatch) 53 } 54 } 55 56 u.Path = path 57 return u, nil 58 } 59 60 // removeHost prevents client-request host to leak into backend structure. 61 func removeHost(outreq *http.Request) { 62 outreq.Host = "" 63 outreq.URL.Host = "" 64 }