FeieHttpClient.php 11 KB

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