Skip to content

Commit

Permalink
Add Lambda Function URL HTTP request and response types (#436)
Browse files Browse the repository at this point in the history
* Add Lambda Function URL HTTP request and response types

* naming update, remove fields documented to always be

* update testdata

* updated testdata
  • Loading branch information
bmoffatt committed Apr 13, 2022
1 parent bc1ec47 commit 138d021
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 0 deletions.
61 changes: 61 additions & 0 deletions events/lambda_function_urls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.

package events

// LambdaFunctionURLRequest contains data coming from the HTTP request to a Lambda Function URL.
type LambdaFunctionURLRequest struct {
Version string `json:"version"` // Version is expected to be `"2.0"`
RawPath string `json:"rawPath"`
RawQueryString string `json:"rawQueryString"`
Cookies []string `json:"cookies,omitempty"`
Headers map[string]string `json:"headers"`
QueryStringParameters map[string]string `json:"queryStringParameters,omitempty"`
RequestContext LambdaFunctionURLRequestContext `json:"requestContext"`
Body string `json:"body,omitempty"`
IsBase64Encoded bool `json:"isBase64Encoded"`
}

// LambdaFunctionURLRequestContext contains the information to identify the AWS account and resources invoking the Lambda function.
type LambdaFunctionURLRequestContext struct {
AccountID string `json:"accountId"`
RequestID string `json:"requestId"`
Authorizer *LambdaFunctionURLRequestContextAuthorizerDescription `json:"authorizer,omitempty"`
APIID string `json:"apiId"` // APIID is the Lambda URL ID
DomainName string `json:"domainName"` // DomainName is of the format `"<url-id>.lambda-url.<region>.on.aws"`
DomainPrefix string `json:"domainPrefix"` // DomainPrefix is the Lambda URL ID
Time string `json:"time"`
TimeEpoch int64 `json:"timeEpoch"`
HTTP LambdaFunctionURLRequestContextHTTPDescription `json:"http"`
}

// LambdaFunctionURLRequestContextAuthorizerDescription contains authorizer information for the request context.
type LambdaFunctionURLRequestContextAuthorizerDescription struct {
IAM *LambdaFunctionURLRequestContextAuthorizerIAMDescription `json:"iam,omitempty"`
}

// LambdaFunctionURLRequestContextAuthorizerIAMDescription contains IAM information for the request context.
type LambdaFunctionURLRequestContextAuthorizerIAMDescription struct {
AccessKey string `json:"accessKey"`
AccountID string `json:"accountId"`
CallerID string `json:"callerId"`
UserARN string `json:"userArn"`
UserID string `json:"userId"`
}

// LambdaFunctionURLRequestContextHTTPDescription contains HTTP information for the request context.
type LambdaFunctionURLRequestContextHTTPDescription struct {
Method string `json:"method"`
Path string `json:"path"`
Protocol string `json:"protocol"`
SourceIP string `json:"sourceIp"`
UserAgent string `json:"userAgent"`
}

// LambdaFunctionURLResponse configures the HTTP response to be returned by Lambda Function URL for the request.
type LambdaFunctionURLResponse struct {
StatusCode int `json:"statusCode"`
Headers map[string]string `json:"headers"`
Body string `json:"body"`
IsBase64Encoded bool `json:"isBase64Encoded"`
Cookies []string `json:"cookies"`
}
57 changes: 57 additions & 0 deletions events/lambda_function_urls_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.

package events

import (
"encoding/json"
"io/ioutil"
"testing"

"github.com/stretchr/testify/assert"
)

func TestLambdaFunctionURLResponseMarshaling(t *testing.T) {

// read json from file
inputJSON, err := ioutil.ReadFile("./testdata/lambda-urls-response.json")
if err != nil {
t.Errorf("could not open test file. details: %v", err)
}

// de-serialize into Go object
var inputEvent LambdaFunctionURLResponse
if err := json.Unmarshal(inputJSON, &inputEvent); err != nil {
t.Errorf("could not unmarshal event. details: %v", err)
}

// serialize to json
outputJSON, err := json.Marshal(inputEvent)
if err != nil {
t.Errorf("could not marshal event. details: %v", err)
}

assert.JSONEq(t, string(inputJSON), string(outputJSON))
}

func TestLambdaFunctionURLRequestMarshaling(t *testing.T) {

// read json from file
inputJSON, err := ioutil.ReadFile("./testdata/lambda-urls-request.json")
if err != nil {
t.Errorf("could not open test file. details: %v", err)
}

// de-serialize into Go object
var inputEvent LambdaFunctionURLRequest
if err := json.Unmarshal(inputJSON, &inputEvent); err != nil {
t.Errorf("could not unmarshal event. details: %v", err)
}

// serialize to json
outputJSON, err := json.Marshal(inputEvent)
if err != nil {
t.Errorf("could not marshal event. details: %v", err)
}

assert.JSONEq(t, string(inputJSON), string(outputJSON))
}
44 changes: 44 additions & 0 deletions events/testdata/lambda-urls-request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"version": "2.0",
"rawPath": "/my/path",
"rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
"cookies": [
"cookie1",
"cookie2"
],
"headers": {
"header1": "value1",
"header2": "value1,value2"
},
"queryStringParameters": {
"parameter1": "value1,value2",
"parameter2": "value"
},
"requestContext": {
"accountId": "123456789012",
"apiId": "<urlid>",
"authorizer": {
"iam": {
"accessKey": "AKIA...",
"accountId": "111122223333",
"callerId": "AIDA...",
"userArn": "arn:aws:iam::111122223333:user/example-user",
"userId": "AIDA..."
}
},
"domainName": "<url-id>.lambda-url.us-west-2.on.aws",
"domainPrefix": "<url-id>",
"http": {
"method": "POST",
"path": "/my/path",
"protocol": "HTTP/1.1",
"sourceIp": "123.123.123.123",
"userAgent": "agent"
},
"requestId": "id",
"time": "12/Mar/2020:19:03:58 +0000",
"timeEpoch": 1583348638390
},
"body": "Hello from client!",
"isBase64Encoded": false
}
13 changes: 13 additions & 0 deletions events/testdata/lambda-urls-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"statusCode": 201,
"headers": {
"Content-Type": "application/json",
"My-Custom-Header": "Custom Value"
},
"body": "{ \"message\": \"Hello, world!\" }",
"cookies": [
"Cookie_1=Value1; Expires=21 Oct 2021 07:48 GMT",
"Cookie_2=Value2; Max-Age=78000"
],
"isBase64Encoded": false
}

0 comments on commit 138d021

Please sign in to comment.