CGI-Emulate-PSGI-Streaming

 view release on metacpan or  search on metacpan

META.json  view on Meta::CPAN

{
   "abstract" : "streaming PSGI adapter for CGI",
   "author" : [
      "Gianni Ceccarelli <gianni.ceccarelli@broadbean.com>"
   ],
   "dynamic_config" : 0,
   "generated_by" : "Dist::Zilla version 6.015, CPAN::Meta::Converter version 2.150010",
   "license" : [
      "perl_5"
   ],
   "meta-spec" : {
      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",

META.json  view on Meta::CPAN

            "Plack::Util" : "0",
            "Test::Deep" : "0",
            "Test::More" : "0"
         }
      }
   },
   "release_status" : "stable",
   "resources" : {
      "repository" : {
         "type" : "git",
         "url" : "ssh://git@bitbucket.org/broadbean/p5-cgi-emulate-psgi-streaming.git"
      }
   },
   "version" : "1.0.1",
   "x_generated_by_perl" : "v5.26.1",
   "x_serialization_backend" : "Cpanel::JSON::XS version 4.08",
   "x_spdx_expression" : "Artistic-1.0-Perl OR GPL-1.0-or-later"
}

META.yml  view on Meta::CPAN

---
abstract: 'streaming PSGI adapter for CGI'
author:
  - 'Gianni Ceccarelli <gianni.ceccarelli@broadbean.com>'
build_requires:
  CGI: '0'
  Data::Dump: '0'
  Encode: '0'
  Plack::Util: '0'
  Test::Deep: '0'
  Test::More: '0'
configure_requires:

META.yml  view on Meta::CPAN

  Carp: '0'
  HTTP::Response: '0'
  POSIX: '0'
  SelectSaver: '0'
  Tie::Handle: '0'
  parent: '0'
  perl: '5.008001'
  strict: '0'
  warnings: '0'
resources:
  repository: ssh://git@bitbucket.org/broadbean/p5-cgi-emulate-psgi-streaming.git
version: 1.0.1
x_generated_by_perl: v5.26.1
x_serialization_backend: 'YAML::Tiny version 1.73'
x_spdx_expression: 'Artistic-1.0-Perl OR GPL-1.0-or-later'

Makefile.PL  view on Meta::CPAN

# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.015.
use strict;
use warnings;

use 5.008001;

use ExtUtils::MakeMaker;

