Fixed HTTP/1.1 issues
Christian Hansen [Tue, 31 May 2005 22:37:11 +0000 (22:37 +0000)]
lib/Catalyst/Engine.pm
lib/Catalyst/Engine/HTTP/Daemon.pm

index 9c92866..6af7d74 100644 (file)
@@ -204,14 +204,22 @@ sub finalize {
     if ( $#{ $c->error } >= 0 ) {
         $c->finalize_error;
     }
-
-    if ( !$c->response->body && $c->response->status !~ /^(1|3)\d\d$/ ) {
+    
+    if ( !$c->response->body && $c->response->status == 200 ) {
         $c->finalize_error;
     }
 
     if ( $c->response->body && !$c->response->content_length ) {
-        use bytes;    # play safe with a utf8 aware perl
-        $c->response->content_length( length $c->response->body );
+        $c->response->content_length( bytes::length( $c->response->body ) );
+    }
+    
+    if ( $c->response->status =~ /^(1\d\d|[23]04)$/ ) {
+        $c->response->headers->remove_header("Content-Length");
+        $c->response->body('');
+    }
+    
+    if ( $c->request->method eq 'HEAD' ) {
+        $c->response->body('');
     }
 
     my $status = $c->finalize_headers;
@@ -441,7 +449,7 @@ sub prepare {
             {
                 body    => '',
                 cookies => {},
-                headers => HTTP::Headers->new,
+                headers => HTTP::Headers->new( 'Content-Length' => 0 ),
                 status  => 200
             }
         ),
@@ -699,7 +707,7 @@ sub setup_components {
     
     my $callback = sub {
         my ( $component, $context ) = @_;
-
+        
         unless ( $component->isa('Catalyst::Base') ) {
             return $component;
         }
index 53cd254..fee9bce 100644 (file)
@@ -122,10 +122,10 @@ sub run {
                 my $nread = $client->sysread( my $buf, 4096 );
 
                 unless ( $nread ) {
-                
+
                     next if $! == EWOULDBLOCK;
                     next if $! == EINPROGRESS;
-                    next if $! == EINTR;                
+                    next if $! == EINTR;
 
                     $select->remove($client);
                     $client->close;
@@ -169,6 +169,8 @@ sub run {
 
             unless ( $client->response_buffer ) {
 
+                $client->response->header( Server => $daemon->product_tokens );
+
                 my $connection = $client->request->header('Connection');
 
                 if ( $connection && $connection =~ /Keep-Alive/i ) {
@@ -176,7 +178,11 @@ sub run {
                     $client->response->header( 'Keep-Alive' => 'timeout=60, max=100' );
                 }
 
-                $client->response_buffer = $client->response->as_string;
+                if ( $connection && $connection =~ /close/i ) {
+                    $client->response->header( 'Connection' => 'close' );
+                }
+
+                $client->response_buffer = $client->response->as_string("\x0D\x0A");
                 $client->response_offset = 0;
             }
 
@@ -185,10 +191,10 @@ sub run {
                                             $client->response_offset );
 
             unless ( $nwrite ) {
-            
+
                 next if $! == EWOULDBLOCK;
                 next if $! == EINPROGRESS;
-                next if $! == EINTR;            
+                next if $! == EINTR;
 
                 $select->remove($client);
                 $client->close;
@@ -200,9 +206,28 @@ sub run {
 
             if ( $client->response_offset == $client->response_length ) {
 
+                my $persistent = 0;
+
                 my $connection = $client->request->header('Connection');
+                my $protocol   = $client->request->protocol;
+
+                if ( $protocol eq 'HTTP/1.1' ) {
+
+                    $persistent++;
+
+                    if ( $connection && $connection =~ /close/i ) {
+                        $persistent--;
+                    }
+                }
+
+                else {
+
+                    if ( $connection && $connection =~ /Keep-Alive/i ) {
+                        $persistent++;
+                    }
+                }
 
-                unless ( $connection && $connection =~ /Keep-Alive/i ) {
+                unless ( $persistent ) {
                     $select->remove($client);
                     $client->close;
                 }