PHP-CLI web server

WBOY
Release: 2016-07-25 08:47:37
Original
1174 people have browsed it
Requires pthreads extension
php command line mode to run

I wrote it in a hurry and don’t have time to optimize it. I will take the time to optimize it when I have time

来自源地址: http://www.haowei.me/archives/1009.html
  1. ini_set('display_errors', false);
  2. error_reporting(0);
  3. if(!class_exists('thread')) {
  4. logs('PHP runtime environment not support multi thread');
  5. exit(0);
  6. }
  7. if(!function_exists('mime_content_type')) {
  8. logs('PHP runtime environment not support function mime_content_type()');
  9. exit(0);
  10. }
  11. class pthread extends thread {
  12. protected $socket = null;
  13. protected $arguments = null;
  14. protected $connections = 0;
  15. protected $octet_stream = false;
  16. public function __construct($socket, $arguments = array()) {
  17. $this->socket = $socket;
  18. $this->arguments = $arguments;
  19. if(!isset($this->arguments['ServerTokens']))
  20. $this->arguments['ServerTokens'] = 'off';
  21. }
  22. public function run() {
  23. date_default_timezone_set('UTC');
  24. $clients = 1;
  25. $maxRequests = !isset($this->arguments['MaxRequests'])?
  26. intval($this->arguments['MaxRequests']):
  27. 100;
  28. $timeout = 5;
  29. $connfd = socket_accept($this->socket);
  30. socket_set_option($connfd, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0));
  31. $session = 1;
  32. while($session) {
  33. $buffer = '';
  34. while (( $buffer .= socket_read($connfd, 1024, PHP_BINARY_READ) ))
  35. if(strpos($buffer, "rnrn") !== false) break;
  36. if($buffer == '') {
  37. socket_close($connfd);
  38. $session = 0;
  39. }else{
  40. $availableRequests = $maxRequests - $clients;
  41. $clients++;
  42. $i = 0;
  43. $headers = array();
  44. array_push($headers, 'HTTP/1.1 200 OK');
  45. array_push($headers, 'Date: '. gmtdate());
  46. array_push($headers, 'Server: PHP-CLI/1.0');
  47. array_push($headers, 'Content-Type: text/html; charset=utf-8');
  48. array_push($headers, 'Connection: close');
  49. if($this->arguments['ServerTokens'] == 'on')
  50. $headers[2] = 'Server: PHP-CLI';
  51. $buffer = explode("rn", $buffer);
  52. $http_user_agent = '';
  53. $http_request_method = '';
  54. $http_request_file = '';
  55. $http_protocol = '';
  56. $extension = '';
  57. $mime_types = '';
  58. $this->octet_stream = false;
  59. foreach($buffer as $line) {
  60. $pattern = '/(GET|POST)s/(.*)s(HTTP/1.[0-1])$/';
  61. if(preg_match($pattern, $line)) {
  62. $http_request_method = preg_replace($pattern, '\1', $line);
  63. $http_request_file = preg_replace($pattern, '\2', $line);
  64. $http_protocol = preg_replace($pattern, '\3', $line);
  65. }
  66. $pattern = '/^User-Agent: (.+)$/';
  67. if(preg_match($pattern, $line)) {
  68. $http_user_agent = preg_replace($pattern, '\1', $line);
  69. }
  70. }
  71. $local_request_file = $this->arguments['DocumentRoot'].'/'. $http_request_file;
  72. if(file_exists($local_request_file) && is_file($local_request_file))
  73. $extension = pathinfo($local_request_file, PATHINFO_EXTENSION);
  74. if(file_exists($local_request_file)) {
  75. $array_key_exists = array_key_exists($extension, $this->arguments['MimeTypes']);
  76. if(is_file($local_request_file)) {
  77. if($array_key_exists) {
  78. $mime_types = $this->arguments['MimeTypes'][$extension];
  79. $headers[3] = sprintf('Content-Type: %s; charset=%s', $mime_types, 'utf-8');
  80. }else{
  81. $this->octet_stream = true;
  82. $headers[3] = sprintf('Content-Type: application/octet-stream');
  83. array_push($headers, 'Accept-Ranges: bytes');
  84. array_push($headers, 'Accept-Length: '.filesize($local_request_file));
  85. array_push($headers, 'Content-Disposition: attachment; filename='.basename($local_request_file));
  86. }
  87. }
  88. }
  89. $html = '';
  90. $code = '';
  91. $this->HttpStatusCode($local_request_file, $headers, $html, $code);
  92. if($availableRequests > 0) {
  93. $headers[4] = "Connection: keep-alive";
  94. $headers[5] = 'Keep-Alive: timeout='.$timeout.', max='.$maxRequests;
  95. }
  96. $headers[6] = 'Content-Length: '. strlen($html);
  97. $response = array(
  98. 'header'=> implode("rn", $headers) . "rn",
  99. 'html'=> $html);
  100. socket_write($connfd, implode("rn", $response));
  101. if($availableRequests <= 0) {
  102. socket_close($connfd);
  103. $session = 0;
  104. }
  105. $length = strlen($html);
  106. socket_getpeername($connfd, $address, $port);
  107. logs(sprintf('%s:%.0f -- "%s %s %s" %s %.0f "-" "%s"',
  108. $address,
  109. $port,
  110. $http_request_method,
  111. '/'.$http_request_file,
  112. $http_protocol,
  113. $code,
  114. $length,
  115. $http_user_agent));
  116. //logs('times '. intval($clients - 1), false);
  117. }
  118. }
  119. }
  120. public function error_page($statusCode, $ServerTokens) {
  121. $httpStatus = array('403'=> '403 Forbidden', '404'=> '404 Not Found');
  122. $string = "
  123. %s
  124. %s


  125. %s
  126. ";
  127. if(!in_array($ServerTokens, array('on', 'off')))
  128. $ServerTokens = 'off';
  129. return (string) sprintf($string,
  130. $httpStatus[$statusCode],
  131. $httpStatus[$statusCode],
  132. $ServerTokens == 'off' ? 'PHP-CLI/1.0' : 'PHP-CLI');
  133. }
  134. public function HttpStatusCode($file, &$headers, &$html, &$code) {
  135. $code = '200';
  136. if(!file_exists($file)) {
  137. $headers[0] = 'HTTP/1.1 404 Not Found';
  138. $html = $this->error_page('404', $this->arguments['ServerTokens']);
  139. $code = '404';
  140. return 0;
  141. }
  142. if(is_dir($file)){
  143. $find = false;
  144. $directoryIndex = $this->arguments['DirectoryIndex'];
  145. if(empty($directoryIndex)) {
  146. $headers[0] = 'HTTP/1.1 403 Forbidden';
  147. $code = '403';
  148. }else{
  149. $list = explode(' ', $directoryIndex);
  150. foreach($list as $index) {
  151. if(file_exists($file .'/'. $index)) {
  152. $file .= '/'. $index;
  153. if(file_exists($file) && is_file($file))
  154. $extension = pathinfo($file, PATHINFO_EXTENSION);
  155. $array_key_exists = array_key_exists($extension, $this->arguments['MimeTypes']);
  156. if($array_key_exists) {
  157. $mime_types = $this->arguments['MimeTypes'][$extension];
  158. }else{
  159. $this->otect_stream = true;
  160. $headers[3] = sprintf('Content-Type: application/octet-stream');
  161. array_push($headers, 'Accept-Ranges: bytes');
  162. array_push($headers, 'Accept-Length: '.filesize($local_request_file));
  163. array_push($headers, 'Content-Disposition: attachment; filename='.basename($local_request_file));
  164. }
  165. $find = true;
  166. break;
  167. }
  168. }
  169. }
  170. if(!$find) {
  171. $html = $this->error_page('403', $this->arguments['ServerTokens']);
  172. }else{
  173. if(!$this->octet_stream)
  174. $headers[3] = sprintf('Content-Type: %s; charset=%s', $mime_types, 'utf-8');
  175. $html = $this->get_local_handle_buffer($file);
  176. }
  177. return -1;
  178. }else{
  179. $html = $this->get_local_handle_buffer($file);
  180. }
  181. return 1;
  182. }
  183. public function get_local_handle_buffer($file) {
  184. $handle = fopen($file, 'rb');
  185. return $this->get_buffer($handle);
  186. }
  187. public function get_buffer($handle) {
  188. $buffer = '';
  189. if(!is_resource($handle)) return null;
  190. while(!feof($handle))
  191. $buffer .= fgets($handle, 1024);
  192. fclose($handle);
  193. return $buffer;
  194. }
  195. }
  196. function gmtdate() {
  197. return (string) date('D, d M Y H:i:s'). ' GMT';
  198. }
  199. function logs($string, $perfix = true) {
  200. ob_start();
  201. echo $perfix ?
  202. sprintf("[ %s ] %sn", date('d-M-Y H:i:s'), $string) :
  203. sprintf("
Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template