[8] [DFN[PSGI]] は、 [[Perl]] における [[HTTPサーバー]]と [[Webアプリケーション]]との[[インターフェイス][API]]の[[仕様]]です。
[TIME[2009年][year:2009]]に [[Tatsuhiko Miyagawa]] らにより制定、実装されました。

[9] [[WSGI]] に強い影響を受けており、これを [[Perl]] に移植したものとなっています。

[10] 現在では多くの [[Perl]] の [[HTTPサーバー]]や [[Webアプリケーション]]が対応しています。

* 仕様書

[REFS[
- [23] [CITE@en[psgi-specs/PSGI.pod at master · plack/psgi-specs]] ([TIME[2017-06-07 13:46:32 +09:00]]) <https://github.com/plack/psgi-specs/blob/master/PSGI.pod>
- [26] [CITE@en[psgi-specs/Extensions.pod at master · plack/psgi-specs]] ([TIME[2017-06-07 14:16:46 +09:00]]) <https://github.com/plack/psgi-specs/blob/master/PSGI/Extensions.pod>
- [25] [CITE@en[PSGI file evaluation convention · plack/psgi-specs Wiki]] ([TIME[2017-06-07 14:10:19 +09:00]]) <https://github.com/plack/psgi-specs/wiki/PSGI-file-evaluation-convention>
]REFS]

* プロトコル

[16] 
[FIG(short list)[
- [[PSGIアプリケーション]]
- [[メタ変数]]
- [CODE[psgix]]
- [CITE[manakai PSGI extensions]]
- [[ミドルウェア]]
]FIG]

[11] [RUBYB[[[環境]]]@en[environment]]は、
[[CGI]] の[[メタ変数]]の流れを汲む[[ハッシュ参照]]で、
[[HTTPサーバー]]から [[Webアプリケーション]]への伝達に使われます。

** 限界

[12] [[サーバー]]と[[アプリケーション]]の責務が明確に定められていません。例えば、
[[ヘッダー値]]に不適切な[[改行]]が含まれると [[HTTPメッセージ]]として正しく解釈できなくなり、
ときに[[セキュリティー]]の問題を引き起こすことがありますが、
これをどちらが保証するべきなのか、[[サーバー]]だとしたらどのように処理するべきなのか
(黙って訂正するべきなのか、何らかの方法でエラーとするべきなのか)
がはっきりしていません。

[13] [[HTTP]] の機能のうち、 [[理由句]]には対応していません。
[[CGI]] その他の既存の手法に対する明白な欠点です。

[14] [[WebSocket]] を扱うことができません。いくつかの実装は [[ad hoc]] 
な対応をしていますが、[[標準化]]されていない (可搬性がない) だけでなく、
技術的に美しくない強引な方法を採っています。

[18] [CODE[CONNECT]] を扱うことができません。

[15] [[server push]] を扱うことができません。

[17] [[要求]]の受信中に[[クライアント]]との[[接続][HTTP接続]]が切断された場合や、
長い処理の途中で[[サーバー]]が[[再起動]]されようとしている時など、
中断した方が良いかもしれない場合にその旨を[[サーバー]]から[[アプリケーション]]に伝達する手段がありません。

[REFS[
- [6] [CITE@en[debug-ito/Plack-App-WebSocket]]
([TIME[2015-04-17 15:12:33 +09:00]] 版)
<https://github.com/debug-ito/Plack-App-WebSocket>
- [7] [CITE[PSGIアプリでWebSocketを使う場合、responderはどうすべきか? - DebugIto’s diary]]
([TIME[2015-04-17 15:14:38 +09:00]] 版)
<http://d.hatena.ne.jp/debug-ito/20131110/1384067449>
- [21] [CITE@en[motemen/Plack-Middleware-WebSocket: WebSocket handshake helper middleware]] ([TIME[2017-02-18 14:12:52 +09:00]]) <https://github.com/motemen/Plack-Middleware-WebSocket>
]REFS]

* [CODE[.psgi]] ファイル

