At least pass the port param to _run_psgi_app to get http-server.t running again.
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Engine.pm
index 84450c4..ca836f9 100644 (file)
@@ -11,6 +11,9 @@ use HTTP::Body;
 use HTTP::Headers;
 use URI::QueryParam;
 use Moose::Util::TypeConstraints;
+use Plack::Loader;
+use Plack::Middleware::Conditional;
+use Plack::Middleware::ReverseProxy;
 
 use namespace::clean -except => 'meta';
 
@@ -23,15 +26,17 @@ has read_position => (is => 'rw');
 has _prepared_write => (is => 'rw');
 
 has _response_cb => (
-    is     => 'ro',
-    isa    => 'CodeRef',
-    writer => '_set_response_cb',
+    is      => 'ro',
+    isa     => 'CodeRef',
+    writer  => '_set_response_cb',
+    clearer => '_clear_response_cb',
 );
 
 has _writer => (
-    is     => 'ro',
-    isa    => duck_type([qw(write close)]),
-    writer => '_set_writer',
+    is      => 'ro',
+    isa     => duck_type([qw(write close)]),
+    writer  => '_set_writer',
+    clearer => '_clear_writer',
 );
 
 # Amount of data to read from input on each pass
@@ -74,6 +79,8 @@ sub finalize_body {
     }
 
     $self->_writer->close;
+    $self->_clear_writer;
+    $self->_clear_env;
 
     return;
 }
@@ -317,6 +324,7 @@ sub finalize_headers {
     $ctx->response->headers->scan(sub { push @headers, @_ });
 
     $self->_set_writer($self->_response_cb->([ $ctx->response->status, \@headers ]));
+    $self->_clear_response_cb;
 
     return;
 }
@@ -427,7 +435,7 @@ sub prepare_connection {
     $request->protocol( $env->{SERVER_PROTOCOL} );
     $request->remote_user( $env->{REMOTE_USER} );
     $request->method( $env->{REQUEST_METHOD} );
-    $request->secure( $env->{'psgi.url_scheme'} eq 'https' );
+    $request->secure( $env->{'psgi.url_scheme'} eq 'https' ? 1 : 0 );
 
     return;
 }
@@ -513,7 +521,7 @@ sub prepare_path {
     # set the request URI
     my $req_uri = $env->{REQUEST_URI};
     $req_uri =~ s/\?.*$//;
-    my $path = $self->unescape_uri($req_uri);
+    my $path = $req_uri;
     $path =~ s{^/+}{};
 
     # Using URI directly is way too slow, so we construct the URLs manually
@@ -526,10 +534,6 @@ sub prepare_path {
         $host .= ":$port";
     }
 
-    # Escape the path
-    $path =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
-    $path =~ s/\?/%3F/g; # STUPID STUPID SPECIAL CASE
-
     my $query = $env->{QUERY_STRING} ? '?' . $env->{QUERY_STRING} : '';
     my $uri   = $scheme . '://' . $host . '/' . $path . $query;
 
@@ -704,7 +708,7 @@ sub read {
     my $rc = $self->read_chunk( $c, my $buffer, $readlen );
     if ( defined $rc ) {
         if (0 == $rc) { # Nothing more to read even though Content-Length
-                        # said there should be. FIXME - Warn in the log here?
+                        # said there should be.
             $self->finalize_read;
             return;
         }
@@ -725,7 +729,10 @@ there is no more data to be read.
 
 =cut
 
-sub read_chunk { }
+sub read_chunk {
+    my ($self, $ctx) = (shift, shift);
+    return $self->env->{'psgi.input'}->read(@_);
+}
 
 =head2 $self->read_length
 
@@ -743,9 +750,15 @@ Start the engine. Implemented by the various engine classes.
 =cut
 
 sub run {
-    my ($self, $app) = @_;
+    my ($self, $app, @args) = @_;
+    # FIXME - Do something sensible with the options we're passed
+    $self->_run_psgi_app($self->_build_psgi_app($app, @args), @args);
+}
+
+sub _build_psgi_app {
+    my ($self, $app, @args) = @_;
 
-    return sub {
+    my $psgi_app = sub {
         my ($env) = @_;
 
         return sub {
@@ -754,6 +767,24 @@ sub run {
             $app->handle_request(env => $env);
         };
     };
+
+    $psgi_app = Plack::Middleware::Conditional->wrap(
+        $psgi_app,
+        condition => sub {
+            my ($env) = @_;
+            return if $app->config->{ignore_frontend_proxy};
+            return $env->{REMOTE_ADDR} eq '127.0.0.1' || $app->config->{using_frontend_proxy};
+        },
+        builder   => sub { Plack::Middleware::ReverseProxy->wrap($_[0]) },
+    );
+
+    return $psgi_app;
+}
+
+sub _run_psgi_app {
+    my ($self, $psgi_app, @args) = @_;
+    # FIXME - Need to be able to specify engine and pass options..
+    Plack::Loader->auto(port => $args[0])->run($psgi_app);
 }
 
 =head2 $self->write($c, $buffer)