Changeset 1c2d107ca45fd019c7ef543e43e97ecabe5698f7

Show
Ignore:
Timestamp:
06/26/07 14:36:01 (7 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1182868561 +0000
git-parent:

[83e87ae54d050ecbfa3d34da8e727c259c3618da]

git-author:
Theo Schlossnagle <jesus@omniti.com> 1182868561 +0000
Message:

redo this to obey correct keep-alive semantics

git-svn-id: https://labs.omniti.com/resmon/trunk@42 8c0face9-b7db-6ec6-c4b3-d5f7145c7d55

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • lib/Resmon/Status.pm

    r5c504ea r1c2d107  
    1212 
    1313my $SEGSIZE = 1024*256; 
     14my $KEEPALIVE_TIMEOUT = 5; 
     15my $REQUEST_TIMEOUT = 60; 
    1416sub new { 
    1517  my $class = shift; 
     
    107109sub service { 
    108110  my $self = shift; 
    109   my ($client, $req, $proto) = @_; 
     111  my ($client, $req, $proto, $snip) = @_; 
    110112  my $state = $self->get_shared_state(); 
    111113  if($req eq '/' or $req eq '/status') { 
    112114    my $response .= $self->dump_xml(); 
    113     $client->print(http_header(200, $proto?length($response):0)); 
     115    $client->print(http_header(200, length($response), 'text/xml', $snip)); 
    114116    $client->print($response . "\r\n"); 
    115117    return; 
    116118  } elsif($req eq '/status.txt') { 
    117119    my $response = $self->dump_oldstyle(); 
    118     $client->print(http_header(200, $proto?length($response):0, 'text/plain')); 
     120    $client->print(http_header(200, length($response), 'text/plain', $snip)); 
    119121    $client->print($response . "\r\n"); 
    120122    return; 
     
    128130                     xml_info($1,$2,$info). 
    129131                     "</ResmonRestults>\n"; 
    130         $client->print(http_header(200, $proto?length($response):0)); 
     132        $client->print(http_header(200, length($response), 'text/xml', $snip)); 
    131133        $client->print( $response . "\r\n"); 
    132134        return; 
     
    140142  my $len = shift; 
    141143  my $type = shift || 'text/xml'; 
     144  my $close_connection = shift || 1; 
    142145  return qq^HTTP/1.0 $code OK 
    143146Server: resmon 
    144 ^ . (defined($len) ? "Content-length: $len" : "Connection: close") . q^ 
    145 Content-Type: text/plain; charset=utf-8 
     147^ . (defined($len) ? "Content-length: $len\n" : "") . 
     148    (($close_connection || !$len) ? "Connection: close\n" : "") . 
     149qq^Content-Type: $type; charset=utf-8 
    146150 
    147151^; 
     
    180184        my $req; 
    181185        my $proto; 
    182         while(<$client>) { 
    183           eval { 
    184             s/\r\n/\n/g; 
    185             chomp; 
    186             if(!$req) { 
    187               if(/^GET \s*(\S+)\s*?(?: HTTP\/(0\.9|1\.0|1\.1)\s*)?$/) { 
    188                 $req = $1; 
    189                 $proto = $2; 
     186        my $close_connection; 
     187        local $SIG{ALRM} = sub { die "timeout\n" }; 
     188        eval { 
     189          alarm($KEEPALIVE_TIMEOUT); 
     190          while(<$client>) { 
     191            alarm($REQUEST_TIMEOUT); 
     192            eval { 
     193              s/\r\n/\n/g; 
     194              chomp; 
     195              if(!$req) { 
     196                if(/^GET \s*(\S+)\s*?(?: HTTP\/(0\.9|1\.0|1\.1)\s*)?$/) { 
     197                  $req = $1; 
     198                  $proto = $2; 
     199                  # Protocol 1.1 and high are keep-alive by default 
     200                  $close_connection = ($proto <= 1.0)?1:0; 
     201                } 
     202                elsif(/./) { 
     203                  die "protocol deviations.\n"; 
     204                } 
    190205              } 
    191206              else { 
    192                 die "protocol deviations.\n"; 
     207                if(/^$/) { 
     208                  $self->service($client, $req, $proto, $close_connection); 
     209                  last if ($close_connection); 
     210                  alarm($KEEPALIVE_TIMEOUT); 
     211                  $req = undef; 
     212                  $proto = undef; 
     213                } 
     214                elsif(/^\S+\s*:\s*.{1,4096}$/) { 
     215                  # Valid request header... noop 
     216                  if(/^Connection: (\S+)/) { 
     217                    if(($proto <= 1.0 && lc($2) eq 'keep-alive') || 
     218                       ($proto == 1.1 && lc($2) ne 'close')) { 
     219                      $close_connection = 0; 
     220                    } 
     221                  } 
     222                } 
     223                else { 
     224                  die "protocol deviations.\n"; 
     225                } 
    193226              } 
     227            }; 
     228            if($@) { 
     229              print $client http_header(500, 0, 'text/plain', 1); 
     230              print $client "$@\r\n"; 
     231              last; 
    194232            } 
    195             elsif(/^$/) { 
    196               $self->service($client, $req, $proto); 
    197               last unless ($proto); 
    198               $req = undef; 
    199               $proto = undef; 
    200             } 
    201             elsif(/^\S+\s*:\s*.{1,4096}$/) { 
    202               # Valid request header... noop 
    203             } 
    204             else { 
    205               die "protocol deviations.\n"; 
    206             } 
    207           }; 
    208           if($@) { 
    209             print $client http_header(500, 0, 'text/plain'); 
    210             print $client "$@\r\n"; 
    211             last; 
    212233          } 
    213         } 
     234        }; 
    214235        $client->close(); 
    215236      }