Http.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. namespace App\Common\Protocols;
  3. /**
  4. * 判断http协议的数据包是否完整
  5. * @param string $http_string
  6. * @return integer 0表示完整 否则还需要integer长度的数据
  7. */
  8. function http_input($http_string)
  9. {
  10. // 查找\r\n\r\n
  11. $data_length = strlen($http_string);
  12. if(!strpos($http_string, "\r\n\r\n"))
  13. {
  14. return 1;
  15. }
  16. // POST请求还要读包体
  17. if(strpos($http_string, "POST"))
  18. {
  19. // 找Content-Length
  20. $match = array();
  21. if(preg_match("/\r\nContent-Length: ?(\d?)\r\n/", $http_string, $match))
  22. {
  23. $content_lenght = $match[1];
  24. }
  25. else
  26. {
  27. return 0;
  28. }
  29. // 看包体长度是否符合
  30. $tmp = explode("\r\n\r\n", $http_string);
  31. $remain_length = $content_lenght - strlen($tmp[1]);
  32. return $remain_length >= 0 ? $remain_length : 0;
  33. }
  34. return 0;
  35. }
  36. /**
  37. * 解析http协议,设置$_POST $_GET $_COOKIE $_REQUEST
  38. * @param string $http_string
  39. */
  40. function http_start($http_string)
  41. {
  42. $_POST = $_GET = $_COOKIE = $_REQUEST = $_SESSION = array();
  43. $GLOBALS['HTTP_RAW_POST_DATA'] = '';
  44. HttpCache::$header = array();
  45. HttpCache::$instance = new HttpCache();
  46. $_SERVER = array(
  47. 'REQUEST_URI' => '/',
  48. 'HTTP_HOST' => '127.0.0.1',
  49. 'HTTP_COOKIE' => '',
  50. );
  51. // 将header分割成数组
  52. $header_data = explode("\r\n", $http_string);
  53. // 需要解析$_POST
  54. if(strpos($http_string, "POST") === 0)
  55. {
  56. $tmp = explode("\r\n\r\n", $http_string);
  57. parse_str($tmp[1], $_POST);
  58. // $GLOBALS['HTTP_RAW_POST_DATA']
  59. $GLOBALS['HTTP_RAW_POST_DATA'] = $tmp[1];
  60. }
  61. // REQUEST_URI
  62. $tmp = explode(' ', $header_data[0]);
  63. $_SERVER['REQUEST_URI'] = isset($tmp[1]) ? $tmp[1] : '/';
  64. // PHP_SELF
  65. $base_name = basename($_SERVER['REQUEST_URI']);
  66. $_SERVER['PHP_SELF'] = empty($base_name) ? 'index.php' : $base_name;
  67. unset($header_data[0]);
  68. foreach($header_data as $content)
  69. {
  70. // 解析HTTP_HOST
  71. if(strpos($content, 'Host') === 0)
  72. {
  73. $tmp = explode(':', $content);
  74. if(isset($tmp[1]))
  75. {
  76. $_SERVER['HTTP_HOST'] = $tmp[1];
  77. }
  78. if(isset($tmp[2]))
  79. {
  80. $_SERVER['SERVER_PORT'] = $tmp[2];
  81. }
  82. }
  83. // 解析Cookie
  84. elseif(stripos($content, 'Cookie') === 0)
  85. {
  86. $_SERVER['HTTP_COOKIE'] = trim(substr($content, strlen('Cookie:')));
  87. if($_SERVER['HTTP_COOKIE'])
  88. {
  89. parse_str(str_replace('; ', '&', $_SERVER['HTTP_COOKIE']), $_COOKIE);
  90. }
  91. }
  92. }
  93. // 'REQUEST_TIME_FLOAT' => 1375774613.237,
  94. $_SERVER['REQUEST_TIME_FLOAT'] = microtime(true);
  95. $_SERVER['REQUEST_TIME'] = intval($_SERVER['REQUEST_TIME_FLOAT']);
  96. // GET
  97. parse_str(preg_replace('/^\/.*?\?/', '', $_SERVER['REQUEST_URI']), $_GET);
  98. unset($_GET['/']);
  99. $_REQUEST = array_merge($_GET, $_POST);
  100. }
  101. function http_end($content)
  102. {
  103. // 没有http-code默认给个
  104. if(!isset(HttpCache::$header['Http-Code']))
  105. {
  106. $header = "HTTP/1.1 200 OK\r\n";
  107. }
  108. else
  109. {
  110. $header = HttpCache::$header['Http-Code']."\r\n";
  111. unset(HttpCache::$header['Http-Code']);
  112. }
  113. // 没有Content-Type默认给个
  114. if(!isset(HttpCache::$header['Content-Type']))
  115. {
  116. $header .= "Content-Type: text/html;charset=utf-8\r\n";
  117. }
  118. // 其它header
  119. foreach(HttpCache::$header as $item)
  120. {
  121. $header .= $item."\r\n";
  122. }
  123. // header
  124. $header .= "Server: WorkerMan/2.1\r\nContent-Length: ".strlen($content)."\r\n";
  125. $header .= "\r\n";
  126. HttpCache::$header = array();
  127. // 保存cookie
  128. session_write_close();
  129. $_POST = $_GET = $_COOKIE = $_REQUEST = $_SESSION = array();
  130. $GLOBALS['HTTP_RAW_POST_DATA'] = '';
  131. HttpCache::$instance = null;
  132. // 整个http包
  133. return $header.$content;
  134. }
  135. /**
  136. * 设置http头
  137. * @return bool
  138. */
  139. function header($content)
  140. {
  141. if(strpos($content, 'HTTP') === 0)
  142. {
  143. $key = 'Http-Code';
  144. }
  145. else
  146. {
  147. $key = strstr($content, ":", true);
  148. if(empty($key))
  149. {
  150. return false;
  151. }
  152. }
  153. HttpCache::$header[$key] = $content;
  154. if('location' == strtolower($key))
  155. {
  156. header("HTTP/1.1 302 Moved Temporarily");
  157. }
  158. return true;
  159. }
  160. /**
  161. * 设置cookie
  162. * @param string $name
  163. * @param string $value
  164. * @param integer $maxage
  165. * @param string $path
  166. * @param string $domain
  167. * @param bool $secure
  168. * @param bool $HTTPOnly
  169. */
  170. function setcookie($name, $value = '', $maxage = 0, $path = '', $domain = '', $secure = false, $HTTPOnly = false) {
  171. header(
  172. 'Set-Cookie: ' . $name . '=' . rawurlencode($value)
  173. . (empty($domain) ? '' : '; Domain=' . $domain)
  174. . (empty($maxage) ? '' : '; Max-Age=' . $maxage)
  175. . (empty($path) ? '' : '; Path=' . $path)
  176. . (!$secure ? '' : '; Secure')
  177. . (!$HTTPOnly ? '' : '; HttpOnly'), false);
  178. }
  179. /**
  180. * session_start
  181. *
  182. */
  183. function session_start()
  184. {
  185. if(HttpCache::$instance->sessionStarted)
  186. {
  187. echo "already sessionStarted\nn";
  188. return true;
  189. }
  190. HttpCache::$instance->sessionStarted = true;
  191. // 没有sid,则创建一个session文件,生成一个sid
  192. if(!isset($_COOKIE[HttpCache::$sessionName]) || !is_file(HttpCache::$sessionPath . '/sess_' . $_COOKIE[HttpCache::$sessionName]))
  193. {
  194. $file_name = tempnam(HttpCache::$sessionPath, 'sess_');
  195. if(!$file_name)
  196. {
  197. return false;
  198. }
  199. HttpCache::$instance->sessionFile = $file_name;
  200. $session_id = substr(basename($file_name), strlen('sess_'));
  201. return setcookie(
  202. HttpCache::$sessionName
  203. , $session_id
  204. , ini_get('session.cookie_lifetime')
  205. , ini_get('session.cookie_path')
  206. , ini_get('session.cookie_domain')
  207. , ini_get('session.cookie_secure')
  208. , ini_get('session.cookie_httponly')
  209. );
  210. }
  211. if(!HttpCache::$instance->sessionFile)
  212. {
  213. HttpCache::$instance->sessionFile = HttpCache::$sessionPath . '/sess_' . $_COOKIE[HttpCache::$sessionName];
  214. }
  215. // 有sid则打开文件,读取session值
  216. if(HttpCache::$instance->sessionFile)
  217. {
  218. $raw = file_get_contents(HttpCache::$instance->sessionFile);
  219. if($raw)
  220. {
  221. session_decode($raw);
  222. }
  223. }
  224. }
  225. /**
  226. * 保存session
  227. */
  228. function session_write_close()
  229. {
  230. if(HttpCache::$instance->sessionStarted && !empty($_SESSION))
  231. {
  232. $session_str = session_encode();
  233. if($session_str && HttpCache::$instance->sessionFile)
  234. {
  235. return file_put_contents(HttpCache::$instance->sessionFile, $session_str);
  236. }
  237. }
  238. return empty($_SESSION);
  239. }
  240. function jump_exit()
  241. {
  242. throw new \Exception('jump_exit');
  243. }
  244. /**
  245. * 解析http协议数据包 缓存先关
  246. * @author walkor
  247. */
  248. class HttpCache
  249. {
  250. public static $instance = null;
  251. public static $header = array();
  252. public static $sessionPath = '';
  253. public static $sessionName = '';
  254. public $sessionStarted = false;
  255. public $sessionFile = '';
  256. public static function init()
  257. {
  258. self::$sessionName = ini_get('session.name');
  259. self::$sessionPath = session_save_path();
  260. if(!self::$sessionPath)
  261. {
  262. self::$sessionPath = sys_get_temp_dir();
  263. }
  264. @\session_start();
  265. }
  266. }