my %WriteMakefileArgs = (
  "ABSTRACT" => "streaming PSGI adapter for CGI",
  "AUTHOR" => "Gianni Ceccarelli <gianni.ceccarelli\@broadbean.com>",
  "CONFIGURE_REQUIRES" => {
    "ExtUtils::MakeMaker" => 0
  },
  "DISTNAME" => "CGI-Emulate-PSGI-Streaming",
  "LICENSE" => "perl",
  "MIN_PERL_VERSION" => "5.008001",
  "NAME" => "CGI::Emulate::PSGI::Streaming",
  "PREREQ_PM" => {
    "CGI::Emulate::PSGI" => 0,

README.md  view on Meta::CPAN

# `CGI::Emulate::PSGI::Streaming`

This is a subclass of
[`CGI::Emulate::PSGI`](https://metacpan.org/release/CGI-Emulate-PSGI)
that produces streaming PSGI responses, instead of buffering the
script's output.

lib/CGI/Emulate/PSGI/Streaming.pm  view on Meta::CPAN

package CGI::Emulate::PSGI::Streaming;
use strict;
use warnings;
our $VERSION = '1.0.1'; # VERSION
use parent 'CGI::Emulate::PSGI';
use CGI::Parse::PSGI::Streaming;
use SelectSaver;
use Carp qw(croak);
use 5.008001;

# ABSTRACT: streaming PSGI adapter for CGI


sub handler {
    my ($class, $code) = @_;

    # this closure is the PSGI application
    return sub {
        my $env = shift;

        # this is the PSGI response, as a coderef because we want to
        # have it streaming; as the PSGI spec says, it will be invoked
        # by the backend, once per request, with a responder callback
        return sub {
            my ($responder) = @_;

            # we have the responder (i.e. the thing we will send the
            # response to), so we can now build the output filehandle
            my $stdout = CGI::Parse::PSGI::Streaming::parse_cgi_output_streaming_fh($responder);

            my $saver = SelectSaver->new("::STDOUT");
            # emulate_environment comes from CGI::Emulate::PSGI
            local %ENV = (%ENV, $class->emulate_environment($env));

            local *STDIN  = $env->{'psgi.input'};
            local *STDOUT = $stdout;
            local *STDERR = $env->{'psgi.errors'};

            # call the CGI code, and let it print to its heart's content

lib/CGI/Emulate/PSGI/Streaming.pm  view on Meta::CPAN

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

CGI::Emulate::PSGI::Streaming - streaming PSGI adapter for CGI

=head1 VERSION

version 1.0.1

=head1 SYNOPSIS

  my $app = CGI::Emulate::PSGI::Streaming->handler(sub {
    # Existing CGI code
  });

lib/CGI/Emulate/PSGI/Streaming.pm  view on Meta::CPAN


This module allows an application designed for the CGI environment to
run in a PSGI environment, and thus on any of the backends that PSGI
supports.

It is a subclass of L<< C<CGI::Emulate::PSGI> >>. The parsing logic is
implemented in L<< C<CGI::Parse::PSGI::Streaming> >>, which is heavily
based on L<< C<CGI::Parse::PSGI> >>.

Please note that using the PSGI application produced by this module
under a non-streaming backend will probably not work.

=head1 METHODS

=head2 C<handler>

  my $app = CGI::Emulate::PSGI::Streaming->handler($code);

Creates a streaming PSGI application code reference out of CGI code
reference.

=head1 CGI.pm

(This section is copied from L<<
C<CGI::Emulate::PSGI>|CGI::Emulate::PSGI/CGI.pm >>)

If your application uses L<CGI>, be sure to cleanup the global
variables in the handler loop yourself, so:

lib/CGI/Parse/PSGI/Streaming.pm  view on Meta::CPAN

use strict;
use warnings;
our $VERSION = '1.0.1'; # VERSION
use HTTP::Response;
use CGI::Parse::PSGI::Streaming::Handle;
use SelectSaver;

# ABSTRACT: creates a filehandle that parses CGI output and writes to a PSGI responder


sub parse_cgi_output_streaming_fh {
    my ($responder) = @_;

    # ugly-ish way to get a ref to a new filehandle
    my $output = \do {local *HANDLE};

    # state for the callback closure
    my $headers; # string, accumulated headers
    my $response; # HTTP::Response object with parsed headers
    my $writer; # the writer object returned by the responder

lib/CGI/Parse/PSGI/Streaming.pm  view on Meta::CPAN


  sub {
    my ($env) = @_;

    my $q = CGI::PSGI->new($env);

    return sub {
      my ($psgi_responder) = @_;

      my $tied_stdout =
        CGI::Parse::PSGI::Streaming::parse_cgi_output_streaming_fh(
          $psgi_responder,
        );

      select $tied_stdout;
      old_sub_that_expects_a_cgi_object_and_prints($q);
      close $tied_stdout;
    };
   };

=head1 DESCRIPTION

You should probably not do what the L</synopsis> says, and just use
L<< C<CGI::Emulate::PSGI::Streaming> >> directly.

=head1 FUNCTIONS

=head2 C<parse_cgi_output_streaming_fh>

  my $tied_stdout =
    CGI::Parse::PSGI::Streaming::parse_cgi_output_streaming_fh(
      $psgi_responder,
    );

This function, given a PSGI responder object, builds a L<tied
filehandle|perltie/Tying FileHandles> that your old CGI code can print
to.

The tied handle will parse CGI headers, and pass them on to the
responder in the format that it expects them. The handle will then
feed whatever is printed to it, on to the writer object that the

t/parse.t  view on Meta::CPAN

    my $output = shift;
    my $r;
    my $responder = sub {
        my ($response) = @_;
        $r = $response;
        return Plack::Util::inline_object(
            write => sub { push @{$r->[2]}, shift },
            close => sub {},
        );
    };
    my $stdout = CGI::Parse::PSGI::Streaming::parse_cgi_output_streaming_fh(
        $responder,
    );
    print {$stdout} $output;

    my $h = HTTP::Headers->new;
    while (my($k, $v) = splice @{$r->[1]}, 0, 2) {
        $h->header($k, $v);
    }
    return $r, $h;
}

t/rt133593.t  view on Meta::CPAN

    my $output = shift;
    my $r;
    my $responder = sub {
        my ($response) = @_;
        $r = $response;
        return Plack::Util::inline_object(
            write => sub { push @{$r->[2]}, shift },
            close => sub {},
        );
    };
    my $stdout = CGI::Parse::PSGI::Streaming::parse_cgi_output_streaming_fh(
        $responder,
    );
    binmode $stdout, ':encoding(UTF-8)';
    print {$stdout} $output;

    my $h = HTTP::Headers->new;
    while (my($k, $v) = splice @{$r->[1]}, 0, 2) {
        $h->header($k, $v);
    }
    return $r, $h;



( run in 0.269 second using v1.01-cache-2.11-cpan-a5abf4f5562 )