Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 511 lines (346 sloc) 14.336 kb
30917ff @miyagawa POD fixes
miyagawa authored
1 =encoding utf-8
2
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
3 =head1 NAME
4
5 PSGI - Perl Web Server Gateway Interface Specification
6
7 =head1 ABSTRACT
8
ff0e6de @miyagawa paragraphized
miyagawa authored
9 This document specifies a standard interface between web servers and
10 Perl web applications or frameworks, to promote web application
11 portability and reduce the duplicated efforts by web application
12 framework developers.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
13
0f6003f @miyagawa Added a note that PSGI is not an API for end users
miyagawa authored
14 Keep in mind that PSGI is not Yet Another web application
15 framework. PSGI is a specification to decouple web server environments
65afea5 @miyagawa apply grammer fixes from hanekomu
miyagawa authored
16 from web application framework code. PSGI is also not the web
0f6003f @miyagawa Added a note that PSGI is not an API for end users
miyagawa authored
17 application API. Web application developers (end users) are not
65afea5 @miyagawa apply grammer fixes from hanekomu
miyagawa authored
18 supposed to run their web applications directly using the PSGI
19 interface, but instead are encouraged to use frameworks that
20 support PSGI, or use the helper implementations like Plack (more on
21 that later).
0f6003f @miyagawa Added a note that PSGI is not an API for end users
miyagawa authored
22
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
23 =head1 TERMINOLOGIES
24
25 =over 4
26
27 =item Servers
28
a19c5ba @miyagawa minor grammer fixes
miyagawa authored
29 Servers are web servers that accept HTTP requests, dispatch the
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
30 requests to the web appilcations and return the HTTP response to the
31 clients. In PSGI specification it's a Perl process that's running
a19c5ba @miyagawa minor grammer fixes
miyagawa authored
32 inside an HTTP server (e.g. mod_perl in Apache), a daemon process
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
33 called from a web server (e.g. FastCGI daemon) or a pure perl HTTP
34 server.
35
a19c5ba @miyagawa minor grammer fixes
miyagawa authored
36 Servers are also called I<PSGI implementations> as well as
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
37 I<Backends>.
38
39 =item Applications
40
a19c5ba @miyagawa minor grammer fixes
miyagawa authored
41 Applications are web applications that actually get HTTP requests
42 and return HTTP response. In PSGI it's a code reference: see below.
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
43
44 =item Middleware
45
46 Middleware is a PSGI application, which is a code reference, but also
47 runs like a server to run other applications. It can be thought of a
48 I<plugin> to extend PSGI application: see below.
49
50 =item Framework developers
51
a19c5ba @miyagawa minor grammer fixes
miyagawa authored
52 Framework developers are authors of web application frameworks. They
53 need to write adapters (or engines) to read PSGI input, then run the
54 application logic and returns PSGI response to the server.
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
55
56 =item Web application developers
57
58 Web application developers are developers who write code that uses one
59 of the web application framework that uses PSGI interface. They
a19c5ba @miyagawa minor grammer fixes
miyagawa authored
60 usually don't need to deal with nor care about PSGI protocol at all.
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
61
30917ff @miyagawa POD fixes
miyagawa authored
62 =back
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
63
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
64 =head1 SPECIFICATION
65
66 =head2 Applications
67
ff0e6de @miyagawa paragraphized
miyagawa authored
68 A PSGI application is a Perl code reference. It takes exactly one
69 argument, the environment and returns an array reference of exactly
70 three values.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
71
72 sub app {
73 my $env = shift;
74 return [
75 '200',
76 [ 'Content-Type' => 'text/plain' ],
31bd78b @miyagawa s/objects/object/ because it sounded like an array of IO::Handle objects
miyagawa authored
77 [ "Hello World" ], # or IO::Handle-like object
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
78 ];
79 }
80
81 =head3 The Environment
82
ff0e6de @miyagawa paragraphized
miyagawa authored
83 The environment MUST be a hash reference that includes CGI-like
84 headers. The application is free to modify the environment. The
85 environment is required to include these variables (adopted from
86 PEP333, Rack and JSGI) except when they'd be empty, but see below:
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
87
88 =over 4
89
90 =item *
91
ff0e6de @miyagawa paragraphized
miyagawa authored
92 C<REQUEST_METHOD>: The HTTP request method, such as "GET" or
93 "POST". This cannot ever be an empty string, and so is always
94 required.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
95
96 =item *
97
ff0e6de @miyagawa paragraphized
miyagawa authored
98 C<SCRIPT_NAME>: The initial portion of the request URL's I<path> that
99 corresponds to the application, so that the application knows its
65afea5 @miyagawa apply grammer fixes from hanekomu
miyagawa authored
100 virtual "location". This may be an empty string if the application
ff0e6de @miyagawa paragraphized
miyagawa authored
101 corresponds to the "root" of the server.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
102
103 =item *
104
ff0e6de @miyagawa paragraphized
miyagawa authored
105 C<PATH_INFO>: The remainder of the request URL's "path", designating
106 the virtual "location" of the request's target within the
65afea5 @miyagawa apply grammer fixes from hanekomu
miyagawa authored
107 application. This may be an empty string if the request URL targets
ff0e6de @miyagawa paragraphized
miyagawa authored
108 the application root and does not have a trailing slash. This value
b2f90a3 @miyagawa PATH_INFO should be decoded by servers
miyagawa authored
109 should be URI decoded by servers to be compatible to RFC 3875.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
110
111 =item *
112
c6d7946 @miyagawa added REQUEST_URI to the PSGI spec
miyagawa authored
113 C<REQUEST_URI>: The undecoded, raw request URL line. It is the raw URI
114 path and query part that appears in the HTTP C<GET /... HTTP/1.x> line
115 and doesn't contain URI scheme and host names.
116
117 Unlike C<PATH_INFO>, this value SHOULD NOT be decoded by servers and
118 hence it is an application's responsibility to properly decode paths
119 to map URL to application handlers, when using C<REQUEST_URI> over
120 C<PATH_INFO>.
121
122 =item *
123
ff0e6de @miyagawa paragraphized
miyagawa authored
124 C<QUERY_STRING>: The portion of the request URL that follows the C<?>,
125 if any. May be empty, but is always required.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
126
127 =item *
128
ff0e6de @miyagawa paragraphized
miyagawa authored
129 C<SERVER_NAME>, C<SERVER_PORT>: When combined with C<SCRIPT_NAME> and
130 C<PATH_INFO>, these variables can be used to complete the URL. Note,
131 however, that C<HTTP_HOST>, if present, should be used in preference
132 to C<SERVER_NAME> for reconstructing the request URL. C<SERVER_NAME>
133 and C<SERVER_PORT> can never be empty strings, and so are always
134 required.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
135
136 =item *
137
ff0e6de @miyagawa paragraphized
miyagawa authored
138 C<SERVER_PROTOCOL>: The version of the protocol the client used to
139 send the request. Typically this will be something like "HTTP/1.0" or
140 "HTTP/1.1" and may be used by the application to determine how to
141 treat any HTTP request headers.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
142
143 =item *
144
ff0e6de @miyagawa paragraphized
miyagawa authored
145 C<HTTP_> Variables: Variables corresponding to the client-supplied
146 HTTP request headers (i.e., variables whose names begin with
147 C<HTTP_>). The presence or absence of these variables should
65afea5 @miyagawa apply grammer fixes from hanekomu
miyagawa authored
148 correspond to the presence or absence of the appropriate HTTP header
ff0e6de @miyagawa paragraphized
miyagawa authored
149 in the request.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
150
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
151 If there are multiple header lines sent with the same key, the server
152 should treat them as if they're sent in one line, i.e. combine them
153 with C<, > as in RFC 2616.
154
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
155 =back
156
ff0e6de @miyagawa paragraphized
miyagawa authored
157 In addition to this, the PSGI environment MUST include these
158 PSGI-specific variables:
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
159
160 =over 4
161
162 =item *
163
164 C<psgi.version>: An array ref [1,0] representing this version of PSGI.
165
166 =item *
167
168 C<psgi.url_scheme>: A string C<http> or C<https>, depending on the request URL.
169
170 =item *
171
65afea5 @miyagawa apply grammer fixes from hanekomu
miyagawa authored
172 C<psgi.input>: the input stream. See below.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
173
174 =item *
175
176 C<psgi.errors>: the error stream. See below.
177
eee7655 @miyagawa Added psgi.multithread and psgi.multiprocess per discussion on about Apa...
miyagawa authored
178 =item *
179
180 C<psgi.multithread>: true if the application may be simultaneously
181 invoked by another thread in the same process, false otherwise.
182
183 =item *
184
185 C<psgi.multiprocess>: true if an equivalent application object may be
186 simultaneously invoked by another process, false otherwise.
187
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
188 =back
189
190 The PSGI environment MAY include these optional PSGI variables:
191
192 =over 4
193
194 =item *
195
ff0e6de @miyagawa paragraphized
miyagawa authored
196 C<psgi.run_once>: true if the server expects (but does not guarantee!)
197 that the application will only be invoked this one time during the
198 life of its containing process. Normally, this will only be true for a
199 server based on CGI (or something similar).
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
200
201 =item *
202
e21be68 @miyagawa s/.async/.nonblocking/ per discussions with nothingmuch++
miyagawa authored
203 C<psgi.nonblocking>: true if the server is calling the application in an
204 non-blocking event loop.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
205
206 =back
207
65afea5 @miyagawa apply grammer fixes from hanekomu
miyagawa authored
208 The server or the application can store its own data in the
ff0e6de @miyagawa paragraphized
miyagawa authored
209 environment, too. The keys MUST contain at least one dot, and should
210 be prefixed uniquely. The prefix C<psgi.> is reserved for use with the
211 PSGI core implementation and other accepted extensions and MUST NOT be
212 used otherwise. The environment MUST NOT contain the keys
213 C<HTTP_CONTENT_TYPE> or C<HTTP_CONTENT_LENGTH> (use the versions
214 without C<HTTP_>). The CGI keys (named without a period) MUST have a
215 scalar variable containing strings. There are the following
216 restrictions:
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
217
218 =over 4
219
220 =item *
221
222 C<psgi.version> MUST be an array of integers.
223
224 =item *
225
65afea5 @miyagawa apply grammer fixes from hanekomu
miyagawa authored
226 C<psgi.url_scheme> MUST be a scalar variable containing either the
ff0e6de @miyagawa paragraphized
miyagawa authored
227 string C<http> or C<https>.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
228
229 =item *
230
231 There MUST be a valid input stream in C<psgi.input>.
232
233 =item *
234
235 There MUST be a valid error stream in C<psgi.errors>.
236
237 =item *
238
239 The C<REQUEST_METHOD> MUST be a valid token.
240
241 =item *
242
243 The C<SCRIPT_NAME>, if non-empty, MUST start with C</>
244
245 =item *
246
247 The C<PATH_INFO>, if non-empty, MUST start with C</>
248
249 =item *
250
251 The C<CONTENT_LENGTH>, if given, MUST consist of digits only.
252
253 =item *
254
ff0e6de @miyagawa paragraphized
miyagawa authored
255 One of C<SCRIPT_NAME> or C<PATH_INFO> MUST be set. C<PATH_INFO> should
65afea5 @miyagawa apply grammer fixes from hanekomu
miyagawa authored
256 be C</> if C<SCRIPT_NAME> is empty. C<SCRIPT_NAME> should never be C</>,
257 but should instead be empty.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
258
259 =back
260
261 =head3 The Input Stream
262
ff0e6de @miyagawa paragraphized
miyagawa authored
263 The input stream in C<psgi.input> is an IO::Handle-like object which
264 streams the raw HTTP POST or PUT data. If it is a file handle then it
265 MUST be opened in binary mode. The input stream MUST respond to
266 C<read> and MAY implement C<seek>.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
267
ff0e6de @miyagawa paragraphized
miyagawa authored
268 The built-in filehandle or IO::Handle based objects should work fine
269 everywhere. Application developers SHOULD NOT inspect the type or
270 class of the stream, but instead just call C<read> to duck type.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
271
e764e4f @miyagawa Added a note about read() built-in
miyagawa authored
272 Application developers SHOULD NOT use the built-in C<read> function to
273 read from the input stream, because C<read> function only works with
65afea5 @miyagawa apply grammer fixes from hanekomu
miyagawa authored
274 the real IO object (a glob ref based file handle or PerlIO) and makes
275 duck typing difficult. Web application framework developers, if
276 they know the input stream will be used with the built-in read() in any
d36f900 @miyagawa web framework should deal with this IO thing
miyagawa authored
277 upstream code they can't touch, SHOULD use PerlIO or tie handle to
278 work around with this problem.
e764e4f @miyagawa Added a note about read() built-in
miyagawa authored
279
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
280 =over 4
281
282 =item read
283
284 $input->read($buf, $len [, $offset ]);
285
a87c263 @miyagawa mentions return value of psgi.input and psgi.errors methods
miyagawa authored
286 Returns the number of characters actually read, 0 at end of file, or
287 undef if there was an error.
288
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
289 =item seek
290
291 $input->seek($pos, $whence);
292
a87c263 @miyagawa mentions return value of psgi.input and psgi.errors methods
miyagawa authored
293 Returns 1 on success, 0 otherwise.
294
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
295 =back
296
297 =head3 The Error Stream
298
ff0e6de @miyagawa paragraphized
miyagawa authored
299 The error stream in C<psgi.errors> is an IO::Handle-like object to
300 print errors. The error stream must implement C<print>.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
301
ff0e6de @miyagawa paragraphized
miyagawa authored
302 The built-in filehandle or IO::Handle based objects should work fine
303 everywhere. Application developers SHOULD NOT inspect the type or
304 class of the stream, but instead just call C<print> to duck type.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
305
306 =over 4
307
308 =item print
309
310 $errors->print($error);
311
a87c263 @miyagawa mentions return value of psgi.input and psgi.errors methods
miyagawa authored
312 Returns true if successful.
313
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
314 =back
315
316 =head3 The Response
317
318 =head4 Status
319
320 HTTP status code, is an integer and MUST be greater than or equal to 100.
321
322 =head4 Headers
323
79b722f @miyagawa clarified it's not a hash ref
miyagawa authored
324 The headers must be an array reference (and NOT a hash reference!)
325 containing key and value pairs. Its number of elements MUST be
326 even. The header MUST NOT contain a C<Status> key, contain keys with
327 C<:> or newlines in their name, contain keys that end in C<-> or C<_>
328 but only contain keys that consist of letters, digits, C<_> or C<->
329 and start with a letter. The value of the header must be a scalar
330 value that contain a string. The value string MUST NOT contain
0dd2975 @miyagawa header value can contain whitespace
miyagawa authored
331 characters below chr(37) except chr(32) (whitespace).
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
332
ff0e6de @miyagawa paragraphized
miyagawa authored
333 If the same key name appears multiple times in an array ref, those
334 header lines MUST be sent to the client separately (e.g. multiple
335 C<Set-Cookie> lines).
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
336
337 =head4 Content-Type
338
ff0e6de @miyagawa paragraphized
miyagawa authored
339 There MUST be a C<Content-Type> except when the C<Status> is 1xx, 204
340 or 304, in which case there MUST be none given.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
341
342 =head4 Content-Length
343
ff0e6de @miyagawa paragraphized
miyagawa authored
344 There MUST NOT be a C<Content-Length> header when the C<Status> is
345 1xx, 204 or 304.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
346
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
347 If the Status is not 1xx, 204 or 304 and there is no C<Content-Length>
77b3dfe @miyagawa apps are not supposed to add Transfer-Encoding, remove it
miyagawa authored
348 header, servers MAY calculate the content length by looking at Body,
349 in case it can be calculated (i.e. if it's an array ref of body chunk
350 or a real file handle), and append to the outgoing headers.
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
351
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
352 =head4 Body
353
ff0e6de @miyagawa paragraphized
miyagawa authored
354 The response body is returned from the application in one of following
355 two types of scalar variable.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
356
357 =over 4
358
359 =item *
360
361 An array reference containing body as lines.
362
363 my $body = [ "Hello\n", "World\n" ];
364
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
365 Note that the elements in an array reference are NOT REQUIRED to end
366 in a newline. The servers SHOULD just write each elements as is to the
367 client, and SHOULD NOT care if the line ends with newline or not.
368
369 So, when you have a big chunk of HTML in a single scalar C<$body>,
370
371 [ $body ]
372
373 is a valie response body.
374
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
375 =item *
376
377 An IO::Handle-like object or a built-in filehandle.
378
379 open my $body, "</path/to/file";
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
380 open my $body, "<:via(SomePerlIO)", ...;
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
381 my $body = IO::File->new("/path/to/file");
382
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
383 my $body = SomeClass->new(); # mock class that implements getline() and close()
384
0e5a284 @miyagawa more clarifications about what is Plack and what is Adapter. s/implement...
miyagawa authored
385 Servers SHOULD NOT check the type or class of the body but instead
0e5b33e @miyagawa Updated spec: body can respond ->path.
miyagawa authored
386 just call C<getline> (i.e. duck type) to iterate over the body and
387 call C<close> when done.
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
388
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
389 Servers MAY check if the body is a real filehandle using C<fileno> and
390 C<Scalar::Util::reftype> and if it's a real filehandle that has a file
391 descriptor, it MAY optimize the file serving using techniques like
392 I<sendfile(2)>.
393
0e5b33e @miyagawa Updated spec: body can respond ->path.
miyagawa authored
394 The body object MAY respond to C<path> method to return the local file
395 system path, which MAY be used by some servers to switch to more
396 efficient file serving method using the file path instead of a file
397 descriptor.
398
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
399 Servers are RECOMMENDED to set C<$/> special variable to the buffer
400 size when reading content from C<$body> using C<getline> method, in
401 case it's a binary filehandle. Applications, when it returns a mock
402 object that implements C<getline> are NOT REQUIRED to respect the
403 C<$/> value.
404
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
405 =back
406
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
407 =head2 Middleware
408
5d680fe @miyagawa s/existent/existing/
miyagawa authored
409 Middleware is itself a PSGI application but it takes an existing PSGI
a19c5ba @miyagawa minor grammer fixes
miyagawa authored
410 application and runs it like a server, mostly to do pre-processing on
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
411 C<$env> or post-processing on the response objects.
412
413 Here's a simple example that appends special HTTP header
414 I<X-PSGI-Used> to any PSGI application.
415
416 # $app is a simple PSGI application
417 my $app = sub {
418 my $env = shift;
419 return [ '200', [ 'Content-Type' => 'text/plain' ], [ "Hello World" ] ];
420 };
421
422 # $xheader is a middleware to wrap $app
423 my $xheader = sub {
424 my $env = shift;
425 my $res = $app->($env);
426 push @{$res->[1]}, 'X-PSGI-Used' => 1;
427 return $res;
428 };
429
430 Middleware itself MUST behave exactly like a PSGI application: take
431 C<$env> and return C<$res>.
432
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
433 =head1 ACKNOWLEDGEMENTS
434
435 Some parts of this specification are adopted from the following specifications.
436
437 =over 4
438
439 =item *
440
441 PEP333 Python Web Server Gateway Interface L<http://www.python.org/dev/peps/pep-0333>
442
443 =item *
444
445 Rack L<http://rack.rubyforge.org/doc/SPEC.html>
446
447 =item *
448
449 JSGI Specification L<http://jackjs.org/jsgi-spec.html>
450
451 =back
452
453 I'd like to thank authors of these great documents.
454
455 =head1 AUTHOR
456
457 Tatsuhiko Miyagawa E<lt>miyagawa@bulknews.netE<gt>
458
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
459 =head1 CONTRIBUTORS
460
461 The following people have contributed to the PSGI specification and
462 Plack implementation by commiting their code, sending patches,
463 reporting bugs, asking questions, suggesting useful advices,
464 nitpicking, chatting on IRC or commenting on my blog (in no particular
465 order):
466
467 Tokuhiro Matsuno
468 Kazuhiro Osawa
469 Yuval Kogman
470 Kazuho Oku
471 Alexis Sukrieh
048f9a3 @miyagawa update Dann's name. README links to the site
miyagawa authored
472 Takatoshi Kitano
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
473 Stevan Little
474 Daisuke Murase
475 mala
476 Pedro Melo
477 Jesse Luehrs
478 John Beppu
479 Shawn M Moore
480 Mark Stosberg
481 Matt S Trout
482 Jesse Vincent
483 Chia-liang Kao
484 Dave Rolsky
485 Hans Dieter Pearcey
486 Randy J Ray
487 Benjamin Trott
488 Max Maischein
489 Slaven Rezić
490 Marcel Grünauer
491 Masayoshi Sekimura
492 Brock Wilcox
493 Piers Cawley
ecdb6c0 @miyagawa added some HTTP::Engine contributors
miyagawa authored
494 Daisuke Maki
495 Kang-min Liu
2b08fe3 @miyagawa oops
miyagawa authored
496 Yasuhiro Matsumoto
5623139 @miyagawa changed the Content-Length from SHOULD to MAY
miyagawa authored
497 Ash Berlin
31284b9 @miyagawa Added Artur for his advice around gearman/schwartz
miyagawa authored
498 Artur Bergman
ba2001a @miyagawa more questions around HTTP::Engine confusions
miyagawa authored
499 Simon Cozens
500 Scott McWhirter
a87c263 @miyagawa mentions return value of psgi.input and psgi.errors methods
miyagawa authored
501 Jiro Nishiguchi
01b3c47 @miyagawa Sorry!
miyagawa authored
502 Masahiro Chiba
1173dc0 @miyagawa New spec: feedbacks got merged.
miyagawa authored
503
e85dbb3 @miyagawa First draft of the PSGI spec and FAQ.
miyagawa authored
504 =head1 COPYRIGHT AND LICENSE
505
506 Copyright Tatsuhiko Miyagawa, 2009.
507
508 This document is licensed under the Creative Commons license by-sa.
509
510 =cut
Something went wrong with that request. Please try again.