]> Sergey Matveev's repositories - public-inbox.git/commitdiff
remove direct CGI.pm support
authorEric Wong <e@80x24.org>
Thu, 25 Feb 2016 03:10:50 +0000 (03:10 +0000)
committerEric Wong <e@80x24.org>
Thu, 25 Feb 2016 04:03:02 +0000 (04:03 +0000)
Relying on Plack::Handler::CGI is much easier for long-term
maintenance and development.

Nowadays, we even include our own httpd implementation to
facilitate easier deployment with PSGI/Plack.

INSTALL
Makefile.PL
lib/PublicInbox/ExtMsg.pm
lib/PublicInbox/Feed.pm
lib/PublicInbox/GitHTTPBackend.pm
lib/PublicInbox/WWW.pm
public-inbox.cgi

diff --git a/INSTALL b/INSTALL
index 538a95dbb8616154cadfe4aa544db6201a8bb0ee..54c344c7af1b486ab8191a8a592b6c814ed1378f 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -39,7 +39,7 @@ Requirements (server MDA)
 
 Optional modules:
 
-  - CGI[1]                     perl-modules[2]
+  - Plack[1]                   libplack-perl
   - Mail::Thread (2.5+)[1]     libmail-thread-perl
   - URI::Escape[1]             liburi-perl
   - Search::Xapian[3]          libsearch-xapian-perl
@@ -49,9 +49,6 @@ Optional modules:
   - Danga::Socket[4]           libdanga-socket-perl
 
 [1] - Only required for serving/generating Atom and HTML pages.
-[2] - Keep in mind this will be split into a separate Debian package
-      when CGI.pm is dropped from the Perl standard library.
-      Plack/PSGI and mod_perl2 are both supported.
 [3] - Optional for HTML web interface and NNTP server
 [4] - Optional for NNTP server
 
