Function: map read_http (request-or-response [, obj conn])

Reads lines from the connection conn (or, if not provided, from the player that typed the command that initiated the current task) and attempts to parse the lines as if they are an HTTP request or response. request-or-response must be either the string "request" or "response". It dictates the type of parsing that will be done.

Just like read(), if conn is provided, then the programmer must either be a wizard or the owner of conn; if conn is not provided, then read_http() may only be called by a wizard and only in the task that was last spawned by a command from the connection in question. Otherwise, E_PERM is raised. Likewise, if conn is not currently connected and has no pending lines of input, or if the connection is closed while a task is waiting for input but before any lines of input are received, then read_http() raises E_INVARG.

If parsing fails because the request or response is syntactically incorrect, read_http() will return a map with the single key "error" and a list of values describing the reason for the error. If parsing succeeds, read_http() will return a map with an appropriate subset of the following keys, with values parsed from the HTTP request or response: "method", "uri", "headers", "body", "status" and "upgrade".

read_http() assumes the input strings are binary strings. When called interactively, as in the example below, the programmer must insert the literal line terminators or parsing will fail.

The following example interactively reads an HTTP request from the player's connection.

read_http("request", player)
GET /path HTTP/1.1~0D~0A
Host: example.com~0D~0A
~0D~0A

In this example, the string ~0D~0A ends the request. The call returns the following (the request has no body):

["headers" -> ["Host" -> "example.com"], "method" -> "GET", "uri" -> "/path"]

The following example interactively reads an HTTP response from the player's connection.

read_http("response", player)
HTTP/1.1 200 Ok~0D~0A
Content-Length: 10~0D~0A
~0D~0A
1234567890

The call returns the following:

["body" -> "1234567890", "headers" -> ["Content-Length" -> "10"], "status" -> 200]