patch to make prepare_parameters not be both a builder and a preparer
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Engine.pm
index 9a6c287..65ef3fe 100644 (file)
@@ -33,6 +33,12 @@ around env => sub {
   return $self->$orig;
 };
 
+# XXX - Only here for Engine::PSGI compat
+sub prepare_connection {
+    my ($self, $ctx) = @_;
+    $ctx->request->prepare_connection;
+}
+
 =head1 NAME
 
 Catalyst::Engine - The Catalyst Engine
@@ -175,7 +181,6 @@ sub finalize_error {
         $name  = "<h1>$name</h1>";
 
         # Don't show context in the dump
-        $c->req->_clear_context;
         $c->res->_clear_context;
 
         # Don't show body parser in the dump
@@ -319,29 +324,14 @@ sub finalize_error {
 
 =head2 $self->finalize_headers($c)
 
-Abstract method, allows engines to write headers to response
+Allows engines to write headers to response
 
 =cut
 
 sub finalize_headers {
     my ($self, $ctx) = @_;
 
-    # This is a less-than-pretty hack to avoid breaking the old
-    # Catalyst::Engine::PSGI. 5.9 Catalyst::Engine sets a response_cb and
-    # expects us to pass headers to it here, whereas Catalyst::Enngine::PSGI
-    # just pulls the headers out of $ctx->response in its run method and never
-    # sets response_cb. So take the lack of a response_cb as a sign that we
-    # don't need to set the headers.
-
-    return unless ($ctx->response->_has_response_cb);
-
-    my @headers;
-    $ctx->response->headers->scan(sub { push @headers, @_ });
-
-    my $writer = $ctx->response->_response_cb->([ $ctx->response->status, \@headers ]);
-    $ctx->response->_set_writer($writer);
-    $ctx->response->_clear_response_cb;
-
+    $ctx->finalize_headers unless $ctx->response->finalized_headers;
     return;
 }
 
@@ -374,33 +364,7 @@ sets up the L<Catalyst::Request> object body using L<HTTP::Body>
 sub prepare_body {
     my ( $self, $c ) = @_;
 
-    my $appclass = ref($c) || $c;
-    my $request = $c->request;
-    if ( my $length = $request->_read_length ) {
-        unless ( $request->_body ) {
-            my $type = $request->header('Content-Type');
-            $request->_body(HTTP::Body->new( $type, $length ));
-            $request->_body->cleanup(1); # Make extra sure!
-            $request->_body->tmpdir( $appclass->config->{uploadtmp} )
-              if exists $appclass->config->{uploadtmp};
-        }
-
-        # Check for definedness as you could read '0'
-        while ( defined ( my $buffer = $self->read($c) ) ) {
-            $c->prepare_body_chunk($buffer);
-        }
-
-        # paranoia against wrong Content-Length header
-        my $remaining = $length - $c->request->_read_position;
-        if ( $remaining > 0 ) {
-            Catalyst::Exception->throw(
-                "Wrong Content-Length value: $length" );
-        }
-    }
-    else {
-        # Defined but will cause all body code to be skipped
-        $c->request->_body(0);
-    }
+    $c->request->prepare_body;
 }
 
 =head2 $self->prepare_body_chunk($c)
@@ -409,10 +373,11 @@ Add a chunk to the request body.
 
 =cut
 
+# XXX - Can this be deleted?
 sub prepare_body_chunk {
     my ( $self, $c, $chunk ) = @_;
 
-    $c->request->_body->add($chunk);
+    $c->request->prepare_body_chunk($chunk);
 }
 
 =head2 $self->prepare_body_parameters($c)
@@ -424,94 +389,22 @@ Sets up parameters from body.
 sub prepare_body_parameters {
     my ( $self, $c ) = @_;
 
-    return unless $c->request->_body;
-
-    $c->request->body_parameters( $c->request->_body->param );
-}
-
-=head2 $self->prepare_connection($c)
-
-Abstract method implemented in engines.
-
-=cut
-
-sub prepare_connection {
-    my ($self, $ctx) = @_;
-
-    my $request = $ctx->request;
-    my $env = $ctx->request->env;
-
-    $request->address( $env->{REMOTE_ADDR} );
-    $request->hostname( $env->{REMOTE_HOST} )
-        if exists $env->{REMOTE_HOST};
-    $request->protocol( $env->{SERVER_PROTOCOL} );
-    $request->remote_user( $env->{REMOTE_USER} );
-    $request->method( $env->{REQUEST_METHOD} );
-    $request->secure( $env->{'psgi.url_scheme'} eq 'https' ? 1 : 0 );
-
-    return;
-}
-
-=head2 $self->prepare_cookies($c)
-
-Parse cookies from header. Sets a L<CGI::Simple::Cookie> object.
-
-=cut
-
-sub prepare_cookies {
-    my ( $self, $c ) = @_;
-
-    if ( my $header = $c->request->header('Cookie') ) {
-        $c->req->cookies( { CGI::Simple::Cookie->parse($header) } );
-    }
-}
-
-=head2 $self->prepare_headers($c)
-
-=cut
-
-sub prepare_headers {
-    my ($self, $ctx) = @_;
-
-    my $env = $ctx->request->env;
-    my $headers = $ctx->request->headers;
-
-    for my $header (keys %{ $env }) {
-        next unless $header =~ /^(HTTP|CONTENT|COOKIE)/i;
-        (my $field = $header) =~ s/^HTTPS?_//;
-        $field =~ tr/_/-/;
-        $headers->header($field => $env->{$header});
-    }
+    $c->request->prepare_body_parameters;
 }
 
 =head2 $self->prepare_parameters($c)
 
-sets up parameters from query and post parameters.
+Sets up parameters from query and post parameters.
+If parameters have already been set up will clear
+existing parameters and set up again.
 
 =cut
 
 sub prepare_parameters {
     my ( $self, $c ) = @_;
 
-    my $request = $c->request;
-    my $parameters = $request->parameters;
-    my $body_parameters = $request->body_parameters;
-    my $query_parameters = $request->query_parameters;
-    # We copy, no references
-    foreach my $name (keys %$query_parameters) {
-        my $param = $query_parameters->{$name};
-        $parameters->{$name} = ref $param eq 'ARRAY' ? [ @$param ] : $param;
-    }
-
-    # Merge query and body parameters
-    foreach my $name (keys %$body_parameters) {
-        my $param = $body_parameters->{$name};
-        my @values = ref $param eq 'ARRAY' ? @$param : ($param);
-        if ( my $existing = $parameters->{$name} ) {
-          unshift(@values, (ref $existing eq 'ARRAY' ? @$existing : $existing));
-        }
-        $parameters->{$name} = @values > 1 ? \@values : $values[0];
-    }
+    $c->request->_clear_parameters;
+    return $c->request->parameters;
 }
 
 =head2 $self->prepare_path($c)
@@ -626,13 +519,12 @@ sub prepare_query_parameters {
             $query{$param} = $value;
         }
     }
-
     $c->request->query_parameters( \%query );
 }
 
 =head2 $self->prepare_read($c)
 
