Second Life Grid Protocols/Foundation
The protocols are based on a foundation that is reused throughout the design. These protocols and design patterns should be the only basis for higher level protcols.
REST & HTTP
In the absence of other requirements, most protocols should be built on top of HTTP using REST design principles. While HTTP and REST may be argued to be less efficient than other base protocols, the advantages far outweigh the costs in the vast majority of cases: It handles many aspects that any mature protocol would have to design in such as versioning, metadata, cache semantics, and encodings. It is broadly implemented, well understood, and interoperable with many existing tools.
Services built on HTTP should follow common REST semantics. This means choosing the right method (GET, PUT, POST, DELETE, etc...) for each operation, carefully designing URL layout, and being aware of cache semantics. As much as possible, the protocols should be couched in terms of remote resources to be viewed with GET, stored with PUT, and operated upon with POST. It is recognized that this area is one of design sense and not absolutes. For example, we will assume that PUT, where sensible, may occur more than once to a given URL.
HTTP suffers from one difficult failure mode: If a client receives no response whatsoever, it cannot distinguish if the request never reached the server or if the request was delivered and acted upon but the response lost. For some functions, this kind of failure must be handled in a safe way. Certified HTTP was designed for just this case.
Where functions in this specification require such functionality, then cHTTP delivery to escrow services should be employed. However, alternatives that don't require such machinery should be favored if at all reasonable.
When functionality must be authorized to an authenticated party, these protocols should make use of capabilities. Capabilities offer a uniform method of handling authorization and divide the responsibilities of authentication, authorization and function execution to independent pieces of code. This offers greater flexibility to the implementor of both client and server sides, while making the code easier to be correct due to clean separation of concerns.
Almost all payloads in these protocols should be in the form of LLSD structures. While LLSD may not be perfect, it offers a good match with the functionality of Second Life, and is already extensively used throughout the system. The benefits of a common data encoding are manifest.
LLSD is usually encoded in XML. However, a binary encoding also exists. In general, the encoding choice should be left to the lower level transports. For example, when moved over HTTP, the encoding can be negotiated using standard mime-type negotiation ("Accept" and "Content-Type" headers). Encoding and decoding libraries exist for C++, Python, Perl and PHP.
Typically, a function will take a single LLSD as its arguments and return a single LLSD as the result. Unless the natural format for such a payload is an array (a set of answers, for example), the top level type should always be a map, even when just a single value is needed. These top level maps should be considered name-value pairs that are expected to be extended in the future. Hence code must expect and handle both additional and missing keys. This idiom is often used anywhere a map is used. Maps that are used to associate data with data should be avoided in favor of an array of maps. need an example here
Messages are a common, simple design pattern for using HTTP. A message is equivalent to a POST operation that returns only a simple status and an empty response. The status is only interpreted as success or failure and carries no additional information.
This use corresponds to the Message System of Second Life. Its use should be limited to few, if any new functions in the protocols. However, it is recognized that during transition, this form will be the easiest way to incorporate the existing functionality.
This needs its own full page write up
The HTTP design pattern fails in one case: When a domain host (agent or region) wishes to invoke a function on the viewer. In this case, due to the prevalence of NAT routers and firewalls, the host cannot assume that it can initiate a TCP connection to the viewer.
In these cases, the Event Queue service enables a host to viewer form of HTTP request to take place, even though the connections come from the viewer to the host: The viewer polls the host to both query the availability of new requests and to return the results of prior ones. This polling is not a significant drain because it is done by the "long poll" technique: If the host has no requests, rather than returning an empty result, it leaves the connection open, unanswered until it does.
The Event Queue is already in use in Second Life, though it currently only supports messages and not full HTTP transactions.
For almost all protocols, the above foundations should be used. A given function can then be defined by the following:
- Who are the invoker(s) and implementor(s)
- How is the function addressed: URL, Capability or Event?
- Transport semantics: HTTP, cHTTP or Message
- LLSD argument
- LLSD result