root/lang/perl/Mozilla-Screenshot/trunk/examples/screenshot-httpd-poe.pl @ 114

Revision 114, 3.1 kB (checked in by masaki, 6 years ago)

lang/perl/Mozilla-Screenshot: imported

Line 
1#!/usr/bin/perl
2
3BEGIN {
4    unless ($ENV{DISPLAY}) {
5        die q"can't find DISPLAY ($ENV{DISPLAY})";
6    }
7}
8
9use strict;
10use warnings;
11use Pod::Usage qw(pod2usage);
12use Getopt::Long qw(GetOptions);
13use Class::Inspector;
14use Socket qw(INADDR_LOOPBACK);
15use IO::Poll;
16use HTTP::Response;
17use HTTP::Status;
18use Mozilla::Screenshot;
19
20use POE qw(
21    Sugar::Args
22    Wheel::SocketFactory
23    Wheel::ReadWrite
24    Wheel::Run
25    Filter::Stream
26    Filter::HTTPD
27    Component::TSTP
28);
29
30GetOptions(
31    'h|help'    => sub { pod2usage 1 },
32    'p|port=i'  => \ (my $port = 3000),
33    'x|proxy=s' => \ my $proxy,
34) or pod2usage 1;
35
36$ENV{HTTP_PROXY} = $proxy if $proxy;
37
38POE::Component::TSTP->create;
39
40POE::Session->create(
41    inline_states  => {
42        _start => sub { sweet_args->kernel->yield('server_start') },
43    },
44    package_states => [ main => Class::Inspector->methods('main') ],
45    heap           => { port => $port },
46);
47
48POE::Kernel->sig($_ => sub { POE::Kernel->stop }) for qw( INT TERM HUP );
49POE::Kernel->run;
50exit;
51
52sub server_start {
53    my $poe = sweet_args;
54
55    $poe->heap->{server} = POE::Wheel::SocketFactory->new(
56        BindAddress  => INADDR_LOOPBACK,
57        BindPort     => $poe->heap->{port},
58        SuccessEvent => 'server_accept',
59        FailureEvent => 'server_error',
60        Reuse        => 'on',
61    );
62
63    $poe->heap->{ua} = Mozilla::Screenshot->new({ env_proxy => $ENV{HTTP_PROXY} ? 1 : 0 });
64}
65
66sub server_accept {
67    my $poe = sweet_args;
68
69    my $connection = POE::Wheel::ReadWrite->new(
70        Handle       => $poe->args->[0],
71        InputEvent   => 'client_input',
72        FlushedEvent => 'client_flush',
73        ErrorEvent   => 'client_error',
74        Filter       => POE::Filter::HTTPD->new,
75    );
76
77    $poe->heap->{connection}->{$connection->ID} = $connection;
78}
79
80sub server_error { delete sweet_args->heap->{server} }
81
82sub client_input {
83    my $poe = sweet_args;
84    my $req = $poe->args->[0];
85
86    my $res = HTTP::Response->new;
87    $res->protocol('HTTP/1.0');
88    $res->request($req);
89    $res->date(time);
90    $res->header(Connection => 'close');
91
92    if (my $uri = $req->header('Content-Location')) {
93        my $image;
94        eval { $image = $poe->heap->{ua}->fetch($uri)->save_to_buffer('png') };
95        $@ ? $res->code(RC_INTERNAL_SERVER_ERROR) : do {
96            $res->code(RC_OK);
97            $res->content_type('image/png');
98            $res->content_length(length $image);
99            $res->content($image);
100        };
101    }
102    else {
103        $res->code(RC_BAD_REQUEST);
104    }
105
106    $poe->heap->{connection}->{$poe->args->[1]}->put($res);
107}
108
109sub client_flush {
110    my $poe = sweet_args;
111    $poe->kernel->yield(client_close => $poe->args->[0]);
112}
113
114sub client_close {
115    my $poe = sweet_args;
116    delete $poe->heap->{connection}->{$poe->args->[0]};
117}
118
119sub client_error {
120    my $poe = sweet_args;
121    $poe->kernel->yield(client_close => $poe->args->[3]);
122}
123
124__END__
125
126=head1 NAME
127
128screenshot-httpd-poe.pl - sample screenshot httpd with POE
129
130=head1 SYNOPSIS
131
132screenshot-httpd-poe.pl [options]
133
134 Options:
135   -h --help      display this help and exits
136   -p --port      port (defaults to 3000)
137   -x --proxy     proxy (defaults to $ENV{HTTP_PROXY})
138
139=cut
Note: See TracBrowser for help on using the browser.