index 5eec5ef0f7e92d294f2ec12345fde1cc8f3d1c0c..621baf60d3ace4ffb474144543ef3e567e28519a 100644 (file)
@@ -17,7 +17,6 @@ WriteMakefile(
                # note: we use ssoma(1) and spamc(1), NOT the Perl modules
                # We also depend on git through ssoma.
                # Keep this sorted and synced to the INSTALL document
-               'CGI' => 0,
                'Date::Parse' => 0,
                'Email::Address' => 0,
                'Email::Filter' => 0,
@@ -27,6 +26,7 @@ WriteMakefile(
                'File::Path::Expand' => 0,
                'IPC::Run' => 0,
                'Mail::Thread' => '2.5', # 2.5+ needed for Email::Simple compat
+               'Plack' => 0,
                'URI::Escape' => 0,
                # We have more test dependencies, but do not force
                # users to install them
index d89a7e3097b50489f0e92a5df3d8eb8e7c618f86..cf9b6d58ba8d3b9836300a28cf96cf2000c1fa8f 100644 (file)
@@ -86,15 +86,7 @@ sub ext_msg {
        eval { require PublicInbox::Msgmap };
        my $have_mm = $@ ? 0 : 1;
        my $cgi = $ctx->{cgi};
-       my $base_url;
-       my $scheme;
-       if (ref($cgi) eq 'CGI') {
-               $base_url = $cgi->url(-base) . '/';
-               $scheme = $cgi->protocol;
-       } else { # Plack::Request
-               $base_url = $cgi->base->as_string;
-               $scheme = $cgi->env->{'psgi.url_scheme'};
-       }
+       my $base_url = $cgi->base->as_string;
        if ($have_mm) {
                my $tmp_mid = $mid;
                my $url;
@@ -145,6 +137,7 @@ again:
        if (@EXT_URL && index($mid, '@') >= 0) {
                $code = 300;
                $s .= "\nPerhaps try an external site:\n\n";
+               my $scheme = $cgi->scheme;
                foreach my $u (@EXT_URL) {
                        $u = "$scheme:$u" if $u =~ m!\A//!;
                        my $r = sprintf($u, $href);
index a0aa62af4e2697eac563d0708a00407246ab4993..a5828a8e16bf9f475c1897b60f7cd4279e064c24 100644 (file)
@@ -284,14 +284,7 @@ sub get_feedopts {
 
        my $url_base;
        if ($cgi) {
-               my $base;
-               if (ref($cgi) eq 'CGI') {
-                       $base = $cgi->url(-base);
-               } else { # Plack::Request
-                       $base = $cgi->base->as_string;
-                       $base =~ s!/\z!!;
-               }
-               $url_base = "$base/$listname";
+               $url_base = $cgi->base->as_string . $listname;
                if (my $mid = $ctx->{mid}) { # per-thread feed:
                        $rv{atomurl} = "$url_base/$mid/t.atom";
                } else {
index 71b7a8f1b1c12278730dd8c8cd64cf6f3a93d415..562c290e0828bc10c58a33b34d13ee708f37310d 100644 (file)
@@ -55,7 +55,7 @@ sub serve {
        my $len = $size;
        my @h;
 
-       my $env = $cgi->{env} || \%ENV;
+       my $env = $cgi->{env};
        my $range = $env->{HTTP_RANGE};
        if (defined $range && $range =~ /\bbytes=(\d*)-(\d*)\z/) {
                ($code, $len) = prepare_range($cgi, $in, \@h, $1, $2, $size);
@@ -117,9 +117,7 @@ sub prepare_range {
                        push @$h, "bytes $beg-$end/$size";
 
                        # FIXME: Plack::Middleware::Deflater bug?
-                       if (my $env = $cgi->{env}) {
-                               $env->{'psgix.no-compress'} = 1;
-                       }
+                       $cgi->{env}->{'psgix.no-compress'} = 1;
                }
        }
        ($code, $len);
index 1f28df20fbcae79a0461a4003834a1d9671b0500..651c19e05bbacde34e0db79de2980db0f41efde4 100644 (file)
@@ -223,12 +223,6 @@ sub get_thread {
        PublicInbox::View::thread_html($ctx, $foot, $srch);
 }
 
-sub self_url {
-       my ($cgi) = @_;
-                                               # Plack::Request
-       ref($cgi) eq 'CGI' ? $cgi->self_url : $cgi->uri->as_string;
-}
-
 sub ctx_get {
        my ($ctx, $key) = @_;
        my $val = $ctx->{$key};
@@ -258,9 +252,7 @@ sub footer {
        my $urls = try_cat("$git_dir/cloneurl");
        my @urls = split(/\r?\n/, $urls || '');
        my %seen = map { $_ => 1 } @urls;
-       my $cgi = $ctx->{cgi};
-       my $http = (ref($cgi) eq 'CGI') ? $cgi->url(-base) . "/$listname" :
-                       $cgi->base->as_string . $listname;
+       my $http = $ctx->{cgi}->base->as_string . $listname;
        $seen{$http} or unshift @urls, $http;
        if (scalar(@urls) == 1) {
                $urls = "URL for <a\nhref=\"" . SSOMA_URL .
@@ -325,7 +317,7 @@ sub get_thread_mbox {
 sub get_thread_atom {
        my ($ctx) = @_;
        searcher($ctx) or return need_search($ctx);
-       $ctx->{self_url} = self_url($ctx->{cgi});
+       $ctx->{self_url} = $ctx->{cgi}->uri->as_string;
        require PublicInbox::Feed;
        PublicInbox::Feed::generate_thread_atom($ctx);
 }
@@ -390,16 +382,8 @@ sub r301 {
        my ($ctx, $listname, $mid, $suffix) = @_;
        my $cgi = $ctx->{cgi};
        my $url;
-       my $qs;
-       if (ref($cgi) eq 'CGI') {
-               $url = $cgi->url(-base) . '/';
-               $qs = $cgi->query_string;
-       } else { # Plack::Request
-               $url = $cgi->base->as_string;
-               $qs = $cgi->env->{QUERY_STRING};
-       }
-
-       $url .= $listname . '/';
+       my $qs = $cgi->env->{QUERY_STRING};
+       $url = $cgi->base->as_string . $listname . '/';
        $url .= (uri_escape_utf8($mid) . '/') if (defined $mid);
        $url .= $suffix if (defined $suffix);
        $url .= "?$qs" if $qs ne '';
index 4b74a62ae04f59710e32774e611d6e9d3b04cb71..e73e23ca7663662c907021a695a857fbdd6af4cb 100755 (executable)
@@ -1,62 +1,35 @@
 #!/usr/bin/perl -w
-# Copyright (C) 2014-2015 all contributors <meta@public-inbox.org>
-# License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
+# Copyright (C) 2014-2016 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ or later <https://www.gnu.org/licenses/agpl-3.0.txt>
 #
 # Enables using PublicInbox::WWW as a CGI script
 use strict;
 use warnings;
-use IO::Handle;
+use Plack::Loader;
+use Plack::Builder;
+use Plack::Request;
+use Plack::Handler::CGI;
 use PublicInbox::WWW;
-use CGI qw/-nosticky/;
-our $NO_SCRIPT_NAME;
-our %HTTP_CODES;
-BEGIN {
-       $NO_SCRIPT_NAME = 1 if $ENV{NO_SCRIPT_NAME};
-       if ($ENV{MOD_PERL}) {
-               CGI->compile;
-               PublicInbox::WWW->preload;
-       }
-
-       %HTTP_CODES = (
-               200 => 'OK',
-               300 => 'Multiple Choices',
-               301 => 'Moved Permanently',
-               302 => 'Found',
-               404 => 'Not Found',
-               405 => 'Method Not Allowed',
-               501 => 'Not Implemented',
-       );
-}
-
-# some servers (Ruby webrick) include scheme://host[:port] here,
-# which confuses CGI.pm when generating self_url.
-# RFC 3875 does not mention REQUEST_URI at all,
-# so nuke it since CGI.pm functions without it.
-delete $ENV{REQUEST_URI};
-$ENV{SCRIPT_NAME} = '' if $NO_SCRIPT_NAME;
-my $req = CGI->new;
-my $ret = PublicInbox::WWW::run($req, $req->request_method);
+BEGIN { PublicInbox::WWW->preload if $ENV{MOD_PERL} }
 
-my $out = select;
-$out->binmode;
-
-if (ref($ret) eq 'CODE') {
-       $ret->(*dump_header);
-} else {
-       my ($status, $headers, $body) = @$ret;
+my $have_deflater = eval { require Plack::Middleware::Deflater; 1 };
+my $app = builder {
+       if ($have_deflater) {
+               enable 'Deflater',
+                       content_type => [ 'text/html', 'text/plain',
+                                       'application/atom+xml' ];
+       }
 
-       dump_header([$status, $headers])->write($body->[0]);
-}
+       # Enable to ensure redirects and Atom feed URLs are generated
+       # properly when running behind a reverse proxy server which
+       # sets X-Forwarded-For and X-Forwarded-Proto request headers.
+       # See Plack::Middleware::ReverseProxy documentation for details
+       # enable 'ReverseProxy';
 
-sub dump_header {
-       my ($res) = @_;
-       my $fh = select;
-       my ($status, $headers) = @$res;
-       $fh->write("Status: $status $HTTP_CODES{$status}\r\n");
-       my @tmp = @$headers;
-       while (my ($k, $v) = splice(@tmp, 0, 2)) {
-               $fh->write("$k: $v\r\n");
+       enable 'Head';
+       sub {
+               my $req = Plack::Request->new(@_);
+               PublicInbox::WWW::run($req, $req->method);
        }
-       $fh->write("\r\n");
-       $fh;
-}
+};
+Plack::Handler::CGI->new->run($app);