LIME over HTTP

This specification is a work in progress and is subject to change without notice.

LIME over HTTP (LOH) is an emulation layer that allows receiving and sending LIME envelopes through a HTTP connection. It works by mapping some LIME features to similar ones into the HTTP protocol and using conventions for headers and URIs. A LIME compatible HTTP server should translate HTTP requests into LIME envelopes and submit they to its LIME backend.

Envelopes

The envelope to HTTP mapping is straightforward: The envelope properties should be HTTP headers or query string parameters. The property mapping for all envelope types is:

Property HTTP mapping
id X-Id header or id URL query string parameter.
from X-From header or from URL query string parameter.
to X-To header or to URL query string parameter.
pp X-Pp header or pp URL query string parameter.
metadata All non-standard headers (starting with X-), except the LIME specific headers.

Sessions

The concept of session in LIME is directly related to the persistent connection state. Since the HTTP protocol doesn't support that, it is not possible to map this feature directly. However, the HTTP server should establish a session with it's LIME backend for authentication purposes. The session negotiation should be skipped, since its not possible to upgrade the HTTP compression and encryption options. Its highly recommended that the HTTP server uses TLS encryption (HTTPS) to avoid problems with sensitive data. For every call, the HTTP client should send the Authorization header and the server should establish a session using the request authentication information, mapping the schemes accordingly.

By default, the server keeps the session alive for further client requests with the same Authorization header value. This allows the to clients use features like the definition of the presence status for receiving messages. The default behavior is the same when sending the header X-Session: Keep-Alive.

In every response with alive session, the server should return the X-Session-Id header with the identifier of the session and the X-Session-Expiration header, with the information of the lifetime of the specified session. The value of the session expiration can change after every request, since it is relative to the last request date. Even with an active session, the client needs to send its credentials for all requests. The server should store the cached session using a hashed value of the Authorization header as a key. For server behind load balancers, its important to use sticky sessions to avoid multiple active HTTP sessions for the same identity. If the client doesn't wants to keep an open session or to close an existing session, it must send the X-Session: Close header.

Messages

The client can send and receive messages thought the HTTP server, using the http://{host:port}/messages resource URI. For receiving, the client needs an active session (X-Session: Keep-Alive) and set the presence as usual. Thus the HTTP server should receive the messages and store them for further retrieving by the client. The property mapping for the message envelope is:

Property HTTP mapping
type Content-Type header
content The HTTP message body encoded according to the MIME type.

The expected server behavior is:

URI Method Behavior
/messages POST The server should compose a message envelope, send it to the LIME backend and return the HTTP status code 202 (Accepted) and the body value should be the id of the sent message.
/messages?waitUntil={notification} POST The server should compose a message envelope, send it to the LIME backend and await for the specified notification or a further one (i.e. an delivered notification can be used to complete a waitUntil=dispatched request.) If the received notification event is Failure, the HTTP response status code should be an 4xx (client error) or 5xx (server error), according to the failure reason and the reason phrase the value of the reason description; otherwise, the status should be 201 (Created) and the body value should be the id of the sent message.
/messages GET The server should return the list of id of stored messages addressed to the request identity.
/messages/{id} GET The server should return the stored message with the specified id.
/messages/{id} DELETE The server should delete the stored message with the specified id.

Examples

Sending an async text message with the destination in the query string:

C:

POST http://localhost:8080/messages?to=heisenberg%40breakingbad.com HTTP/1.1
Content-Type: text/plain
Host: localhost:8080
Authorization: Basic amVzc2VAYnJlYWtpbmdiYWQuY29tOmJpdGNo
Content-Length: 8

Science!
    
S:

HTTP/1.1 202 Accepted
Content-Type: text/plain
Date: Wed, 01 Oct 2014 18:50:57 GMT
Content-Length: 36

dd079a4d-bb82-4a6b-8479-a420fc9ca91c

Sending a text message with the destination in the headers and waiting for the dispatched notification:

C:

POST https://breakingbad.com/messages?waitUntil=dispatched HTTP/1.1
Content-Type: text/plain
Host: breakingbad.com
X-To: heisenberg@breakingbad.com
Authorization: Basic amVzc2VAYnJlYWtpbmdiYWQuY29tOmJpdGNo
Content-Length: 21
Yeah, bitch! Magnets!

S:

HTTP/1.1 201 Created
Content-Type: text/plain
Date: Wed, 01 Oct 2014 18:46:47 GMT
Content-Length: 36

27bf69ca-2a53-4a68-ac9d-6f8c833f50f9

Sending a message to an unavailable destination:

C:

POST http://localhost:8080/messages HTTP/1.1
Content-Type: text/plain
X-To: hank@breakingbad.com
Host: localhost:8080
Authorization: Basic aGVpc2VuYmVyZ0BicmVha2luZ2JhZC5jb206OTk5OTk5
Content-Length: 5

Hank?
    
S:

HTTP/1.1 403 Destination not found
X-Reason-Code: 42
Date: Wed, 01 Oct 2014 19:48:37 GMT
Content-Length: 0

Get stored messages ids:

C:

GET http://localhost:8080/messages HTTP/1.1
Content-Type: text/plain
X-To: heisenberg@breakingbad.com
Host: localhost:8080
Authorization: Basic aGVpc2VuYmVyZ0BicmVha2luZ2JhZC5jb206OTk5OTk5
Content-Length: 0
    
S:

HTTP/1.1 200 OK
Content-Type: text/plain
X-Session-Id: fe78f967-39f1-4392-865b-7725d976664b
Date: Wed, 01 Oct 2014 21:30:33 GMT
Content-Length: 114

