forked from ring-clojure/ring
-
Notifications
You must be signed in to change notification settings - Fork 6
/
SPEC
122 lines (95 loc) · 4.09 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
121
122
=== Ring Spec (Draft Version)
Ring is defined in terms of Components, Handlers, Requests, and Responses,
each of which are described below.
== Components
Ring components constitute the logic of the web application and are abstracted
form the details of the HTTP protocol. They are implemented as Clojure
functions that process a given request to generate and return a response.
A component is either an 'endpoint' or 'middleware'. An endpoint component is
used at the leaf of a component tree, i.e. it does not call any other components
to generate it's response. A 'middleware' component in contrast may invoke
other components to generate its response. We can combine 1 or more endpoints
with 0 or more middleware components to build a complete Ring 'app'. Such an
app can then be run by a Ring handler.
== Handlers
A Ring handler is a server implementation than can 'run' apps. Handlers are
responsible for implementing the HTTP protocol and abstracting the apps that
they run from the details of the protocol.
Handlers are implemented as functions of two arguments, an options map and a
Ring app. The options map provides any needed configuration to the handler, such
as the port on which to run.
Once initialized, handlers receive HTTP requests, parse them to construct an
Ring request, and then invoke their Ring app with this request as an
argument. Once the app returns a Ring response, the handler uses it to construct
and send an HTTP response to the client.
== Ring Requests
A Ring request 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 starts 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.
: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.
If a component invokes another component with an environment containing
additional keys, these keys must be namespaced using the Clojure
:name.space/key-name convention. The ring.* namespaces are reserved.
== Ring Responses
A Ring response 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, 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.
As with environments, keys other than those listed above should be appropriately
namespaced.