├── .gitignore ├── PSGI.pm ├── Makefile.PL ├── .shipit ├── README.md ├── MANIFEST ├── Changes ├── PSGI ├── Extensions.pod └── FAQ.pod └── PSGI.pod /.gitignore: -------------------------------------------------------------------------------- 1 | *.tar.gz 2 | *~ 3 | -------------------------------------------------------------------------------- /PSGI.pm: -------------------------------------------------------------------------------- 1 | package PSGI; 2 | our $VERSION = "1.102"; 3 | 1; 4 | -------------------------------------------------------------------------------- /Makefile.PL: -------------------------------------------------------------------------------- 1 | use inc::Module::Install; 2 | name 'PSGI'; 3 | all_from 'PSGI.pm'; 4 | auto_set_repository; 5 | WriteAll; 6 | -------------------------------------------------------------------------------- /.shipit: -------------------------------------------------------------------------------- 1 | steps = FindVersion, ChangeVersion, CheckChangeLog, DistTest, Commit, Tag, MakeDist, UploadCPAN 2 | git.push_to = origin 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is PSGI, Perl Web Server Gateway Interface -- ala Python's WSGI and Ruby's Rack. 2 | 3 | The [PSGI protocol specification](http://github.com/plack/psgi-specs/blob/master/PSGI.pod) is currently at 1.0, and we're working on revising it to make version 1.1. See also the [FAQ](http://github.com/plack/psgi-specs/blob/master/FAQ.pod). 4 | 5 | See the [PSGI/Plack website](http://plackperl.org/) for more links. 6 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | .shipit 2 | Changes 3 | inc/Module/Install.pm 4 | inc/Module/Install/Base.pm 5 | inc/Module/Install/Can.pm 6 | inc/Module/Install/Fetch.pm 7 | inc/Module/Install/Makefile.pm 8 | inc/Module/Install/Metadata.pm 9 | inc/Module/Install/Repository.pm 10 | inc/Module/Install/Win32.pm 11 | inc/Module/Install/WriteAll.pm 12 | Makefile.PL 13 | MANIFEST This list of files 14 | META.yml 15 | PSGI.pm 16 | PSGI.pod 17 | PSGI/FAQ.pod 18 | PSGI/Extensions.pod 19 | README.md 20 | -------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | 1.102 Wed Jul 24 13:12:28 PDT 2013 2 | - Add psgix.cleanup extension 3 | 4 | 1.101 Sat Jul 21 15:01:20 PDT 2012 5 | - Fix typos and formatting 6 | - Mention CGI variables ala PEP 333 7 | 8 | 1.10 Fri Mar 9 08:46:27 PST 2012 9 | - Released as PSGI 1.1 10 | 11 | 1.09_3 Wed Jun 22 13:48:31 PDT 2011 12 | - Separated extensions into PSGI::Extensions 13 | - Added psgix.harakiri and psgix.harakiri.commit 14 | - Updated terminology section 15 | - Clarified that body should be encoded byte strings and do not contain wide characters 16 | - Clarified that header values must be defined 17 | 18 | 1.09_2 Tue Jun 7 15:21:47 PDT 2011 19 | - Fixed a dumb mistake about allowed characters in header values 20 | - Updated FAQ document 21 | - psgi.input MUST have seek() only if psgix.input.buffered is true 22 | 23 | 1.09_1 Mon Mar 28 11:35:44 PDT 2011 24 | - 1.1 beta 25 | - Upped psgi.version to be [1,1] 26 | - Lots of grammar and style fixes 27 | - Removed poll_cb from writer spec 28 | - Streaming interface now SHOULD be implemented, rather than MAY 29 | - Promoted psgi.streaming, nonblocking and run_once keys to be MUST 30 | - Added psgix.logger and psgix.session extensions 31 | - Updated FAQ 32 | 33 | 1.03 Tue Oct 27 13:44:01 PDT 2009 34 | - Added an optional callback interface to allow delayed response and streaming 35 | 36 | 1.02 Tue Oct 13 01:57:28 PDT 2009 37 | - No spec changes. Just to let PAUSE index this stuff. 38 | 39 | 1.01 Tue Oct 13 01:17:28 PDT 2009 40 | - PAUSE distribution issue -------------------------------------------------------------------------------- /PSGI/Extensions.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | PSGI::Extensions - PSGI extensions 4 | 5 | =head1 SPECIFICATION 6 | 7 | The PSGI environment MAY include the following additional 8 | extensions. They are OPTIONAL and applications and middleware 9 | components SHOULD check if they exist in the environment before 10 | using the functionality provided. 11 | 12 | =over 4 13 | 14 | =item * 15 | 16 | C: The raw IO socket to access the client connection to do 17 | low-level socket operations. This is only available in PSGI servers 18 | that run as an HTTP server, and should be used when (and only when) 19 | you want to I out of PSGI abstraction, to implement 20 | protocols over HTTP such as BOSH or WebSocket. 21 | 22 | =item * 23 | 24 | C: A boolean which is true if the HTTP request 25 | body (for POST or PUT requests) is buffered using a temporary 26 | filehandle or PerlIO in C. When this is set, applications 27 | or middleware components can safely C from C without 28 | worrying about non-blocking I/O and then can call C to rewind 29 | the input for the transparent access. 30 | 31 | =item * 32 | 33 | C: A code reference to log messages. The code reference 34 | is passed one argument as a hash reference that represents a message 35 | to be logged. The hash reference MUST include at least two keys: 36 | C and C where C MUST be one of the following 37 | strings: C, C, C, C and C. C 38 | SHOULD be a plain string or a scalar variable that stringifies. 39 | 40 | =item * 41 | 42 | C: A hash reference for storing and retrieving session 43 | data. Updates made on this hash reference SHOULD be persisted by 44 | middleware components and SHOULD be restored in the succeeding 45 | requests. How to persist and restore session data, as well as how to 46 | identify the requesting clients are implementation specific. 47 | 48 | C: A hash reference to tell Middleware 49 | components how to manipulate session data after the request. 50 | Acceptable keys and values are implementation specific. 51 | 52 | =item * 53 | 54 | C: A boolean which is true if the PSGI server supports 55 | harakiri mode, that kills a worker (typically a forked child process) 56 | after the current request is complete. 57 | 58 | C: A boolean which is set to true by the PSGI 59 | application or middleware when it wants the server to kill the worker 60 | after the current request. 61 | 62 | =item * 63 | 64 | C - A boolean flag indicating whether a PSGI server 65 | supports cleanup handlers. Absence of the key assumes false 66 | (i.e. unsupported). Middleware and applications MUST check this key 67 | before utilizing the cleanup handlers. 68 | 69 | C - Array reference to stack callback 70 | handlers. This reference MUST be initialized as an empty array 71 | reference by the servers. Applications can register the callbacks by 72 | simply push()ing a code reference to this array reference. Callbacks 73 | will be called once a request is complete, and will receive C<$env> 74 | as its first argument, and return value of the callbacks will be 75 | simply ignored. An exception thrown inside callbacks MAY also be 76 | ignored. 77 | 78 | If the server also supports C, it SHOULD implement in 79 | a way that cleanup handlers run before harakiri checker, so that the 80 | cleanup handlers can commit the harakiri flag. 81 | 82 | =back 83 | 84 | =head1 COPYRIGHT AND LICENSE 85 | 86 | Copyright Tatsuhiko Miyagawa, 2009-2011. 87 | 88 | This document is licensed under the Creative Commons license by-sa. 89 | 90 | =cut 91 | -------------------------------------------------------------------------------- /PSGI.pod: -------------------------------------------------------------------------------- 1 | =encoding utf-8 2 | 3 | =head1 NAME 4 | 5 | PSGI - Perl Web Server Gateway Interface Specification 6 | 7 | =head1 ABSTRACT 8 | 9 | This document specifies a standard interface between web servers and 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 12 | framework developers. 13 | 14 | Please keep in mind that PSGI is not Yet Another web application 15 | framework. PSGI is a specification to decouple web server environments 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. 20 | 21 | =head1 TERMINOLOGY 22 | 23 | =over 4 24 | 25 | =item Web Servers 26 | 27 | I 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 | 31 | =item PSGI Server 32 | 33 | A I is a Perl program providing an environment for a 34 | I 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 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 to actually be 44 | a web server or part of one, as I only defines an interface 45 | between the server and the application, not between the server and the 46 | world. 47 | 48 | A I is often also called I 49 | because it is similar to a I, which is Java 50 | process providing an environment for I. 51 | 52 | =item Applications 53 | 54 | I accept HTTP requests and return HTTP responses. 55 | 56 | I 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 will also be referred to as I 62 | for the remainder of this document. 63 | 64 | =item Middleware 65 | 66 | I is a PSGI application (a code reference) I a 67 | I. I looks like an I when called from a 68 | I, and it in turn can call other I. It can be thought of 69 | a I to extend a PSGI application. 70 | 71 | =item Framework developers 72 | 73 | I 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. 76 | 77 | =item Web application developers 78 | 79 | I are developers who write code on top of a web 80 | application framework. These developers should never have to deal with PSGI 81 | directly. 82 | 83 | =back 84 | 85 | =head1 SPECIFICATION 86 | 87 | =head2 Application 88 | 89 | A PSGI application is a Perl code reference. It takes exactly one 90 | argument, the environment, and returns an array reference containing exactly 91 | three values. 92 | 93 | my $app = sub { 94 | my $env = shift; 95 | return [ 96 | '200', 97 | [ 'Content-Type' => 'text/plain' ], 98 | [ "Hello World" ], # or IO::Handle-like object 99 | ]; 100 | }; 101 | 102 | =head3 The Environment 103 | 104 | The environment MUST be a hash reference that includes CGI-like headers, as 105 | detailed below. The application is free to modify the environment. The 106 | environment MUST include these keys (adopted from L, 108 | L and 109 | L) except when they would normally be 110 | empty. 111 | 112 | When an environment key is described as a boolean, its value MUST conform 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 115 | application MAY treat this as a false value. 116 | 117 | The values for all CGI keys (named without a period) MUST be a scalar 118 | string. 119 | 120 | See below for details. 121 | 122 | =over 4 123 | 124 | =item * 125 | 126 | C: The HTTP request method, such as "GET" or 127 | "POST". This B be an empty string, and so is always 128 | required. 129 | 130 | =item * 131 | 132 | C: The initial portion of the request URL's I, 133 | corresponding to the application. This tells the application its 134 | virtual "location". This may be an empty string if the application 135 | corresponds to the server's root URI. 136 | 137 | If this key is not empty, it MUST start with a forward slash (C). 138 | 139 | =item * 140 | 141 | C: The remainder of the request URL's I, designating 142 | the virtual "location" of the request's target within the 143 | application. This may be an empty string if the request URL targets 144 | the application root and does not have a trailing slash. This value 145 | should be URI decoded by servers in order to be compatible with L. 146 | 147 | If this key is not empty, it MUST start with a forward slash (C). 148 | 149 | =item * 150 | 151 | C: The undecoded, raw request URL line. It is the raw URI 152 | path and query part that appears in the HTTP C line 153 | and doesn't contain URI scheme and host names. 154 | 155 | Unlike C, this value B 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. 158 | 159 | =item * 160 | 161 | C: The portion of the request URL that follows the C, 162 | if any. This key MAY be empty, but B always be present, even if empty. 163 | 164 | =item * 165 | 166 | C, C: When combined with C and 167 | C, these keys can be used to complete the URL. Note, 168 | however, that C, if present, should be used in preference 169 | to C for reconstructing the request URL. C 170 | and C B be empty strings, and are always 171 | required. 172 | 173 | =item * 174 | 175 | C: 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. 179 | 180 | =item * 181 | 182 | C: 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. 185 | 186 | =item * 187 | 188 | C: 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. 191 | 192 | =item * 193 | 194 | C Keys: These keys correspond to the client-supplied 195 | HTTP request headers. The presence or absence of these keys should 196 | correspond to the presence or absence of the appropriate HTTP header 197 | in the request. 198 | 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, as in 202 | L. 203 | 204 | If there are multiple header lines sent with the same key, the server 205 | should treat them as if they were sent in one line and combine them 206 | with C<, >, as in L. 207 | 208 | =back 209 | 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 | 216 | In addition to the keys above, the PSGI environment MUST also include these 217 | PSGI-specific keys: 218 | 219 | =over 4 220 | 221 | =item * 222 | 223 | C: An array reference [1,1] representing this version of 224 | PSGI. The first number is the major version and the second it the minor 225 | version. 226 | 227 | =item * 228 | 229 | C: A string C or C, depending on the request URL. 230 | 231 | =item * 232 | 233 | C: the input stream. See below for details. 234 | 235 | =item * 236 | 237 | C: the error stream. See below for details. 238 | 239 | =item * 240 | 241 | C: This is a boolean value, which MUST be true if the 242 | application may be simultaneously invoked by another thread in the same 243 | process, false otherwise. 244 | 245 | =item * 246 | 247 | C: This is a boolean value, which MUST be true if an 248 | equivalent application object may be simultaneously invoked by another 249 | process, false otherwise. 250 | 251 | =item * 252 | 253 | C: 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 256 | server based on CGI (or something similar). 257 | 258 | =item * 259 | 260 | C: A boolean which is true if the server is calling the 261 | application in an non-blocking event loop. 262 | 263 | =item * 264 | 265 | C: A boolean which is true if the server supports callback 266 | style delayed response and streaming writer object. 267 | 268 | =back 269 | 270 | The server or the application can store its own data in the 271 | environment as well. These keys MUST contain at least one dot, and 272 | SHOULD be prefixed uniquely. 273 | 274 | The C prefix is reserved for use with the PSGI core 275 | specification, and C prefix is reserved for officially blessed 276 | extensions. These prefixes B be used by other servers or 277 | application. See L for the list of 278 | officially approved extensions. 279 | 280 | The environment B contain keys named C or 281 | C. 282 | 283 | One of C or C MUST be set. When 284 | C is C, C should be C and C 285 | should be empty. C B be C, but MAY be 286 | empty. 287 | 288 | =head3 The Input Stream 289 | 290 | The input stream in C is an L-like object which 291 | streams the raw HTTP POST or PUT data. If it is a file handle then it 292 | MUST be opened in binary mode. The input stream B respond to 293 | C and MAY implement C. 294 | 295 | Perl's built-in filehandles or L based objects should work as-is 296 | in a PSGI server. Application developers B inspect the type or 297 | class of the stream. Instead, they SHOULD simply call C on the object. 298 | 299 | Application developers B use Perl's built-in C or iterator 300 | (C<< <$fh> >>) to read from the input stream. Instead, application 301 | developers should call C as a method (C<< $fh->read >>) to allow for 302 | duck typing. 303 | 304 | Framework developers, if they know the input stream will be used with the 305 | built-in read() in any upstream code they can't touch, SHOULD use PerlIO or 306 | a tied handle to work around with this problem. 307 | 308 | The input stream object is expected to provide a C method: 309 | 310 | =over 4 311 | 312 | =item read 313 | 314 | $input->read($buf, $len [, $offset ]); 315 | 316 | Returns the number of characters actually read, 0 at end of file, or 317 | undef if there was an error. 318 | 319 | =back 320 | 321 | It may also implement an optional C method. If 322 | C environment is true, it MUST implement the 323 | C method. 324 | 325 | =over 4 326 | 327 | =item seek 328 | 329 | $input->seek($pos, $whence); 330 | 331 | Returns 1 on success, 0 otherwise. 332 | 333 | =back 334 | 335 | See the L documentation for more details on exactly how these 336 | methods should work. 337 | 338 | =head3 The Error Stream 339 | 340 | The error stream in C is an L-like object to 341 | print errors. The error stream must implement a C method. 342 | 343 | As with the input stream, Perl's built-in filehandles or L based 344 | objects should work as-is in a PSGI server. Application developers B inspect the type or class of the stream. Instead, they SHOULD simply 346 | call C on the object. 347 | 348 | =over 4 349 | 350 | =item print 351 | 352 | $errors->print($error); 353 | 354 | Returns true if successful. 355 | 356 | =back 357 | 358 | =head3 The Response 359 | 360 | Applications MUST return a response as either a three element array 361 | reference, or a code reference for a delayed/streaming response. 362 | 363 | The response array reference consists of the following elements: 364 | 365 | =head4 Status 366 | 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. 370 | 371 | =head4 Headers 372 | 373 | The headers MUST be an array reference (B a hash reference) 374 | of key/value pairs. This means it MUST contain an even number of elements. 375 | 376 | The header B contain a key named C, nor any keys with C<:> 377 | or newlines in their name. It B contain any keys that end in C<-> or 378 | C<_>. 379 | 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 be a 382 | scalar string and defined. The value string B contain 383 | characters below octal 037 i.e. chr(31). 384 | 385 | If the same key name appears multiple times in an array ref, those 386 | header lines MUST be sent to the client separately (e.g. multiple 387 | C lines). 388 | 389 | =head4 Content-Type 390 | 391 | There MUST be a C except when the C is 1xx, 204 392 | or 304, in which case there B be a content type. 393 | 394 | =head4 Content-Length 395 | 396 | There B be a C header when the C is 397 | 1xx, 204 or 304. 398 | 399 | If the Status is not 1xx, 204 or 304 and there is no C header, 400 | a PSGI server MAY calculate the content length by looking at the Body. This 401 | value can then be appended to the list of headers returned by the application. 402 | 403 | =head4 Body 404 | 405 | The response body MUST be returned from the application as either 406 | an array reference or a handle containing the response body as byte 407 | strings. The body MUST be encoded into appropriate encodings and 408 | B contain wide characters (> 255). 409 | 410 | =over 4 411 | 412 | =item * 413 | 414 | If the body is an array reference, it is expected to contain an array of lines 415 | which make up the body. 416 | 417 | my $body = [ "Hello\n", "World\n" ]; 418 | 419 | Note that the elements in an array reference are B to end 420 | in a newline. A server SHOULD write each elements as-is to the 421 | client, and B care if the line ends with newline or not. 422 | 423 | An array reference with a single value is valid. So C<[ $html ]> is a valid 424 | response body. 425 | 426 | =item * 427 | 428 | The body can instead be a handle, either a Perl built-in filehandle or an 429 | L-like object. 430 | 431 | open my $body, "new("/path/to/file"); 434 | 435 | # mock class that implements getline() and close() 436 | my $body = SomeClass->new(); 437 | 438 | Servers B check the type or class of the body. Instead, they should 439 | simply call C to iterate over the body, and 440 | call C when done. 441 | 442 | Servers MAY check if the body is a real filehandle using C and 443 | C. If the body is real filehandle, the server MAY 444 | optimize using techniques like I. 445 | 446 | The body object MAY also respond to a C method. This method is 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 449 | serve the file. 450 | 451 | Servers SHOULD set the C<$/> special variable to the buffer size when 452 | reading content from C<$body> using the C method. This is done by 453 | setting C<$/> with a reference to an integer (C<$/ = \8192>). 454 | 455 | If the body filehandle is a Perl built-in filehandle L object, 456 | they will respect this value. Similarly, an object which provides the same API 457 | MAY also respect this special variable, but are not required to do so. 458 | 459 | =back 460 | 461 | =head2 Delayed Response and Streaming Body 462 | 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 | 468 | This interface SHOULD be implemented by PSGI servers, and 469 | C environment MUST be set to true in such servers. 470 | 471 | To enable a delayed response, the application SHOULD return a 472 | callback as its response. An application MAY check if the 473 | C environment is true and falls back to the direct 474 | response if it isn't. 475 | 476 | This callback will be called with I subroutine reference (referred to 477 | as the I from now on) as its only argument. The I 478 | should in turn be called with the standard three element array reference 479 | response. This is best illustrated with an example: 480 | 481 | my $app = sub { 482 | my $env = shift; 483 | 484 | # Delays response until it fetches content from the network 485 | return sub { 486 | my $responder = shift; 487 | 488 | fetch_content_from_server(sub { 489 | my $content = shift; 490 | $responder->([ 200, $headers, [ $content ] ]); 491 | }); 492 | }; 493 | }; 494 | 495 | An application MAY omit the third element (the body) when calling 496 | the I. If the body is omitted, the I MUST 497 | return I object which implements C and C 498 | methods. Again, an example illustrates this best. 499 | 500 | my $app = sub { 501 | my $env = shift; 502 | 503 | # immediately starts the response and stream the content 504 | return sub { 505 | my $responder = shift; 506 | my $writer = $responder->( 507 | [ 200, [ 'Content-Type', 'application/json' ]]); 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 | 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 522 | push technology, but could also be used to implement unbuffered writes 523 | in a blocking server. 524 | 525 | =head2 Middleware 526 | 527 | A I 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. 533 | 534 | Here's a simple example that appends a special HTTP header 535 | I to any PSGI application. 536 | 537 | # $app is a simple PSGI application 538 | my $app = sub { 539 | my $env = shift; 540 | return [ '200', 541 | [ 'Content-Type' => 'text/plain' ], 542 | [ "Hello World" ] ]; 543 | }; 544 | 545 | # $xheader is a piece of middleware that wraps $app 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 | 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 556 | understand. 557 | 558 | =head1 CHANGELOGS 559 | 560 | 1.1: 2010.02.xx 561 | 562 | =over 4 563 | 564 | =item * 565 | 566 | Added optional PSGI keys as extensions: C and C. 567 | 568 | =item * 569 | 570 | C SHOULD be implemented by PSGI servers, rather than B. 571 | 572 | =item * 573 | 574 | PSGI keys C, C and C 575 | MUST be set by PSGI servers. 576 | 577 | =item * 578 | 579 | Removed C from writer methods. 580 | 581 | =back 582 | 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 592 | 593 | =item * 594 | 595 | Rack L 596 | 597 | =item * 598 | 599 | JSGI Specification L 600 | 601 | =back 602 | 603 | I'd like to thank the authors of these great documents. 604 | 605 | =head1 AUTHOR 606 | 607 | Tatsuhiko Miyagawa Emiyagawa@bulknews.netE 608 | 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, giving useful advice, 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 622 | Takatoshi Kitano 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 644 | Daisuke Maki 645 | Kang-min Liu 646 | Yasuhiro Matsumoto 647 | Ash Berlin 648 | Artur Bergman 649 | Simon Cozens 650 | Scott McWhirter 651 | Jiro Nishiguchi 652 | Masahiro Chiba 653 | Patrick Donelan 654 | Paul Driver 655 | Florian Ragwitz 656 | 657 | =head1 COPYRIGHT AND LICENSE 658 | 659 | Copyright Tatsuhiko Miyagawa, 2009-2011. 660 | 661 | This document is licensed under the Creative Commons license by-sa. 662 | 663 | =cut 664 | -------------------------------------------------------------------------------- /PSGI/FAQ.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | PSGI::FAQ - Frequently Asked Questions and answers 4 | 5 | =head1 QUESTIONS 6 | 7 | =head2 General 8 | 9 | =head3 How do you pronounce PSGI? 10 | 11 | We read it simply P-S-G-I. 12 | 13 | =head3 So what is this? 14 | 15 | PSGI is an interface between web servers and perl-based web 16 | applications akin to what CGI does for web servers and CGI scripts. 17 | 18 | =head3 Why do we need this? 19 | 20 | Perl has the L module (which used to be in core before Perl 5.20) 21 | that somewhat abstracts the difference between CGI, mod_perl and FastCGI. 22 | However, most web application framework developers (e.g. Catalyst and Jifty) 23 | usually avoid using it to maximize the performance and to access low-level 24 | APIs. So they end up writing adapters for all of those different 25 | environments, some of which may be well tested while others are not. 26 | 27 | PSGI allows web application framework developers to only write an 28 | adapter for PSGI. End users can choose from among all the backends that 29 | support the PSGI interface. 30 | 31 | =head3 You said PSGI is similar to CGI. How is the PSGI interface different from CGI? 32 | 33 | The PSGI interface is intentionally designed to be very similar to CGI so 34 | that supporting PSGI in addition to CGI would be extremely easy. Here's 35 | a highlight of the key differences between CGI and PSGI: 36 | 37 | =over 4 38 | 39 | =item * 40 | 41 | In CGI, servers are the actual web servers written in any languages 42 | but mostly in C, and script is a script that can be written in any 43 | language such as C, Perl, Shell scripts, Ruby or Python. 44 | 45 | In PSGI, servers are still web servers, but they're perl processes that 46 | are usually embedded in the web server (like mod_perl) or a perl daemon 47 | process called by a web server (like FastCGI), or an entirely perl based 48 | web server. And PSGI application is a perl code reference. 49 | 50 | =item * 51 | 52 | In CGI, we use STDIN, STDERR, and environment variables to read 53 | parameters and the HTTP request body and to send errors from the 54 | application. 55 | 56 | In PSGI, we use the C<$env> hash references and the I and 57 | I streams to pass that data between servers and applications. 58 | 59 | =item * 60 | 61 | In CGI, applications are supposed to print HTTP headers and body to 62 | STDOUT to pass it back to the web server. 63 | 64 | In PSGI, applications are supposed to return a HTTP status code, 65 | headers, and body (as an array ref or a filehandle-like object) to the 66 | application as an array reference. 67 | 68 | =back 69 | 70 | =head3 My framework already does CGI, FCGI and mod_perl. Why do I want to support PSGI? 71 | 72 | There are many benefits for the web application framework to support PSGI. 73 | 74 | =over 4 75 | 76 | =item * 77 | 78 | You can stop writing code to support many web server 79 | environments. 80 | 81 | Plack has a lot of well-tested server adapters to environments such as 82 | CGI, FastCGI and mod_perl. There are also many new web servers built 83 | to support the PSGI standard interface, such as L, L 84 | and L. Once your framework supports PSGI, there's nothing you 85 | need to do to run your application on these new web servers. You can 86 | get that I. 87 | 88 | Also, even if your framework already supports most server environments 89 | like discussed above, you can now drop these code in favor of only 90 | supporting PSGI. This is what L and L have done, when 91 | they implemented the PSGI support. Less code means less bugs :) 92 | 93 | =item * 94 | 95 | Your framework can now use all of Plack middleware components. 96 | 97 | Just search for C on CPAN and you'll see hundreds 98 | of PSGI compatible middleware components. They're often newly created, 99 | but also extracted from plugins for certain web frameworks such as 100 | L. By supporting PSGI interface, your framework can make use 101 | of all of these useful middleware, such as session management, content 102 | caching, URL rewriting and debug panel to name just a few. 103 | 104 | =item * 105 | 106 | You can test the application using the consistent L interface. 107 | 108 | Any PSGI application can be tested using L, either 109 | through a mock request or a live server implementation. There's also 110 | L to allow Mechanize-style testing. 111 | 112 | =back 113 | 114 | =head3 I'm writing a web application. What's the benefit of PSGI for me? 115 | 116 | If the framework you're using supports PSGI, that means your 117 | application can run on any of existing and future PSGI 118 | implementations. You can provide a C<.psgi> file that returns PSGI 119 | application, the end users of your application should be able to 120 | configure and run your application in a bunch of different ways. 121 | 122 | =head3 But I'm writing a web application in CGI and it works well. Should I switch to PSGI? 123 | 124 | If you're writing a web application with a plain CGI.pm and without 125 | using any web frameworks, you're limiting your application in the 126 | plain CGI environments, along with mod_perl and FastCGI with some 127 | tweaks. If you're the only one developer and user of your application 128 | then that's probably fine. 129 | 130 | One day you want to deploy your application in a shared hosting 131 | environment for your clients, or run your server in the standalone 132 | mode rather than as a CGI script, or distribute your application as 133 | open source software. Limiting your application in the CGI environment 134 | by using CGI.pm will bite you then. 135 | 136 | You can start using one of PSGI compatible frameworks (either 137 | full-stack ones or micro ones), or use L if you are 138 | anti frameworks, to make your application PSGI aware, to be more 139 | future proof. 140 | 141 | Even if you ignore PSGI today and write applications in plain CGI, you 142 | can always later switch to PSGI with the L wrapper. 143 | 144 | =head3 What should I do to support PSGI? 145 | 146 | If you're a web server developer, write a PSGI implementation that 147 | calls a PSGI application. Also join the development on Plack, the PSGI 148 | toolkit and utilities, to add a server adapter for your web server. 149 | 150 | If you're a web application framework developer, write an adapter for 151 | PSGI. Now you're freed from supporting all different server 152 | environments. 153 | 154 | If you're a web application developer (or a web application framework 155 | user), choose the framework that supports PSGI, or ask the author to 156 | support it. :) If your application is a large scale installable 157 | application that doesn't use any existing frameworks (e.g. WebGUI or 158 | Movable Type) you're considered as a framework developer instead from 159 | the PSGI point of view. So, writing an adapter for PSGI on your 160 | application would make more sense. 161 | 162 | =head3 Is PSGI faster than (my framework)? 163 | 164 | Again, PSGI is not an implementation, but there's a potential for a 165 | very fast PSGI implementation that preloads everything and runs fully 166 | optimized code as a preforked standalone with XS parsers, an 167 | event-based tiny web server written in C and embedded perl that 168 | supports PSGI, or a plain-old CGI.pm based backend that doesn't load 169 | any modules at all and runs pretty quickly without eating so much 170 | memory under the CGI environment. 171 | 172 | There are prefork web server implementations such as L and 173 | L, as well as fully asynchronous event based implementations 174 | such as L, L or L. They're pretty fast and 175 | they include adapters for Plack so you can run with the L 176 | utility. 177 | 178 | Users of your framework can choose which backend is the best for their 179 | needs. You, as a web application framework developer, don't need to 180 | think about lots of different users with different needs. 181 | 182 | =head2 Plack 183 | 184 | =head3 What is Plack? What is the difference between PSGI and Plack? 185 | 186 | PSGI is a specification, so there's no software or module called PSGI. 187 | End users will need to choose one of the PSGI server implementations 188 | to run PSGI applications on. Plack is a set of PSGI utilities and 189 | contains the reference PSGI server L, as well as 190 | Web server adapters for CGI, FastCGI and mod_perl. 191 | 192 | Plack also has useful APIs and helpers on top of PSGI, such as 193 | L to provide a nice object-oriented API on request 194 | objects, L that allows you to run an PSGI application from 195 | the command line and configure it using C (a la Rack's 196 | Rackup), and L that allows you to test your application 197 | using standard L and L pair through 198 | mocked HTTP or live HTTP servers. See L for details. 199 | 200 | =head3 What kind of server backends would be available? 201 | 202 | In Plack, we already support most web servers like Apache2, and also 203 | the ones that supports standard CGI or FastCGI, but also try to 204 | support special web servers that can embed perl, like Perlbal or 205 | nginx. We think it would be really nice if Apache module mod_perlite 206 | and Google AppEngine supported PSGI too, so that you could run your 207 | PSGI/Plack based perl app in the cloud. 208 | 209 | =head3 Ruby is Rack and JavaScript is Jack. Why is it not called Pack? 210 | 211 | Well Pack indeed is a cute name, but Perl has a built-in function pack 212 | so it's a little confusing, especially when speaking instead of writing. 213 | 214 | =head3 What namespaces should I use to implement PSGI support? 215 | 216 | B. 218 | 219 | The PSGI namespace is reserved for PSGI specifications and reference 220 | unit tests that implementors have to pass. It should not be used by 221 | particular implementations. 222 | 223 | If you write a plugin or an extension to support PSGI for an 224 | (imaginary) web application framework called C, name the code 225 | such as C. 226 | 227 | If you write a web server that supports PSGI interface, then name it 228 | however you want. You can optionally support L's 229 | abstract interface or write an adapter for it, which is: 230 | 231 | my $server = Plack::Handler::FooBar->new(%opt); 232 | $server->run($app); 233 | 234 | By supporting this C and C in your server, it becomes 235 | plackup compatible, so users can run your app via C. You're 236 | recommended to, but not required to follow this API, in which case you 237 | have to provide your own PSGI app launcher. 238 | 239 | =head3 I have a CGI or mod_perl application that I want to run on PSGI/Plack. What should I do? 240 | 241 | You have several choices: 242 | 243 | =over 4 244 | 245 | =item CGI::PSGI 246 | 247 | If you have a web application (or framework) that uses CGI.pm to handle 248 | query parameters, L can help you migrate to PSGI. You'll 249 | need to change how you create CGI objects and how to return the response 250 | headers and body, but the rest of your code will work unchanged. 251 | 252 | =item CGI::Emulate::PSGI and CGI::Compile 253 | 254 | If you have a dead old CGI script that you want to change as little as 255 | possible (or even no change at all), then L and 256 | L can compile and wrap them up as a PSGI application. 257 | 258 | Compared to L, this might be less efficient because of 259 | STDIN/STDOUT capturing and environment variable mangling, but should 260 | work with any CGI implementation, not just CGI.pm, and L 261 | does the job of compiling a CGI script into a code reference just like 262 | mod_perl's Registry does. 263 | 264 | =item Plack::Request and Plack::Response 265 | 266 | If you have an L based application (framework), or want to 267 | write an app from scratch and need a better interface than L, or 268 | you're used to L, then L and 269 | L might be what you want. It gives you a nice 270 | Request/Response object API on top of the PSGI env hash and response 271 | array. 272 | 273 | =back 274 | 275 | NOTE: Don't forget that whenever you have a CGI script that runs once 276 | and exits, and you turn it into a persistent process, it may have 277 | cleanup that needs to happen after every request -- variables that need 278 | to be reset, files that need to be closed or deleted, etc. PSGI can do 279 | nothing about that (you have to fix it) except give you this friendly 280 | reminder. 281 | 282 | =head2 HTTP::Engine 283 | 284 | =head3 Why PSGI/Plack instead of HTTP::Engine? 285 | 286 | HTTP::Engine was a great experiment, but it mixed the application 287 | interface (the C interface) with implementations, and 288 | the monolithic class hierarchy and role based interfaces make it really 289 | hard to write a new backend. We kept the existing HTTP::Engine and broke 290 | it into three parts: The interface specification (PSGI), Reference 291 | server implementations (Plack::Handler) and Standard APIs and Tools 292 | (Plack). 293 | 294 | =head3 Will HTTP::Engine be dead? 295 | 296 | It won't be dead. HTTP::Engine will stay as it is and still be useful 297 | if you want to write a micro webserver application rather than a 298 | framework. 299 | 300 | =head3 Do I have to rewrite my HTTP::Engine application to follow PSGI interface? 301 | 302 | No, you don't need to rewrite your existing HTTP::Engine application. 303 | It can be easily turned into a PSGI application using 304 | L. 305 | 306 | Alternatively, you can use L and L 307 | which gives compatible APIs to L and 308 | L: 309 | 310 | use Plack::Request; 311 | use Plack::Response; 312 | 313 | sub request_handler { 314 | my $req = Plack::Request->new(shift); 315 | my $res = Plack::Response->new; 316 | # ... 317 | return $res->finalize; 318 | } 319 | 320 | And this C is a PSGI application now. 321 | 322 | =head2 API Design 323 | 324 | Keep in mind that most design choices made in the PSGI spec are to 325 | minimize the requirements on backends so they can optimize things. 326 | Adding a fancy interface or allowing flexibility in the PSGI layers 327 | might sound catchy to end users, but it would just add things that 328 | backends have to support, which would end up getting in the way of 329 | optimizations, or introducing more bugs. What makes a fancy API to 330 | attract web application developers is your framework, not PSGI. 331 | 332 | =head3 Why a big env hash instead of objects with APIs? 333 | 334 | The simplicity of the interface is the key that made WSGI and Rack 335 | successful. PSGI is a low-level interface between backends and web 336 | application framework developers. If we define an API on what type of 337 | objects should be passed and which method they need to implement, 338 | there will be so much duplicated code in the backends, some of 339 | which may be buggy. 340 | 341 | For instance, PSGI defines C<< $env->{SERVER_NAME} >> as a 342 | string. What if the PSGI spec required it to be an instance of Net::IP? 343 | Backend code would have to depend on the Net::IP module, or have to 344 | write a mock object that implements ALL of Net::IP's methods. 345 | Backends depending on specific modules or having to reinvent lots 346 | of stuff is considered harmful and that's why the interface is as minimal 347 | as possible. 348 | 349 | Making a nice API for the end users is a job that web application 350 | frameworks (adapter developers) should do, not something PSGI needs to 351 | define. 352 | 353 | =head3 Why is the application a code ref rather than an object with a ->call method? 354 | 355 | Requiring an object I a code ref would make EVERY 356 | backend's code a few lines more tedious, while requiring an object 357 | I a code ref would make application developers write 358 | another class and instantiate an object. 359 | 360 | In other words, yes an object with a C method could work, but 361 | again PSGI was designed to be as simple as possible, and making a code 362 | reference out of class/object is no brainer but the other way round 363 | always requires a few lines of code and possibly a new file. 364 | 365 | =head3 Why are the headers returned as an array ref and not a hash ref? 366 | 367 | Short: In order to support multiple headers (e.g. C). 368 | 369 | Long: In Python WSGI, the response header is a list of (C, 370 | C) I i.e. C 371 | so there can be multiple entries for the same header key. In Rack and 372 | JSGI, a header value is a String consisting of lines separated by 373 | "C<\n>". 374 | 375 | We liked Python's specification here, and since Perl hashes don't 376 | allow multiple entries with the same key (unless it's Cd), using 377 | an array reference to store C<< [ key => value, key => value ] >> is 378 | the simplest solution to keep both framework adapters and 379 | backends simple. Other options, like allowing an array ref 380 | in addition to a plain scalar, make either side of the code 381 | unnecessarily tedious. 382 | 383 | =head3 I want to send Unicode content in the HTTP response. How can I do so? 384 | 385 | PSGI mocks wire protocols like CGI, and the interface doesn't care too 386 | much about the character encodings and string semantics. That means, 387 | all the data on PSGI environment values, content body etc. are sent as 388 | byte strings, and it is an application's responsibility to properly 389 | decode or encode characters such that it's being sent over HTTP. 390 | 391 | If you have a decoded string in your application and want to send them 392 | in C as an HTTP body, you should use L module to encode 393 | it to utf-8. Note that if you use one of PSGI-supporting frameworks, 394 | chances are that they allow you to set Unicode text in the response 395 | body and they do the encoding for you. Check the documentation of your 396 | framework to see if that's the case. 397 | 398 | This design decision was made so it gives more flexibility to PSGI 399 | applications and frameworks, without putting complicated work into 400 | PSGI web servers and interface specification itself. 401 | 402 | =head3 No iterators support in $body? 403 | 404 | We learned that WSGI and Rack really enjoy the benefit of Python and 405 | Ruby's language beauty, which are iterable objects in Python or 406 | iterators in Ruby. 407 | 408 | Rack, for instance, expects the body as an object that responds to 409 | the C method and then yields the buffer, so 410 | 411 | body.each { |buf| request.write(buf) } 412 | 413 | would just magically work whether body is an Array, FileIO object or an 414 | object that implements iterators. Perl doesn't have such a beautiful 415 | thing in the language unless L is loaded. PSGI should not make 416 | autobox as a requirement, so we only support a simple array ref or file 417 | handle. 418 | 419 | Writing an IO::Handle-like object is pretty easy since it's only 420 | C and C. You can also use PerlIO to write an object that 421 | behaves like a filehandle, though it might be considered a little 422 | unstable. 423 | 424 | See also L to turn anything iterators-like into 425 | IO::Handle-like. 426 | 427 | =head3 How should server determine to switch to sendfile(2) based serving? 428 | 429 | First of all, an application SHOULD always set a IO::Handle-like 430 | object (or an array of chunks) that responds to C and 431 | C as a body. That is guaranteed to work with any servers. 432 | 433 | Optionally, if the server is written in perl or can tell a file 434 | descriptor number to the C-land to serve the file, then the server MAY 435 | check if the body is a real filehandle (possibly using 436 | L's C function), then get a file descriptor 437 | with C and call sendfile(2) or equivalent zero-copy data 438 | transfer using that. 439 | 440 | Otherwise, if the server can't send a file using the file descriptor 441 | but needs a local file path (like mod_perl or nginx), the application 442 | can return an IO::Handle-like object that also responds to C 443 | method. This type of IO-like object can easily be created using 444 | L, L or L's 445 | C function. 446 | 447 | Middlewares can also look to see if the body has C method and 448 | does something interesting with it, like setting C 449 | headers. 450 | 451 | To summarize: 452 | 453 | =over 4 454 | 455 | =item * 456 | 457 | When to serve static files, applications should always return a real 458 | filehandle or IO::Handle object. That should work everywhere, and can 459 | be optimized in some environments. 460 | 461 | =item * 462 | 463 | Applications can also set IO::Handle like object with an additional 464 | C method, then it should work everywhere again, and can be 465 | optimized in even more environments. 466 | 467 | =back 468 | 469 | =head3 What if I want to stream content or do a long-poll Comet? 470 | 471 | The most straightforward way to implement server push is for your 472 | application to return a IO::Handle-like object as a content body that 473 | implements C to return pushed content. This is guaranteed to 474 | work everywhere, but it's more like I than I, and it's 475 | hard to do non-blocking I/O unless you use Coro. 476 | 477 | If you want to do server push, where your application runs in an event 478 | loop and push content body to the client as it's ready, you should 479 | return a callback to delay the response. 480 | 481 | # long-poll comet like a chat application 482 | my $app = sub { 483 | my $env = shift; 484 | unless ($env->{'psgi.streaming'}) { 485 | die "This application needs psgi.streaming support"; 486 | } 487 | return sub { 488 | my $respond = shift; 489 | wait_for_new_message(sub { 490 | my $message = shift; 491 | my $body = [ $message->to_json ]; 492 | $respond->([200, ['Content-Type', 'application/json'], $body]); 493 | }); 494 | }; 495 | }; 496 | 497 | C can be blocking or non-blocking: it's up to 498 | you. Most of the time you want it to be non-blocking and should use 499 | event loops like L. You may also check C 500 | value to see that it's possible and fallback to a blocking call 501 | otherwise. 502 | 503 | Also, to stream the content body (like streaming messages over the 504 | Flash socket or multipart XMLHTTPRequest): 505 | 506 | my $app = sub { 507 | my $env = shift; 508 | unless ($env->{'psgi.streaming'}) { 509 | die "This application needs psgi.streaming support"; 510 | } 511 | return sub { 512 | my $respond = shift; 513 | my $writer = $respond->([200, ['Content-Type', 'text/plain']]); 514 | wait_for_new_message(sub { 515 | my $message = shift; 516 | if ($message) { 517 | $writer->write($message->to_json); 518 | } else { 519 | $writer->close; 520 | } 521 | }); 522 | }; 523 | }; 524 | 525 | =head3 Which framework should I use to do streaming though? 526 | 527 | We have servers that support non-blocking (where C 528 | is set to true), but the problem is that framework side doesn't 529 | necessarily support asynchronous event loop. For instance Catalyst has 530 | C method on the response object: 531 | 532 | while ($cond) { 533 | $c->res->write($some_stuff); 534 | } 535 | 536 | This should work with all servers with C support even 537 | if they are blocking, and it should be fine if they're running in 538 | multiple processes (C is true). 539 | 540 | L also supports setting an IO::Handle-like 541 | object that supports C, so using L 542 | 543 | my $io = io_from_getline sub { 544 | return $data; # or undef when done() 545 | }; 546 | $c->res->body($io); 547 | 548 | And that works fine to do streaming, but it's blocking (I) 549 | rather than asynchronous server push, so again you should be careful 550 | not to run this application on non-blocking (and non-multiprocess) 551 | server environments. 552 | 553 | We expect that more web frameworks will appear that is focused on, or 554 | existent frameworks will add support for, asynchronous and 555 | non-blocking streaming interface. 556 | 557 | =head3 Is psgi.streaming interface a requirement for the servers? 558 | 559 | It is specified as B, so unless there is a strong reason not 560 | to implement the interface, all servers are encouraged to implement 561 | this interface. 562 | 563 | However, if you implement a PSGI server using an Perl XS interface for 564 | the ultimate performance or integration with web servers like Apache 565 | or nginx, or implement a sandbox like environment (like Google 566 | AppEngine or Heroku) or distributed platform using tools like Gearman, 567 | you might not want to implement this interface. 568 | 569 | That's fine, and in that case applications relying on the streaming 570 | interface can still use L to 571 | fallback to the buffered write on unsupported servers. 572 | 573 | =head3 Why CGI-style environment variables instead of HTTP headers as a hash? 574 | 575 | Most existing web application frameworks already have code or a handler 576 | to run under the CGI environment. Using CGI-style hash keys instead of 577 | HTTP headers makes it trivial for the framework developers to implement 578 | an adapter to support PSGI. For instance, L is 579 | only a few dozens lines different from L and was 580 | written in less than an hour. 581 | 582 | =head3 Why is PATH_INFO URI decoded? 583 | 584 | To be compatible with CGI spec (RFC 3875) and most web servers' 585 | implementations (like Apache and lighttpd). 586 | 587 | I understand it could be inconvenient that you can't distinguish 588 | C from C in the trailing path, but the CGI spec 589 | clearly says C should be decoded by servers, and that web 590 | servers can deny such requests containing C<%2f> (since such requests 591 | would lose information in PATH_INFO). Leaving those reserved characters 592 | undecoded (partial decoding) would make things worse, since then you 593 | can't tell C from C and could be a security hole 594 | with double encoding or decoding. 595 | 596 | For web application frameworks that need more control over the actual 597 | raw URI (such as L), we made the C environment 598 | hash key REQUIRED. The servers should set the undecoded (unparsed) 599 | original URI (containing the query string) to this key. Note that 600 | C is completely raw even if the encoded entities are 601 | URI-safe. 602 | 603 | For comparison, WSGI (PEP-333) defines both C and 604 | C be decoded and Rack leaves it implementation dependent, 605 | while I most of PATH_INFO left encoded in Ruby web server 606 | implementations. 607 | 608 | L 609 | L 610 | 611 | =head1 SEE ALSO 612 | 613 | WSGI's FAQ clearly answers lots of questions about how some API design 614 | decisions were made, some of which can directly apply to PSGI. 615 | 616 | L 617 | 618 | =head1 MORE QUESTIONS? 619 | 620 | If you have a question that is not answered here, or things you totally 621 | disagree with, come join the IRC channel #plack on irc.perl.org or 622 | mailing list L. Be sure you 623 | clarify which hat you're wearing: application developers, server 624 | implementors or middleware developers. And don't criticize the spec just 625 | to criticize it: show your exact code that doesn't work or get too messy 626 | because of spec restrictions etc. We'll ignore all nitpicks and bikeshed 627 | discussion. 628 | 629 | =head1 AUTHOR 630 | 631 | Tatsuhiko Miyagawa Emiyagawa@bulknews.netE 632 | 633 | =head1 COPYRIGHT AND LICENSE 634 | 635 | Copyright Tatsuhiko Miyagawa, 2009-2010. 636 | 637 | This document is licensed under the Creative Commons license by-sa. 638 | 639 | =cut 640 | --------------------------------------------------------------------------------