Move actual reading into request
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Request.pm
index b16e59a..1f7465c 100644 (file)
@@ -14,6 +14,17 @@ use namespace::clean -except => 'meta';
 
 with 'MooseX::Emulate::Class::Accessor::Fast';
 
+has env => (is => 'ro', writer => '_set_env');
+
+has _read_position => ( is => 'rw', default => 0 );
+has _read_length => ( is => 'ro',
+    default => sub {
+        my $self = shift;
+        $self->header('Content-Length') || 0;
+    },
+    lazy => 1,
+);
+
 has action => (is => 'rw');
 has address => (is => 'rw');
 has arguments => (is => 'rw', default => sub { [] });
@@ -39,10 +50,43 @@ has headers => (
 has _context => (
   is => 'rw',
   weak_ref => 1,
-  handles => ['read'],
   clearer => '_clear_context',
 );
 
+# Amount of data to read from input on each pass
+our $CHUNKSIZE = 64 * 1024;
+
+sub read {
+    my ($self, $maxlength) = @_;
+    my $remaining = $self->_read_length - $self->_read_position;
+    $maxlength ||= $CHUNKSIZE;
+
+    # Are we done reading?
+    if ( $remaining <= 0 ) {
+        return;
+    }
+
+    my $readlen = ( $remaining > $maxlength ) ? $maxlength : $remaining;
+    my $rc = $self->read_chunk( my $buffer, $readlen );
+    if ( defined $rc ) {
+        if (0 == $rc) { # Nothing more to read even though Content-Length
+                        # said there should be.
+            return;
+        }
+        $self->_read_position( $self->_read_position + $rc );
+        return $buffer;
+    }
+    else {
+        Catalyst::Exception->throw(
+            message => "Unknown error reading input: $!" );
+    }
+}
+
+sub read_chunk {
+    my $self = shift;
+    return $self->env->{'psgi.input'}->read(@_);
+}
+
 has body_parameters => (
   is => 'rw',
   required => 1,
@@ -110,7 +154,7 @@ has _body => (
 sub body {
   my $self = shift;
   $self->_context->prepare_body();
-  $self->_body(@_) if scalar @_;
+  croak 'body is a reader' if scalar @_;
   return blessed $self->_body ? $self->_body->body : $self->_body;
 }
 
@@ -120,7 +164,7 @@ has hostname => (
   lazy      => 1,
   default   => sub {
     my ($self) = @_;
-    gethostbyaddr( inet_aton( $self->address ), AF_INET ) || 'localhost'
+    gethostbyaddr( inet_aton( $self->address ), AF_INET ) || $self->address
   },
 );
 
@@ -138,6 +182,8 @@ sub query_params    { shift->query_parameters(@_) }
 sub path_info       { shift->path(@_) }
 sub snippets        { shift->captures(@_) }
 
+=for stopwords param params
+
 =head1 NAME
 
 Catalyst::Request - provides information about the current client request
@@ -210,7 +256,7 @@ Returns a reference to an array containing the arguments.
 
 For example, if your action was
 
-    package MyApp::C::Foo;
+    package MyApp::Controller::Foo;
 
     sub moose : Local {
         ...
@@ -223,12 +269,12 @@ Arguments get automatically URI-unescaped for you.
 
 =head2 $req->args
 
-Shortcut for arguments.
+Shortcut for L</arguments>.
 
 =head2 $req->base
 
 Contains the URI base. This will always have a trailing slash. Note that the
-URI scheme (eg., http vs. https) must be determined through heuristics;
+URI scheme (e.g., http vs. https) must be determined through heuristics;
 depending on your server configuration, it may be incorrect. See $req->secure
 for more info.
 
@@ -237,8 +283,9 @@ C<http://localhost:3000/some/path> then C<base> is C<http://localhost:3000/>.
 
 =head2 $req->body
 
-Returns the message body of the request, unless Content-Type is
-C<application/x-www-form-urlencoded> or C<multipart/form-data>.
+Returns the message body of the request, as returned by L<HTTP::Body>: a string,
+unless Content-Type is C<application/x-www-form-urlencoded>, C<text/xml>, or
+C<multipart/form-data>, in which case a L<File::Temp> object is returned.
 
 =head2 $req->body_parameters
 
@@ -300,7 +347,7 @@ Returns a reference to a hash containing the cookies.
 
     print $c->request->cookies->{mycookie}->value;
 
-The cookies in the hash are indexed by name, and the values are L<CGI::Cookie>
+The cookies in the hash are indexed by name, and the values are L<CGI::Simple::Cookie>
 objects.
 
 =head2 $req->header
@@ -315,7 +362,7 @@ Returns an L<HTTP::Headers> object containing the headers for the current reques
 
 =head2 $req->hostname
 
-Returns the hostname of the client.
+Returns the hostname of the client. Use C<< $req->uri->host >> to get the hostname of the server.
 
 =head2 $req->input
 
@@ -426,6 +473,10 @@ Shortcut for $req->parameters.
 
 Returns the path, i.e. the part of the URI after $req->base, for the current request.
 
+    http://localhost/path/foo
+
+    $c->request->path will contain 'path/foo'
+
 =head2 $req->path_info
 
 Alias for path, added for compatibility with L<CGI>.
@@ -473,7 +524,11 @@ Reads a chunk of data from the request body. This method is intended to be
 used in a while loop, reading $maxlength bytes on every call. $maxlength
 defaults to the size of the request if not specified.
 
-You have to set MyApp->config->{parse_on_demand} to use this directly.
+=head2 $req->read_chunk(\$buff, $max)
+
+Reads a chunk..
+
+You have to set MyApp->config(parse_on_demand => 1) to use this directly.
 
 =head2 $req->referer
 
@@ -482,8 +537,8 @@ Shortcut for $req->headers->referer. Returns the referring page.
 =head2 $req->secure
 
 Returns true or false, indicating whether the connection is secure
-(https). Note that the URI scheme (eg., http vs. https) must be determined
-through heuristics, and therefore the reliablity of $req->secure will depend
+(https). Note that the URI scheme (e.g., http vs. https) must be determined
+through heuristics, and therefore the reliability of $req->secure will depend
 on your server configuration. If you are serving secure pages on the standard
 SSL port (443) and/or setting the HTTPS environment variable, $req->secure
 should be valid.
@@ -569,7 +624,7 @@ L<Catalyst::Request::Upload> objects.
 
 =head2 $req->uri
 
-Returns a URI object for the current request. Stringifies to the URI text.
+Returns a L<URI> object for the current request. Stringifies to the URI text.
 
 =head2 $req->mangle_params( { key => 'value' }, $appendmode);
 
@@ -649,7 +704,7 @@ You may also pass an optional second parameter that puts C<uri_with> into
 append mode:
 
   $req->uri_with( { key => 'value' }, { mode => 'append' } );
-  
+
 See C<mangle_params> for an explanation of this behavior.
 
 =cut
@@ -672,11 +727,6 @@ sub uri_with {
     return $uri;
 }
 
-=head2 $req->user
-
-Returns the currently logged in user. B<Highly deprecated>, do not call,
-this will be removed in version 5.81.
-
 =head2 $req->remote_user
 
 Returns the value of the C<REMOTE_USER> environment variable.