MCPcopy
hub / github.com/aws/aws-lambda-go / Wrap

Function Wrap

lambdaurl/http_handler.go:105–156  ·  view source on GitHub ↗

Wrap converts an http.Handler into a Lambda request handler. Only Lambda Function URLs configured with `InvokeMode: RESPONSE_STREAM` are supported with the returned handler. The response body of the handler will conform to the content-type `application/vnd.awslambda.http-integration-response`.

(handler http.Handler)

Source from the content-addressed store, hash-verified

103// Only Lambda Function URLs configured with `InvokeMode: RESPONSE_STREAM` are supported with the returned handler.
104// The response body of the handler will conform to the content-type `application/vnd.awslambda.http-integration-response`.
105func Wrap(handler http.Handler) func(context.Context, *events.LambdaFunctionURLRequest) (*events.LambdaFunctionURLStreamingResponse, error) {
106 return func(ctx context.Context, request *events.LambdaFunctionURLRequest) (*events.LambdaFunctionURLStreamingResponse, error) {
107
108 var body io.Reader = strings.NewReader(request.Body)
109 if request.IsBase64Encoded {
110 body = base64.NewDecoder(base64.StdEncoding, body)
111 }
112 url := "https://" + request.RequestContext.DomainName + request.RawPath
113 if request.RawQueryString != "" {
114 url += "?" + request.RawQueryString
115 }
116 ctx = context.WithValue(ctx, requestContextKey{}, request)
117 httpRequest, err := http.NewRequestWithContext(ctx, request.RequestContext.HTTP.Method, url, body)
118 if err != nil {
119 return nil, err
120 }
121 httpRequest.RemoteAddr = request.RequestContext.HTTP.SourceIP
122 for k, v := range request.Headers {
123 httpRequest.Header.Add(k, v)
124 }
125
126 ready := make(chan header) // Signals when it's OK to start returning the response body to Lambda
127 r, w := io.Pipe()
128 responseWriter := &httpResponseWriter{writer: w, ready: ready}
129 if detectContentType, ok := ctx.Value(detectContentTypeContextKey{}).(bool); ok {
130 responseWriter.detectContentType = detectContentType
131 }
132 go func() {
133 defer close(ready)
134 defer w.Close() // TODO: recover and CloseWithError the any panic value once the runtime API client supports plumbing fatal errors through the reader
135 //nolint:errcheck
136 defer responseWriter.Write(nil) // force default status, headers, content type detection, if none occurred during the execution of the handler
137 handler.ServeHTTP(responseWriter, httpRequest)
138 }()
139 header := <-ready
140 response := &events.LambdaFunctionURLStreamingResponse{
141 Body: r,
142 StatusCode: header.code,
143 }
144 if len(header.header) > 0 {
145 response.Headers = make(map[string]string, len(header.header))
146 for k, v := range header.header {
147 if k == "Set-Cookie" {
148 response.Cookies = v
149 } else {
150 response.Headers[k] = strings.Join(v, ",")
151 }
152 }
153 }
154 return response, nil
155 }
156}
157
158// Start wraps a http.Handler and calls lambda.StartHandlerFunc
159// Only supports:

Callers 3

StartFunction · 0.85
TestWrapFunction · 0.85
TestRequestContextFunction · 0.85

Calls 3

WriteMethod · 0.95
ValueMethod · 0.65
CloseMethod · 0.45

Tested by 2

TestWrapFunction · 0.68
TestRequestContextFunction · 0.68

Used in the wild real call sites across dependent graphs

searching dependent graphs…