Http.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. namespace App\Common\Protocols;
  3. /**
  4. * http 协议解析 相关
  5. * @author walkor <worker-man@qq.com>
  6. * */
  7. class Http
  8. {
  9. /**
  10. * 构造函数
  11. */
  12. private function __construct(){}
  13. /**
  14. * http头
  15. * @var array
  16. */
  17. public static $header = array();
  18. /**
  19. * cookie
  20. * @var array
  21. */
  22. protected static $cookie = array();
  23. /**
  24. * 判断数据包是否全部接收完成
  25. *
  26. * @param string $data
  27. * @return int 0:完成 1:还要接收数据
  28. */
  29. public static function input($data)
  30. {
  31. // 查找\r\n\r\n
  32. $data_length = strlen($data);
  33. if(!strpos($data, "\r\n\r\n"))
  34. {
  35. return 1;
  36. }
  37. // POST请求还要读包体
  38. if(strpos($data, "POST"))
  39. {
  40. // 找Content-Length
  41. $match = array();
  42. if(preg_match("/\r\nContent-Length: ?(\d?)\r\n/", $data, $match))
  43. {
  44. $content_lenght = $match[1];
  45. }
  46. else
  47. {
  48. return 0;
  49. }
  50. // 看包体长度是否符合
  51. $tmp = explode("\r\n\r\n", $data);
  52. if(strlen($tmp[1]) >= $content_lenght)
  53. {
  54. return 0;
  55. }
  56. return 1;
  57. }
  58. else
  59. {
  60. return 0;
  61. }
  62. // var_export($header_data);
  63. return 0;
  64. }
  65. /**
  66. * 解析http协议包,并设置相应环境变量
  67. *
  68. * @param string $data
  69. * @return array
  70. */
  71. public static function decode($data)
  72. {
  73. $_SERVER = array(
  74. 'REQUEST_URI' => '/',
  75. 'HTTP_HOST' => '127.0.0.1',
  76. 'HTTP_COOKIE' => '',
  77. );
  78. $_POST = $_GET = $_COOKIE = $REQUEST = $GLOBALS['HTTP_RAW_POST_DATA'] = array();
  79. // 将header分割成数组
  80. $header_data = explode("\r\n", $data);
  81. // 需要解析$_POST
  82. if(strpos($data, "POST") === 0)
  83. {
  84. $tmp = explode("\r\n\r\n", $data);
  85. parse_str($tmp[1], $_POST);
  86. // $GLOBALS['HTTP_RAW_POST_DATA']
  87. $GLOBALS['HTTP_RAW_POST_DATA'] = $tmp[1];
  88. }
  89. // REQUEST_URI
  90. $tmp = explode(' ', $header_data[0]);
  91. $_SERVER['REQUEST_URI'] = isset($tmp[1]) ? $tmp[1] : '/';
  92. // PHP_SELF
  93. $base_name = basename($_SERVER['REQUEST_URI']);
  94. $_SERVER['PHP_SELF'] = empty($base_name) ? 'index.php' : $base_name;
  95. unset($header_data[0]);
  96. foreach($header_data as $content)
  97. {
  98. // 解析HTTP_HOST
  99. if(strpos($content, 'Host') === 0)
  100. {
  101. $tmp = explode(':', $content);
  102. if(isset($tmp[1]))
  103. {
  104. $_SERVER['HTTP_HOST'] = $tmp[1];
  105. }
  106. if(isset($tmp[2]))
  107. {
  108. $_SERVER['SERVER_PORT'] = $tmp[2];
  109. }
  110. }
  111. // 解析Cookie
  112. elseif(strpos($content, 'Cookie') === 0)
  113. {
  114. $tmp = explode(' ', $content);
  115. if(isset($tmp[1]))
  116. {
  117. $_SERVER['HTTP_COOKIE'] = $tmp[1];
  118. }
  119. if($_SERVER['HTTP_COOKIE'])
  120. {
  121. parse_str(str_replace('; ', '&', $_SERVER['HTTP_COOKIE']), $_COOKIE);
  122. }
  123. }
  124. }
  125. // 'REQUEST_TIME_FLOAT' => 1375774613.237,
  126. $_SERVER['REQUEST_TIME_FLOAT'] = microtime(true);
  127. $_SERVER['REQUEST_TIME'] = intval($_SERVER['REQUEST_TIME_FLOAT']);
  128. // GET
  129. parse_str(preg_replace('/^\/.*?\?/', '', $_SERVER['REQUEST_URI']), $_GET);
  130. unset($_GET['/']);
  131. }
  132. /**
  133. * 设置http头
  134. * @return bool
  135. */
  136. public static function header($content)
  137. {
  138. if(strpos($content, 'HTTP') === 0)
  139. {
  140. $key = 'Http-Code';
  141. }
  142. else
  143. {
  144. $key = strstr($content, ":", true);
  145. if(empty($key))
  146. {
  147. return false;
  148. }
  149. }
  150. self::$header[$key] = $content;
  151. return true;
  152. }
  153. /**
  154. * Set the cookie
  155. * @param string $name Name of cookie
  156. * @param string $value Value
  157. * @param integer $maxage . Optional. Max-Age. Default is 0.
  158. * @param string $path . Optional. Path. Default is empty string.
  159. * @param bool|string $domain . Optional. Secure. Default is false.
  160. * @param boolean $secure . Optional. HTTPOnly. Default is false.
  161. * @param bool $HTTPOnly
  162. * @return void
  163. */
  164. public static function setcookie($name, $value = '', $maxage = 0, $path = '', $domain = '', $secure = false, $HTTPOnly = false) {
  165. self::header(
  166. 'Set-Cookie: ' . $name . '=' . rawurlencode($value)
  167. . (empty($domain) ? '' : '; Domain=' . $domain)
  168. . (empty($maxage) ? '' : '; Max-Age=' . $maxage)
  169. . (empty($path) ? '' : '; Path=' . $path)
  170. . (!$secure ? '' : '; Secure')
  171. . (!$HTTPOnly ? '' : '; HttpOnly'), false);
  172. }
  173. /**
  174. * 清除header
  175. * @return void
  176. */
  177. public static function clear()
  178. {
  179. self::$header = array();
  180. }
  181. /**
  182. * 打包http协议,用于返回数据
  183. *
  184. * @param string $data
  185. * @return string
  186. */
  187. public static function encode($data)
  188. {
  189. // header
  190. $header = "Server: WorkerMan/1.0\r\nContent-Length: ".strlen($data)."\r\n";
  191. // 没有Content-Type默认给个
  192. if(!isset(self::$header['Content-Type']))
  193. {
  194. $header = "Content-Type: text/html;charset=utf-8\r\n".$header;
  195. }
  196. // 没有http-code默认给个
  197. if(!isset(self::$header['Http-Code']))
  198. {
  199. $header = "HTTP/1.1 200 OK\r\n".$header;
  200. }
  201. else
  202. {
  203. $header = self::$header['Http-Code']."\r\n".$header;
  204. unset(self::$header['Http-Code']);
  205. }
  206. // 其它header
  207. foreach(self::$header as $content)
  208. {
  209. $header .= $content."\r\n";
  210. }
  211. $header .= "\r\n";
  212. self::clear();
  213. // 整个http包
  214. return $header.$data;
  215. }
  216. }