diff --git a/examples/container/my-container/server.py b/examples/container/my-container/server.py index 0403cb9f..2009e569 100644 --- a/examples/container/my-container/server.py +++ b/examples/container/my-container/server.py @@ -1,4 +1,5 @@ from flask import Flask +import os DEFAULT_PORT = "8080" MESSAGE = "Hello, World from Scaleway Container !\n" @@ -14,4 +15,4 @@ def root(): # Scaleway's system will inject a PORT environment variable on which your application should start the server. port_env = os.getenv("PORT", DEFAULT_PORT) port = int(port_env) - app.run(debug=True, host="0.0.0.0", port=port) \ No newline at end of file + app.run(debug=True, host="0.0.0.0", port=port) diff --git a/examples/container/package.json b/examples/container/package.json index 33ed4202..8399e1be 100644 --- a/examples/container/package.json +++ b/examples/container/package.json @@ -10,8 +10,8 @@ "license": "ISC", "dependencies": {}, "devDependencies": { - "serverless-scaleway-functions": "^0.1.6" + "serverless-scaleway-functions": "^0.1.7" }, "description": "" } - \ No newline at end of file + diff --git a/examples/golang/vendor/github.com/scaleway/scaleway-functions-go/LICENSE b/examples/golang/vendor/github.com/scaleway/scaleway-functions-go/LICENSE new file mode 100644 index 00000000..f3a907ee --- /dev/null +++ b/examples/golang/vendor/github.com/scaleway/scaleway-functions-go/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Scaleway + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/examples/golang/vendor/github.com/scaleway/scaleway-functions-go/events/http.go b/examples/golang/vendor/github.com/scaleway/scaleway-functions-go/events/http.go new file mode 100644 index 00000000..0296f2eb --- /dev/null +++ b/examples/golang/vendor/github.com/scaleway/scaleway-functions-go/events/http.go @@ -0,0 +1,39 @@ +package events + +// APIGatewayProxyRequest contains data coming from the API Gateway proxy +type APIGatewayProxyRequest struct { + Resource string `json:"resource"` // The resource path defined in API Gateway + Path string `json:"path"` // The url path for the caller + HTTPMethod string `json:"httpMethod"` + Headers map[string]string `json:"headers"` + MultiValueHeaders map[string][]string `json:"multiValueHeaders"` + QueryStringParameters map[string]string `json:"queryStringParameters"` + MultiValueQueryStringParameters map[string][]string `json:"multiValueQueryStringParameters"` + PathParameters map[string]string `json:"pathParameters"` + StageVariables map[string]string `json:"stageVariables"` + RequestContext APIGatewayProxyRequestContext `json:"requestContext"` + Body string `json:"body"` + IsBase64Encoded bool `json:"isBase64Encoded,omitempty"` +} + +// APIGatewayProxyResponse configures the response to be returned by API Gateway for the request +type APIGatewayProxyResponse struct { + StatusCode int `json:"statusCode"` + Headers map[string]string `json:"headers"` + MultiValueHeaders map[string][]string `json:"multiValueHeaders"` + Body string `json:"body"` + IsBase64Encoded bool `json:"isBase64Encoded,omitempty"` +} + +// APIGatewayProxyRequestContext contains the information to identify the AWS account and resources invoking the +// Lambda function. It also includes Cognito identity information for the caller. +type APIGatewayProxyRequestContext struct { + AccountID string `json:"accountId"` + ResourceID string `json:"resourceId"` + Stage string `json:"stage"` + RequestID string `json:"requestId"` + ResourcePath string `json:"resourcePath"` + Authorizer map[string]interface{} `json:"authorizer"` + HTTPMethod string `json:"httpMethod"` + APIID string `json:"apiId"` // The API Gateway rest API Id +} diff --git a/examples/golang/vendor/github.com/scaleway/scaleway-functions-go/lambda/entry.go b/examples/golang/vendor/github.com/scaleway/scaleway-functions-go/lambda/entry.go new file mode 100644 index 00000000..6a460da8 --- /dev/null +++ b/examples/golang/vendor/github.com/scaleway/scaleway-functions-go/lambda/entry.go @@ -0,0 +1,112 @@ +package lambda + +import ( + "encoding/base64" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + "strconv" + "time" + + "github.com/scaleway/scaleway-functions-go/events" +) + +const defaultPort = 8080 + +// FunctionHandler - Handler for Event +type FunctionHandler func(req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) + +// Start takes the function Handler, at the moment only supporting HTTP Triggers (Api Gateway Proxy events) +// It takes care of wrapping the handler with an HTTP server, which receives requests when functions are triggered +// And execute the handler after formatting the HTTP Request to an API Gateway Proxy Event +func Start(handler FunctionHandler) { + portEnv := os.Getenv("PORT") + port, err := strconv.Atoi(portEnv) + if err != nil { + port = defaultPort + } + + s := &http.Server{ + Addr: fmt.Sprintf(":%d", port), + ReadTimeout: 3 * time.Second, + WriteTimeout: 3 * time.Second, + MaxHeaderBytes: 1 << 20, // Max header of 1MB + } + + http.HandleFunc("/", makeRequestHandler(handler)) + log.Fatal(s.ListenAndServe()) +} + +func makeRequestHandler(handler FunctionHandler) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + var input string + + if r.Body != nil { + defer r.Body.Close() + + bodyBytes, bodyErr := ioutil.ReadAll(r.Body) + + if bodyErr != nil { + log.Printf("Error reading body from request.") + } + + input = string(bodyBytes) + } + + // HTTP Headers - only first value + // TODO: use HeaderMultipleValue + headers := map[string]string{} + for key, value := range r.Header { + headers[key] = value[len(value)-1] + } + + queryParameters := map[string]string{} + for key, value := range r.URL.Query() { + queryParameters[key] = value[len(value)-1] + } + + isBase64Encoded := true + _, err := base64.StdEncoding.DecodeString(input) + if err != nil { + isBase64Encoded = false + } + + event := events.APIGatewayProxyRequest{ + Path: r.URL.Path, + HTTPMethod: r.Method, + Headers: headers, + QueryStringParameters: queryParameters, + StageVariables: map[string]string{}, + Body: input, + IsBase64Encoded: isBase64Encoded, + RequestContext: events.APIGatewayProxyRequestContext{ + Stage: "", + HTTPMethod: r.Method, + }, + } + + result, resultErr := handler(event) + + if result.Headers != nil { + for key, value := range result.Headers { + w.Header().Set(key, value) + } + } + + if resultErr != nil { + log.Print(resultErr) + w.WriteHeader(http.StatusInternalServerError) + } else { + if result.StatusCode == 0 { + w.WriteHeader(http.StatusOK) + } else { + w.WriteHeader(result.StatusCode) + } + } + + responseBody := []byte(result.Body) + w.Write(responseBody) + } +} diff --git a/package.json b/package.json index daa065cc..92ea7f06 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "serverless-scaleway-functions", - "version": "0.1.6", + "version": "0.1.7", "description": "Provider plugin for the Serverless Framework v1.x which adds support for Scaleway Functions.", "main": "index.js", "author": "scaleway.com",