webserver.php
changeset 26 300d374d89b0
parent 24 d275dc8f4203
child 29 8210fdc7c317
child 32 86140ed9087d
equal deleted inserted replaced
24:d275dc8f4203 26:300d374d89b0
    19  */
    19  */
    20 
    20 
    21 define('HTTPD_VERSION', '0.1b1');
    21 define('HTTPD_VERSION', '0.1b1');
    22 
    22 
    23 /**
    23 /**
       
    24  * Length of keep-alive connections
       
    25  * @const int
       
    26  */
       
    27 
       
    28 define('HTTPD_KEEP_ALIVE_TIMEOUT', 300);
       
    29 
       
    30 /**
    24  * Webserver system icons
    31  * Webserver system icons
    25  */
    32  */
    26 
    33 
    27 define('HTTPD_ICON_SCRIPT', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGSSURBVCjPVVFNSwJhEF78Ad79Cf6PvXQRsotUlzKICosuRYmR2RJR0KE6lBFFZVEbpFBSqKu2rum6llFS9HHI4iUhT153n6ZtIWMOM+/MM88z7wwH7s9Ub16SJcnbmrNcxVm2q7Z8/QPvEOtntpj92NkCqITLepEpjix7xQtiLOoQ2b6+E7YAN/5nfOEJ2WbKqOIOJ4bYVMEQx4LfBBQDsvFMhUcCVU1/CxVXmDBGA5ZETrhDCQVcYAPbyEJBhvrnBVPiSpNr6cYDNCQwo4zzU/ySckkgDYuNuVpI42T9k4gLKGMPs/xPzzovQiY2hQYe0jlJfyNNhTqiWDYBq/wBMcSRpnyPzu1oS7WtxjVBSthU1vgVksiQ3Dn6Gp5ah2YOKQo5GiuHPA6xT1EKpxQNCNYejgIR457KKio0S56YckjSa9jo//3mrj+BV0QQagqGTOo+Y7gZIf1puP3WHoLhEb2PjTlCTCWGXtbp8DCX3hZuOdaIc9A+aQvWk4ihq95p67a7nP+u+Ws+r0dql9z/zv0NCYhdCPKZ7oYAAAAASUVORK5CYII=');
    34 define('HTTPD_ICON_SCRIPT', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGSSURBVCjPVVFNSwJhEF78Ad79Cf6PvXQRsotUlzKICosuRYmR2RJR0KE6lBFFZVEbpFBSqKu2rum6llFS9HHI4iUhT153n6ZtIWMOM+/MM88z7wwH7s9Ub16SJcnbmrNcxVm2q7Z8/QPvEOtntpj92NkCqITLepEpjix7xQtiLOoQ2b6+E7YAN/5nfOEJ2WbKqOIOJ4bYVMEQx4LfBBQDsvFMhUcCVU1/CxVXmDBGA5ZETrhDCQVcYAPbyEJBhvrnBVPiSpNr6cYDNCQwo4zzU/ySckkgDYuNuVpI42T9k4gLKGMPs/xPzzovQiY2hQYe0jlJfyNNhTqiWDYBq/wBMcSRpnyPzu1oS7WtxjVBSthU1vgVksiQ3Dn6Gp5ah2YOKQo5GiuHPA6xT1EKpxQNCNYejgIR457KKio0S56YckjSa9jo//3mrj+BV0QQagqGTOo+Y7gZIf1puP3WHoLhEb2PjTlCTCWGXtbp8DCX3hZuOdaIc9A+aQvWk4ihq95p67a7nP+u+Ws+r0dql9z/zv0NCYhdCPKZ7oYAAAAASUVORK5CYII=');
    28 define('HTTPD_ICON_FOLDER', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGrSURBVDjLxZO7ihRBFIa/6u0ZW7GHBUV0UQQTZzd3QdhMQxOfwMRXEANBMNQX0MzAzFAwEzHwARbNFDdwEd31Mj3X7a6uOr9BtzNjYjKBJ6nicP7v3KqcJFaxhBVtZUAK8OHlld2st7Xl3DJPVONP+zEUV4HqL5UDYHr5xvuQAjgl/Qs7TzvOOVAjxjlC+ePSwe6DfbVegLVuT4r14eTr6zvA8xSAoBLzx6pvj4l+DZIezuVkG9fY2H7YRQIMZIBwycmzH1/s3F8AapfIPNF3kQk7+kw9PWBy+IZOdg5Ug3mkAATy/t0usovzGeCUWTjCz0B+Sj0ekfdvkZ3abBv+U4GaCtJ1iEm6ANQJ6fEzrG/engcKw/wXQvEKxSEKQxRGKE7Izt+DSiwBJMUSm71rguMYhQKrBygOIRStf4TiFFRBvbRGKiQLWP29yRSHKBTtfdBmHs0BUpgvtgF4yRFR+NUKi0XZcYjCeCG2smkzLAHkbRBmP0/Uk26O5YnUActBp1GsAI+S5nRJJJal5K1aAMrq0d6Tm9uI6zjyf75dAe6tx/SsWeD//o2/Ab6IH3/h25pOAAAAAElFTkSuQmCC');
    35 define('HTTPD_ICON_FOLDER', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGrSURBVDjLxZO7ihRBFIa/6u0ZW7GHBUV0UQQTZzd3QdhMQxOfwMRXEANBMNQX0MzAzFAwEzHwARbNFDdwEd31Mj3X7a6uOr9BtzNjYjKBJ6nicP7v3KqcJFaxhBVtZUAK8OHlld2st7Xl3DJPVONP+zEUV4HqL5UDYHr5xvuQAjgl/Qs7TzvOOVAjxjlC+ePSwe6DfbVegLVuT4r14eTr6zvA8xSAoBLzx6pvj4l+DZIezuVkG9fY2H7YRQIMZIBwycmzH1/s3F8AapfIPNF3kQk7+kw9PWBy+IZOdg5Ug3mkAATy/t0usovzGeCUWTjCz0B+Sj0ekfdvkZ3abBv+U4GaCtJ1iEm6ANQJ6fEzrG/engcKw/wXQvEKxSEKQxRGKE7Izt+DSiwBJMUSm71rguMYhQKrBygOIRStf4TiFFRBvbRGKiQLWP29yRSHKBTtfdBmHs0BUpgvtgF4yRFR+NUKi0XZcYjCeCG2smkzLAHkbRBmP0/Uk26O5YnUActBp1GsAI+S5nRJJJal5K1aAMrq0d6Tm9uI6zjyf75dAe6tx/SsWeD//o2/Ab6IH3/h25pOAAAAAElFTkSuQmCC');
   346       $this->in_scriptlet = false;
   353       $this->in_scriptlet = false;
   347       
   354       
   348       // read request
   355       // read request
   349       $last_line = '';
   356       $last_line = '';
   350       $client_headers = '';
   357       $client_headers = '';
   351       while ( $line = @socket_read($remote, 1024, PHP_NORMAL_READ) )
   358       if ( defined('HTTPD_WS_CHILD') )
   352       {
   359       {
   353         $line = str_replace("\r", "", $line);
   360         if ( !@socket_set_timeout($remote, HTTPD_KEEP_ALIVE_TIMEOUT) )
   354         if ( empty($line) )
   361         {
   355           continue;
   362           status('stream_set_timeout() on $remote failed.');
   356         if ( $line == "\n" && $last_line == "\n" )
   363           var_dump($remote);
   357           break;
   364         }
   358         $client_headers .= $line;
   365       }
   359         $last_line = $line;
   366       if ( $line = @socket_read($remote, 1024, PHP_NORMAL_READ) )
       
   367       {
       
   368         do
       
   369         {
       
   370           $line = str_replace("\r", "", $line);
       
   371           if ( empty($line) )
       
   372             continue;
       
   373           if ( $line == "\n" && $last_line == "\n" )
       
   374             break;
       
   375           $client_headers .= $line;
       
   376           $last_line = $line;
       
   377         }
       
   378         while ( $line = @socket_read($remote, 1024, PHP_NORMAL_READ) );
       
   379       }
       
   380       else
       
   381       {
       
   382         if ( defined('HTTPD_WS_CHILD') )
       
   383         {
       
   384           $md = @socket_get_status($remote);
       
   385           if ( @$md['timed_out'] )
       
   386           {
       
   387             status('[debug] keep-alive connection timed out');
       
   388             continue; // will jump back to the start of the loop and kill the child process
       
   389           }
       
   390         }
   360       }
   391       }
   361       
   392       
   362       // parse request
   393       // parse request
   363       $client_headers = trim($client_headers);
   394       $client_headers = trim($client_headers);
   364       $client_headers = explode("\n", $client_headers);
   395       $client_headers = explode("\n", $client_headers);
   652       else if ( defined('HTTPD_WS_CHILD') )
   683       else if ( defined('HTTPD_WS_CHILD') )
   653       {
   684       {
   654         // if ( defined('HTTPD_WS_CHILD') )
   685         // if ( defined('HTTPD_WS_CHILD') )
   655         //   status('Continuing connection');
   686         //   status('Continuing connection');
   656         // @socket_write($remote, "\r\n\r\n");
   687         // @socket_write($remote, "\r\n\r\n");
       
   688         $last_finish_time = time();
   657       }
   689       }
   658       else
   690       else
   659       {
   691       {
   660         @socket_shutdown($remote);
   692         @socket_shutdown($remote);
   661         @socket_close($remote);
   693         @socket_close($remote);
  1113   function send_http_error($socket, $http_code, $errstring)
  1145   function send_http_error($socket, $http_code, $errstring)
  1114   {
  1146   {
  1115     global $http_responses;
  1147     global $http_responses;
  1116     $reason_code = ( isset($http_responses[$http_code]) ) ? $http_responses[$http_code] : 'Unknown';
  1148     $reason_code = ( isset($http_responses[$http_code]) ) ? $http_responses[$http_code] : 'Unknown';
  1117     
  1149     
  1118     // if we're in a scriptlet, include custom headers
  1150     // generate error page
  1119     if ( $this->in_scriptlet )
       
  1120       $headers = implode("\r\n", $this->response_headers);
       
  1121     else
       
  1122       $headers = '';
       
  1123       
       
  1124     $this->send_client_headers($socket, $http_code, 'text/html', $headers);
       
  1125     $html = <<<EOF
  1151     $html = <<<EOF
  1126 <html>
  1152 <html>
  1127   <head>
  1153   <head>
  1128     <title>$http_code $reason_code</title>
  1154     <title>$http_code $reason_code</title>
  1129   </head>
  1155   </head>
  1133     <hr />
  1159     <hr />
  1134     <address>Served by $this->server_string</address>
  1160     <address>Served by $this->server_string</address>
  1135   </body>
  1161   </body>
  1136 </html>
  1162 </html>
  1137 EOF;
  1163 EOF;
       
  1164     
       
  1165     // length of the response (required if we want keep-alive to work)
       
  1166     $this->header('Content-length: ' . strlen($html));
       
  1167     
       
  1168     // if we're in a scriptlet, include custom headers
       
  1169     if ( $this->in_scriptlet )
       
  1170       $headers = implode("\r\n", $this->response_headers);
       
  1171     else
       
  1172       $headers = 'Content-length: ' . strlen($html);
       
  1173       
       
  1174     $this->send_client_headers($socket, $http_code, 'text/html', $headers);
  1138     @socket_write($socket, $html);
  1175     @socket_write($socket, $html);
  1139   } 
  1176   } 
  1140   
  1177   
  1141   /**
  1178   /**
  1142    * Adds a new handler
  1179    * Adds a new handler