-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
665 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{ | ||
"event": { | ||
"resource": "/{proxy+}", | ||
"path": "/hello/world", | ||
"httpMethod": "GET", | ||
"headers": null, | ||
"queryStringParameters": null, | ||
"pathParameters": { | ||
"proxy": "hello/world" | ||
}, | ||
"stageVariables": null, | ||
"requestContext": { | ||
"accountId": "EXAMPLE", | ||
"resourceId": "EXAMPLE", | ||
"stage": "test-invoke-stage", | ||
"requestId": "test-invoke-request", | ||
"identity": { | ||
"cognitoIdentityPoolId": null, | ||
"accountId": "EXAMPLE", | ||
"cognitoIdentityId": null, | ||
"caller": "EXAMPLE", | ||
"apiKey": "test-invoke-api-key", | ||
"sourceIp": "test-invoke-source-ip", | ||
"accessKey": "EXAMPLE", | ||
"cognitoAuthenticationType": null, | ||
"cognitoAuthenticationProvider": null, | ||
"userArn": "arn:aws:iam::EXAMPLE:root", | ||
"userAgent": "Apache-HttpClient/4.5.x (Java/1.8.0_102)", | ||
"user": "EXAMPLE" | ||
}, | ||
"resourcePath": "/{proxy+}", | ||
"httpMethod": "GET", | ||
"apiId": "EXAMPLE" | ||
}, | ||
"body": null, | ||
"isBase64Encoded": false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package main | ||
|
||
import ( | ||
"net/http" | ||
"path" | ||
|
||
"github.com/apex/go-apex" | ||
"github.com/apex/go-apex/proxy" | ||
) | ||
|
||
func main() { | ||
mux := http.NewServeMux() | ||
mux.HandleFunc("/", handleRoot) | ||
mux.HandleFunc("/hello/", handleHello) | ||
|
||
apex.Handle(proxy.Serve(mux)) | ||
} | ||
|
||
func handleRoot(w http.ResponseWriter, r *http.Request) { | ||
w.Write([]byte("Root")) | ||
} | ||
|
||
func handleHello(w http.ResponseWriter, r *http.Request) { | ||
_, name := path.Split(r.URL.Path) | ||
w.Write([]byte("Hello " + name)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
|
||
# API Gateway Proxy request handling support | ||
|
||
This package provides an Apex-compatible handler for [proxy requests](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html). | ||
|
||
Each proxy request matches a wildcard path in AWS API Gateway, which is then converted to a standard `http.Request` before dispatching using the `http.Handler` interface. | ||
|
||
|
||
## Usage | ||
|
||
Any router or middleware framework supporting the `http.Handler` interface should be compatible with this adapter. | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/apex/go-apex" | ||
"github.com/apex/go-apex/proxy" | ||
) | ||
|
||
func main() { | ||
mux := http.NewServeMux() | ||
mux.HandleFunc("/", hello) | ||
mux.HandleFunc("/foo", foo) | ||
mux.HandleFunc("/bar", bar) | ||
apex.Handle(proxy.Serve(mux)) | ||
} | ||
|
||
... | ||
``` | ||
|
||
|
||
## Notes | ||
|
||
### Stdout vs Stderr | ||
|
||
As with any Apex handler, you must make sure that your handler doesn't write anything to stdout. | ||
If your web framework logs to stdout by default, such as Martini, you need to change the logger output to use stderr. | ||
|
||
### Content-Types passed through as plain text output: | ||
|
||
Any output with a Content-Type that doesn't match one of those listed below will be Base64 encoded in the output record. | ||
In order for this to be returned from API Gateway correctly, you will need to enable binary support and | ||
map the content types containing binary data. | ||
|
||
In practice you can usually map all types as binary using the `*/*` pattern for binary support if you aren't using other | ||
API Gateway resources which conflict with this. | ||
|
||
The text-mode Content-Type regular expressions used by default are: | ||
|
||
* text/.* | ||
* application/json | ||
* application/.*\+json | ||
* application/xml | ||
* application/.*\+xml | ||
|
||
You can override this by calling `proxy.SetTextContentTypes` with a list of regular expressions matching the types that should | ||
not be Base64 encoded. | ||
|
||
### Output encoding | ||
API gateway will automatically gzip-encode the output of your API, so it's not necessary to gzip the output of your webapp. | ||
|
||
If you use your own gzip encoding, it's likely to interfere with the Base64 output for text content types - this hasn't been tested. | ||
|
||
## Differences from eawsy | ||
|
||
This implementation reuses a large portion of the event definitions from the eawsy AWS Lambda projects: | ||
|
||
* https://github.com/eawsy/aws-lambda-go-event | ||
* https://github.com/eawsy/aws-lambda-go-net | ||
|
||
However, it wraps a web application in an apex-compatible adapter which makes direct calls to an http.Handler instance | ||
rather than creating a fake `net.Conn` and marshalling/unmarshalling the request data. | ||
|
||
A ResponseWriter implementation captures the response of the handler and constructs an API Gateway Proxy response. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// | ||
// Copyright 2017 Alsanium, SAS. or its affiliates. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
// Originally from https://github.com/eawsy/aws-lambda-go-event/blob/master/service/lambda/runtime/event/apigatewayproxyevt/decoder.go | ||
// Changes (kothar - 2017-02): | ||
// Relocated to go-apex/proxy | ||
|
||
package proxy | ||
|
||
import "encoding/json" | ||
|
||
type requestContextAlias RequestContext | ||
|
||
type authorizer map[string]string | ||
|
||
// UnmarshalJSON interprets the data as a dynamic map which may carry either a | ||
// Amazon Cognito set of claims or a custom set of attributes. It then choose | ||
// the good one at runtime and fill the authorizer with it. | ||
func (a *authorizer) UnmarshalJSON(data []byte) error { | ||
var cognito struct { | ||
Claims *map[string]string | ||
} | ||
var custom map[string]string | ||
|
||
err := json.Unmarshal(data, &cognito) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if cognito.Claims != nil { | ||
*a = authorizer(*cognito.Claims) | ||
return nil | ||
} | ||
|
||
err = json.Unmarshal(data, &custom) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
*a = authorizer(custom) | ||
return nil | ||
} | ||
|
||
type jsonRequestContext struct { | ||
*requestContextAlias | ||
Authorizer authorizer | ||
} | ||
|
||
// UnmarshalJSON interprets data as a RequestContext with a special authorizer. | ||
// It then leverages type aliasing and struct embedding to fill RequestContext | ||
// with an usual map[string]string. | ||
func (rc *RequestContext) UnmarshalJSON(data []byte) error { | ||
var jrc jsonRequestContext | ||
if err := json.Unmarshal(data, &jrc); err != nil { | ||
return err | ||
} | ||
|
||
*rc = *(*RequestContext)(jrc.requestContextAlias) | ||
rc.Authorizer = jrc.Authorizer | ||
|
||
return nil | ||
} | ||
|
||
// MarshalJSON reverts the effect of type aliasing and struct embedding used | ||
// during the marshalling step to make the pattern seamless. | ||
func (rc *RequestContext) MarshalJSON() ([]byte, error) { | ||
return json.Marshal(&jsonRequestContext{ | ||
(*requestContextAlias)(rc), | ||
rc.Authorizer, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
// | ||
// Copyright 2017 Alsanium, SAS. or its affiliates. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
// Originally from https://github.com/eawsy/aws-lambda-go-event/blob/master/service/lambda/runtime/event/apigatewayproxyevt/definition.go | ||
// Changes (kothar - 2017-02): | ||
// Relocated to go-apex/proxy | ||
|
||
package proxy | ||
|
||
import "encoding/json" | ||
|
||
// Identity provides identity information about the API caller. | ||
type Identity struct { | ||
// The API owner key associated with the API. | ||
APIKey string | ||
|
||
// The AWS account ID associated with the request. | ||
AccountID string | ||
|
||
// The User Agent of the API caller. | ||
UserAgent string | ||
|
||
// The source IP address of the TCP connection making the request to | ||
// Amazon API Gateway. | ||
SourceIP string | ||
|
||
// The Amazon Access Key associated with the request. | ||
AccessKey string | ||
|
||
// The principal identifier of the caller making the request. | ||
// It is same as the User and interchangeable. | ||
Caller string | ||
|
||
// The principal identifier of the user making the request. | ||
// It is same as the Caller and interchangeable. | ||
User string | ||
|
||
// The Amazon Resource Name (ARN) of the effective user identified after | ||
// authentication. | ||
UserARN string | ||
|
||
// The Amazon Cognito identity ID of the caller making the request. | ||
// Available only if the request was signed with Amazon Cognito credentials. | ||
CognitoIdentityID string | ||
|
||
// The Amazon Cognito identity pool ID of the caller making the request. | ||
// Available only if the request was signed with Amazon Cognito credentials. | ||
CognitoIdentityPoolID string | ||
|
||
// The Amazon Cognito authentication type of the caller making the request. | ||
// Available only if the request was signed with Amazon Cognito credentials. | ||
CognitoAuthenticationType string | ||
|
||
// The Amazon Cognito authentication provider used by the caller making the | ||
// request. | ||
// Available only if the request was signed with Amazon Cognito credentials. | ||
CognitoAuthenticationProvider string | ||
} | ||
|
||
// RequestContext provides contextual information about an Amazon API Gateway | ||
// Proxy event. | ||
type RequestContext struct { | ||
// The identifier Amazon API Gateway assigns to the API. | ||
APIID string | ||
|
||
// The identifier Amazon API Gateway assigns to the resource. | ||
ResourceID string | ||
|
||
// An automatically generated ID for the API call. | ||
RequestID string | ||
|
||
// The incoming request HTTP method name. | ||
// Valid values include: DELETE, GET, HEAD, OPTIONS, PATCH, POST, and PUT. | ||
HTTPMethod string | ||
|
||
// The resource path as defined in Amazon API Gateway. | ||
ResourcePath string | ||
|
||
// The AWS account ID associated with the API. | ||
AccountID string | ||
|
||
// The deployment stage of the API call (for example, Beta or Prod). | ||
Stage string | ||
|
||
// The API caller identification information. | ||
Identity *Identity | ||
|
||
// If used with Amazon Cognito, it represents the claims returned from the | ||
// Amazon Cognito user pool after the method caller is successfully | ||
// authenticated. | ||
// If used with Amazon API Gateway custom authorizer, it represents the | ||
// specified key-value pair of the context map returned from the custom | ||
// authorizer AWS Lambda function. | ||
Authorizer map[string]string `json:"-"` | ||
} | ||
|
||
// Event represents an Amazon API Gateway Proxy Event. | ||
type Event struct { | ||
// The incoming request HTTP method name. | ||
// Valid values include: DELETE, GET, HEAD, OPTIONS, PATCH, POST, and PUT. | ||
HTTPMethod string | ||
|
||
// The incoming reauest HTTP headers. | ||
// Duplicate entries are not supported. | ||
Headers map[string]string | ||
|
||
// The resource path with raw placeholders as defined in Amazon API Gateway. | ||
Resource string | ||
|
||
// The incoming request path parameters corresponding to the resource path | ||
// placeholders values as defined in Resource. | ||
PathParameters map[string]string | ||
|
||
// The real path corresponding to the path parameters injected into the | ||
// Resource placeholders. | ||
Path string | ||
|
||
// The incoming request query string parameters. | ||
// Duplicate entries are not supported. | ||
QueryStringParameters map[string]string | ||
|
||
// If used with Amazon API Gateway binary support, it represents the Base64 | ||
// encoded binary data from the client. | ||
// Otherwise it represents the raw data from the client. | ||
Body string | ||
|
||
// A flag to indicate if the applicable request payload is Base64 encoded. | ||
IsBase64Encoded bool | ||
|
||
// The name-value pairs defined as configuration attributes associated with | ||
// the deployment stage of the API. | ||
StageVariables map[string]string | ||
|
||
// The contextual information associated with the API call. | ||
RequestContext *RequestContext | ||
} | ||
|
||
// String returns the string representation. | ||
func (e *Event) String() string { | ||
s, _ := json.MarshalIndent(e, "", " ") | ||
return string(s) | ||
} | ||
|
||
// GoString returns the string representation. | ||
func (e *Event) GoString() string { | ||
return e.String() | ||
} |
Oops, something went wrong.