PHP-CLI Web 服务器

WBOY
Freigeben: 2016-07-25 08:47:37
Original
1190 Leute haben es durchsucht
需要 pthreads 扩展
php 命令行模式运行

写的比较急,没时间优化,有时间我会抽空优化一下

来自源地址: 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, "\r\n\r\n") !== 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("\r\n", $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("\r\n", $headers) . "\r\n",
  99. 'html'=> $html);
  100. socket_write($connfd, implode("\r\n", $response));
  101. if($availableRequests socket_close($connfd);
  102. $session = 0;
  103. }
  104. $length = strlen($html);
  105. socket_getpeername($connfd, $address, $port);
  106. logs(sprintf('%s:%.0f -- "%s %s %s" %s %.0f "-" "%s"',
  107. $address,
  108. $port,
  109. $http_request_method,
  110. '/'.$http_request_file,
  111. $http_protocol,
  112. $code,
  113. $length,
  114. $http_user_agent));
  115. //logs('times '. intval($clients - 1), false);
  116. }
  117. }
  118. }
  119. public function error_page($statusCode, $ServerTokens) {
  120. $httpStatus = array('403'=> '403 Forbidden', '404'=> '404 Not Found');
  121. $string = "
  122. %s
  123. %s


  124. %s
  125. ";
  126. if(!in_array($ServerTokens, array('on', 'off')))
  127. $ServerTokens = 'off';
  128. return (string) sprintf($string,
  129. $httpStatus[$statusCode],
  130. $httpStatus[$statusCode],
  131. $ServerTokens == 'off' ? 'PHP-CLI/1.0' : 'PHP-CLI');
  132. }
  133. public function HttpStatusCode($file, &$headers, &$html, &$code) {
  134. $code = '200';
  135. if(!file_exists($file)) {
  136. $headers[0] = 'HTTP/1.1 404 Not Found';
  137. $html = $this->error_page('404', $this->arguments['ServerTokens']);
  138. $code = '404';
  139. return 0;
  140. }
  141. if(is_dir($file)){
  142. $find = false;
  143. $directoryIndex = $this->arguments['DirectoryIndex'];
  144. if(empty($directoryIndex)) {
  145. $headers[0] = 'HTTP/1.1 403 Forbidden';
  146. $code = '403';
  147. }else{
  148. $list = explode(' ', $directoryIndex);
  149. foreach($list as $index) {
  150. if(file_exists($file .'/'. $index)) {
  151. $file .= '/'. $index;
  152. if(file_exists($file) && is_file($file))
  153. $extension = pathinfo($file, PATHINFO_EXTENSION);
  154. $array_key_exists = array_key_exists($extension, $this->arguments['MimeTypes']);
  155. if($array_key_exists) {
  156. $mime_types = $this->arguments['MimeTypes'][$extension];
  157. }else{
  158. $this->otect_stream = true;
  159. $headers[3] = sprintf('Content-Type: application/octet-stream');
  160. array_push($headers, 'Accept-Ranges: bytes');
  161. array_push($headers, 'Accept-Length: '.filesize($local_request_file));
  162. array_push($headers, 'Content-Disposition: attachment; filename='.basename($local_request_file));
  163. }
  164. $find = true;
  165. break;
  166. }
  167. }
  168. }
  169. if(!$find) {
  170. $html = $this->error_page('403', $this->arguments['ServerTokens']);
  171. }else{
  172. if(!$this->octet_stream)
  173. $headers[3] = sprintf('Content-Type: %s; charset=%s', $mime_types, 'utf-8');
  174. $html = $this->get_local_handle_buffer($file);
  175. }
  176. return -1;
  177. }else{
  178. $html = $this->get_local_handle_buffer($file);
  179. }
  180. return 1;
  181. }
  182. public function get_local_handle_buffer($file) {
  183. $handle = fopen($file, 'rb');
  184. return $this->get_buffer($handle);
  185. }
  186. public function get_buffer($handle) {
  187. $buffer = '';
  188. if(!is_resource($handle)) return null;
  189. while(!feof($handle))
  190. $buffer .= fgets($handle, 1024);
  191. fclose($handle);
  192. return $buffer;
  193. }
  194. }
  195. function gmtdate() {
  196. return (string) date('D, d M Y H:i:s'). ' GMT';
  197. }
  198. function logs($string, $perfix = true) {
  199. ob_start();
  200. echo $perfix ?
  201. sprintf("[ %s ] %s\n", date('d-M-Y H:i:s'), $string) :
  202. sprintf("\0\0[ %s ]\n", $string);
  203. ob_end_flush();
  204. }
  205. $mime_types = array(
  206. 'htm'=> 'text/html',
  207. 'html'=> 'text/html',
  208. 'jpg'=> 'image/jpeg',
  209. 'jpeg'=> 'image/jpeg',
  210. 'png'=> 'image/png',
  211. 'js'=> 'text/javascript',
  212. 'css'=> 'text/css',
  213. 'xml'=> 'text/xml');
  214. $conf = array(
  215. 'MimeTypes'=> $mime_types,
  216. 'ServerTokens'=> 'on',
  217. 'MaxRequests'=> 100,
  218. 'Timeout'=> 15,
  219. 'Listen'=> 8080,
  220. 'DocumentRoot'=> '/home/www',
  221. 'DirectoryIndex'=> 'index.htm index.html');
  222. error_reporting(E_ALL);
  223. logs('Initializing the operating environment');
  224. sleep(1);
  225. set_time_limit(0);
  226. logs('Initializing PHP-CLI execution timeout');
  227. sleep(1);
  228. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  229. logs('Initializing the socket');
  230. sleep(1);
  231. logs('Initialization bind local address any ip address');
  232. sleep(1);
  233. $int = socket_bind($socket, '0.0.0.0', $conf['Listen']);
  234. logs('Initialization bind local port '.$conf['Listen']);
  235. if(!$int){
  236. logs($conf['Listen'].' Port is occupied by other services'."\n");
  237. exit(0);
  238. }
  239. sleep(1);
  240. socket_listen($socket, 1024);
  241. logs('Opening a socket listening');
  242. sleep(1);
  243. logs('Waiting for clients to access');
  244. echo "\n";
  245. $i = 0;
  246. while(1) {
  247. $pthread[$i] = new pthread($socket, $conf);
  248. $pthread[$i]->start();
  249. $pthread[$i]->join();
  250. }
复制代码


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage