Skip to content

Instantly share code, notes, and snippets.

@nicholasjackson
Last active January 23, 2018 12:17
Show Gist options
  • Save nicholasjackson/27a68f059232b8e815d9290b2737ce58 to your computer and use it in GitHub Desktop.
Save nicholasjackson/27a68f059232b8e815d9290b2737ce58 to your computer and use it in GitHub Desktop.
Generic message protocol for OpenFaaS Afterburner

Generic message protocol for OpenFaaS Afterburner

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.

Message format

[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.

Example message with body

{
  "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

Example message with no body

{
  "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)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment