Permalink
Newer
100644
117 lines (89 sloc)
3.65 KB
|
60fba46
|
||
| 1 | === Ring Spec (1.0) | |
|
9d80bfa
|
||
| 2 | Ring is defined in terms of handlers, middleware, adapters, requests maps, and | |
| 3 | response maps, each of which are described below. | |
|
68e08fb
|
||
| 4 | ||
| 5 | ||
|
37ff268
|
||
| 6 | == Handlers | |
|
9d80bfa
|
||
| 7 | Ring handlers constitute the core logic of the web application. Handlers are | |
| 8 | implemented as Clojure functions that process a given request map to generate | |
| 9 | and return a response map. | |
|
68e08fb
|
||
| 10 | ||
| 11 | ||
|
37ff268
|
||
| 12 | == Middleware | |
| 13 | Ring middleware augments the functionality of handlers by invoking them in the | |
|
24fe773
|
||
| 14 | process of generating responses. Typically middleware will be implemented as a | |
| 15 | higher-order function that takes one or more handlers and configuration options | |
|
37ff268
|
||
| 16 | as arguments and returns a new handler with the desired compound behavior. | |
| 17 | ||
| 18 | ||
| 19 | == Adapters | |
| 20 | Handlers are run via Ring adapters, which are in turn responsible for | |
| 21 | implementing the HTTP protocol and abstracting the handlers that they run from | |
| 22 | the details of the protocol. | |
|
68e08fb
|
||
| 23 | ||
|
cbeebac
|
||
| 24 | Adapters are implemented as functions of two arguments: a handler and an options | |
| 25 | map. The options map provides any needed configuration to the adapter, such as | |
| 26 | the port on which to run. | |
|
68e08fb
|
||
| 27 | ||
|
37ff268
|
||
| 28 | Once initialized, adapters receive HTTP requests, parse them to construct an | |
| 29 | request map, and then invoke their handler with this request map as an | |
| 30 | argument. Once the handler returns a response map, the adapter uses it to | |
| 31 | construct and send an HTTP response to the client. | |
|
68e08fb
|
||
| 32 | ||
| 33 | ||
|
37ff268
|
||
| 34 | == Request Map | |
| 35 | A request map is a Clojure map containing at least the following keys and | |
|
68e08fb
|
||
| 36 | corresponding values: | |
| 37 | ||
| 38 | :server-port | |
| 39 | (Required, Integer) | |
| 40 | The port on which the request is being handled. | |
| 41 | ||
| 42 | :server-name | |
| 43 | (Required, String) | |
| 44 | The resolved server name, or the server IP address. | |
| 45 | ||
| 46 | :remote-addr | |
| 47 | (Required, String) | |
| 48 | The IP address of the client or the last proxy that sent the request. | |
| 49 | ||
| 50 | :uri | |
| 51 | (Required, String) | |
|
7629093
|
||
| 52 | The request URI. Must start with "/". | |
|
68e08fb
|
||
| 53 | ||
| 54 | :query-string | |
| 55 | (Optional, String) | |
| 56 | The query string, if present. | |
| 57 | ||
| 58 | :scheme | |
| 59 | (Required, Keyword) | |
| 60 | The transport protocol, must be one of :http or :https. | |
| 61 | ||
| 62 | :request-method | |
| 63 | (Required, Keyword) | |
| 64 | The HTTP request method, must be one of :get, :head, :options, :put, :post, or | |
| 65 | :delete. | |
| 66 | ||
| 67 | :content-type | |
| 68 | (Optional, String) | |
| 69 | The MIME type of the request body, if known. | |
| 70 | ||
| 71 | :content-length | |
| 72 | (Optional, Integer) | |
| 73 | The number of bytes in the request body, if known. | |
| 74 | ||
| 75 | :character-encoding | |
| 76 | (Optional, String) | |
| 77 | The name of the character encoding used in the request body, if known. | |
| 78 | ||
| 79 | :headers | |
| 80 | (Required, IPersistentMap) | |
| 81 | A Clojure map of downcased header name Strings to corresponding header value | |
| 82 | Strings. | |
| 83 | ||
| 84 | :body | |
| 85 | (Optional, InputStream) | |
| 86 | An InputStream for the request body, if present. | |
| 87 | ||
| 88 | ||
|
37ff268
|
||
| 89 | == Response Map | |
| 90 | A response map is a Clojure map containing at least the following keys and corresponding values: | |
|
68e08fb
|
||
| 91 | ||
| 92 | :status | |
| 93 | (Required, Integer) | |
| 94 | The HTTP status code, must be greater than or equal to 100. | |
| 95 | ||
| 96 | :headers | |
| 97 | (Required, IPersistentMap) | |
| 98 | A Clojure map of HTTP header names to header values. These values may be | |
| 99 | either Strings, in which case one name/value header will be sent in the | |
| 100 | HTTP response, or a seq of Strings, in which case a name/value header will be | |
| 101 | sent for each such String value. | |
| 102 | ||
| 103 | :body | |
|
85690ef
|
||
| 104 | (Optional, {String, ISeq, File, InputStream}) | |
|
68e08fb
|
||
| 105 | A representation of the response body, if a response body is appropriate for | |
| 106 | the response's status code. The respond body is handled according to its type: | |
| 107 | String: | |
| 108 | Contents are sent to the client as-is. | |
|
30598be
|
||
| 109 | ISeq: | |
| 110 | Each element of the seq is sent to the client as a string. | |
|
68e08fb
|
||
| 111 | File: | |
| 112 | Contents at the specified location are sent to the client. The server may | |
| 113 | use an optimized method to send the file if such a method is available. | |
| 114 | InputStream: | |
| 115 | Contents are consumed from the stream and sent to the client. When the | |
| 116 | stream is exhausted, it is .close'd. |