POD2-RU-PSGI

 view release on metacpan or  search on metacpan

lib/POD2/RU/PSGI.pod  view on Meta::CPAN

Переменная окружения получается путём конвертации имени поля заголовка HTTP в
верхний регистр, замещения всех дефисов C<-> на подчёркивания C<_> и
подстановки приставки C<HTTP>, как в L<RFC 3875|http://www.ietf.org/rfc/rfc3875>.

Если есть несколько строк заголовка, отправленных с одним ключом (именем
переменной), серверу следует рассматривать их так, как будто они были посланы в
одной строке и объединять их при помощи C<, >, как описано в
L<RFC 2616|http://www.ietf.org/rfc/rfc2616>.

=back

В добавление к ключам, описанным выше, окружение PSGI B<ДОЛЖНО> также включать
следующие специфичные для PSGI ключи:

=over 4

=item *

C<psgi.version>: Ссылка на массив [1,1], представляющий используемую версию
PSGI. Первое число - старший номер версии, второе - младший номер версии.

=item *

C<psgi.url_scheme>: Строка C<http> или C<https>, зависящая от URL запроса.

=item *

C<psgi.input>: входной поток. Подробности см. ниже.

=item *

C<psgi.errors>: поток ошибок. Подробности см. ниже.

=item *

C<psgi.multithread>: Это булево значение, которое B<ДОЛЖНО> быть true, если
приложение может быть одновременно вызвано другой нитью того же процесса,
иначе false.

=item *

C<psgi.multiprocess>: Это булево значение, которое B<ДОЛЖНО> быть true, если
эквивалентный объект приложения может быть одновременно вызван другим
процессом, иначе false.

=item *

C<psgi.run_once>: Булево значение, содержащее true, если сервер ожидает (но не
гарантирует!), что приложение будет вызвано только в этот единственный раз за
время жизни содержащего его процесса. Обычно это бывает верно только для
сервера, основанного на CGI (или на чём-то похожем).


=item *

C<psgi.nonblocking>: Булево значение, содержащее true, если сервер вызывает
приложение в неблокирующем событийном цикле.

=item *

C<psgi.streaming>: Булево значение, равное true, если сервер ожидает
отложенного ответа в стиле callback и потокового пишущего объекта.

=back

Сервер или приложение может также сохранять свои данные в переменных
окружения. Эти переменные B<ДОЛЖНЫ> содержать по меньшей мере одну точку, и их
B<СЛЕДУЕТ> называть, начиная с уникальной приставки.

Приставка C<psgi.> зарезервирована для использования с основной спецификацией
PSGI, а приставка C<psgix.> зарезервирована для официально одобренных
расширений. Эти приставки B<НЕ ДОЛЖНЫ> использоваться другими серверами или
приложением. См. список официально одобренных расширений в
L<psgi-extensions|PSGI::Extentions>.

Окружение B<НЕ ДОЛЖНО> содержать ключи с именем C<HTTP_CONTENT_TYPE> или
C<HTTP_CONTENT_LENGTH>.

Одна из переменных C<SCRIPT_NAME> или C<PATH_INFO> B<ДОЛЖНА> быть установлена.
Когда C<REQUEST_URI> - это C</>, переменной C<PATH_INFO> следует быть равной
C</>, а переменной C<SCRIPT_NAME> следует быть пустой. Переменная
C<SCRIPT_NAME> B<НЕ ДОЛЖНА> быть равной C</>, но B<МОЖЕТ> быть пустой.


=head3 Входной Поток

Входной поток в C<psgi.input> - это L<IO::Handle>-подобный объект, который
отдаёт поток необработанных данных HTTP POST или PUT запросов. Если это
дескриптор файла, он B<ДОЛЖЕН> быть открыт в бинарном режиме. Входной поток
B<ДОЛЖЕН> отвечать на запрос C<read> и B<МОЖЕТ> реализовывать C<seek>.

Встроенные в Perl файловые дескрипторы или основанные на L<IO::Handle> объекты
должны работать "как есть" внутри PSGI сервера. Разработчикам приложений B<НЕ
СЛЕДУЕТ> контролировать тип или класс потока. Вместо этого им B<СЛЕДУЕТ>
просто вызывать метод C<read> объекта.

Разработчикам приложений B<НЕ СЛЕДУЕТ> использовать встроенную функцию Perl
C<read> или итератор (C<< <$fh> >>) для чтения из входного потока. Вместо
этого разработчикам приложений следует вызывать C<read> как метод
(C<< $fh->read >>) для обеспечения утиной типизации.

