about summary refs log tree commit homepage
path: root/script/public-inbox-httpd
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2016-02-27 21:57:57 +0000
committerEric Wong <e@80x24.org>2016-02-27 21:57:57 +0000
commit052f26f3ada1042afa5acadbecc48b487f4e2d52 (patch)
treeb6b30f94cdb20534ffc074359db30084c9858fa6 /script/public-inbox-httpd
parent617f35dacbd4e5972bf2d82411b45009bbc79a42 (diff)
downloadpublic-inbox-052f26f3ada1042afa5acadbecc48b487f4e2d52.tar.gz
This seems to match more closely with what is expected of Perl
packages based on how blib is used.  Hopefully makes the top-level
source tree less cluttered and things easier-to-find.
Diffstat (limited to 'script/public-inbox-httpd')
-rwxr-xr-xscript/public-inbox-httpd129
1 files changed, 129 insertions, 0 deletions
diff --git a/script/public-inbox-httpd b/script/public-inbox-httpd
new file mode 100755
index 00000000..6109af01
--- /dev/null
+++ b/script/public-inbox-httpd
@@ -0,0 +1,129 @@
+#!/usr/bin/perl -w
+# Copyright (C) 2016 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+#
+# Standalone HTTP server for public-inbox.
+use strict;
+use warnings;
+use Plack::Util;
+use PublicInbox::Daemon;
+use PublicInbox::HTTP;
+use Plack::Request;
+use Plack::Builder;
+my %httpds;
+my $app;
+my $refresh = sub {
+        if (@ARGV) {
+                eval { $app = Plack::Util::load_psgi(@ARGV) };
+                if ($@) {
+                        die $@,
+"$0 runs in /, command-line paths must be absolute\n";
+                }
+        } else {
+                require PublicInbox::WWW;
+                PublicInbox::WWW->preload;
+                my $www = PublicInbox::WWW->new;
+                $app = eval {
+                        my $deflate_types = eval {
+                                require Plack::Middleware::Deflater;
+                                [ 'text/html', 'text/plain',
+                                        'application/atom+xml' ]
+                        };
+                        builder {
+                                enable 'Chunked';
+                                if ($deflate_types) {
+                                        enable 'Deflater',
+                                                content_type => $deflate_types
+                                }
+                                enable 'ReverseProxy';
+                                enable 'Head';
+                                sub { $www->call(@_) };
+                        };
+                };
+        }
+};
+
+daemon_run('0.0.0.0:8080', $refresh,
+        sub ($$$) { # post_accept
+                my ($client, $addr, $srv) = @_;
+                my $fd = fileno($srv);
+                my $h = $httpds{$fd} ||= PublicInbox::HTTPD->new($srv, $app);
+                PublicInbox::HTTP->new($client, $addr, $h),
+        });
+
+1;
+
+package PublicInbox::HTTPD::Async;
+use strict;
+use warnings;
+use base qw(Danga::Socket);
+use fields qw(cb);
+
+sub new {
+        my ($class, $io, $cb) = @_;
+        my $self = fields::new($class);
+        $io->blocking(0);
+        $self->SUPER::new($io);
+        $self->{cb} = $cb;
+        $self->watch_read(1);
+        $self;
+}
+
+sub event_read { $_[0]->{cb}->() }
+sub event_hup { $_[0]->{cb}->() }
+sub event_err { $_[0]->{cb}->() }
+sub sysread { shift->{sock}->sysread(@_) }
+
+1;
+
+package PublicInbox::HTTPD;
+use strict;
+use warnings;
+use Plack::Util;
+
+sub pi_httpd_async {
+        my ($io, $cb) = @_;
+        PublicInbox::HTTPD::Async->new($io, $cb);
+}
+
+sub new {
+        my ($class, $sock, $app) = @_;
+        my $n = getsockname($sock) or die "not a socket: $sock $!\n";
+        my ($port, $addr);
+        if (length($n) >= 28) {
+                require Socket6;
+                ($port, $addr) = Socket6::unpack_sockaddr_in6($n);
+        } else {
+                ($port, $addr) = Socket::unpack_sockaddr_in($n);
+        }
+
+        my %env = (
+                REMOTE_HOST => '',
+                REMOTE_PORT => 0,
+                SERVER_NAME => $addr,
+                SERVER_PORT => $port,
+                SCRIPT_NAME => '',
+                'psgi.version' => [ 1, 1 ],
+                'psgi.errors' => \*STDERR,
+                'psgi.url_scheme' => 'http',
+                'psgi.nonblocking' => Plack::Util::TRUE,
+                'psgi.streaming' => Plack::Util::TRUE,
+                'psgi.run_once'         => Plack::Util::FALSE,
+                'psgi.multithread' => Plack::Util::FALSE,
+                'psgi.multiprocess' => Plack::Util::TRUE,
+                'psgix.harakiri'=> Plack::Util::FALSE,
+                'psgix.input.buffered' => Plack::Util::TRUE,
+                'pi-httpd.async' => do {
+                        no warnings 'once';
+                        *pi_httpd_async
+                },
+        );
+        bless {
+                err => \*STDERR,
+                out => \*STDOUT,
+                app => $app,
+                env => \%env,
+        }, $class;
+}
+
+1;