X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FEngine.pm;h=8936fab819a399f4e8e97c7e64d242d1ec85c83a;hb=ea72fece19fee2a788a7e9cab6076392fdd674a0;hp=8b3a701d57aa0a58926e168ea20754cba000d1f5;hpb=0fc2d522eec43202c21e9f0062e43f10db4d9008;p=catagits%2FCatalyst-Runtime.git
diff --git a/lib/Catalyst/Engine.pm b/lib/Catalyst/Engine.pm
index 8b3a701..8936fab 100644
--- a/lib/Catalyst/Engine.pm
+++ b/lib/Catalyst/Engine.pm
@@ -1,6 +1,5 @@
package Catalyst::Engine;
-use Class::C3;
use Moose;
with 'MooseX::Emulate::Class::Accessor::Fast';
@@ -11,16 +10,16 @@ use HTML::Entities;
use HTTP::Body;
use HTTP::Headers;
use URI::QueryParam;
-use Scalar::Util ();
+
+use namespace::clean -except => 'meta';
+
+has env => (is => 'rw');
# input position and length
has read_length => (is => 'rw');
has read_position => (is => 'rw');
-no Moose;
-
-# Stringify to class
-use overload '""' => sub { return ref shift }, fallback => 1;
+has _prepared_write => (is => 'rw');
# Amount of data to read from input on each pass
our $CHUNKSIZE = 64 * 1024;
@@ -48,11 +47,13 @@ sub finalize_body {
my ( $self, $c ) = @_;
my $body = $c->response->body;
no warnings 'uninitialized';
- if ( Scalar::Util::blessed($body) && $body->can('read') or ref($body) eq 'GLOB' ) {
- while ( !eof $body ) {
- read $body, my ($buffer), $CHUNKSIZE;
- last unless $self->write( $c, $buffer );
- }
+ if ( blessed($body) && $body->can('read') or ref($body) eq 'GLOB' ) {
+ my $got;
+ do {
+ $got = read $body, my ($buffer), $CHUNKSIZE;
+ $got = 0 unless $self->write( $c, $buffer );
+ } while $got > 0;
+
close $body;
}
else {
@@ -78,7 +79,7 @@ sub finalize_cookies {
my $val = $response->cookies->{$name};
my $cookie = (
- Scalar::Util::blessed($val)
+ blessed($val)
? $val
: CGI::Simple::Cookie->new(
-name => $name,
@@ -86,7 +87,8 @@ sub finalize_cookies {
-expires => $val->{expires},
-domain => $val->{domain},
-path => $val->{path},
- -secure => $val->{secure} || 0
+ -secure => $val->{secure} || 0,
+ -httponly => $val->{httponly} || 0,
)
);
@@ -100,7 +102,7 @@ sub finalize_cookies {
=head2 $self->finalize_error($c)
-Output an apropriate error message, called if there's an error in $c
+Output an appropriate error message. Called if there's an error in $c
after the dispatch has finished. Will output debug messages if Catalyst
is in debug mode, or a `please come back later` message otherwise.
@@ -110,7 +112,7 @@ sub finalize_error {
my ( $self, $c ) = @_;
$c->res->content_type('text/html; charset=utf-8');
- my $name = $c->config->{name} || join(' ', split('::', ref $c));
+ my $name = ref($c)->config->{name} || join(' ', split('::', ref $c));
my ( $title, $error, $infos );
if ( $c->debug ) {
@@ -127,11 +129,11 @@ sub finalize_error {
$name = "
$name
";
# Don't show context in the dump
- delete $c->req->{_context};
- delete $c->res->{_context};
+ $c->req->_clear_context;
+ $c->res->_clear_context;
# Don't show body parser in the dump
- delete $c->req->{_body};
+ $c->req->_clear_body;
my @infos;
my $i = 0;
@@ -160,6 +162,9 @@ EOF
(no) Vennligst prov igjen senere
(dk) Venligst prov igen senere
(pl) Prosze sprobowac pozniej
+(pt) Por favor volte mais tarde
+(ru) ÐопÑобÑйÑе еÑе Ñаз позже
+(ua) СпÑобÑйÑе Ñе Ñаз пÑзнÑÑе
$name = '';
@@ -245,7 +250,7 @@ EOF
}
/* from http://users.tkk.fi/~tkarvine/linux/doc/pre-wrap/pre-wrap-css3-mozilla-opera-ie.html */
/* Browser specific (not valid) styles to make preformatted text wrap */
- pre {
+ pre {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
@@ -312,16 +317,18 @@ sets up the L object body using L
sub prepare_body {
my ( $self, $c ) = @_;
+ my $appclass = ref($c) || $c;
if ( my $length = $self->read_length ) {
my $request = $c->request;
- unless ( $request->{_body} ) {
+ unless ( $request->_body ) {
my $type = $request->header('Content-Type');
- $request->{_body} = HTTP::Body->new( $type, $length );
- $request->{_body}->{tmpdir} = $c->config->{uploadtmp}
- if exists $c->config->{uploadtmp};
+ $request->_body(HTTP::Body->new( $type, $length ));
+ $request->_body->tmpdir( $appclass->config->{uploadtmp} )
+ if exists $appclass->config->{uploadtmp};
}
-
- while ( my $buffer = $self->read($c) ) {
+
+ # Check for definedness as you could read '0'
+ while ( defined ( my $buffer = $self->read($c) ) ) {
$c->prepare_body_chunk($buffer);
}
@@ -335,7 +342,7 @@ sub prepare_body {
}
else {
# Defined but will cause all body code to be skipped
- $c->request->{_body} = 0;
+ $c->request->_body(0);
}
}
@@ -348,21 +355,21 @@ Add a chunk to the request body.
sub prepare_body_chunk {
my ( $self, $c, $chunk ) = @_;
- $c->request->{_body}->add($chunk);
+ $c->request->_body->add($chunk);
}
=head2 $self->prepare_body_parameters($c)
-Sets up parameters from body.
+Sets up parameters from body.
=cut
sub prepare_body_parameters {
my ( $self, $c ) = @_;
-
- return unless $c->request->{_body};
-
- $c->request->body_parameters( $c->request->{_body}->param );
+
+ return unless $c->request->_body;
+
+ $c->request->body_parameters( $c->request->_body->param );
}
=head2 $self->prepare_connection($c)
@@ -441,7 +448,7 @@ process the query string and extract query parameters.
sub prepare_query_parameters {
my ( $self, $c, $query_string ) = @_;
-
+
# Check for keywords (no = signs)
# (yes, index() is faster than a regex :))
if ( index( $query_string, '=' ) < 0 ) {
@@ -453,17 +460,17 @@ sub prepare_query_parameters {
# replace semi-colons
$query_string =~ s/;/&/g;
-
- my @params = split /&/, $query_string;
+
+ my @params = grep { length $_ } split /&/, $query_string;
for my $item ( @params ) {
-
- my ($param, $value)
+
+ my ($param, $value)
= map { $self->unescape_uri($_) }
split( /=/, $item, 2 );
-
+
$param = $self->unescape_uri($item) unless defined $param;
-
+
if ( exists $query{$param} ) {
if ( ref $query{$param} ) {
push @{ $query{$param} }, $value;
@@ -491,7 +498,7 @@ sub prepare_read {
# Initialize the read position
$self->read_position(0);
-
+
# Initialize the amount of data we think we need to read
$self->read_length( $c->request->header('Content-Length') || 0 );
}
@@ -512,9 +519,9 @@ sub prepare_uploads {
my ( $self, $c ) = @_;
my $request = $c->request;
- return unless $request->{_body};
+ return unless $request->_body;
- my $uploads = $request->{_body}->upload;
+ my $uploads = $request->_body->upload;
my $parameters = $request->parameters;
foreach my $name (keys %$uploads) {
my $files = $uploads->{$name};
@@ -560,6 +567,10 @@ sub prepare_write { }
=head2 $self->read($c, [$maxlength])
+Reads from the input stream by calling C<< $self->read_chunk >>.
+
+Maintains the read_length and read_position counters as data is read.
+
=cut
sub read {
@@ -577,6 +588,11 @@ sub read {
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. FIXME - Warn in the log here?
+ $self->finalize_read;
+ return;
+ }
$self->read_position( $self->read_position + $rc );
return $buffer;
}
@@ -588,8 +604,9 @@ sub read {
=head2 $self->read_chunk($c, $buffer, $length)
-Each engine inplements read_chunk as its preferred way of reading a chunk
-of data.
+Each engine implements read_chunk as its preferred way of reading a chunk
+of data. Returns the number of bytes read. A return of 0 indicates that
+there is no more data to be read.
=cut
@@ -621,19 +638,21 @@ Writes the buffer to the client.
sub write {
my ( $self, $c, $buffer ) = @_;
- unless ( $self->{_prepared_write} ) {
+ unless ( $self->_prepared_write ) {
$self->prepare_write($c);
- $self->{_prepared_write} = 1;
+ $self->_prepared_write(1);
}
-
+
+ return 0 if !defined $buffer;
+
my $len = length($buffer);
my $wrote = syswrite STDOUT, $buffer;
-
+
if ( !defined $wrote && $! == EWOULDBLOCK ) {
# Unable to write on the first try, will retry in the loop below
$wrote = 0;
}
-
+
if ( defined $wrote && $wrote < $len ) {
# We didn't write the whole buffer
while (1) {
@@ -645,11 +664,11 @@ sub write {
next if $! == EWOULDBLOCK;
return;
}
-
+
last if $wrote >= $len;
}
}
-
+
return $wrote;
}
@@ -672,15 +691,25 @@ sub unescape_uri {
, see finalize_body
-=head1 AUTHORS
+=head2 $self->env
+
+Hash containing enviroment variables including many special variables inserted
+by WWW server - like SERVER_*, REMOTE_*, HTTP_* ...
-Sebastian Riedel,
+Before accesing enviroment variables consider whether the same information is
+not directly available via Catalyst objects $c->request, $c->engine ...
+
+BEWARE: If you really need to access some enviroment variable from your Catalyst
+application you should use $c->engine->env->{VARNAME} instead of $ENV{VARNAME},
+as in some enviroments the %ENV hash does not contain what you would expect.
+
+=head1 AUTHORS
-Andy Grundman,
+Catalyst Contributors, see Catalyst.pm
=head1 COPYRIGHT
-This program is free software, you can redistribute it and/or modify it under
+This library is free software. You can redistribute it and/or modify it under
the same terms as Perl itself.
=cut