github.com/avenga/couper@v1.12.2/handler/producer/proxy.go (about) 1 package producer 2 3 import ( 4 "context" 5 "net/http" 6 7 "github.com/hashicorp/hcl/v2/hclsyntax" 8 "go.opentelemetry.io/otel/trace" 9 10 "github.com/avenga/couper/config/request" 11 "github.com/avenga/couper/eval" 12 "github.com/avenga/couper/telemetry" 13 ) 14 15 type Proxy struct { 16 Content *hclsyntax.Body 17 Name string // label 18 dependsOn string 19 RoundTrip http.RoundTripper 20 } 21 22 func (p *Proxy) Produce(clientReq *http.Request) *Result { 23 ctx := clientReq.Context() 24 var rootSpan trace.Span 25 ctx, rootSpan = telemetry.NewSpanFromContext(ctx, "proxies", trace.WithSpanKind(trace.SpanKindProducer)) 26 27 outCtx := withRoundTripName(ctx, p.Name) 28 outCtx = context.WithValue(outCtx, request.RoundTripProxy, true) 29 if p.dependsOn != "" { 30 outCtx = context.WithValue(outCtx, request.EndpointSequenceDependsOn, p.dependsOn) 31 } 32 33 // span end by result reader 34 outCtx, _ = telemetry.NewSpanFromContext(outCtx, p.Name, trace.WithSpanKind(trace.SpanKindServer)) 35 36 // since proxy and backend may work on the "same" outReq this must be cloned. 37 outReq := clientReq.Clone(outCtx) 38 removeHost(outReq) 39 40 hclCtx := eval.ContextFromRequest(clientReq).HCLContext() 41 url, err := NewURLFromAttribute(hclCtx, p.Content, "url", outReq) 42 if err != nil { 43 return &Result{Err: err} 44 } 45 46 // proxy should pass query if not redefined with url attribute 47 if outReq.URL.RawQuery != "" && url.RawQuery == "" { 48 url.RawQuery = outReq.URL.RawQuery 49 } 50 51 outReq.URL = url 52 53 result := roundtrip(p.RoundTrip, outReq) 54 55 rootSpan.End() 56 return result 57 } 58 59 func (p *Proxy) SetDependsOn(ps string) { 60 p.dependsOn = ps 61 }