| 1 | package HTTP::Engine::Interface::ModPerl; |
|---|
| 2 | use HTTP::Engine::Interface |
|---|
| 3 | builder => 'CGI', |
|---|
| 4 | writer => { |
|---|
| 5 | attribute => { |
|---|
| 6 | chunk_size => { |
|---|
| 7 | is => 'ro', |
|---|
| 8 | isa => 'Int', |
|---|
| 9 | default => 4096, |
|---|
| 10 | } |
|---|
| 11 | }, |
|---|
| 12 | finalize => sub { |
|---|
| 13 | my ($self, $req, $res) = @_; |
|---|
| 14 | my $r = $req->_connection->{apache_request} or die "missing apache request"; |
|---|
| 15 | $r->status( $res->status ); |
|---|
| 16 | $req->headers->scan( |
|---|
| 17 | sub { |
|---|
| 18 | my ($key, $val) = @_; |
|---|
| 19 | $r->headers_out->add($key => $val); |
|---|
| 20 | } |
|---|
| 21 | ); |
|---|
| 22 | |
|---|
| 23 | sub { |
|---|
| 24 | my ($r, $body) = @_; |
|---|
| 25 | no warnings 'uninitialized'; |
|---|
| 26 | if ((Scalar::Util::blessed($body) && $body->can('read')) || (ref($body) eq 'GLOB')) { |
|---|
| 27 | while (!eof $body) { |
|---|
| 28 | read $body, my ($buffer), $self->chunk_size; |
|---|
| 29 | last unless $r->print($buffer); |
|---|
| 30 | } |
|---|
| 31 | close $body; |
|---|
| 32 | } else { |
|---|
| 33 | $r->print($body); |
|---|
| 34 | } |
|---|
| 35 | }->($r, $res->body); |
|---|
| 36 | }, |
|---|
| 37 | } |
|---|
| 38 | ; |
|---|
| 39 | |
|---|
| 40 | |
|---|
| 41 | BEGIN |
|---|
| 42 | { |
|---|
| 43 | if (! exists $ENV{MOD_PERL_API_VERSION} || |
|---|
| 44 | $ENV{MOD_PERL_API_VERSION} != 2) |
|---|
| 45 | { |
|---|
| 46 | die "HTTP::Engine::Interface::ModPerl only supports mod_perl2"; |
|---|
| 47 | } |
|---|
| 48 | } |
|---|
| 49 | |
|---|
| 50 | use Apache2::Const -compile => qw(OK); |
|---|
| 51 | use Apache2::Connection; |
|---|
| 52 | use Apache2::RequestRec; |
|---|
| 53 | use Apache2::RequestIO (); |
|---|
| 54 | use Apache2::RequestUtil; |
|---|
| 55 | use Apache2::ServerRec; |
|---|
| 56 | use APR::Table; |
|---|
| 57 | use HTTP::Engine; |
|---|
| 58 | |
|---|
| 59 | has 'apache' => ( |
|---|
| 60 | is => 'rw', |
|---|
| 61 | isa => 'Apache2::RequestRec', |
|---|
| 62 | is_weak => 1, |
|---|
| 63 | ); |
|---|
| 64 | |
|---|
| 65 | has 'context_key' => ( |
|---|
| 66 | is => 'rw', |
|---|
| 67 | isa => 'Str', |
|---|
| 68 | ); |
|---|
| 69 | |
|---|
| 70 | no Moose; |
|---|
| 71 | |
|---|
| 72 | my %HE; |
|---|
| 73 | |
|---|
| 74 | sub handler : method |
|---|
| 75 | { |
|---|
| 76 | my $class = shift; |
|---|
| 77 | my $r = shift; |
|---|
| 78 | |
|---|
| 79 | local %ENV = %ENV; |
|---|
| 80 | |
|---|
| 81 | # ModPerl is currently the only environment where the inteface comes |
|---|
| 82 | # before the actual invocation of HTTP::Engine |
|---|
| 83 | |
|---|
| 84 | my $context_key = join ':', $ENV{SERVER_NAME}, $ENV{SERVER_PORT}, $r->location; |
|---|
| 85 | my $engine = $HE{ $context_key }; |
|---|
| 86 | if (! $engine ) { |
|---|
| 87 | $engine = $class->create_engine($r, $context_key); |
|---|
| 88 | $HE{ $context_key } = $engine; |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | $engine->interface->apache( $r ); |
|---|
| 92 | $engine->interface->context_key( $context_key ); |
|---|
| 93 | |
|---|
| 94 | $engine->interface->handle_request( |
|---|
| 95 | _connection => { |
|---|
| 96 | input_handle => \*STDIN, |
|---|
| 97 | output_handle => \*STDOUT, |
|---|
| 98 | env => \%ENV, |
|---|
| 99 | apache_request => $r, |
|---|
| 100 | }, |
|---|
| 101 | ); |
|---|
| 102 | |
|---|
| 103 | return &Apache2::Const::OK; |
|---|
| 104 | } |
|---|
| 105 | |
|---|
| 106 | sub create_engine |
|---|
| 107 | { |
|---|
| 108 | my ($self, $r) = @_; |
|---|
| 109 | |
|---|
| 110 | HTTP::Engine->new( |
|---|
| 111 | interface => HTTP::Engine::Interface::ModPerl->new( |
|---|
| 112 | request_handler => sub { HTTP::Engine::Response->new(status => 200) }, |
|---|
| 113 | ) |
|---|
| 114 | ); |
|---|
| 115 | } |
|---|
| 116 | |
|---|
| 117 | sub run { die "THIS IS DUMMY" } |
|---|
| 118 | |
|---|
| 119 | __INTERFACE__ |
|---|
| 120 | |
|---|
| 121 | __END__ |
|---|
| 122 | |
|---|
| 123 | =head1 NAME |
|---|
| 124 | |
|---|
| 125 | HTTP::Engine::Interface::ModPerl - mod_perl Adaptor for HTTP::Engine |
|---|
| 126 | |
|---|
| 127 | =head1 CONFIG |
|---|
| 128 | |
|---|
| 129 | required configuration in httpd.conf |
|---|
| 130 | |
|---|
| 131 | SetHandler modperl |
|---|
| 132 | PerlOptions +SetupEnv |
|---|
| 133 | |
|---|
| 134 | or |
|---|
| 135 | |
|---|
| 136 | SetHandler perl-script |
|---|
| 137 | |
|---|
| 138 | =head1 AUTHORS |
|---|
| 139 | |
|---|
| 140 | Daisuke Maki |
|---|
| 141 | |
|---|
| 142 | Tokuhiro Matsuno |
|---|
| 143 | |
|---|
| 144 | Kazuhiro Osawa |
|---|
| 145 | |
|---|
| 146 | =head1 SEE ALSO |
|---|
| 147 | |
|---|
| 148 | L<HTTP::Engine>, L<Apache2> |
|---|
| 149 | |
|---|
| 150 | =cut |
|---|