]> Sergey Matveev's repositories - public-inbox.git/blob - public-inbox-cgi
get a basic CGI feed sender running
[public-inbox.git] / public-inbox-cgi
1 #!/usr/bin/perl -w
2 # Copyright (C) 2014, Eric Wong <normalperson@yhbt.net> and all contributors
3 # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
4 #
5 # We focus on the lowest common denominators here:
6 # - targeted at text-only console browsers (lynx, w3m, etc..)
7 # - Only basic HTML, CSS only for line-wrapping <pre> text content for GUIs
8 # - No JavaScript, graphics or icons allowed.
9 # - Must not rely on static content
10 # - UTF-8 is only for user-content, 7-bit US-ASCII for us
11
12 use 5.008;
13 use strict;
14 use warnings;
15 use CGI qw(:cgi :escapeHTML -nosticky); # PSGI/FastCGI/mod_perl compat
16 use CGI::Util qw(unescape);
17 use Encode;
18 use PublicInbox::Config;
19 our $LISTNAME_RE = qr!\A/([\w\.\-]+)!;
20 our $pi_config;
21 BEGIN {
22         $pi_config = PublicInbox::Config->new;
23         # TODO: detect and reload config as needed
24         if ($ENV{MOD_PERL}) {
25                 CGI->compile;
26         }
27 }
28
29 sub main {
30         my $cgi = CGI->new;
31         if ($cgi->request_method !~ /\AGET|HEAD\z/) {
32                 return r($cgi, "405 Method Not Allowed");
33         }
34         my $path_info = decode_utf8($ENV{PATH_INFO});
35         if ($path_info eq "/") {
36                 r($cgi, "404 Not Found");
37         } elsif ($path_info =~ m!$LISTNAME_RE/?\z!o) {
38                 get_list_log($cgi, $1);
39         } elsif ($path_info =~ m!$LISTNAME_RE/all\z!o) {
40                 get_list_all($cgi, $1);
41         } elsif ($path_info =~ m!$LISTNAME_RE/index\.atom\.xml\z!o) {
42                 get_atom_index($cgi, $1);
43         } elsif ($path_info =~ m!$LISTNAME_RE/all\.atom\.xml\z!o) {
44                 get_atom_all($cgi, $1);
45         } elsif ($path_info =~ m!$LISTNAME_RE/mid/(\S+)\.txt\z!o) {
46                 get_mid_txt($cgi, $1, $2);
47         } elsif ($path_info =~ m!$LISTNAME_RE/mid/(\S+)\.html\z!o) {
48                 get_mid_html($cgi, $1, $2);
49         } elsif ($path_info =~ m!$LISTNAME_RE/mid/(\S+)\z!o) {
50                 redirect_mid_html($cgi, $1, $2);
51         } else {
52                 r($cgi, "404 Not Found");
53         }
54 }
55
56 binmode STDOUT, ':utf8';
57 main();
58
59 # simple response for errors
60 sub r {
61         print $_[0]->header(-type => "text/plain",
62                                 -status => $_[1],
63                                 -charset => 'utf-8');
64 }
65
66 # /$LISTNAME/all.atom.xml       -> Atom feed, includes replies
67 sub get_atom_all {
68         my ($cgi, $listname) = @_;
69         my $git_dir = $pi_config->get($listname, "mainrepo");
70         defined $git_dir or return r($cgi, "404 Not Found");
71
72         require PublicInbox::Feed;
73         print $cgi->header(-type => "application/xml", -charset => 'us-ascii',
74                                 -status => '200 OK');
75
76         print PublicInbox::Feed->generate($git_dir, undef,
77                                         $pi_config, $listname, $cgi);
78 }
79
80 # /$LISTNAME/index.atom.xml     -> Atom feed
81 sub get_atom_index {
82         my ($cgi, $listname) = @_;
83         my $git_dir = $pi_config->get($listname, "mainrepo");
84         defined $git_dir or return r($cgi, "404 Not Found");
85
86         require PublicInbox::Feed;
87         print $cgi->header(-type => "application/xml", -charset => 'us-ascii',
88                                 -status => '200 OK');
89
90         print PublicInbox::Feed->generate($git_dir, undef,
91                                         $pi_config, $listname, $cgi, 1);
92 }