Improved documentation for `Rack::Builder`.
[rack.git] / SPEC.rdoc
blob802195550990297ff801db2947d434e36f6a4237
1 This specification aims to formalize the Rack protocol. You
2 can (and should) use Rack::Lint to enforce it.
4 When you develop middleware, be sure to add a Lint before and
5 after to catch all mistakes.
7 = Rack applications
9 A Rack application is a Ruby object (not a class) that
10 responds to +call+.
11 It takes exactly one argument, the *environment*
12 and returns a non-frozen Array of exactly three values:
13 The *status*,
14 the *headers*,
15 and the *body*.
17 == The Environment
19 The environment must be an unfrozen instance of Hash that includes
20 CGI-like headers. The Rack application is free to modify the
21 environment.
23 The environment is required to include these variables
24 (adopted from {PEP 333}[https://peps.python.org/pep-0333/]), except when they'd be empty, but see
25 below.
26 <tt>REQUEST_METHOD</tt>:: The HTTP request method, such as
27                           "GET" or "POST". This cannot ever
28                           be an empty string, and so is
29                           always required.
30 <tt>SCRIPT_NAME</tt>:: The initial portion of the request
31                        URL's "path" that corresponds to the
32                        application object, so that the
33                        application knows its virtual
34                        "location". This may be an empty
35                        string, if the application corresponds
36                        to the "root" of the server.
37 <tt>PATH_INFO</tt>:: The remainder of the request URL's
38                      "path", designating the virtual
39                      "location" of the request's target
40                      within the application. This may be an
41                      empty string, if the request URL targets
42                      the application root and does not have a
43                      trailing slash. This value may be
44                      percent-encoded when originating from
45                      a URL.
46 <tt>QUERY_STRING</tt>:: The portion of the request URL that
47                         follows the <tt>?</tt>, if any. May be
48                         empty, but is always required!
49 <tt>SERVER_NAME</tt>:: When combined with <tt>SCRIPT_NAME</tt> and
50                        <tt>PATH_INFO</tt>, these variables can be
51                        used to complete the URL. Note, however,
52                        that <tt>HTTP_HOST</tt>, if present,
53                        should be used in preference to
54                        <tt>SERVER_NAME</tt> for reconstructing
55                        the request URL.
56                        <tt>SERVER_NAME</tt> can never be an empty
57                        string, and so is always required.
58 <tt>SERVER_PORT</tt>:: An optional +Integer+ which is the port the
59                        server is running on. Should be specified if
60                        the server is running on a non-standard port.
61 <tt>SERVER_PROTOCOL</tt>:: A string representing the HTTP version used
62                            for the request.
63 <tt>HTTP_</tt> Variables:: Variables corresponding to the
64                            client-supplied HTTP request
65                            headers (i.e., variables whose
66                            names begin with <tt>HTTP_</tt>). The
67                            presence or absence of these
68                            variables should correspond with
69                            the presence or absence of the
70                            appropriate HTTP header in the
71                            request. See
72                            {RFC3875 section 4.1.18}[https://tools.ietf.org/html/rfc3875#section-4.1.18]
73                            for specific behavior.
74 In addition to this, the Rack environment must include these
75 Rack-specific variables:
76 <tt>rack.version</tt>:: The Array representing this version of Rack
77                         See Rack::VERSION, that corresponds to
78                         the version of this SPEC.
79 <tt>rack.url_scheme</tt>:: +http+ or +https+, depending on the
80                            request URL.
81 <tt>rack.input</tt>:: See below, the input stream.
82 <tt>rack.errors</tt>:: See below, the error stream.
83 <tt>rack.hijack?</tt>:: present and true if the server supports
84                         connection hijacking. See below, hijacking.
85 <tt>rack.hijack</tt>:: an object responding to #call that must be
86                        called at least once before using
87                        rack.hijack_io.
88                        It is recommended #call returns rack.hijack_io
89                        as well as setting it in env if necessary.
90 <tt>rack.hijack_io</tt>:: if rack.hijack? is true, and rack.hijack
91                           has received #call, this will contain
92                           an object resembling an IO. See hijacking.
93 Additional environment specifications have approved to
94 standardized middleware APIs. None of these are required to
95 be implemented by the server.
96 <tt>rack.session</tt>:: A hash-like interface for storing
97                         request session data.
98                         The store must implement:
99                         store(key, value)         (aliased as []=);
100                         fetch(key, default = nil) (aliased as []);
101                         delete(key);
102                         clear;
103                         to_hash (returning unfrozen Hash instance);
104 <tt>rack.logger</tt>:: A common object interface for logging messages.
105                        The object must implement:
106                         info(message, &block)
107                         debug(message, &block)
108                         warn(message, &block)
109                         error(message, &block)
110                         fatal(message, &block)
111 <tt>rack.multipart.buffer_size</tt>:: An Integer hint to the multipart parser as to what chunk size to use for reads and writes.
112 <tt>rack.multipart.tempfile_factory</tt>:: An object responding to #call with two arguments, the filename and content_type given for the multipart form field, and returning an IO-like object that responds to #<< and optionally #rewind. This factory will be used to instantiate the tempfile for each multipart form file upload field, rather than the default class of Tempfile.
113 The server or the application can store their own data in the
114 environment, too.  The keys must contain at least one dot,
115 and should be prefixed uniquely.  The prefix <tt>rack.</tt>
116 is reserved for use with the Rack core distribution and other
117 accepted specifications and must not be used otherwise.
119 The <tt>SERVER_PORT</tt> must be an Integer if set.
120 The <tt>SERVER_NAME</tt> must be a valid authority as defined by RFC7540.
121 The <tt>HTTP_HOST</tt> must be a valid authority as defined by RFC7540.
122 The <tt>SERVER_PROTOCOL</tt> must match the regexp <tt>HTTP/\d(\.\d)?</tt>.
123 If the <tt>HTTP_VERSION</tt> is present, it must equal the <tt>SERVER_PROTOCOL</tt>.
124 The environment must not contain the keys
125 <tt>HTTP_CONTENT_TYPE</tt> or <tt>HTTP_CONTENT_LENGTH</tt>
126 (use the versions without <tt>HTTP_</tt>).
127 The CGI keys (named without a period) must have String values.
128 If the string values for CGI keys contain non-ASCII characters,
129 they should use ASCII-8BIT encoding.
130 There are the following restrictions:
131 * <tt>rack.version</tt> must be an array of Integers.
132 * <tt>rack.url_scheme</tt> must either be +http+ or +https+.
133 * There must be a valid input stream in <tt>rack.input</tt>.
134 * There must be a valid error stream in <tt>rack.errors</tt>.
135 * There may be a valid hijack stream in <tt>rack.hijack_io</tt>
136 * The <tt>REQUEST_METHOD</tt> must be a valid token.
137 * The <tt>SCRIPT_NAME</tt>, if non-empty, must start with <tt>/</tt>
138 * The <tt>PATH_INFO</tt>, if non-empty, must start with <tt>/</tt>
139 * The <tt>CONTENT_LENGTH</tt>, if given, must consist of digits only.
140 * One of <tt>SCRIPT_NAME</tt> or <tt>PATH_INFO</tt> must be
141   set. <tt>PATH_INFO</tt> should be <tt>/</tt> if
142   <tt>SCRIPT_NAME</tt> is empty.
143   <tt>SCRIPT_NAME</tt> never should be <tt>/</tt>, but instead be empty.
145 === The Input Stream
147 The input stream is an IO-like object which contains the raw HTTP
148 POST data.
149 When applicable, its external encoding must be "ASCII-8BIT" and it
150 must be opened in binary mode, for Ruby 1.9 compatibility.
151 The input stream must respond to +gets+, +each+, and +read+.
152 * +gets+ must be called without arguments and return a string,
153   or +nil+ on EOF.
154 * +read+ behaves like IO#read.
155   Its signature is <tt>read([length, [buffer]])</tt>.
157   If given, +length+ must be a non-negative Integer (>= 0) or +nil+,
158   and +buffer+ must be a String and may not be nil.
160   If +length+ is given and not nil, then this method reads at most
161   +length+ bytes from the input stream.
163   If +length+ is not given or nil, then this method reads
164   all data until EOF.
166   When EOF is reached, this method returns nil if +length+ is given
167   and not nil, or "" if +length+ is not given or is nil.
169   If +buffer+ is given, then the read data will be placed
170   into +buffer+ instead of a newly created String object.
171 * +each+ must be called without arguments and only yield Strings.
172 * +close+ must never be called on the input stream.
174 === The Error Stream
176 The error stream must respond to +puts+, +write+ and +flush+.
177 * +puts+ must be called with a single argument that responds to +to_s+.
178 * +write+ must be called with a single argument that is a String.
179 * +flush+ must be called without arguments and must be called
180   in order to make the error appear for sure.
181 * +close+ must never be called on the error stream.
183 === Hijacking
185 ==== Request (before status)
187 If rack.hijack? is true then rack.hijack must respond to #call.
188 rack.hijack must return the io that will also be assigned (or is
189 already present, in rack.hijack_io.
191 rack.hijack_io must respond to:
192 <tt>read, write, read_nonblock, write_nonblock, flush, close,
193 close_read, close_write, closed?</tt>
195 The semantics of these IO methods must be a best effort match to
196 those of a normal ruby IO or Socket object, using standard
197 arguments and raising standard exceptions. Servers are encouraged
198 to simply pass on real IO objects, although it is recognized that
199 this approach is not directly compatible with SPDY and HTTP 2.0.
201 IO provided in rack.hijack_io should preference the
202 IO::WaitReadable and IO::WaitWritable APIs wherever supported.
204 There is a deliberate lack of full specification around
205 rack.hijack_io, as semantics will change from server to server.
206 Users are encouraged to utilize this API with a knowledge of their
207 server choice, and servers may extend the functionality of
208 hijack_io to provide additional features to users. The purpose of
209 rack.hijack is for Rack to "get out of the way", as such, Rack only
210 provides the minimum of specification and support.
212 If rack.hijack? is false, then rack.hijack should not be set.
214 If rack.hijack? is false, then rack.hijack_io should not be set.
216 ==== Response (after headers)
218 It is also possible to hijack a response after the status and headers
219 have been sent.
220 In order to do this, an application may set the special header
221 <tt>rack.hijack</tt> to an object that responds to <tt>call</tt>
222 accepting an argument that conforms to the <tt>rack.hijack_io</tt>
223 protocol.
225 After the headers have been sent, and this hijack callback has been
226 called, the application is now responsible for the remaining lifecycle
227 of the IO. The application is also responsible for maintaining HTTP
228 semantics. Of specific note, in almost all cases in the current SPEC,
229 applications will have wanted to specify the header Connection:close in
230 HTTP/1.1, and not Connection:keep-alive, as there is no protocol for
231 returning hijacked sockets to the web server. For that purpose, use the
232 body streaming API instead (progressively yielding strings via each).
234 Servers must ignore the <tt>body</tt> part of the response tuple when
235 the <tt>rack.hijack</tt> response API is in use.
237 The special response header <tt>rack.hijack</tt> must only be set
238 if the request env has <tt>rack.hijack?</tt> <tt>true</tt>.
240 ==== Conventions
242 * Middleware should not use hijack unless it is handling the whole
243   response.
244 * Middleware may wrap the IO object for the response pattern.
245 * Middleware should not wrap the IO object for the request pattern. The
246   request pattern is intended to provide the hijacker with "raw tcp".
248 == The Response
250 === The Status
252 This is an HTTP status. It must be an Integer greater than or equal to
253 100.
255 === The Headers
257 The headers must be a unfrozen Hash.
258 The header keys must be Strings.
259 Special headers starting "rack." are for communicating with the
260 server, and must not be sent back to the client.
261 The header must not contain a +Status+ key.
262 Header keys must conform to RFC7230 token specification, i.e. cannot
263 contain non-printable ASCII, DQUOTE or "(),/:;<=>?@[\]{}".
264 Header keys must not contain uppercase ASCII characters (A-Z).
265 Header values must be either a String instance,
266 or an Array of String instances,
267 such that each String instance must not contain characters below 037.
269 === The content-type
271 There must not be a <tt>content-type</tt> header key when the +Status+ is 1xx,
272 204, or 304.
274 === The content-length
276 There must not be a <tt>content-length</tt> header key when the
277 +Status+ is 1xx, 204, or 304.
279 === The Body
281 The Body is typically an +Array+ of +String+ instances, an enumerable
282 that yields +String+ instances, a +Proc+ instance, or a File-like
283 object.
285 The Body must respond to +each+ or +call+. It may optionally respond to
286 +to_path+.
288 A Body that responds to +each+ is considered to be an Enumerable Body.
290 A Body that responds to +call+ is considered to be a Streaming Body.
292 A Body that responds to +to_path+ is expected to generate the same
293 content as would be produced by reading a local file opened with the
294 path returned by calling +to_path+.
296 A body that responds to both +each+ and +call+ must be treated as an
297 Enumerable Body, not a Streaming Body. If it responds to +each+, you
298 must call +each+ and not +call+. If the body doesn't respond to
299 +each+, then you can assume it responds to +call+.
301 ==== Enumerable Body
303 The Enumerable Body must respond to +each+.
304 It must only be called once.
305 and must only yield String values.
307 The Body itself should not be an instance of String, as this will
308 break in Ruby 1.9.
310 Middleware must not call +each+ directly on the Body.
311 Instead, middleware can return a new Body that calls +each+ on the
312 original Body, yielding at least once per iteration.
314 If the Body responds to +to_ary+, it must return an Array whose
315 contents are identical to that produced by calling +each+.
316 Middleware may call +to_ary+ directly on the Body and return a new Body in its place.
317 In other words, middleware can only process the Body directly if it responds to +to_ary+.
319 If the Body responds to +close+, it will be called after iteration. If
320 the original Body is replaced by a new Body, the new Body
321 must close the original Body after iteration, if it responds to +close+.
322 If the Body responds to both +to_ary+ and +close+, its
323 implementation of +to_ary+ must call +close+ after iteration.
325 If the Body responds to +to_path+, it must return a String
326 identifying the location of a file whose contents are identical
327 to that produced by calling +each+; this may be used by the
328 server as an alternative, possibly more efficient way to
329 transport the response.
331 The Body commonly is an Array of Strings, the application
332 instance itself, or a File-like object.
334 ==== Streaming Body
336 The Streaming Body must respond to +call+.
337 It must only be called once.
338 It takes a +stream+ argument.
340 The +stream+ argument must implement:
341 <tt>read, write, flush, close, close_read, close_write, closed?</tt>
343 The semantics of these IO methods must be a best effort match to
344 those of a normal Ruby IO or Socket object, using standard arguments
345 and raising standard exceptions. Servers are encouraged to simply
346 pass on real IO objects, although it is recognized that this approach
347 is not directly compatible with HTTP/2.
349 == Thanks
350 Some parts of this specification are adopted from {PEP 333 – Python Web Server Gateway Interface v1.0}[https://peps.python.org/pep-0333/]
351 I'd like to thank everyone involved in that effort.