1515package main
1616
1717import (
18+ "encoding/json"
1819 "fmt"
1920 "io/ioutil"
2021 "log"
@@ -34,9 +35,12 @@ const (
3435)
3536
3637type 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
4246var (
@@ -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+
190217func api () error {
191218 apiRouter := http .NewServeMux ()
192219 apiRouter .HandleFunc (awsEndpoint + "/init/error" , initError )
0 commit comments