4e28e514-8706-42b6-9ba4-5dbab0ac72b5
dd079a4d-bb82-4a6b-8479-a420fc9ca91c
27bf69ca-2a53-4a68-ac9d-6f8c833f50f9

Get a message by its id:

C:
GET http://localhost:8080/messages/27bf69ca-2a53-4a68-ac9d-6f8c833f50f9 HTTP/1.1
Content-Type: text/plain
X-To: heisenberg@breakingbad.com
Host: localhost:8080
Authorization: Basic aGVpc2VuYmVyZ0BicmVha2luZ2JhZC5jb206OTk5OTk5
Content-Length: 0
    
HTTP/1.1 200 OK
Content-Type: text/plain
X-Session-Id: fe78f967-39f1-4392-865b-7725d976664b
X-From: jesse@breakingbad.com/default
X-To: heisenberg@breakingbad.com/default
Date: Wed, 01 Oct 2014 21:29:23 GMT
Content-Length: 21

Yeah, bitch! Magnets!

Notifications

The client can send and receive notifications thought the HTTP server, using the http://{host:port}/notifications resource URI. For receiving, the client needs an active session (X-Session: Keep-Alive). Thus the HTTP server should receive the notifications and store them for further retrieving by the client. The server only stores the last received notification for a specified message id, overwritting the existing ones. The property mapping for the notification envelope is:

Property HTTP mapping
event The HTTP message body.
reason In case of a failure notification, the HTTP response status code should be a semantically related value to the envelope reason code. The HTTP response reason phrase should be the envelope reason description value.

The expected server behavior is:

URI Method Behavior
/notifications POST The server should compose a notification envelope and send it to the LIME backend.
/notifications GET The server should return the list of id of stored notifications addressed to the request identity.
/notifications/{id} GET The server should return the stored notification with the specified id.
/notifications/{id} DELETE The server should delete the stored notification with the specified id.

Examples

Sending a received notification:

C:

POST http://localhost:8080/notifications HTTP/1.1
Content-Type: text/plain
X-To: heisenberg@breakingbad.com
Host: localhost:8080
Authorization: Basic aGVpc2VuYmVyZ0BicmVha2luZ2JhZC5jb206OTk5OTk5
Content-Length: 8
Content-Type: text/plain
X-Id: 4e28e514-8706-42b6-9ba4-5dbab0ac72b5

received


S:

HTTP/1.1 202 Accepted
Content-Type: text/plain
Server: Microsoft-HTTPAPI/2.0
X-Session-Id: b94d5f7a-0409-4eec-93c7-1b5b15d889de
Date: Thu, 02 Oct 2014 15:19:30 GMT
Content-Length: 36

4e28e514-8706-42b6-9ba4-5dbab0ac72b5

Getting all stored notifications ids:

C:

GET http://localhost:8080/notifications HTTP/1.1
Content-Type: text/plain
Host: localhost:8080
Authorization: Basic aGVpc2VuYmVyZ0BicmVha2luZ2JhZC5jb206OTk5OTk5

S:

HTTP/1.1 200 OK
Content-Type: text/plain
Server: Microsoft-HTTPAPI/2.0
X-Session-Id: 2a55a5b4-1b3e-49a8-8fba-307954e4a8ef
Date: Thu, 02 Oct 2014 15:38:05 GMT
Content-Length: 76

6bb9a442-5e10-4360-af40-d9fe19924ec2
4e28e514-8706-42b6-9ba4-5dbab0ac72b5

    

Getting a failed notification:

C:

GET http://localhost:8080/notifications/6bb9a442-5e10-4360-af40-d9fe19924ec2 HTTP/1.1
Content-Type: text/plain
Host: localhost:8080
Authorization: Basic aGVpc2VuYmVyZ0BicmVha2luZ2JhZC5jb206OTk5OTk5

S:

HTTP/1.1 400 Unsupported content type
Content-Type: text/plain
Server: Microsoft-HTTPAPI/2.0
X-Session-Id: 2a55a5b4-1b3e-49a8-8fba-307954e4a8ef
X-From: jesse@breakingbad.com/default
X-To: heisenberg@breakingbad.com/default
X-Reason-Code: 21
Date: Thu, 02 Oct 2014 15:39:42 GMT
Content-Length: 6

failed

Commands

The client can send commands requests thought the HTTP server, using the http://{host:port}/commands resource URI.

Property HTTP mapping
method The HTTP request method. The LIME-HTTP mapping is:
  • get - GET
  • set - POST
  • delete - DELETE
uri The value of the HTTP request URI, excluding the http://{host:port}/commands base host.
type Content-Type header.
resource The HTTP message body encoded according to the MIME type.
reason In case of a failure notification, the HTTP response status code should be a semantically related value to the envelope reason code. The HTTP response reason phrase should be the envelope reason description value.

The expected server behavior is:

URI Method Behavior
/commands/* POST The server should compose a command envelope with set method with the /* URI.
/commands/* GET The server should compose a command envelope with get method with the /* URI.
/commands/* DELETE The server should compose a command envelope with delete method with the /* URI.

Examples

Sending a presence command:

C:

POST http://localhost:8080/commands/presence HTTP/1.1
Host: localhost:8080
Authorization: Basic aGVpc2VuYmVyZ0BicmVha2luZ2JhZC5jb206OTk5OTk5
Content-Type: application/vnd.lime.presence+json
Content-Length: 22

{"status":"available"}

S:

HTTP/1.1 203 Created
Server: Microsoft-HTTPAPI/2.0
X-Session-Id: b94d5f7a-0409-4eec-93c7-1b5b15d889de
Date: Thu, 02 Oct 2014 15:19:30 GMT
Content-Length: 0