Implementing HTTP request parsing is problematic for Afterburner functions, and requires a full implementation of the HTTP RFC for each request to ensure compliance with the standard.
This proposal sets out an example of a simple text based protocol which is language agnostic, off-loading the parsing of the request to the watchdog not the function handler.
[HEADER required] \r\n [BODY optional] 0\r\n\r\n
The message format corresponds of a HEADER
in JSON format which contains the decoded values from the HTTP request, this is terminated by the \r\n
characters. Optionally a body can also be provided which is terminated by the 0\r\n
characters, the entire message is always terminated by 0\r\n
regardless of the presence of a body.
The benefit to this protocol is that it allows a bound and strongly typed header and also the capability to stream the body as it is read from the original request.
{
"http_headers": [{"key": "mykey", "value": "abc"}],
"http_query": [{"key": "mykey", "value": "abc"}],
"environment": [{"key": "mykey", "value": "abc"}]
}
\r\n
This is the body stored as plain text
0\r\n
{
"headers": [{"key": "mykey", "value": "abc"}],
"query": [{"key": "mykey", "value": "abc"}],
"environment": [{"key": "mykey", "value": "abc"}]
}
\r\n
0\r\n
The protocol is simple and text based allowing the implementation to be performed in any language, below is a simpleish go parser for a message (warning psudo code):
type Header struct {
HTTPHeader map[string]string
HTTPHeader map[string]string
HTTPQuery map[string]string
}
func parseStream(stdin os.Stdin) {
b := bufio.NewReader(stdin)
header, _ := b.ReadString("\r\n")
body, _ := b.ReadString("0\r\n")
var h Header
json.Unmarshal([]byte(header), &header)
handler(h, body)
}