FeieHttpClient.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. <?php
  2. namespace app\common\library\printer\party;
  3. /**
  4. * 飞鹅云打印机API类
  5. * Class FeieHttpClient
  6. * @package app\common\library\printer\party
  7. */
  8. class FeieHttpClient
  9. {
  10. // Request vars
  11. var $host;
  12. var $port;
  13. var $path;
  14. var $method;
  15. var $postdata = '';
  16. var $cookies = [];
  17. var $referer;
  18. var $accept = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,image/jpeg,image/gif,*/*';
  19. var $accept_encoding = 'gzip';
  20. var $accept_language = 'en-us';
  21. var $user_agent = 'Incutio HttpClient v0.9';
  22. var $timeout = 20;
  23. var $use_gzip = true;
  24. var $persist_cookies = true;
  25. var $persist_referers = true;
  26. var $debug = false;
  27. var $handle_redirects = true;
  28. var $max_redirects = 5;
  29. var $headers_only = false;
  30. var $username;
  31. var $password;
  32. var $status;
  33. var $headers = [];
  34. var $content = '';
  35. var $errormsg;
  36. var $redirect_count = 0;
  37. var $cookie_host = '';
  38. public function __construct($host, $port = 80)
  39. {
  40. $this->host = $host;
  41. $this->port = $port;
  42. }
  43. function get($path, $data = false)
  44. {
  45. $this->path = $path;
  46. $this->method = 'GET';
  47. if ($data) {
  48. $this->path .= '?' . $this->buildQueryString($data);
  49. }
  50. return $this->doRequest();
  51. }
  52. function post($path, $data)
  53. {
  54. $this->path = $path;
  55. $this->method = 'POST';
  56. $this->postdata = $this->buildQueryString($data);
  57. return $this->doRequest();
  58. }
  59. function buildQueryString($data)
  60. {
  61. $querystring = '';
  62. if (is_array($data)) {
  63. foreach ($data as $key => $val) {
  64. if (is_array($val)) {
  65. foreach ($val as $val2) {
  66. $querystring .= urlencode($key) . '=' . urlencode($val2) . '&';
  67. }
  68. } else {
  69. $querystring .= urlencode($key) . '=' . urlencode($val) . '&';
  70. }
  71. }
  72. $querystring = substr($querystring, 0, -1); // Eliminate unnecessary &
  73. } else {
  74. $querystring = $data;
  75. }
  76. return $querystring;
  77. }
  78. function doRequest()
  79. {
  80. if (!$fp = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout)) {
  81. switch ($errno) {
  82. case -3:
  83. $this->errormsg = 'Socket creation failed (-3)';
  84. break;
  85. case -4:
  86. $this->errormsg = 'DNS lookup failure (-4)';
  87. break;
  88. case -5:
  89. $this->errormsg = 'Connection refused or timed out (-5)';
  90. break;
  91. default:
  92. $this->errormsg = 'Connection failed (' . $errno . ')';
  93. $this->errormsg .= ' ' . $errstr;
  94. $this->debug($this->errormsg);
  95. }
  96. return false;
  97. }
  98. socket_set_timeout($fp, $this->timeout);
  99. $request = $this->buildRequest();
  100. $this->debug('Request', $request);
  101. fwrite($fp, $request);
  102. $this->headers = [];
  103. $this->content = '';
  104. $this->errormsg = '';
  105. $inHeaders = true;
  106. $atStart = true;
  107. while (!feof($fp)) {
  108. $line = fgets($fp, 4096);
  109. if ($atStart) {
  110. $atStart = false;
  111. if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/', $line, $m)) {
  112. $this->errormsg = "Status code line invalid: " . htmlentities($line);
  113. $this->debug($this->errormsg);
  114. return false;
  115. }
  116. // $http_version = $m[1];
  117. $this->status = $m[2];
  118. // $status_string = $m[3];
  119. $this->debug(trim($line));
  120. continue;
  121. }
  122. if ($inHeaders) {
  123. if (trim($line) == '') {
  124. $inHeaders = false;
  125. $this->debug('Received Headers', $this->headers);
  126. if ($this->headers_only) {
  127. break;
  128. }
  129. continue;
  130. }
  131. if (!preg_match('/([^:]+):\\s*(.*)/', $line, $m)) {
  132. continue;
  133. }
  134. $key = strtolower(trim($m[1]));
  135. $val = trim($m[2]);
  136. if (isset($this->headers[$key])) {
  137. if (is_array($this->headers[$key])) {
  138. $this->headers[$key][] = $val;
  139. } else {
  140. $this->headers[$key] = [$this->headers[$key], $val];
  141. }
  142. } else {
  143. $this->headers[$key] = $val;
  144. }
  145. continue;
  146. }
  147. $this->content .= $line;
  148. }
  149. fclose($fp);
  150. if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] == 'gzip') {
  151. $this->debug('Content is gzip encoded, unzipping it');
  152. $this->content = substr($this->content, 10);
  153. $this->content = gzinflate($this->content);
  154. }
  155. if ($this->persist_cookies && isset($this->headers['set-cookie']) && $this->host == $this->cookie_host) {
  156. $cookies = $this->headers['set-cookie'];
  157. if (!is_array($cookies)) {
  158. $cookies = [$cookies];
  159. }
  160. foreach ($cookies as $cookie) {
  161. if (preg_match('/([^=]+)=([^;]+);/', $cookie, $m)) {
  162. $this->cookies[$m[1]] = $m[2];
  163. }
  164. }
  165. $this->cookie_host = $this->host;
  166. }
  167. if ($this->persist_referers) {
  168. $this->debug('Persisting referer: ' . $this->getRequestURL());
  169. $this->referer = $this->getRequestURL();
  170. }
  171. if ($this->handle_redirects) {
  172. if (++$this->redirect_count >= $this->max_redirects) {
  173. $this->errormsg = 'Number of redirects exceeded maximum (' . $this->max_redirects . ')';
  174. $this->debug($this->errormsg);
  175. $this->redirect_count = 0;
  176. return false;
  177. }
  178. $location = isset($this->headers['location']) ? $this->headers['location'] : '';
  179. $uri = isset($this->headers['uri']) ? $this->headers['uri'] : '';
  180. if ($location || $uri) {
  181. $url = parse_url($location . $uri);
  182. return $this->get($url['path']);
  183. }
  184. }
  185. return true;
  186. }
  187. function buildRequest()
  188. {
  189. $headers = [];
  190. $headers[] = "{$this->method} {$this->path} HTTP/1.0";
  191. $headers[] = "Host: {$this->host}";
  192. $headers[] = "User-Agent: {$this->user_agent}";
  193. $headers[] = "Accept: {$this->accept}";
  194. if ($this->use_gzip) {
  195. $headers[] = "Accept-encoding: {$this->accept_encoding}";
  196. }
  197. $headers[] = "Accept-language: {$this->accept_language}";
  198. if ($this->referer) {
  199. $headers[] = "Referer: {$this->referer}";
  200. }
  201. if ($this->cookies) {
  202. $cookie = 'Cookie: ';
  203. foreach ($this->cookies as $key => $value) {
  204. $cookie .= "$key=$value; ";
  205. }
  206. $headers[] = $cookie;
  207. }
  208. if ($this->username && $this->password) {
  209. $headers[] = 'Authorization: BASIC ' . base64_encode($this->username . ':' . $this->password);
  210. }
  211. if ($this->postdata) {
  212. $headers[] = 'Content-Type: application/x-www-form-urlencoded';
  213. $headers[] = 'Content-Length: ' . strlen($this->postdata);
  214. }
  215. $request = implode("\r\n", $headers) . "\r\n\r\n" . $this->postdata;
  216. return $request;
  217. }
  218. function getStatus()
  219. {
  220. return $this->status;
  221. }
  222. function getContent()
  223. {
  224. return $this->content;
  225. }
  226. function getHeaders()
  227. {
  228. return $this->headers;
  229. }
  230. function getHeader($header)
  231. {
  232. $header = strtolower($header);
  233. if (isset($this->headers[$header])) {
  234. return $this->headers[$header];
  235. } else {
  236. return false;
  237. }
  238. }
  239. function getError()
  240. {
  241. return $this->errormsg;
  242. }
  243. function getCookies()
  244. {
  245. return $this->cookies;
  246. }
  247. function getRequestURL()
  248. {
  249. $url = 'http://' . $this->host;
  250. if ($this->port != 80) {
  251. $url .= ':' . $this->port;
  252. }
  253. $url .= $this->path;
  254. return $url;
  255. }
  256. function setUserAgent($string)
  257. {
  258. $this->user_agent = $string;
  259. }
  260. function setAuthorization($username, $password)
  261. {
  262. $this->username = $username;
  263. $this->password = $password;
  264. }
  265. function setCookies($array)
  266. {
  267. $this->cookies = $array;
  268. }
  269. function useGzip($boolean)
  270. {
  271. $this->use_gzip = $boolean;
  272. }
  273. function setPersistCookies($boolean)
  274. {
  275. $this->persist_cookies = $boolean;
  276. }
  277. function setPersistReferers($boolean)
  278. {
  279. $this->persist_referers = $boolean;
  280. }
  281. function setHandleRedirects($boolean)
  282. {
  283. $this->handle_redirects = $boolean;
  284. }
  285. function setMaxRedirects($num)
  286. {
  287. $this->max_redirects = $num;
  288. }
  289. function setHeadersOnly($boolean)
  290. {
  291. $this->headers_only = $boolean;
  292. }
  293. function setDebug($boolean)
  294. {
  295. $this->debug = $boolean;
  296. }
  297. function quickGet($url)
  298. {
  299. $bits = parse_url($url);
  300. $host = $bits['host'];
  301. $port = isset($bits['port']) ? $bits['port'] : 80;
  302. $path = isset($bits['path']) ? $bits['path'] : '/';
  303. if (isset($bits['query'])) {
  304. $path .= '?' . $bits['query'];
  305. }
  306. $client = new self($host, $port);
  307. if (!$client->get($path)) {
  308. return false;
  309. } else {
  310. return $client->getContent();
  311. }
  312. }
  313. function quickPost($url, $data)
  314. {
  315. $bits = parse_url($url);
  316. $host = $bits['host'];
  317. $port = isset($bits['port']) ? $bits['port'] : 80;
  318. $path = isset($bits['path']) ? $bits['path'] : '/';
  319. $client = new self($host, $port);
  320. if (!$client->post($path, $data)) {
  321. return false;
  322. } else {
  323. return $client->getContent();
  324. }
  325. }
  326. function debug($msg, $object = false)
  327. {
  328. if ($this->debug) {
  329. print '<div style="border: 1px solid red; padding: 0.5em; margin: 0.5em;"><strong>HttpClient Debug:</strong> ' . $msg;
  330. if ($object) {
  331. ob_start();
  332. print_r($object);
  333. $content = htmlentities(ob_get_contents());
  334. ob_end_clean();
  335. print '<pre>' . $content . '</pre>';
  336. }
  337. print '</div>';
  338. }
  339. }
  340. }