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