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  }