[19] [[PSGIアプリケーション]]を返す [[Perlスクリプト]]を[[拡張子]]が [CODE[.psgi]] 
の[[ファイル]] [SRC[>>25]] とすることがよくあるようです。[[PSGI]] を実装した[[サーバー]]は、
指定された[[ファイル]]を [CODE[do][do (Perl)]] などによって読み込み、
得られた[[コード参照]]を[[アプリケーション][PSGIアプリケーション]]として実行することが期待されています。

[20] [[CGIスクリプト]]を[[拡張子]] [CODE[.cgi]] の[[ファイル]]とする[[慣習]]に倣ったもののようです。

* 実装

[28] 
[[PSGI]] の開発者らによる [[Plack]] が[[日本]]では広く用いられています。
[[Starlet]] や [[Twiggy]] のような主要な [[PSGI]] 対応[[Webサーバー]]や、
各種 [[WAF]] が [[Plack]] を利用しており、一般の開発者が [[PSGI]] と [[Plack]]
を混同する元凶となっています。

[30] 実際には [[Plack]] を使わない [[PSGI]] もいくつか存在し、使われています。

[31] ただし[[ミドルウェア]]は、それ自体は [[PSGI]] で規定された概念ですが、実装上は
[[Plack]] を使い [CODE[Plack::Middleware]] という名前を翳したものが多いです。
それらが [[Plack]] 以外の [[PSGI]] の実装と現実的に共存できるのかは不明瞭です。

* 関連

[29] [[Perl5]] とは似て非なる[[言語][プログラミング言語]] [[Perl6]] 向けには、
[[P6W]] という似て非なる [[API]] があります。当初は [[P6SGI]]
と呼ばれ、 [[PSGI]] の影響を強く受けていました。現在も PSGI Protocol 
という動作モードが [[API]] の一部を構成していますが、類似性は薄まっています。
[[PSGI]] が扱えない [[WebSocket]] への対応や、 [[HTTP/2]] の扱いの規定もあります。
[[仕様書]]としては [[PSGI]] よりも厳密に記述されています。

* 歴史

[1] [CITE[PSGI 計画についてのおしらせ。for Japanese Perl Mongers - TokuLog 改めB日記]]
([TIME[2009-09-08 09:30:30 +09:00]] 版)
<http://d.hatena.ne.jp/tokuhirom/20090904/1252091316>

[2] [CITE[PSGI updates: Specs and more reference implementations - bulknews.typepad.com]]
([TIME[2009-09-08 09:40:48 +09:00]] 版)
<http://bulknews.typepad.com/blog/2009/09/psgi-updates-specs-and-more-reference-implementations.html>

[3] [CITE[PSGI - Perl WSGI - bulknews.typepad.com]]
([TIME[2009-09-08 09:44:48 +09:00]] 版)
<http://bulknews.typepad.com/blog/2009/09/psgi-perl-wsgi.html>

[5] [CITE[Feersum - search.cpan.org]]
( ([TIME[2014-10-21 03:49:05 +09:00]] 版))
<http://search.cpan.org/dist/Feersum/lib/Feersum.pm#PSGI_extensions>

- [4] [CITE[PSGI - search.cpan.org]]
([TIME[2012-02-16 22:39:56 +09:00]] 版)
<http://search.cpan.org/dist/PSGI/PSGI.pod>

[22] [CITE@en[plack/psgi-specs: PSGI (Perl WSGI) specifications]]
([TIME[2017-06-07 13:46:04 +09:00]])
<https://github.com/plack/psgi-specs>

[24] [CITE@en[Plack/Lint.pm at master · plack/Plack]]
([TIME[2017-06-07 14:04:52 +09:00]])
<https://github.com/plack/Plack/blob/master/lib/Plack/Middleware/Lint.pm>

[27] [CITE@en[psgi-specs/FAQ.pod at master · plack/psgi-specs]]
([TIME[2017-06-07 14:19:33 +09:00]])
<https://github.com/plack/psgi-specs/blob/master/PSGI/FAQ.pod>