-prepare to read from the engine.
+Prepare to read by initializing the Content-Length from headers.
 
 =cut
 
@@ -702,6 +594,18 @@ sub prepare_uploads {
     }
 }
 
+=head2 $self->write($c, $buffer)
+
+Writes the buffer to the client.
+
+=cut
+
+sub write {
+    my ( $self, $c, $buffer ) = @_;
+
+    $c->response->write($buffer);
+}
+
 =head2 $self->read($c, [$maxlength])
 
 Reads from the input stream by calling C<< $self->read_chunk >>.
@@ -713,30 +617,7 @@ Maintains the read_length and read_position counters as data is read.
 sub read {
     my ( $self, $c, $maxlength ) = @_;
 
-    my $request = $c->request;
-    my $remaining = $request->_read_length - $request->_read_position;
-    $maxlength ||= $CHUNKSIZE;
-
-    # Are we done reading?
-    if ( $remaining <= 0 ) {
-        return;
-    }
-
-    my $readlen = ( $remaining > $maxlength ) ? $maxlength : $remaining;
-    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.
-            return;
-        }
-        my $request = $c->request;
-        $request->_read_position( $request->_read_position + $rc );
-        return $buffer;
-    }
-    else {
-        Catalyst::Exception->throw(
-            message => "Unknown error reading input: $!" );
-    }
+    $c->request->read($maxlength);
 }
 
 =head2 $self->read_chunk($c, \$buffer, $length)
@@ -752,15 +633,6 @@ sub read_chunk {
     return $ctx->request->read_chunk(@_);
 }
 
-=head2 $self->read_length
-
-The length of input data to be read.  This is obtained from the Content-Length
-header.
-
-=head2 $self->read_position
-
-The amount of input data that has already been read.
-
 =head2 $self->run($app, $server)
 
 Start the engine. Builds a PSGI application and calls the
@@ -800,8 +672,7 @@ sub run {
 
 =head2 build_psgi_app ($app, @args)
 
-Builds and returns a PSGI application closure, wrapping it in the reverse proxy
-middleware if the using_frontend_proxy config setting is set.
+Builds and returns a PSGI application closure. (Raw, not wrapped in middleware)
 
 =cut
 
@@ -813,30 +684,12 @@ sub build_psgi_app {
 
         return sub {
             my ($respond) = @_;
+            confess("Did not get a response callback for writer, cannot continiue") unless $respond;
             $app->handle_request(env => $env, response_cb => $respond);
         };
     };
 }
 
-=head2 $self->write($c, $buffer)
-
-Writes the buffer to the client.
-
-=cut
-
-sub write {
-    my ( $self, $c, $buffer ) = @_;
-
-    my $response = $c->response;
-
-    $buffer = q[] unless defined $buffer;
-
-    my $len = length($buffer);
-    $c->res->_writer->write($buffer);
-
-    return $len;
-}
-
 =head2 $self->unescape_uri($uri)
 
 Unescapes a given URI using the most efficient method available.  Engines such