github.com/avenga/couper@v1.12.2/handler/producer/response.go (about)

     1  package producer
     2  
     3  import (
     4  	"io"
     5  	"net/http"
     6  	"strings"
     7  
     8  	"github.com/hashicorp/hcl/v2/hclsyntax"
     9  
    10  	"github.com/avenga/couper/errors"
    11  	"github.com/avenga/couper/eval"
    12  	"github.com/avenga/couper/internal/seetie"
    13  )
    14  
    15  // Response represents the producer <Response> object.
    16  type Response struct {
    17  	Context *hclsyntax.Body
    18  }
    19  
    20  func NewResponse(req *http.Request, resp *hclsyntax.Body, statusCode int) (*http.Response, error) {
    21  	clientres := &http.Response{
    22  		Header:     make(http.Header),
    23  		Proto:      req.Proto,
    24  		ProtoMajor: req.ProtoMajor,
    25  		ProtoMinor: req.ProtoMinor,
    26  		Request:    req,
    27  	}
    28  
    29  	hclCtx := eval.ContextFromRequest(req).HCLContextSync()
    30  
    31  	if attr, ok := resp.Attributes["status"]; ok {
    32  		val, err := eval.Value(hclCtx, attr.Expr)
    33  		if err != nil {
    34  			return nil, err
    35  		} else if statusValue := int(seetie.ValueToInt(val)); statusValue > 0 {
    36  			statusCode = statusValue
    37  		}
    38  	}
    39  	clientres.StatusCode = statusCode
    40  	clientres.Status = http.StatusText(clientres.StatusCode)
    41  
    42  	respBody, ct, bodyErr := eval.GetBody(hclCtx, resp)
    43  	if bodyErr != nil {
    44  		return nil, errors.Evaluation.With(bodyErr)
    45  	}
    46  
    47  	if ct != "" {
    48  		clientres.Header.Set("Content-Type", ct)
    49  	}
    50  
    51  	if attr, ok := resp.Attributes["headers"]; ok {
    52  		val, err := eval.Value(hclCtx, attr.Expr)
    53  		if err != nil {
    54  			return nil, err
    55  		}
    56  
    57  		eval.SetHeader(val, clientres.Header)
    58  	}
    59  
    60  	if respBody != "" {
    61  		r := strings.NewReader(respBody)
    62  		clientres.Body = io.NopCloser(r)
    63  	}
    64  
    65  	return clientres, nil
    66  }