Разработчикам фреймворков, если они знают, что входной поток будет использован
со встроенной функцией read() в любом апстрим-коде, который они не смогут
трогать, B<СЛЕДУЕТ> использовать PerlIO или tied handle для обработки этой
проблемы.

Ожидается, что объект входного потока обеспечивает метод C<read>:

=over 4

=item read

  $input->read($buf, $len [, $offset ]);

Возвращает число действительно прочитанных символов, 0 в конце файла, или
undef при ошибке.

=back

Он может также реализовывать опциональный метод C<seek>. Если
переменная окружения C<psgix.input.buffered> равна true, он B<ДОЛЖЕН>

lib/POD2/RU/PSGI.pod  view on Meta::CPAN

содержать "широких" символов (> 255).

=over 4

=item *

Если тело ответа - ссылка на массив, ожидается, что оно содержит массив строк,
из которых состоит само тело.

  my $body = [ "Hello\n", "World\n" ];

Обратите внимание, что элементы в массиве B<НЕОБЯЗАТЕЛЬНО> должны оканчиваться
переводом строки. Серверу B<СЛЕДУЕТ> отправлять каждый элемент "как есть"
клиенту, и B<НЕ СЛЕДУЕТ> заботиться о том, оканчиваются ли строки переводом
строки, или нет.

Ссылка на массив с единственным значением валидна. Так, C<[ $html ]> -
валидное тело ответа.

=item *

Тело ответа может вместо этого быть дескриптором - или встроенным файловым
дескриптором Perl, или L<IO::Handle>-подобным объектом.

  open my $body, "</path/to/file";
  open my $body, "<:via(SomePerlIO)", ...;
  my $body = IO::File->new("/path/to/file");

  # mock class that implements getline() and close()
  my $body = SomeClass->new();

Серверам B<НЕ СЛЕДУЕТ> проверять тип или класс тела ответа. Вместо этого им
следует просто вызывать C<getline> для перебора строк тела, и вызвать C<close>
по завершению.

Серверы B<МОГУТ> проверять, является ли тело реальным файловым дескриптором,
используя C<fileno> и C<Scalar::Util::reftype>. Если тело - реальный
дескриптор файла, сервер B<МОЖЕТ> оптимизировать выполнение, используя методы
вроде I<sendfile(2)>.

Объект тела также B<МОЖЕТ> иметь метод C<path>. Ожидается, что этот метод
возвратит путь к файлу, доступному серверу. Это позволяет серверу использовать
данную информацию вместо номера файлового дескриптора для отдачи файла.

Серверам B<СЛЕДУЕТ> устанавливать специальную переменную C<$/> для получения
размера буфера при чтении содержимого из C<$body> при помощи метода
C<getline>. Это делается путём присваивания C<$/> ссылки на целое число (C<$/
= \8192>).

Если файловый дескриптор тела ответа - встроенный файловый дескриптор Perl или
объект L<IO::Handle>, они обратят внимание на значение. Похожим образом
объект, предоставляющий аналогичный API, B<МОЖЕТ> также обратить внимание на
эту специальную переменную, но от него не требуется делать это.

=back

=head2 Отложенный Ответ и Потоковое Тело ответа

The PSGI interface allows applications and servers to provide a
callback-style response instead of the three-element array
reference. This allows for a delayed response and a streaming body
(server push).

Интерфейс PSGI позволяет приложениям и серверам предоставлять ответ в виде
вызываемой функции вместо ссылки на трёхэлементный массив. Это позволяет
возвращать отложенные ответы и потоковое тело ответа (server push).

PSGI серверам B<СЛЕДУЕТ> реализовывать этот интерфейс, и переменная
C<psgi.streaming> должна быть равна true в таких серверах.

Чтобы разрешить отложенный ответ, приложению B<СЛЕДУЕТ> возвращать вызываемую
функцию в качестве ответа. Приложение B<МОЖЕТ> проверять, что переменная
C<psgi.streaming> равна true, и возвращаться к непосредственному ответу, если
это не так.

This callback will be called with I<another> subroutine reference (referred to
as the I<responder> from now on) as its only argument. The I<responder>
should in turn be called with the standard three element array reference
response. This is best illustrated with an example:

Эта вызываемая функция будет вызвана со ссылкой наI<другую> функцию (далее
называемую I<ответчик>) в качестве единственного аргумента. I<Ответчик> должен
в свою очередь быть вызван со стандартным ответом в виде ссылки на
трёхэлементный массив. Наилучшим образом это иллюстрируется следующим
примером:

  my $app = sub {
      my $env = shift;

      # Откладывает ответ до тех пор, пока он не получит ответ от сети
      return sub {
          my $responder = shift;

          fetch_content_from_server(sub {
              my $content = shift;
              $responder->([ 200, $headers, [ $content ] ]);
          });
      };
  };

Приложение B<МОЖЕТ> опустить третий элемент (тело) при вызове I<ответчика>.
Если тело пропущено, I<ответчик> B<ДОЛЖЕН> возвратить I<ещё один> объект,
в котором реализованы методы C<write> и C<close>. Снова проиллюстрируем это
примером.

  my $app = sub {
      my $env = shift;

      # immediately starts the response and stream the content
      return sub {
          my $responder = shift;
          my $writer = $responder->(
              [ 200, [ 'Content-Type', 'application/json' ]]);

          wait_for_events(sub {
              my $new_event = shift;
              if ($new_event) {
                  $writer->write($new_event->as_json . "\n");
              } else {
                  $writer->close;
              }
          });
      };
  };

Этот отложенный ответ и потоковый API полезны, если вы хотите реализовать
основанную на неблокирующем вводе/выводе отдачу потока сервером или технологию
long-poll Comet push, но могут также быть использованы для реализации
небуферизованной записи в блокирующем сервере.

=head2 Middleware

Компонент I<middleware> берёт другое PSGI приложение и запускает его. С точки
зрения сервера компонент middleware - PSGI приложение. С точки зрения
приложения, запускаемого компонентом middleware, middleware - это сервер. Как
правило это делается для реализации некоего способа предварительной обработки
хеша PSGI окружения или пост-обработки запроса.

Вот простой пример, который добавляет специальный HTTP заголовок
I<X-PSGI-Used> к любому приложению PSGI.

  # $app - простое приложение PSGI
  my $app = sub {
      my $env = shift;
      return [ '200',
               [ 'Content-Type' => 'text/plain' ],
               [ "Hello World" ] ];
  };

  # $xheader - часть middleware, которая обёрнута вокруг $app
  my $xheader = sub {
      my $env = shift;
      my $res = $app->($env);
      push @{$res->[1]}, 'X-PSGI-Used' => 1;
      return $res;
  };

Middleware B<ДОЛЖНО> вести себя в точности так же, как приложение PSGI с точки
зрения сервера. Middleware B<МОЖЕТ> решить не поддерживать потоковый
интерфейс, обсуждавшийся ранее, но ему B<СЛЕДУЕТ> пропускать беспрепятственно
те типы ответов, которые оно не понимает.

=head1 CHANGELOGS

1.1: 2010.02.xx

=over 4

=item *

Added optional PSGI keys as extensions: C<psgix.logger> and C<psgix.session>.

=item *

C<psgi.streaming> B<SHOULD> be implemented by PSGI servers, rather than B<MAY>.

=item *

PSGI keys C<psgi.run_once>, C<psgi.nonblocking> and C<psgi.streaming>
B<MUST> be set by PSGI servers.

=item *

Removed C<poll_cb> from writer methods.

=back

=head1 ACKNOWLEDGEMENTS

Some parts of this specification are adopted from the following specifications.

=over 4

=item *

PEP333 Python Web Server Gateway Interface L<http://www.python.org/dev/peps/pep-0333>

=item *

Rack L<http://rack.rubyforge.org/doc/SPEC.html>

=item *

JSGI Specification L<http://jackjs.org/jsgi-spec.html>

=back

I'd like to thank authors of these great documents.

=head1 AUTHOR

Tatsuhiko Miyagawa E<lt>miyagawa@bulknews.netE<gt>

=head1 CONTRIBUTORS

The following people have contributed to the PSGI specification and
Plack implementation by commiting their code, sending patches,
reporting bugs, asking questions, suggesting useful advices,
nitpicking, chatting on IRC or commenting on my blog (in no particular
order):

  Tokuhiro Matsuno
  Kazuhiro Osawa
  Yuval Kogman
  Kazuho Oku
  Alexis Sukrieh
  Takatoshi Kitano
  Stevan Little
  Daisuke Murase
  mala
  Pedro Melo
  Jesse Luehrs
  John Beppu
  Shawn M Moore
  Mark Stosberg
  Matt S Trout
  Jesse Vincent
  Chia-liang Kao
  Dave Rolsky



( run in 1.233 second using v1.01-cache-2.11-cpan-39bf76dae61 )