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 |