Skip to content
This repository was archived by the owner on Dec 11, 2023. It is now read-only.

Commit 5740205

Browse files
committed
API Gateway data format support, #23
1 parent 4a6460e commit 5740205

File tree

1 file changed

+50
-23
lines changed

1 file changed

+50
-23
lines changed

main.go

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package main
1616

1717
import (
18+
"encoding/json"
1819
"fmt"
1920
"io/ioutil"
2021
"log"
@@ -34,9 +35,12 @@ const (
3435
)
3536

3637
type message struct {
37-
id string
38-
deadline int64
39-
data []byte
38+
ID string
39+
Deadline int64
40+
StatusCode int
41+
Headers map[string]interface{}
42+
IsBase64Encoded bool
43+
Body string
4044
}
4145

4246
var (
@@ -82,32 +86,37 @@ func newTask(w http.ResponseWriter, r *http.Request) {
8286

8387
now := time.Now().UnixNano()
8488
task := message{
85-
id: fmt.Sprintf("%d", now),
86-
deadline: now + functionTTL,
87-
data: body,
89+
ID: fmt.Sprintf("%d", now),
90+
Deadline: now + functionTTL,
91+
Body: string(body),
8892
}
89-
fmt.Printf("<- %s %s\n", task.id, task.data)
93+
fmt.Printf("<- %s %s\n", task.ID, task.Body)
9094

9195
resultsChannel := make(chan message)
9296
mutex.Lock()
93-
results[task.id] = resultsChannel
97+
results[task.ID] = resultsChannel
9498
mutex.Unlock()
9599
defer close(resultsChannel)
96100

97101
tasks <- task
98102

99103
select {
100104
case <-time.After(time.Duration(functionTTL)):
101-
fmt.Printf("-> ! %s Deadline is reached\n", task.id)
105+
fmt.Printf("-> ! %s Deadline is reached\n", task.ID)
102106
w.WriteHeader(http.StatusGone)
103-
w.Write([]byte(fmt.Sprintf("Deadline is reached, data %s", task.data)))
107+
w.Write([]byte(fmt.Sprintf("Deadline is reached, data %s", task.Body)))
104108
case result := <-resultsChannel:
105-
fmt.Printf("-> %s %s\n", result.id, result.data)
106-
w.WriteHeader(http.StatusOK)
107-
w.Write(result.data)
109+
fmt.Printf("-> %s %d %s\n", result.ID, result.StatusCode, result.Body)
110+
for k, v := range result.Headers {
111+
if value, ok := v.(string); ok {
112+
w.Header().Add(k, value)
113+
}
114+
}
115+
w.WriteHeader(result.StatusCode)
116+
w.Write([]byte(result.Body))
108117
}
109118
mutex.Lock()
110-
delete(results, task.id)
119+
delete(results, task.ID)
111120
mutex.Unlock()
112121
return
113122
}
@@ -116,13 +125,13 @@ func getTask(w http.ResponseWriter, r *http.Request) {
116125
task := <-tasks
117126

118127
// Dummy headers required by Rust client. Replace with something meaningful
119-
w.Header().Set("Lambda-Runtime-Aws-Request-Id", task.id)
120-
w.Header().Set("Lambda-Runtime-Deadline-Ms", strconv.Itoa(int(task.deadline)))
128+
w.Header().Set("Lambda-Runtime-Aws-Request-Id", task.ID)
129+
w.Header().Set("Lambda-Runtime-Deadline-Ms", strconv.Itoa(int(task.Deadline)))
121130
w.Header().Set("Lambda-Runtime-Invoked-Function-Arn", "arn:aws:lambda:us-east-1:123456789012:function:custom-runtime")
122131
w.Header().Set("Lambda-Runtime-Trace-Id", "0")
123132

124133
w.WriteHeader(http.StatusOK)
125-
w.Write(task.data)
134+
w.Write([]byte(task.Body))
126135
return
127136
}
128137

@@ -154,7 +163,7 @@ func responseHandler(w http.ResponseWriter, r *http.Request) {
154163
return
155164
}
156165

157-
data, err := ioutil.ReadAll(r.Body)
166+
body, err := ioutil.ReadAll(r.Body)
158167
if err != nil {
159168
fmt.Printf("! %s\n", err)
160169
return
@@ -170,23 +179,41 @@ func responseHandler(w http.ResponseWriter, r *http.Request) {
170179
return
171180
}
172181

182+
result := message{
183+
Body: string(body),
184+
StatusCode: 200,
185+
}
173186
switch kind {
174187
case "response":
188+
if js, ok := parseJSON(body); ok {
189+
result = js
190+
}
175191
case "error":
176-
fmt.Printf("! Error: %s\n", data)
192+
result.StatusCode = 500
193+
fmt.Printf("! Error: %s\n", body)
177194
default:
178195
w.WriteHeader(http.StatusNotFound)
179196
w.Write([]byte(fmt.Sprintf("Unknown endpoint: %s", kind)))
180197
return
181198
}
182-
resultsChannel <- message{
183-
id: id,
184-
data: data,
185-
}
199+
result.ID = id
200+
resultsChannel <- result
186201
w.WriteHeader(http.StatusAccepted)
187202
return
188203
}
189204

205+
func parseJSON(s []byte) (message, bool) {
206+
var js message
207+
if err := json.Unmarshal(s, &js); err != nil {
208+
fmt.Println(s, err)
209+
return js, false
210+
}
211+
if js.StatusCode == 0 {
212+
return js, false
213+
}
214+
return js, true
215+
}
216+
190217
func api() error {
191218
apiRouter := http.NewServeMux()
192219
apiRouter.HandleFunc(awsEndpoint+"/init/error", initError)

0 commit comments

Comments
 (0)