1PSGI::FAQ(3)          User Contributed Perl Documentation         PSGI::FAQ(3)
2
3
4

NAME

6       PSGI::FAQ - Frequently Asked Questions and answers
7

QUESTIONS

9   General
10       How do you pronounce PSGI?
11
12       We read it simply P-S-G-I, but you may be able to pronounce it "sky" :)
13
14       So what is this?
15
16       PSGI is an interface between web servers and perl-based web
17       applications akin to what CGI does for web servers and CGI scripts.
18
19       Why do we need this?
20
21       Perl has CGI as a core module that somewhat abstracts the difference
22       between CGI, mod_perl and FastCGI. However, most web application
23       framework developers (e.g. Catalyst and Jifty) usually avoid using it
24       to maximize the performance and to access low-level APIs. So they end
25       up writing adapters for all of those different environments, some of
26       which may be well tested while others are not.
27
28       PSGI allows web application framework developers to only write an
29       adapter for PSGI.  End users can choose from among all the backends
30       that support the PSGI interface.
31
32       You said PSGI is similar to CGI. How is the PSGI interaface different
33       from CGI?
34
35       The PSGI interface is intentionally designed to be very similar to CGI
36       so that supporting PSGI in addition to CGI would be extremely easy.
37       Here's a highlight of the key differences between CGI and PSGI:
38
39       ·   In CGI, servers are the actual web servers written in any languages
40           but mostly in C, and script is a script that can be written in any
41           language such as C, Perl, Shell scripts, Ruby or Python.
42
43           In PSGI, servers are still web servers, but they're perl processes
44           that are usually embedded in the web server (like mod_perl) or a
45           perl daemon process called by a web server (like FastCGI), or an
46           entirely perl based web server.
47
48       ·   In CGI, we use STDIN, STDERR, and environment variables to read
49           parameters and the HTTP request body and to send errors from the
50           application.
51
52           In PSGI, we use the $env hash references and the psgi.input and
53           psgi.errors streams to pass that data between servers and
54           applications.
55
56       ·   In CGI, applications are supposed to print HTTP headers and body to
57           STDOUT to pass it back to the web server.
58
59           In PSGI, applications are supposed to return a HTTP status code,
60           headers, and body (as an array ref or a filehandle-like object) to
61           the application as an array reference.
62
63       My framework already does CGI, FCGI and mod_perl. Why do I want to
64       support PSGI?
65
66       If your web application framework already supports most server
67       environments, performance is good, and the backends are well tested,
68       there may not be a direct benefit for you to support PSGI immediately
69       -- though you would be able to remove any code that overlaps with PSGI
70       backends. But if only CGI environment is currently supported,
71       supporting PSGI in addition should be extremely easy, and the benefit
72       you and your framework users will enjoy is huge.
73
74       I'm writing a web application. What's the benefit of PSGI for me?
75
76       If the framework you're using supports PSGI, that means your
77       application can run on any of existing and future PSGI implementations.
78       You can provide a ".psgi" file that returns PSGI application, the end
79       users of your application should be able to configure and run your
80       application in a bunch of different ways.
81
82       But I'm writing a web application in CGI and it works well. Should I
83       switch to PSGI?
84
85       If you're writing a web application with a plain CGI.pm and without
86       using any web frameworks, you're limiting your application in the plain
87       CGI environments, along with mod_perl and FastCGI with some tweaks. If
88       you're the only one developer and user of your application then that's
89       probably fine.
90
91       One day you want to deploy your application in the shared hosting for
92       your clients, or run your server in the standalone mode, or distribute
93       your application as an open source software. Limiting your application
94       in the CGI environment by using CGI.pm will bite you then.
95
96       You can start using one of PSGI compatible frameworks (either full-
97       stack ones or micro ones), or use Plack::Request if you are anti
98       frameworks, to make your application PSGI aware, to be more future
99       proof.
100
101       Even if you ignore PSGI today and write applications in palin CGI, you
102       can always later switch to PSGI with the CGI::PSGI wrapper.
103
104       What should I do to support PSGI?
105
106       If you're a web server developer, write a PSGI implementation that
107       calls a PSGI application. Or join the development on Plack, the
108       reference implementation of PSGI, to add backends for more web servers.
109
110       If you're a web application framework developer, write an adapter for
111       PSGI. Now you're freed from supporting all different server
112       environments.
113
114       If you're a web application developer (or a web application framework
115       user), choose the framework that supports PSGI, or ask the author to
116       support it. :) If your application is a large scale installable
117       application that doesn't use any existing frameworks (e.g. WebGUI or
118       Movable Type) you're considered as a framework developer instead from
119       the PSGI point of view. So, writing an adapter for PSGI on your
120       application would make more sense.
121
122       Is PSGI faster than (my framework)?
123
124       Again, PSGI is not an implementation, but there's a potential for a
125       very fast PSGI implementation that preloads everything and runs fully
126       optimized code as a preforked standalone with XS parsers and
127       sendfile(2) kernel call, an event-based tiny web server written in C
128       and embedded perl that supports PSGI, or a plain-old CGI.pm based
129       backend that doesn't load any modules at all and runs pretty quickly
130       without eating so much memory under the CGI environment.
131
132       The reference implementation Plack already has very fast backends like
133       Standalone::Prefork and Coro.
134
135       Users of your framework can choose which backend is the best for their
136       needs.  You, as a web application framework developer, don't need to
137       think about lots of different users with different needs.
138
139   Plack
140       What is Plack? What is the difference between PSGI and Plack?
141
142       PSGI is a specification, so there's no software or module called PSGI.
143       End users will need to choose one of PSGI server implementations to run
144       PSGI applications on. Plack is a reference PSGI implementation that
145       supports environments like prefork standalone server, CGI, FastCGI,
146       mod_perl, AnyEvent and Coro.
147
148       Plack also has useful APIs and helpers on top of PSGI, such as
149       Plack::Request to provide a nice object-oriented API on request
150       objects, plackup that allows you to run an PSGI application from the
151       command line and configure it using "app.psgi" (a la Rack's Rackup),
152       and Plack::Test that allows you to test your application using standard
153       HTTP::Request and HTTP::Response pair through mocked HTTP or live HTTP
154       servers. See Plack for details.
155
156       What kind of server backends would be available?
157
158       In Plack, we already support most web servers like Apache2, and also
159       the ones that supports standard CGI or FastCGI, but also want to
160       support special web servers that can embed perl, like nginx. We think
161       it would be really nice if Apache module mod_perlite and Google
162       AppEngine supported PSGI too, so that you could run your PSGI/Plack
163       based perl app in the cloud.
164
165       Ruby is Rack and JavaScript is Jack. Why is it not called Pack?
166
167       Well Pack indeed is a cute name, but Perl has a built-in function pack
168       so it's a little confusing, especially when speaking instead of
169       writing.
170
171       What namespaces should I use to implement PSGI support?
172
173       Do not use the PSGI:: namespace to implement PSGI backends or adapters.
174
175       The PSGI namespace is reserved for PSGI specifications and reference
176       unit tests that implementors have to pass. It should not be used by
177       particular implementations.
178
179       If you write a plugin or an extension to support PSGI for an
180       (imaginary) web application framework called "Camper", name the code
181       such as "Camper::Engine::PSGI".
182
183       If you write a web server that supports PSGI interface, then name it
184       however you want. You can optionally support Plack::Server's abstract
185       interface, which is:
186
187         my $server = Plack::Server::FooBar->new(%opt);
188         $server->run($app);
189
190       By supporting this "new" and "run" in your server, it becomes plackup
191       compatible, so users can run your app via "plackup". You're recommended
192       to, but not required to follow this API, in which case you have to
193       provide your own PSGI app launcher.
194
195       I have a CGI or mod_perl application that I want to run on PSGI/Plack.
196       What should I do?
197
198       You have several choices:
199
200       CGI::PSGI
201           If you have a web application (or framework) that uses CGI.pm to
202           handle query parameters, CGI::PSGI can help you migrate to PSGI.
203           You'll need to change how you create CGI objects and how to return
204           the response headers and body, but the rest of your code will work
205           unchanged.
206
207       CGI::Emulate::PSGI
208           If you have a dead old CGI script that you want to change as little
209           as possible (or even no change at all, by running it with "do"),
210           then CGI::Emulate::PSGI can wrap it up as a PSGI application.
211           Compared to CGI::PSGI, this is less efficient, but should work with
212           any CGI implementation, not just CGI.pm.
213
214       Plack::Request and Plack::Response
215           If you have an HTTP::Engine based application (framework), or want
216           to write an app from scratch and need a better interface than CGI,
217           or you're used to Apache::Request, then Plack::Request and
218           Plack::Response might be what you want. It gives you a nice
219           Request/Response object API on top of the PSGI env hash and
220           response array.
221
222       NOTE: Don't forget that whenever you have a CGI script that runs once
223       and exits, and you turn it into a persistent process, it may have
224       cleanup that needs to happen after every request -- variables that need
225       to be reset, files that need to be closed or deleted, etc.  PSGI can do
226       nothing about that (you have to fix it) except give you this friendly
227       reminder.
228
229   HTTP::Engine
230       Why PSGI/Plack instead of HTTP::Engine?
231
232       HTTP::Engine was a great experiment, but it mixed the application
233       interface (the "request_handler" interface) with implementations, and
234       the monolithic class hierarchy and role based interfaces make it really
235       hard to write a new backend. We kept the existing HTTP::Engine and
236       broke it into three parts: The interface specification (PSGI),
237       Reference server implementations (Plack::Server) and Standard APIs and
238       Tools (Plack).
239
240       Will HTTP::Engine be dead?
241
242       It won't be dead. HTTP::Engine will stay as it is and still be useful
243       if you want to write a micro webserver application rather than a
244       framework.
245
246       Do I have to rewrite my HTTP::Engine application to follow PSGI
247       interface?
248
249       No, you don't need to rewrite your existing HTTP::Engine application.
250       It can be easily turned into a PSGI application using
251       HTTP::Engine::Interface::PSGI.
252
253       Alternatively, you can use Plack::Request and Plack::Response which
254       gives compatible APIs to HTTP::Engine::Request and
255       HTTP::Engine::Response:
256
257         use Plack::Request;
258         use Plack::Response;
259
260         sub request_handler {
261             my $req = Plack::Request->new(shift);
262             my $res = Plack::Response->new;
263             # ...
264             return $res->finalize;
265         }
266
267       And this "request_handler" is a PSGI application now.
268
269       What's the benefit of converting my HTTP::Engine app to run on PSGI?
270
271       As of today most web server implementations and middlewares implemented
272       by Plack are mostly available on HTTP::Engine as well, so there might
273       not be direct immediate benefit of switching to PSGI. But PSGI is more
274       future proof, and there are high hope that in the near future we'll
275       have a pretty fast server environments (think of Passenger for Ruby
276       Rack) and/or plenty of useful middlewares that HTTP::Engine doesn't
277       have today.
278
279       See the question My framework already does CGI, FCGI and mod_perl. Why
280       do I want to support PSGI? for more details.
281
282   API Design
283       Keep in mind that most design choices made in the PSGI spec are to
284       minimize the requirements on backends so they can optimize things.
285       Adding a fancy interface or allowing flexibility in the PSGI layers
286       might sound catchy to end users, but it would just add things that
287       backends have to support, which would end up getting in the way of
288       optimizations, or introducing more bugs. What makes a fancy API to
289       attract web application developers is your framework, not PSGI.
290
291       Why a big env hash instead of objects with APIs?
292
293       The simplicity of the interface is the key that made WSGI and Rack
294       successful. PSGI is a low-level interface between backends and web
295       application framework developers. If we define an API on what type of
296       objects should be passed and which method they need to implement, there
297       will be so much duplicated code in the backends, some of which may be
298       buggy.
299
300       For instance, PSGI defines "$env->{REMOTE_ADDR}" as a string. What if
301       the PSGI spec required it to be an instance of Net::IP?  Backend code
302       would have to depend on the Net::IP module, or have to write a mock
303       object that implements ALL of Net::IP's methods.  Backends depending on
304       specific modules or having to reinvent lots of stuff is considered
305       harmful and that's why the interface is as minimal as possible.
306
307       Making a nice API for the end users is a job that web application
308       frameworks (adapter developers) should do, not something PSGI needs to
309       define.
310
311       Why is the application a code ref rather than an object with a ->call
312       method?
313
314       Requiring an object in addition to a code ref would make EVERY
315       backend's code a few lines more tedious, while requiring an object
316       instead of a code ref would make application developers write another
317       class and instanciate an object.
318
319       In other words, yes an object with a "call" method could work, but
320       again PSGI was designed to be as simple as possible, and making a code
321       reference out of class/object is no brainer but the other way round
322       always requires a few lines of code and possibly a new file.
323
324       Why are the headers returned as an array ref and not a hash ref?
325
326       Short: In order to support multiple headers (e.g. "Set-Cookie").
327
328       Long: In Python WSGI, the response header is a list of ("header_name",
329       "header_value") tuples i.e. "type(response_headers) is ListType" so
330       there can be multiple entries for the same header key. In Rack and
331       JSGI, a header value is a String consisting of lines separated by
332       ""\n"".
333
334       We liked Python's specification here, and since Perl hashes don't allow
335       multiple entries with the same key (unless it's "tie"d), using an array
336       reference to store "[ key => value, key => value ]" is the simplest
337       solution to keep both framework adapters and backends simple. Other
338       options, like allowing an array ref in addition to a plain scalar, make
339       either side of the code unnecessarily tedious.
340
341       Note that I'm talking about multiple header lines with the same key,
342       and NOT about multiple header values (e.g. "Accept: text/html,
343       text/plain, *"). Joining the header values with ", " is obviously the
344       application's job. HTTP::Headers does exactly that when it's passed an
345       array reference as a header value, for instance.
346
347       The other option is to always require the application to set a value as
348       an array ref, even if there is only one entry: this would make backend
349       code less tedious, but, for the exact reason of multiple header values
350       vs. multiple header lines with the same name mentioned in the paragraph
351       before, I think it's confusing.
352
353       No iterators support in $body?
354
355       We learned that WSGI and Rack really enjoy the benefit of Python and
356       Ruby's language beauty, which are iterable objects in Python or
357       iterators in Ruby.
358
359       Rack, for instance, expects the body as an object that responds to the
360       "each" method and then yields the buffer, so
361
362         body.each { |buf| request.write(buf) }
363
364       would just magically work whether body is an Array, FileIO object or an
365       object that implements iterators. Perl doesn't have such a beautiful
366       thing in the language unless autobox is loaded.  PSGI should not make
367       autobox as a requirement, so we only support a simple array ref or file
368       handle.
369
370       Writing an IO::Handle-like object is pretty easy since it's only
371       "getline" and "close". You can also use PerlIO to write an object that
372       behaves like a filehandle, though it might be considered a little
373       unstable.
374
375       See also IO::Handle::Util to turn anything iterators-like into
376       IO::Handle-like.
377
378       How should server determine to switch to sendfile(2) based serving?
379
380       First of all, an application SHOULD always set a IO::Handle-like object
381       (or an array of chunks) that responds to "getline" and "close" as a
382       body. That is guaranteed to work with any servers.
383
384       Optionally, if the server is written in perl or can tell a file
385       descriptor number to the C-land to serve the file, then the server MAY
386       check if the body is a real filehandle (possibly using Plack::Util's
387       "is_real_fh" function), then get a file descriptor with "fileno" and
388       call sendfile(2) or equivalent zero-copy data transfer using that.
389
390       Otherwise, if the server can't send a file using the file descriptor
391       but needs a local file path (like mod_perl or nginx), the application
392       can return an IO::Handle-like object that also responds to "path"
393       method. This type of IO-like object can easily be created using
394       IO::File::WithPath, IO::Handle::Util or Plack::Util's "set_io_path"
395       function.
396
397       Middlewares can also look to see if the body has "path" method and does
398       something interesting with it, like setting "X-Sendfile" headers.
399
400       To summarize:
401
402       ·   When to serve static files, applications should always return a
403           real filehandle or IO::Handle object. That should work everywhere,
404           and can be optimized in some environments.
405
406       ·   Applications can also set IO::Handle like object with an additional
407           "path" method, then it should work everywhere again, and can be
408           optimized in even more environments.
409
410       What if I want to stream content or do a long-poll Comet?
411
412       The most straightforward way to implement server push is for your
413       application to return a IO::Handle-like object as a content body that
414       implements "getline" to return pushed content. This is guaranteed to
415       work everywhere, but it's more like pull than push, and it's hard to do
416       non-blocking I/O unless you use Coro.
417
418       If you want to do server push, where your application runs in an event
419       loop and push content body to the client as it's ready, you should
420       first check if the server supports the delayed response, by looking at
421       "psgi.streaming" env hash, and then return a callback to delay the
422       response.
423
424         # long-poll comet like a chat application
425         my $app = sub {
426             my $env = shift;
427             unless ($env->{'psgi.streaming'}) {
428                 die "This application needs psgi.streaming support";
429             }
430             return sub {
431                 my $respond = shift;
432                 wait_for_new_message(sub {
433                     my $message = shift;
434                     my $body = [ $message->to_json ];
435                     $respond->([200, ['Content-Type', 'application/json'], $body]);
436                 });
437             };
438         };
439
440       "wait_for_new_message" can be blocking or non-blocking: it's up to you.
441       Most of the case you want to run it non-blockingly and should use event
442       loops like AnyEvent. You're suggested to check "psgi.nonblocking" value
443       to see that it's possible.
444
445       Also, to stream the content body (like streaming messages over the
446       Flash socket or multipart XMLHTTPRequest):
447
448         my $app = sub {
449             my $env = shift;
450             unless ($env->{'psgi.streaming'}) {
451                 die "This application needs psgi.streaming support";
452             }
453             return sub {
454                 my $respond = shift;
455                 my $writer = $respond->([200, ['Content-Type', 'text/plain']]);
456                 wait_for_new_message(sub {
457                     my $message = shift;
458                     if ($message) {
459                         $writer->poll_cb(sub {
460                             $_[0]->write($message->to_json);
461                         });
462                     } else {
463                         $writer->close;
464                     }
465                 });
466             };
467         };
468
469       "poll_cb" pushes the callback to the buffer to write your content
470       whenever a client is ready to receive the content. You can just use
471       "write" instead of "poll_cb" but that might cause a problem if you
472       stream a massive streaming content against a slow HTTP client.
473
474       Which framework should I use to do streaming though?
475
476       We have servers that support non-blocking (where "psgi.nonblocking" is
477       set to true), but the problem is that framework side doesn't necessary
478       support streaming. For instance Catalyst has "write" method on the
479       response object:
480
481         while ($cond) {
482             $c->res->write($some_stuff);
483         }
484
485       But it obviously blocks in the application unless you run your
486       application in multithread (or Coro) environments.
487       Catalyst::Engine::PSGI also supports setting an IO::Handle-like object
488       that supports "getline", so using IO::Handle::Util
489
490         my $io = io_from_getline sub {
491              return $data; # or undef when done()
492         };
493         $c->res->body($io);
494
495       And that works fine to do streaming, but it's blocking (pull) rather
496       than server push, so you should be careful not to run this application
497       on non-blocking (and non-multiprocess) server environments.
498
499       We expect that more web frameworks will appear that is focused on, or
500       existent frameworks will add support for, asynchronous and non-blocking
501       streaming interface.
502
503       Why CGI-style environment variables instead of HTTP headers as a hash?
504
505       Most existing web application frameworks already have code or a handler
506       to run under the CGI environment. Using CGI-style hash keys instead of
507       HTTP headers makes it trivial for the framework developers to implement
508       an adapter to support PSGI. For instance, Catalyst::Engine::PSGI is
509       only a few dozens lines different from Catalyst::Engine::CGI and was
510       written in less than an hour.
511
512       Why is PATH_INFO URI decoded?
513
514       To be compatible with CGI spec (RFC 3875) and most web servers'
515       implementations (like Apache and lighttpd).
516
517       I understand it could be inconvenient that you can't distinguish
518       "foo%2fbar" from "foo/bar" in the trailing path, but the CGI spec
519       clearly says "PATH_INFO" should be decoded by servers, and that web
520       servers can deny such requests containing %2f (since such requests
521       would lose information in PATH_INFO). Leaving those reserved characters
522       undecoded (partial decoding) would make things worse, since then you
523       can't tell "foo%2fbar" from "foo%252fbar" and could be a security hole
524       with double encoding or decoding.
525
526       For web application frameworks that need more control over the actual
527       raw URI (such as Catalyst), we made the "REQUEST_URI" environment hash
528       key REQUIRED. The servers should set the undecoded (unparsed) original
529       URI (containing the query string) to this key. Note that "REQUEST_URI"
530       is completely raw even if the encoded entities are URI-safe.
531
532       For comparison, WSGI (PEP-333) defines both "SCRIPT_NAME" and
533       "PATH_INFO" be decoded and Rack leaves it implementation dependent,
534       while fixing most of PATH_INFO left encoded in Ruby web server
535       implementations.
536
537       http://www.python.org/dev/peps/pep-0333/#url-reconstruction
538       <http://www.python.org/dev/peps/pep-0333/#url-reconstruction>
539       http://groups.google.com/group/rack-devel/browse_thread/thread/ddf4622e69bea53f
540       <http://groups.google.com/group/rack-
541       devel/browse_thread/thread/ddf4622e69bea53f>
542

SEE ALSO

544       WSGI's FAQ clearly answers lots of questions about how some API design
545       decisions were made, some of which can directly apply to PSGI.
546
547       http://www.python.org/dev/peps/pep-0333/#questions-and-answers
548       <http://www.python.org/dev/peps/pep-0333/#questions-and-answers>
549

MORE QUESTIONS?

551       If you have a question that is not answered here, or things you totally
552       disagree with, come join the IRC channel #plack on irc.perl.org or
553       mailing list http://groups.google.com/group/psgi-plack
554       <http://groups.google.com/group/psgi-plack>. Be sure you clarify which
555       hat you're wearing: application developers, server implementors or
556       middleware developers. And don't criticize the spec just to criticize
557       it: show your exact code that doesn't work or get too messy because of
558       spec restrictions etc. We'll ignore all nitpicks and bikeshed
559       discussion.
560

AUTHOR

562       Tatsuhiko Miyagawa <miyagawa@bulknews.net>
563
565perl v5.12.0                      2009-10-22                      PSGI::FAQ(3)
Impressum