Skip to content
This repository
Newer
Older
100644 663 lines (466 sloc) 20.691 kb
30917ff2 » miyagawa
2009-09-30 POD fixes
1 =encoding utf-8
2
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
3 =head1 NAME
4
5 PSGI - Perl Web Server Gateway Interface Specification
6
7 =head1 ABSTRACT
8
ff0e6def » miyagawa
2009-09-07 paragraphized
9 This document specifies a standard interface between web servers and
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
10 Perl web applications or frameworks. This interface is designed to promote web application
11 portability and reduce the duplication of effort by web application
ff0e6def » miyagawa
2009-09-07 paragraphized
12 framework developers.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
13
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
14 Please keep in mind that PSGI is not Yet Another web application
0f6003f5 » miyagawa
2009-09-07 Added a note that PSGI is not an API for end users
15 framework. PSGI is a specification to decouple web server environments
38d724bf » miyagawa
2010-01-18 Promote psgi.streaming, nonblocking and run_once keys to be MUST.
16 from web application framework code. Nor is PSGI a web application
17 API. Web application developers (end users) will not run their web
18 applications directly using the PSGI interface, but instead are
19 encouraged to use frameworks that support PSGI.
0f6003f5 » miyagawa
2009-09-07 Added a note that PSGI is not an API for end users
20
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
21 =head1 TERMINOLOGY
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
22
23 =over 4
24
9fb9ea65 » milu71
2011-05-19 some more clarity in the TERMINOLOGY section
25 =item Web Servers
26
27 I<Web servers> accept HTTP requests issued by web clients,
28 dispatching those requests to web applications if configured to do so,
29 and return HTTP responses to the request-initiating clients.
30
090788ed » miyagawa
2011-06-16 cleanup
31 =item PSGI Server
32
33 A I<PSGI Server> is a Perl program providing an environment for a
34 I<PSGI application> to run in.
35
36 PSGI specifying an interface for web applications and the main purpose
37 of web applications being to be served to the Internet, a I<PSGI
38 Server> will most likely be either: part of a web server (like Apache
39 mod_perl), connected to a web server (with FastCGI, SCGI), invoked by
40 a web server (as in plain old CGI), or be a standalone web server
41 itself, written entirely or partly in Perl.
42
43 There is, however, no requirement for a I<PSGI Server> to actually be
44 a web server or part of one, as I<PSGI> only defines an interface
45 between the server and the application, not between the server and the
46 world.
47
48 A I<PSGI Server> is often also called I<PSGI Application Container>
49 because it is similar to a I<Java Servlet container>, which is Java
50 process providing an environment for I<Java Servlets>.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
51
52 =item Applications
53
9fb9ea65 » milu71
2011-05-19 some more clarity in the TERMINOLOGY section
54 I<Web applications> accept HTTP requests and return HTTP responses.
55
56 I<PSGI applications> are web applications conforming to the PSGI interface,
57 prescribing they take the form of a code reference
58 with defined input and output.
59
60 For simplicity,
61 I<PSGI Applications> will also be referred to as I<Applications>
62 for the remainder of this document.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
63
64 =item Middleware
65
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
66 I<Middleware> is a PSGI application (a code reference) I<and> a
67 I<Server>. I<Middleware> looks like an I<application> when called from a
68 I<server>, and it in turn can call other I<applications>. It can be thought of
69 a I<plugin> to extend a PSGI application.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
70
71 =item Framework developers
72
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
73 I<Framework developers> are the authors of web application frameworks. They
74 write adapters (or engines) which accept PSGI input, run a web
75 application, and return a PSGI response to the I<server>.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
76
77 =item Web application developers
78
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
79 I<Web application developers> are developers who write code on top of a web
80 application framework. These developers should never have to deal with PSGI
81 directly.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
82
30917ff2 » miyagawa
2009-09-30 POD fixes
83 =back
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
84
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
85 =head1 SPECIFICATION
86
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
87 =head2 Application
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
88
ff0e6def » miyagawa
2009-09-07 paragraphized
89 A PSGI application is a Perl code reference. It takes exactly one
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
90 argument, the environment, and returns an array reference containing exactly
ff0e6def » miyagawa
2009-09-07 paragraphized
91 three values.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
92
e0431ced » miyagawa
2009-11-08 make PSGI app a code ref
93 my $app = sub {
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
94 my $env = shift;
95 return [
96 '200',
97 [ 'Content-Type' => 'text/plain' ],
31bd78b4 » miyagawa
2009-09-07 s/objects/object/ because it sounded like an array of IO::Handle objects
98 [ "Hello World" ], # or IO::Handle-like object
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
99 ];
e0431ced » miyagawa
2009-11-08 make PSGI app a code ref
100 };
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
101
102 =head3 The Environment
103
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
104 The environment MUST be a hash reference that includes CGI-like headers, as
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
105 detailed below. The application is free to modify the environment. The
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
106 environment MUST include these keys (adopted from L<PEP
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
107 333|http://www.python.org/dev/peps/pep-0333/>,
108 L<Rack|http://rack.rubyforge.org/doc/files/SPEC.html> and
109 L<JSGI|http://jackjs.org/jsgi-spec.html>) except when they would normally be
110 empty.
111
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
112 When an environment key is described as a boolean, its value MUST conform
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
113 to Perl's notion of boolean-ness. This means that an empty string or an
114 explicit C<0> are both valid false values. If a boolean key is not present, an
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
115 application MAY treat this as a false value.
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
116
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
117 The values for all CGI keys (named without a period) MUST be a scalar
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
118 string.
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
119
120 See below for details.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
121
122 =over 4
123
124 =item *
125
ff0e6def » miyagawa
2009-09-07 paragraphized
126 C<REQUEST_METHOD>: The HTTP request method, such as "GET" or
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
127 "POST". This B<MUST NOT> be an empty string, and so is always
ff0e6def » miyagawa
2009-09-07 paragraphized
128 required.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
129
130 =item *
131
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
132 C<SCRIPT_NAME>: The initial portion of the request URL's I<path>,
133 corresponding to the application. This tells the application its
65afea5d » miyagawa
2009-09-08 apply grammer fixes from hanekomu
134 virtual "location". This may be an empty string if the application
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
135 corresponds to the server's root URI.
136
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
137 If this key is not empty, it MUST start with a forward slash (C</>).
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
138
139 =item *
140
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
141 C<PATH_INFO>: The remainder of the request URL's I<path>, designating
ff0e6def » miyagawa
2009-09-07 paragraphized
142 the virtual "location" of the request's target within the
65afea5d » miyagawa
2009-09-08 apply grammer fixes from hanekomu
143 application. This may be an empty string if the request URL targets
ff0e6def » miyagawa
2009-09-07 paragraphized
144 the application root and does not have a trailing slash. This value
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
145 should be URI decoded by servers in order to be compatible with L<RFC 3875|http://www.ietf.org/rfc/rfc3875>.
146
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
147 If this key is not empty, it MUST start with a forward slash (C</>).
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
148
149 =item *
150
c6d7946f » miyagawa
2009-10-09 added REQUEST_URI to the PSGI spec
151 C<REQUEST_URI>: The undecoded, raw request URL line. It is the raw URI
152 path and query part that appears in the HTTP C<GET /... HTTP/1.x> line
153 and doesn't contain URI scheme and host names.
154
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
155 Unlike C<PATH_INFO>, this value B<SHOULD NOT> be decoded by servers. It is an
156 application's responsibility to properly decode paths in order to map URLs to
157 application handlers if they choose to use this key instead of C<PATH_INFO>.
c6d7946f » miyagawa
2009-10-09 added REQUEST_URI to the PSGI spec
158
159 =item *
160
ff0e6def » miyagawa
2009-09-07 paragraphized
161 C<QUERY_STRING>: The portion of the request URL that follows the C<?>,
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
162 if any. This key MAY be empty, but B<MUST> always be present, even if empty.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
163
164 =item *
165
ff0e6def » miyagawa
2009-09-07 paragraphized
166 C<SERVER_NAME>, C<SERVER_PORT>: When combined with C<SCRIPT_NAME> and
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
167 C<PATH_INFO>, these keys can be used to complete the URL. Note,
ff0e6def » miyagawa
2009-09-07 paragraphized
168 however, that C<HTTP_HOST>, if present, should be used in preference
169 to C<SERVER_NAME> for reconstructing the request URL. C<SERVER_NAME>
9170aac1 » miyagawa
2010-01-06 lint pod
170 and C<SERVER_PORT> B<MUST NOT> be empty strings, and are always
ff0e6def » miyagawa
2009-09-07 paragraphized
171 required.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
172
173 =item *
174
ff0e6def » miyagawa
2009-09-07 paragraphized
175 C<SERVER_PROTOCOL>: The version of the protocol the client used to
176 send the request. Typically this will be something like "HTTP/1.0" or
177 "HTTP/1.1" and may be used by the application to determine how to
178 treat any HTTP request headers.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
179
180 =item *
181
575189dd » miyagawa
2009-10-28 update CONTENT_LENGTH/CONTENT_TYPE existence
182 C<CONTENT_LENGTH>: The length of the content in bytes, as an
183 integer. The presence or absence of this key should correspond to the
184 presence or absence of HTTP Content-Length header in the request.
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
185
186 =item *
187
575189dd » miyagawa
2009-10-28 update CONTENT_LENGTH/CONTENT_TYPE existence
188 C<CONTENT_TYPE>: The request's MIME type, as specified by the client.
189 The presence or absence of this key should correspond to the presence
190 or absence of HTTP Content-Type header in the request.
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
191
192 =item *
193
194 C<HTTP_*> Keys: These keys correspond to the client-supplied
195 HTTP request headers. The presence or absence of these keys should
65afea5d » miyagawa
2009-09-08 apply grammer fixes from hanekomu
196 correspond to the presence or absence of the appropriate HTTP header
ff0e6def » miyagawa
2009-09-07 paragraphized
197 in the request.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
198
5ba65eef » polettix
2011-06-25 added explanation of HTTP_* keys computing
199 The key is obtained converting the HTTP header field name to upper
200 case, replacing all occurrences of hyphens C<-> with
201 underscores C<_> and prepending C<HTTP_>, as in
202 L<RFC 3875|http://www.ietf.org/rfc/rfc3875>.
203
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
204 If there are multiple header lines sent with the same key, the server
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
205 should treat them as if they were sent in one line and combine them
206 with C<, >, as in L<RFC 2616|http://www.ietf.org/rfc/rfc2616>.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
207
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
208 =back
209
ea3841a6 » miyagawa
2012-04-29 Mention more CGI variables ala PEP 333. Fixes #19
210 A server should attempt to provide as many other CGI variables as are
211 applicable. Note, however, that an application that uses any CGI
212 variables other than the ones listed above are necessarily
213 non-portable to web servers that do not support the relevant
214 extensions.
215
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
216 In addition to the keys above, the PSGI environment MUST also include these
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
217 PSGI-specific keys:
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
218
219 =over 4
220
221 =item *
222
1dc8a402 » miyagawa
2010-01-18 upped psgi.version to [1,1]
223 C<psgi.version>: An array reference [1,1] representing this version of
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
224 PSGI. The first number is the major version and the second it the minor
225 version.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
226
227 =item *
228
229 C<psgi.url_scheme>: A string C<http> or C<https>, depending on the request URL.
230
231 =item *
232
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
233 C<psgi.input>: the input stream. See below for details.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
234
235 =item *
236
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
237 C<psgi.errors>: the error stream. See below for details.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
238
eee76555 » miyagawa
2009-09-09 Added psgi.multithread and psgi.multiprocess per discussion on about …
239 =item *
240
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
241 C<psgi.multithread>: This is a boolean value, which MUST be true if the
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
242 application may be simultaneously invoked by another thread in the same
243 process, false otherwise.
eee76555 » miyagawa
2009-09-09 Added psgi.multithread and psgi.multiprocess per discussion on about …
244
245 =item *
246
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
247 C<psgi.multiprocess>: This is a boolean value, which MUST be true if an
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
248 equivalent application object may be simultaneously invoked by another
249 process, false otherwise.
eee76555 » miyagawa
2009-09-09 Added psgi.multithread and psgi.multiprocess per discussion on about …
250
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
251 =item *
252
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
253 C<psgi.run_once>: A boolean which is true if the server expects (but does not
254 guarantee!) that the application will only be invoked this one time during
255 the life of its containing process. Normally, this will only be true for a
ff0e6def » miyagawa
2009-09-07 paragraphized
256 server based on CGI (or something similar).
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
257
258 =item *
259
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
260 C<psgi.nonblocking>: A boolean which is true if the server is calling the
261 application in an non-blocking event loop.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
262
667bda22 » miyagawa
2009-10-21 Draft streaming response
263 =item *
264
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
265 C<psgi.streaming>: A boolean which is true if the server supports callback
266 style delayed response and streaming writer object.
667bda22 » miyagawa
2009-10-21 Draft streaming response
267
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
268 =back
269
f43792eb » miyagawa
2010-01-18 added psgix.logger and psgix.session
270 The server or the application can store its own data in the
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
271 environment as well. These keys MUST contain at least one dot, and
272 SHOULD be prefixed uniquely.
f43792eb » miyagawa
2010-01-18 added psgix.logger and psgix.session
273
274 The C<psgi.> prefix is reserved for use with the PSGI core
275 specification, and C<psgix.> prefix is reserved for officially blessed
276 extensions. These prefixes B<MUST NOT> be used by other servers or
426ef61a » karenetheridge
2011-12-14 fix typo s/extention/extension/
277 application. See L<psgi-extensions|PSGI::Extensions> for the list of
278 officially approved extensions.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
279
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
280 The environment B<MUST NOT> contain keys named C<HTTP_CONTENT_TYPE> or
281 C<HTTP_CONTENT_LENGTH>.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
282
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
283 One of C<SCRIPT_NAME> or C<PATH_INFO> MUST be set. When
4bf74c0b » miyagawa
2010-01-28 "PATH_INFO should be '/' when SCRIPT_NAME is empty" is only valid when
284 C<REQUEST_URI> is C</>, C<PATH_INFO> should be C</> and C<SCRIPT_NAME>
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
285 should be empty. C<SCRIPT_NAME> B<MUST NOT> be C</>, but MAY be
4bf74c0b » miyagawa
2010-01-28 "PATH_INFO should be '/' when SCRIPT_NAME is empty" is only valid when
286 empty.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
287
288 =head3 The Input Stream
289
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
290 The input stream in C<psgi.input> is an L<IO::Handle>-like object which
ff0e6def » miyagawa
2009-09-07 paragraphized
291 streams the raw HTTP POST or PUT data. If it is a file handle then it
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
292 MUST be opened in binary mode. The input stream B<MUST> respond to
293 C<read> and MAY implement C<seek>.
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
294
295 Perl's built-in filehandles or L<IO::Handle> based objects should work as-is
296 in a PSGI server. Application developers B<SHOULD NOT> inspect the type or
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
297 class of the stream. Instead, they SHOULD simply call C<read> on the object.
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
298
299 Application developers B<SHOULD NOT> use Perl's built-in C<read> or iterator
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
300 (C<< <$fh> >>) to read from the input stream. Instead, application
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
301 developers should call C<read> as a method (C<< $fh->read >>) to allow for
302 duck typing.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
303
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
304 Framework developers, if they know the input stream will be used with the
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
305 built-in read() in any upstream code they can't touch, SHOULD use PerlIO or
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
306 a tied handle to work around with this problem.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
307
4c287d3f » avar
2012-09-29 PSGI.pod: fix typo s/objet/object/
308 The input stream object is expected to provide a C<read> method:
e764e4f8 » miyagawa
2009-09-07 Added a note about read() built-in
309
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
310 =over 4
311
312 =item read
313
314 $input->read($buf, $len [, $offset ]);
315
a87c2634 » miyagawa
2009-10-04 mentions return value of psgi.input and psgi.errors methods
316 Returns the number of characters actually read, 0 at end of file, or
317 undef if there was an error.
318
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
319 =back
320
dc1543ba » miyagawa
2011-05-01 psgi.input MUST have seek() when psgix.input.buffered is true
321 It may also implement an optional C<seek> method. If
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
322 C<psgix.input.buffered> environment is true, it MUST implement the
dc1543ba » miyagawa
2011-05-01 psgi.input MUST have seek() when psgix.input.buffered is true
323 C<seek> method.
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
324
325 =over 4
326
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
327 =item seek
328
329 $input->seek($pos, $whence);
330
a87c2634 » miyagawa
2009-10-04 mentions return value of psgi.input and psgi.errors methods
331 Returns 1 on success, 0 otherwise.
332
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
333 =back
334
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
335 See the L<IO::Handle> documentation for more details on exactly how these
336 methods should work.
337
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
338 =head3 The Error Stream
339
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
340 The error stream in C<psgi.errors> is an L<IO::Handle>-like object to
341 print errors. The error stream must implement a C<print> method.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
342
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
343 As with the input stream, Perl's built-in filehandles or L<IO::Handle> based
344 objects should work as-is in a PSGI server. Application developers B<SHOULD
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
345 NOT> inspect the type or class of the stream. Instead, they SHOULD simply
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
346 call C<print> on the object.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
347
348 =over 4
349
350 =item print
351
352 $errors->print($error);
353
a87c2634 » miyagawa
2009-10-04 mentions return value of psgi.input and psgi.errors methods
354 Returns true if successful.
355
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
356 =back
357
358 =head3 The Response
359
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
360 Applications MUST return a response as either a three element array
f745e834 » miyagawa
2010-01-06 array or code ref. That is MUST per PSGI spec POV. If you return some…
361 reference, or a code reference for a delayed/streaming response.
0d57abbf » miyagawa
2009-10-21 some wording fixes
362
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
363 The response array reference consists of the following elements:
667bda22 » miyagawa
2009-10-21 Draft streaming response
364
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
365 =head4 Status
366
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
367 An HTTP status code. This MUST be an integer greater than or equal to 100,
368 and SHOULD be an HTTP status code as documented in L<RFC
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
369 2616|http://www.w3.org/Protocols/rfc2616>.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
370
371 =head4 Headers
372
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
373 The headers MUST be an array reference (B<not> a hash reference)
374 of key/value pairs. This means it MUST contain an even number of elements.
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
375
1641d76c » miyagawa
2010-05-12 typo
376 The header B<MUST NOT> contain a key named C<Status>, nor any keys with C<:>
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
377 or newlines in their name. It B<MUST NOT> contain any keys that end in C<-> or
378 C<_>.
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
379
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
380 All keys MUST consist only of letters, digits, C<_> or C<->. All
381 keys MUST start with a letter. The value of the header B<MUST> be a
39b51686 » miyagawa
2011-06-21 Header values must be defined
382 scalar string and defined. The value string B<MUST NOT> contain
383 characters below octal 037 i.e. chr(31).
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
384
ff0e6def » miyagawa
2009-09-07 paragraphized
385 If the same key name appears multiple times in an array ref, those
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
386 header lines MUST be sent to the client separately (e.g. multiple
ff0e6def » miyagawa
2009-09-07 paragraphized
387 C<Set-Cookie> lines).
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
388
389 =head4 Content-Type
390
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
391 There MUST be a C<Content-Type> except when the C<Status> is 1xx, 204
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
392 or 304, in which case there B<MUST NOT> be a content type.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
393
394 =head4 Content-Length
395
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
396 There B<MUST NOT> be a C<Content-Length> header when the C<Status> is
ff0e6def » miyagawa
2009-09-07 paragraphized
397 1xx, 204 or 304.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
398
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
399 If the Status is not 1xx, 204 or 304 and there is no C<Content-Length> header,
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
400 a PSGI server MAY calculate the content length by looking at the Body. This
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
401 value can then be appended to the list of headers returned by the application.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
402
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
403 =head4 Body
404
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
405 The response body MUST be returned from the application as either
21a1479d » miyagawa
2011-06-16 The body string should be encoded, not containing any wide characters
406 an array reference or a handle containing the response body as byte
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
407 strings. The body MUST be encoded into appropriate encodings and
21a1479d » miyagawa
2011-06-16 The body string should be encoded, not containing any wide characters
408 B<MUST NOT> contain wide characters (> 255).
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
409
410 =over 4
411
412 =item *
413
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
414 If the body is an array reference, it is expected to contain an array of lines
415 which make up the body.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
416
417 my $body = [ "Hello\n", "World\n" ];
418
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
419 Note that the elements in an array reference are B<NOT REQUIRED> to end
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
420 in a newline. A server SHOULD write each elements as-is to the
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
421 client, and B<SHOULD NOT> care if the line ends with newline or not.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
422
6342aa0b » miyagawa
2009-10-28 change the variable name to be less confusing
423 An array reference with a single value is valid. So C<[ $html ]> is a valid
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
424 response body.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
425
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
426 =item *
427
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
428 The body can instead be a handle, either a Perl built-in filehandle or an
429 L<IO::Handle>-like object.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
430
431 open my $body, "</path/to/file";
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
432 open my $body, "<:via(SomePerlIO)", ...;
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
433 my $body = IO::File->new("/path/to/file");
434
cec09ef8 » milu71
2011-05-19 wrapped long lines for nicer display in 80 column terminals
435 # mock class that implements getline() and close()
436 my $body = SomeClass->new();
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
437
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
438 Servers B<SHOULD NOT> check the type or class of the body. Instead, they should
439 simply call C<getline> to iterate over the body, and
0e5b33e0 » miyagawa
2009-10-07 Updated spec: body can respond ->path.
440 call C<close> when done.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
441
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
442 Servers MAY check if the body is a real filehandle using C<fileno> and
443 C<Scalar::Util::reftype>. If the body is real filehandle, the server MAY
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
444 optimize using techniques like I<sendfile(2)>.
445
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
446 The body object MAY also respond to a C<path> method. This method is
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
447 expected to return the path to a file accessible by the server. This allows
448 the server to use this information instead of a file descriptor number to
e0431ced » miyagawa
2009-11-08 make PSGI app a code ref
449 serve the file.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
450
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
451 Servers SHOULD set the C<$/> special variable to the buffer size when
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
452 reading content from C<$body> using the C<getline> method. This is done by
453 setting C<$/> with a reference to an integer (C<$/ = \8192>).
0e5b33e0 » miyagawa
2009-10-07 Updated spec: body can respond ->path.
454
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
455 If the body filehandle is a Perl built-in filehandle L<IO::Handle> object,
456 they will respect this value. Similarly, an object which provides the same API
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
457 MAY also respect this special variable, but are not required to do so.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
458
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
459 =back
460
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
461 =head2 Delayed Response and Streaming Body
667bda22 » miyagawa
2009-10-21 Draft streaming response
462
c5aa24f2 » miyagawa
2010-01-06 psgi.streaming MAY -> SHOULD. Remove poll_cb from the Writer spec.
463 The PSGI interface allows applications and servers to provide a
464 callback-style response instead of the three-element array
465 reference. This allows for a delayed response and a streaming body
466 (server push).
467
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
468 This interface SHOULD be implemented by PSGI servers, and
469 C<psgi.streaming> environment MUST be set to true in such servers.
667bda22 » miyagawa
2009-10-21 Draft streaming response
470
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
471 To enable a delayed response, the application SHOULD return a
472 callback as its response. An application MAY check if the
c5aa24f2 » miyagawa
2010-01-06 psgi.streaming MAY -> SHOULD. Remove poll_cb from the Writer spec.
473 C<psgi.streaming> environment is true and falls back to the direct
474 response if it isn't.
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
475
476 This callback will be called with I<another> subroutine reference (referred to
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
477 as the I<responder> from now on) as its only argument. The I<responder>
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
478 should in turn be called with the standard three element array reference
479 response. This is best illustrated with an example:
667bda22 » miyagawa
2009-10-21 Draft streaming response
480
481 my $app = sub {
482 my $env = shift;
483
484 # Delays response until it fetches content from the network
485 return sub {
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
486 my $responder = shift;
487
c5aa24f2 » miyagawa
2010-01-06 psgi.streaming MAY -> SHOULD. Remove poll_cb from the Writer spec.
488 fetch_content_from_server(sub {
489 my $content = shift;
490 $responder->([ 200, $headers, [ $content ] ]);
491 });
667bda22 » miyagawa
2009-10-21 Draft streaming response
492 };
493 };
494
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
495 An application MAY omit the third element (the body) when calling
496 the I<responder>. If the body is omitted, the I<responder> MUST
c5aa24f2 » miyagawa
2010-01-06 psgi.streaming MAY -> SHOULD. Remove poll_cb from the Writer spec.
497 return I<yet another> object which implements C<write> and C<close>
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
498 methods. Again, an example illustrates this best.
667bda22 » miyagawa
2009-10-21 Draft streaming response
499
500 my $app = sub {
501 my $env = shift;
502
503 # immediately starts the response and stream the content
504 return sub {
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
505 my $responder = shift;
cec09ef8 » milu71
2011-05-19 wrapped long lines for nicer display in 80 column terminals
506 my $writer = $responder->(
507 [ 200, [ 'Content-Type', 'application/json' ]]);
667bda22 » miyagawa
2009-10-21 Draft streaming response
508
509 wait_for_events(sub {
510 my $new_event = shift;
511 if ($new_event) {
512 $writer->write($new_event->as_json . "\n");
513 } else {
514 $writer->close;
515 }
516 });
517 };
518 };
519
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
520 This delayed response and streaming API is useful if you want to
521 implement a non-blocking I/O based server streaming or long-poll Comet
5589b649 » miyagawa
2010-01-06 Some linting, and fixed wrong FAQ explanation about streaming/nonbloc…
522 push technology, but could also be used to implement unbuffered writes
523 in a blocking server.
667bda22 » miyagawa
2009-10-21 Draft streaming response
524
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
525 =head2 Middleware
526
b4d5be27 » autarch
2009-10-27 Various tweaks from discussion with miyagawa in #psgi, and line-wrapp…
527 A I<middleware> component takes another PSGI application and runs it. From the
528 perspective of a server, a middleware component is a PSGI application. From
529 the perspective of the application being run by the middleware component, the
530 middleware is the server. Generally, this will be done in order to implement
531 some sort of pre-processing on the PSGI environment hash or post-processing on
532 the response.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
533
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
534 Here's a simple example that appends a special HTTP header
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
535 I<X-PSGI-Used> to any PSGI application.
536
537 # $app is a simple PSGI application
538 my $app = sub {
539 my $env = shift;
cec09ef8 » milu71
2011-05-19 wrapped long lines for nicer display in 80 column terminals
540 return [ '200',
541 [ 'Content-Type' => 'text/plain' ],
542 [ "Hello World" ] ];
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
543 };
544
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
545 # $xheader is a piece of middleware that wraps $app
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
546 my $xheader = sub {
547 my $env = shift;
548 my $res = $app->($env);
549 push @{$res->[1]}, 'X-PSGI-Used' => 1;
550 return $res;
551 };
552
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
553 Middleware MUST behave exactly like a PSGI application from the perspective
554 of a server. Middleware MAY decide not to support the streaming interface
555 discussed earlier, but SHOULD pass through the response types that it doesn't
3e2dde3c » autarch
2009-10-27 English cleanup, rewriting parts for clarity, adding links, and small…
556 understand.
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
557
38d724bf » miyagawa
2010-01-18 Promote psgi.streaming, nonblocking and run_once keys to be MUST.
558 =head1 CHANGELOGS
559
560 1.1: 2010.02.xx
561
562 =over 4
563
564 =item *
565
f43792eb » miyagawa
2010-01-18 added psgix.logger and psgix.session
566 Added optional PSGI keys as extensions: C<psgix.logger> and C<psgix.session>.
567
568 =item *
569
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
570 C<psgi.streaming> SHOULD be implemented by PSGI servers, rather than B<MAY>.
38d724bf » miyagawa
2010-01-18 Promote psgi.streaming, nonblocking and run_once keys to be MUST.
571
572 =item *
573
574 PSGI keys C<psgi.run_once>, C<psgi.nonblocking> and C<psgi.streaming>
0b644d06 » miyagawa
2012-03-10 undo B<> for the MUST, SHOULD etc.
575 MUST be set by PSGI servers.
38d724bf » miyagawa
2010-01-18 Promote psgi.streaming, nonblocking and run_once keys to be MUST.
576
577 =item *
578
579 Removed C<poll_cb> from writer methods.
580
581 =back
582
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
583 =head1 ACKNOWLEDGEMENTS
584
585 Some parts of this specification are adopted from the following specifications.
586
587 =over 4
588
589 =item *
590
591 PEP333 Python Web Server Gateway Interface L<http://www.python.org/dev/peps/pep-0333>
592
593 =item *
594
595 Rack L<http://rack.rubyforge.org/doc/SPEC.html>
596
597 =item *
598
599 JSGI Specification L<http://jackjs.org/jsgi-spec.html>
600
601 =back
602
603 I'd like to thank authors of these great documents.
604
605 =head1 AUTHOR
606
607 Tatsuhiko Miyagawa E<lt>miyagawa@bulknews.netE<gt>
608
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
609 =head1 CONTRIBUTORS
610
611 The following people have contributed to the PSGI specification and
612 Plack implementation by commiting their code, sending patches,
613 reporting bugs, asking questions, suggesting useful advices,
614 nitpicking, chatting on IRC or commenting on my blog (in no particular
615 order):
616
617 Tokuhiro Matsuno
618 Kazuhiro Osawa
619 Yuval Kogman
620 Kazuho Oku
621 Alexis Sukrieh
048f9a3f » miyagawa
2009-09-30 update Dann's name. README links to the site
622 Takatoshi Kitano
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
623 Stevan Little
624 Daisuke Murase
625 mala
626 Pedro Melo
627 Jesse Luehrs
628 John Beppu
629 Shawn M Moore
630 Mark Stosberg
631 Matt S Trout
632 Jesse Vincent
633 Chia-liang Kao
634 Dave Rolsky
635 Hans Dieter Pearcey
636 Randy J Ray
637 Benjamin Trott
638 Max Maischein
639 Slaven Rezić
640 Marcel Grünauer
641 Masayoshi Sekimura
642 Brock Wilcox
643 Piers Cawley
ecdb6c01 » miyagawa
2009-09-16 added some HTTP::Engine contributors
644 Daisuke Maki
645 Kang-min Liu
2b08fe38 » miyagawa
2009-10-07 oops
646 Yasuhiro Matsumoto
5623139b » miyagawa
2009-09-23 changed the Content-Length from SHOULD to MAY
647 Ash Berlin
31284b9c » miyagawa
2009-09-29 Added Artur for his advice around gearman/schwartz
648 Artur Bergman
ba2001a8 » miyagawa
2009-10-01 more questions around HTTP::Engine confusions
649 Simon Cozens
650 Scott McWhirter
a87c2634 » miyagawa
2009-10-04 mentions return value of psgi.input and psgi.errors methods
651 Jiro Nishiguchi
01b3c476 » miyagawa
2009-10-07 Sorry!
652 Masahiro Chiba
1ef1c9c2 » miyagawa
2009-10-12 Added patspam for his webgui work
653 Patrick Donelan
d7fc7bbe » miyagawa
2009-10-15 Added frodwith for helping us sort out the non-blocking from POE deve…
654 Paul Driver
93432fb2 » miyagawa
2010-01-11 Added rafl
655 Florian Ragwitz
1173dc05 » miyagawa
2009-09-16 New spec: feedbacks got merged.
656
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
657 =head1 COPYRIGHT AND LICENSE
658
f9641b1f » miyagawa
2011-06-16 move extensions to PSGI::Extentions
659 Copyright Tatsuhiko Miyagawa, 2009-2011.
e85dbb3b » miyagawa
2009-09-07 First draft of the PSGI spec and FAQ.
660
661 This document is licensed under the Creative Commons license by-sa.
662
663 =cut
Something went wrong with that request. Please try again.