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

SEE ALSO

580       WSGI's FAQ clearly answers lots of questions about how some API design
581       decisions were made, some of which can directly apply to PSGI.
582
583       <http://www.python.org/dev/peps/pep-0333/#questions-and-answers>
584

MORE QUESTIONS?

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

AUTHOR

596       Tatsuhiko Miyagawa <miyagawa@bulknews.net>
597
599       Copyright Tatsuhiko Miyagawa, 2009-2010.
600
601       This document is licensed under the Creative Commons license by-sa.
602
603
604
605perl v5.32.0                      2020-07-28                      PSGI::FAQ(3)
Impressum