1=head1 NAME 2 3PSGI::FAQ - Frequently Asked Questions and answers 4 5=head1 QUESTIONS 6 7=head2 General 8 9=head3 How do you pronounce PSGI? 10 11We read it simply P-S-G-I. 12 13=head3 So what is this? 14 15PSGI is an interface between web servers and perl-based web 16applications akin to what CGI does for web servers and CGI scripts. 17 18=head3 Why do we need this? 19 20Perl has L<CGI> as a core module that somewhat abstracts the 21difference between CGI, mod_perl and FastCGI. However, most web 22application framework developers (e.g. Catalyst and Jifty) usually 23avoid using it to maximize the performance and to access low-level 24APIs. So they end up writing adapters for all of those different 25environments, some of which may be well tested while others are not. 26 27PSGI allows web application framework developers to only write an 28adapter for PSGI. End users can choose from among all the backends that 29support the PSGI interface. 30 31=head3 You said PSGI is similar to CGI. How is the PSGI interface different from CGI? 32 33The PSGI interface is intentionally designed to be very similar to CGI so 34that supporting PSGI in addition to CGI would be extremely easy. Here's 35a highlight of the key differences between CGI and PSGI: 36 37=over 4 38 39=item * 40 41In CGI, servers are the actual web servers written in any languages 42but mostly in C, and script is a script that can be written in any 43language such as C, Perl, Shell scripts, Ruby or Python. 44 45In PSGI, servers are still web servers, but they're perl processes that 46are usually embedded in the web server (like mod_perl) or a perl daemon 47process called by a web server (like FastCGI), or an entirely perl based 48web server. And PSGI application is a perl code reference. 49 50=item * 51 52In CGI, we use STDIN, STDERR, and environment variables to read 53parameters and the HTTP request body and to send errors from the 54application. 55 56In PSGI, we use the C<$env> hash references and the I<psgi.input> and 57I<psgi.errors> streams to pass that data between servers and applications. 58 59=item * 60 61In CGI, applications are supposed to print HTTP headers and body to 62STDOUT to pass it back to the web server. 63 64In PSGI, applications are supposed to return a HTTP status code, 65headers, and body (as an array ref or a filehandle-like object) to the 66application 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 72There are many benefits for the web application framework to support PSGI. 73 74=over 4 75 76=item * 77 78You can stop writing code to support many web server 79environments. 80 81Plack has a lot of well-tested server adapters to environments such as 82CGI, FastCGI and mod_perl. There are also many new web servers built 83to support the PSGI standard interface, such as L<Starman>, L<Starlet> 84and L<Twiggy>. Once your framework supports PSGI, there's nothing you 85need to do to run your application on these new web servers. You can 86get that I<for free>. 87 88Also, even if your framework already supports most server environments 89like discussed above, you can now drop these code in favor of only 90supporting PSGI. This is what L<Jifty> and L<Catalyst> have done, when 91they implemented the PSGI support. Less code means less bugs :) 92 93=item * 94 95Your framework can now use all of Plack middleware components. 96 97Just search for C<Plack::Middleware> on CPAN and you'll see hundreds 98of PSGI compatible middleware components. They're often newly created, 99but also extracted from plugins for certain web frameworks such as 100L<Catalyst>. By supporting PSGI interface, your framework can make use 101of all of these useful middleware, such as session management, content 102caching, URL rewriting and debug panel to name just a few. 103 104=item * 105 106You can test the application using the consistent L<Plack::Test> interface. 107 108Any PSGI application can be tested using L<Plack::Test>, either 109through a mock request or a live server implementation. There's also 110L<Test::WWW::Mechanize::PSGI> 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 116If the framework you're using supports PSGI, that means your 117application can run on any of existing and future PSGI 118implementations. You can provide a C<.psgi> file that returns PSGI 119application, the end users of your application should be able to 120configure 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 124If you're writing a web application with a plain CGI.pm and without 125using any web frameworks, you're limiting your application in the 126plain CGI environments, along with mod_perl and FastCGI with some 127tweaks. If you're the only one developer and user of your application 128then that's probably fine. 129 130One day you want to deploy your application in a shared hosting 131environment for your clients, or run your server in the standalone 132mode rather than as a CGI script, or distribute your application as 133open source software. Limiting your application in the CGI environment 134by using CGI.pm will bite you then. 135 136You can start using one of PSGI compatible frameworks (either 137full-stack ones or micro ones), or use L<Plack::Request> if you are 138anti frameworks, to make your application PSGI aware, to be more 139future proof. 140 141Even if you ignore PSGI today and write applications in plain CGI, you 142can always later switch to PSGI with the L<CGI::PSGI> wrapper. 143 144=head3 What should I do to support PSGI? 145 146If you're a web server developer, write a PSGI implementation that 147calls a PSGI application. Also join the development on Plack, the PSGI 148toolkit and utilities, to add a server adapter for your web server. 149 150If you're a web application framework developer, write an adapter for 151PSGI. Now you're freed from supporting all different server 152environments. 153 154If you're a web application developer (or a web application framework 155user), choose the framework that supports PSGI, or ask the author to 156support it. :) If your application is a large scale installable 157application that doesn't use any existing frameworks (e.g. WebGUI or 158Movable Type) you're considered as a framework developer instead from 159the PSGI point of view. So, writing an adapter for PSGI on your 160application would make more sense. 161 162=head3 Is PSGI faster than (my framework)? 163 164Again, PSGI is not an implementation, but there's a potential for a 165very fast PSGI implementation that preloads everything and runs fully 166optimized code as a preforked standalone with XS parsers, an 167event-based tiny web server written in C and embedded perl that 168supports PSGI, or a plain-old CGI.pm based backend that doesn't load 169any modules at all and runs pretty quickly without eating so much 170memory under the CGI environment. 171 172There are prefork web server implementations such as L<Starman> and 173L<Starlet>, as well as fully asynchronous event based implementations 174such as L<Twiggy>, L<Corona> or L<Feersum>. They're pretty fast and 175they include adapters for Plack so you can run with the L<plackup> 176utility. 177 178Users of your framework can choose which backend is the best for their 179needs. You, as a web application framework developer, don't need to 180think 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 186PSGI is a specification, so there's no software or module called PSGI. 187End users will need to choose one of the PSGI server implementations 188to run PSGI applications on. Plack is a set of PSGI utilities and 189contains the reference PSGI server L<HTTP::Server::PSGI>, as well as 190Web server adapters for CGI, FastCGI and mod_perl. 191 192Plack also has useful APIs and helpers on top of PSGI, such as 193L<Plack::Request> to provide a nice object-oriented API on request 194objects, L<plackup> that allows you to run an PSGI application from 195the command line and configure it using C<app.psgi> (a la Rack's 196Rackup), and L<Plack::Test> that allows you to test your application 197using standard L<HTTP::Request> and L<HTTP::Response> pair through 198mocked HTTP or live HTTP servers. See L<Plack> for details. 199 200=head3 What kind of server backends would be available? 201 202In Plack, we already support most web servers like Apache2, and also 203the ones that supports standard CGI or FastCGI, but also try to 204support special web servers that can embed perl, like Perlbal or 205nginx. We think it would be really nice if Apache module mod_perlite 206and Google AppEngine supported PSGI too, so that you could run your 207PSGI/Plack based perl app in the cloud. 208 209=head3 Ruby is Rack and JavaScript is Jack. Why is it not called Pack? 210 211Well Pack indeed is a cute name, but Perl has a built-in function pack 212so it's a little confusing, especially when speaking instead of writing. 213 214=head3 What namespaces should I use to implement PSGI support? 215 216B<Do not use the PSGI:: namespace to implement PSGI backends 217or adapters>. 218 219The PSGI namespace is reserved for PSGI specifications and reference 220unit tests that implementors have to pass. It should not be used by 221particular implementations. 222 223If you write a plugin or an extension to support PSGI for an 224(imaginary) web application framework called C<Camper>, name the code 225such as C<Camper::Engine::PSGI>. 226 227If you write a web server that supports PSGI interface, then name it 228however you want. You can optionally support L<Plack::Handler>'s 229abstract interface or write an adapter for it, which is: 230 231 my $server = Plack::Handler::FooBar->new(%opt); 232 $server->run($app); 233 234By supporting this C<new> and C<run> in your server, it becomes 235plackup compatible, so users can run your app via C<plackup>. You're 236recommended to, but not required to follow this API, in which case you 237have 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 241You have several choices: 242 243=over 4 244 245=item CGI::PSGI 246 247If you have a web application (or framework) that uses CGI.pm to handle 248query parameters, L<CGI::PSGI> can help you migrate to PSGI. You'll 249need to change how you create CGI objects and how to return the response 250headers and body, but the rest of your code will work unchanged. 251 252=item CGI::Emulate::PSGI and CGI::Compile 253 254If you have a dead old CGI script that you want to change as little as 255possible (or even no change at all), then L<CGI::Emulate::PSGI> and 256L<CGI::Compile> can compile and wrap them up as a PSGI application. 257 258Compared to L<CGI::PSGI>, this might be less efficient because of 259STDIN/STDOUT capturing and environment variable mangling, but should 260work with any CGI implementation, not just CGI.pm, and L<CGI::Compile> 261does the job of compiling a CGI script into a code reference just like 262mod_perl's Registry does. 263 264=item Plack::Request and Plack::Response 265 266If you have an L<HTTP::Engine> based application (framework), or want to 267write an app from scratch and need a better interface than L<CGI>, or 268you're used to L<Apache::Request>, then L<Plack::Request> and 269L<Plack::Response> might be what you want. It gives you a nice 270Request/Response object API on top of the PSGI env hash and response 271array. 272 273=back 274 275NOTE: Don't forget that whenever you have a CGI script that runs once 276and exits, and you turn it into a persistent process, it may have 277cleanup that needs to happen after every request -- variables that need 278to be reset, files that need to be closed or deleted, etc. PSGI can do 279nothing about that (you have to fix it) except give you this friendly 280reminder. 281 282=head2 HTTP::Engine 283 284=head3 Why PSGI/Plack instead of HTTP::Engine? 285 286HTTP::Engine was a great experiment, but it mixed the application 287interface (the C<request_handler> interface) with implementations, and 288the monolithic class hierarchy and role based interfaces make it really 289hard to write a new backend. We kept the existing HTTP::Engine and broke 290it into three parts: The interface specification (PSGI), Reference 291server implementations (Plack::Handler) and Standard APIs and Tools 292(Plack). 293 294=head3 Will HTTP::Engine be dead? 295 296It won't be dead. HTTP::Engine will stay as it is and still be useful 297if you want to write a micro webserver application rather than a 298framework. 299 300=head3 Do I have to rewrite my HTTP::Engine application to follow PSGI interface? 301 302No, you don't need to rewrite your existing HTTP::Engine application. 303It can be easily turned into a PSGI application using 304L<HTTP::Engine::Interface::PSGI>. 305 306Alternatively, you can use L<Plack::Request> and L<Plack::Response> 307which gives compatible APIs to L<HTTP::Engine::Request> and 308L<HTTP::Engine::Response>: 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 320And this C<request_handler> is a PSGI application now. 321 322=head2 API Design 323 324Keep in mind that most design choices made in the PSGI spec are to 325minimize the requirements on backends so they can optimize things. 326Adding a fancy interface or allowing flexibility in the PSGI layers 327might sound catchy to end users, but it would just add things that 328backends have to support, which would end up getting in the way of 329optimizations, or introducing more bugs. What makes a fancy API to 330attract web application developers is your framework, not PSGI. 331 332=head3 Why a big env hash instead of objects with APIs? 333 334The simplicity of the interface is the key that made WSGI and Rack 335successful. PSGI is a low-level interface between backends and web 336application framework developers. If we define an API on what type of 337objects should be passed and which method they need to implement, 338there will be so much duplicated code in the backends, some of 339which may be buggy. 340 341For instance, PSGI defines C<< $env->{SERVER_NAME} >> as a 342string. What if the PSGI spec required it to be an instance of Net::IP? 343Backend code would have to depend on the Net::IP module, or have to 344write a mock object that implements ALL of Net::IP's methods. 345Backends depending on specific modules or having to reinvent lots 346of stuff is considered harmful and that's why the interface is as minimal 347as possible. 348 349Making a nice API for the end users is a job that web application 350frameworks (adapter developers) should do, not something PSGI needs to 351define. 352 353=head3 Why is the application a code ref rather than an object with a ->call method? 354 355Requiring an object I<in addition to> a code ref would make EVERY 356backend's code a few lines more tedious, while requiring an object 357I<instead of> a code ref would make application developers write 358another class and instanciate an object. 359 360In other words, yes an object with a C<call> method could work, but 361again PSGI was designed to be as simple as possible, and making a code 362reference out of class/object is no brainer but the other way round 363always 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 367Short: In order to support multiple headers (e.g. C<Set-Cookie>). 368 369Long: In Python WSGI, the response header is a list of (C<header_name>, 370C<header_value>) I<tuples> i.e. C<type(response_headers) is ListType> 371so there can be multiple entries for the same header key. In Rack and 372JSGI, a header value is a String consisting of lines separated by 373"C<\n>". 374 375We liked Python's specification here, and since Perl hashes don't 376allow multiple entries with the same key (unless it's C<tie>d), using 377an array reference to store C<< [ key => value, key => value ] >> is 378the simplest solution to keep both framework adapters and 379backends simple. Other options, like allowing an array ref 380in addition to a plain scalar, make either side of the code 381unnecessarily tedious. 382 383=head3 I want to send Unicode content in the HTTP response. How can I do so? 384 385PSGI mocks wire protocols like CGI, and the interface doesn't care too 386much about the character encodings and string semantics. That means, 387all the data on PSGI environment values, content body etc. are sent as 388byte strings, and it is an application's responsibility to properly 389decode or encode characters such that it's being sent over HTTP. 390 391If you have a decoded string in your application and want to send them 392in C<UTF-8> as an HTTP body, you should use L<Encode> module to encode 393it to utf-8. Note that if you use one of PSGI-supporting frameworks, 394chances are that they allow you to set Unicode text in the response 395body and they do the encoding for you. Check the documentation of your 396framework to see if that's the case. 397 398This design decision was made so it gives more flexibility to PSGI 399applications and frameworks, without putting complicated work into 400PSGI web servers and interface specification itself. 401 402=head3 No iterators support in $body? 403 404We learned that WSGI and Rack really enjoy the benefit of Python and 405Ruby's language beauty, which are iterable objects in Python or 406iterators in Ruby. 407 408Rack, for instance, expects the body as an object that responds to 409the C<each> method and then yields the buffer, so 410 411 body.each { |buf| request.write(buf) } 412 413would just magically work whether body is an Array, FileIO object or an 414object that implements iterators. Perl doesn't have such a beautiful 415thing in the language unless L<autobox> is loaded. PSGI should not make 416autobox as a requirement, so we only support a simple array ref or file 417handle. 418 419Writing an IO::Handle-like object is pretty easy since it's only 420C<getline> and C<close>. You can also use PerlIO to write an object that 421behaves like a filehandle, though it might be considered a little 422unstable. 423 424See also L<IO::Handle::Util> to turn anything iterators-like into 425IO::Handle-like. 426 427=head3 How should server determine to switch to sendfile(2) based serving? 428 429First of all, an application SHOULD always set a IO::Handle-like 430object (or an array of chunks) that responds to C<getline> and 431C<close> as a body. That is guaranteed to work with any servers. 432 433Optionally, if the server is written in perl or can tell a file 434descriptor number to the C-land to serve the file, then the server MAY 435check if the body is a real filehandle (possibly using 436L<Plack::Util>'s C<is_real_fh> function), then get a file descriptor 437with C<fileno> and call sendfile(2) or equivalent zero-copy data 438transfer using that. 439 440Otherwise, if the server can't send a file using the file descriptor 441but needs a local file path (like mod_perl or nginx), the application 442can return an IO::Handle-like object that also responds to C<path> 443method. This type of IO-like object can easily be created using 444L<IO::File::WithPath>, L<IO::Handle::Util> or L<Plack::Util>'s 445C<set_io_path> function. 446 447Middlewares can also look to see if the body has C<path> method and 448does something interesting with it, like setting C<X-Sendfile> 449headers. 450 451To summarize: 452 453=over 4 454 455=item * 456 457When to serve static files, applications should always return a real 458filehandle or IO::Handle object. That should work everywhere, and can 459be optimized in some environments. 460 461=item * 462 463Applications can also set IO::Handle like object with an additional 464C<path> method, then it should work everywhere again, and can be 465optimized in even more environments. 466 467=back 468 469=head3 What if I want to stream content or do a long-poll Comet? 470 471The most straightforward way to implement server push is for your 472application to return a IO::Handle-like object as a content body that 473implements C<getline> to return pushed content. This is guaranteed to 474work everywhere, but it's more like I<pull> than I<push>, and it's 475hard to do non-blocking I/O unless you use Coro. 476 477If you want to do server push, where your application runs in an event 478loop and push content body to the client as it's ready, you should 479return 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 497C<wait_for_new_message> can be blocking or non-blocking: it's up to 498you. Most of the case you want to run it non-blockingly and should use 499event loops like L<AnyEvent>. You may also check C<psgi.nonblocking> 500value to see that it's possible and fallback to a blocking call 501otherwise. 502 503Also, to stream the content body (like streaming messages over the 504Flash 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 527We have servers that support non-blocking (where C<psgi.nonblocking> 528is set to true), but the problem is that framework side doesn't 529necessarily support asynchronous event loop. For instance Catalyst has 530C<write> method on the response object: 531 532 while ($cond) { 533 $c->res->write($some_stuff); 534 } 535 536This should work with all servers with C<psgi.streaming> support even 537if they are blocking, and it should be fine if they're running in 538multiple processes (C<psgi.multiprocess> is true). 539 540L<Catalyst::Engine::PSGI> also supports setting an IO::Handle-like 541object that supports C<getline>, so using L<IO::Handle::Util> 542 543 my $io = io_from_getline sub { 544 return $data; # or undef when done() 545 }; 546 $c->res->body($io); 547 548And that works fine to do streaming, but it's blocking (I<pull>) 549rather than asynchronous server push, so again you should be careful 550not to run this application on non-blocking (and non-multiprocess) 551server environments. 552 553We expect that more web frameworks will appear that is focused on, or 554existent frameworks will add support for, asynchronous and 555non-blocking streaming interface. 556 557=head3 Is psgi.streaming interface a requirement for the servers? 558 559It is specified as B<SHOULD>, so unless there is a strong reason not 560to implement the interface, all servers are encouraged to implement 561this interface. 562 563However, if you implement a PSGI server using an Perl XS interface for 564the ultimate performance or integration with web servers like Apache 565or nginx, or implement a sandbox like environment (like Google 566AppEngine or Heroku) or distributed platform using tools like Gearman, 567you might not want to implement this interface. 568 569That's fine, and in that case applications relying on the streaming 570interface can still use L<Plack::Middleware::BufferedStreaming> to 571fallback to the buffered write on unsupported servers. 572 573=head3 Why CGI-style environment variables instead of HTTP headers as a hash? 574 575Most existing web application frameworks already have code or a handler 576to run under the CGI environment. Using CGI-style hash keys instead of 577HTTP headers makes it trivial for the framework developers to implement 578an adapter to support PSGI. For instance, L<Catalyst::Engine::PSGI> is 579only a few dozens lines different from L<Catalyst::Engine::CGI> and was 580written in less than an hour. 581 582=head3 Why is PATH_INFO URI decoded? 583 584To be compatible with CGI spec (RFC 3875) and most web servers' 585implementations (like Apache and lighttpd). 586 587I understand it could be inconvenient that you can't distinguish 588C<foo%2fbar> from C<foo/bar> in the trailing path, but the CGI spec 589clearly says C<PATH_INFO> should be decoded by servers, and that web 590servers can deny such requests containing C<%2f> (since such requests 591would lose information in PATH_INFO). Leaving those reserved characters 592undecoded (partial decoding) would make things worse, since then you 593can't tell C<foo%2fbar> from C<foo%252fbar> and could be a security hole 594with double encoding or decoding. 595 596For web application frameworks that need more control over the actual 597raw URI (such as L<Catalyst>), we made the C<REQUEST_URI> environment 598hash key REQUIRED. The servers should set the undecoded (unparsed) 599original URI (containing the query string) to this key. Note that 600C<REQUEST_URI> is completely raw even if the encoded entities are 601URI-safe. 602 603For comparison, WSGI (PEP-333) defines both C<SCRIPT_NAME> and 604C<PATH_INFO> be decoded and Rack leaves it implementation dependent, 605while I<fixing> most of PATH_INFO left encoded in Ruby web server 606implementations. 607 608L<http://www.python.org/dev/peps/pep-0333/#url-reconstruction> 609L<http://groups.google.com/group/rack-devel/browse_thread/thread/ddf4622e69bea53f> 610 611=head1 SEE ALSO 612 613WSGI's FAQ clearly answers lots of questions about how some API design 614decisions were made, some of which can directly apply to PSGI. 615 616L<http://www.python.org/dev/peps/pep-0333/#questions-and-answers> 617 618=head1 MORE QUESTIONS? 619 620If you have a question that is not answered here, or things you totally 621disagree with, come join the IRC channel #plack on irc.perl.org or 622mailing list L<http://groups.google.com/group/psgi-plack>. Be sure you 623clarify which hat you're wearing: application developers, server 624implementors or middleware developers. And don't criticize the spec just 625to criticize it: show your exact code that doesn't work or get too messy 626because of spec restrictions etc. We'll ignore all nitpicks and bikeshed 627discussion. 628 629=head1 AUTHOR 630 631Tatsuhiko Miyagawa E<lt>miyagawa@bulknews.netE<gt> 632 633=head1 COPYRIGHT AND LICENSE 634 635Copyright Tatsuhiko Miyagawa, 2009-2010. 636 637This document is licensed under the Creative Commons license by-sa. 638 639=cut 640