/include/http.php

https://bitbucket.org/bialikover/mapstrtpfndr · PHP · 415 lines · 284 code · 44 blank · 87 comment · 14 complexity · d4e07fbf010b5c525bf66360236d6039 MD5 · raw file

  1. <?php
  2. class Http_Exception extends Exception{
  3. const NOT_MODIFIED = 304;
  4. const BAD_REQUEST = 400;
  5. const NOT_FOUND = 404;
  6. const NOT_ALOWED = 405;
  7. const CONFLICT = 409;
  8. const PRECONDITION_FAILED = 412;
  9. const INTERNAL_ERROR = 500;
  10. }
  11. class Http_Multiple_Error
  12. {
  13. private $_status = null;
  14. private $_type = null;
  15. private $_url = null;
  16. private $_params = null;
  17. function __construct($status, $type, $url, $params)
  18. {
  19. $this->_status = $status;
  20. $this->_type = $type;
  21. $this->_url = $url;
  22. $this->_params = $params;
  23. }
  24. function getStatus()
  25. {
  26. return $this->_status;
  27. }
  28. function getType()
  29. {
  30. return $this->_type;
  31. }
  32. function getUrl()
  33. {
  34. return $this->_url;
  35. }
  36. function getParams()
  37. {
  38. return $this->_params;
  39. }
  40. }
  41. class Http
  42. {
  43. private $_host = null;
  44. private $_port = null;
  45. private $_user = null;
  46. private $_pass = null;
  47. private $_protocol = null;
  48. private $_options = null;
  49. const HTTP = 'http';
  50. const HTTPS = 'https';
  51. private $_connMultiple = false;
  52. /**
  53. * Factory of the class. Lazy connect
  54. *
  55. * @param string $host
  56. * @param integer $port
  57. * @param string $user
  58. * @param string $pass
  59. * @return Http
  60. */
  61. static public function connect($host, $port = 80, $protocol = self::HTTP,$options = null)
  62. {
  63. return new self($host, $port, $protocol, $options, false);
  64. }
  65. /**
  66. *
  67. * @return Http
  68. */
  69. static public function multiConnect()
  70. {
  71. return new self(null, null, null, null, true);
  72. }
  73. private $_append = array();
  74. public function add($http)
  75. {
  76. $this->_append[] = $http;
  77. return $this;
  78. }
  79. private $_silentMode = false;
  80. /**
  81. *
  82. * @param bool $mode
  83. * @return Http
  84. */
  85. public function silentMode($mode=true)
  86. {
  87. $this->_silentMode = $mode;
  88. return $this;
  89. }
  90. protected function __construct($host, $port, $protocol, $options, $connMultiple)
  91. {
  92. $this->_connMultiple = $connMultiple;
  93. $this->_host = $host;
  94. $this->_port = $port;
  95. $this->_protocol = $protocol;
  96. $this->_options = $options;
  97. }
  98. public function setCredentials($user, $pass)
  99. {
  100. $this->_user = $user;
  101. $this->_pass = $pass;
  102. return $this;
  103. }
  104. const POST = 'POST';
  105. const GET = 'GET';
  106. const DELETE = 'DELETE';
  107. const PUT = 'PUT';
  108. private $_requests = array();
  109. /**
  110. * @param string $url
  111. * @param array $params
  112. * @return Http
  113. */
  114. public function put($url, $params=array())
  115. {
  116. $this->_requests[] = array(self::PUT, $this->_url($url), $params);
  117. return $this;
  118. }
  119. /**
  120. * @param string $url
  121. * @param array $params
  122. * @return Http
  123. */
  124. public function post($url, $params=array())
  125. {
  126. $this->_requests[] = array(self::POST, $this->_url($url), $params);
  127. return $this;
  128. }
  129. /**
  130. * @param string $url
  131. * @param array $params
  132. * @return Http
  133. */
  134. public function get($url, $params=array())
  135. {
  136. $this->_requests[] = array(self::GET, $this->_url($url), $params);
  137. return $this;
  138. }
  139. /**
  140. * @param string $url
  141. * @param array $params
  142. * @return Http
  143. */
  144. public function delete($url, $params=array())
  145. {
  146. $this->_requests[] = array(self::DELETE, $this->_url($url), $params);
  147. return $this;
  148. }
  149. public function _getRequests()
  150. {
  151. return $this->_requests;
  152. }
  153. /**
  154. * PUT request
  155. *
  156. * @param string $url
  157. * @param array $params
  158. * @return string
  159. */
  160. public function doPut($url, $params=array())
  161. {
  162. return $this->_exec(self::PUT, $this->_url($url), $params);
  163. }
  164. /**
  165. * POST request
  166. *
  167. * @param string $url
  168. * @param array $params
  169. * @return string
  170. */
  171. public function doPost($url, $params=array())
  172. {
  173. return $this->_exec(self::POST, $this->_url($url), $params);
  174. }
  175. /**
  176. * GET Request
  177. *
  178. * @param string $url
  179. * @param array $params
  180. * @return string
  181. */
  182. public function doGet($url, $params=array())
  183. {
  184. return $this->_exec(self::GET, $this->_url($url), $params);
  185. }
  186. /**
  187. * DELETE Request
  188. *
  189. * @param string $url
  190. * @param array $params
  191. * @return string
  192. */
  193. public function doDelete($url, $params=array())
  194. {
  195. return $this->_exec(self::DELETE, $this->_url($url), $params);
  196. }
  197. private $_headers = array();
  198. /**
  199. * setHeaders
  200. *
  201. * @param array $headers
  202. * @return Http
  203. */
  204. public function setHeaders($headers)
  205. {
  206. $this->_headers = $headers;
  207. return $this;
  208. }
  209. /**
  210. * Builds absolute url
  211. *
  212. * @param unknown_type $url
  213. * @return unknown
  214. */
  215. private function _url($url=null)
  216. {
  217. // return "{$this->_protocol}://{$this->_host}:{$this->_port}/{$url}";
  218. return "{$this->_protocol}://{$this->_host}/{$url}";
  219. }
  220. const HTTP_OK = 200;
  221. const HTTP_CREATED = 201;
  222. const HTTP_ACEPTED = 202;
  223. /**
  224. * Performing the real request
  225. *
  226. * @param string $type
  227. * @param string $url
  228. * @param array $params
  229. * @return string
  230. */
  231. private function _exec($type, $url, $params = array())
  232. {
  233. $headers = $this->_headers;
  234. $s = curl_init();
  235. if(is_array($this->_options))
  236. {
  237. foreach($this->_options as $key=>$val)
  238. {
  239. curl_setopt($s, $key, $val);
  240. }
  241. }
  242. if(!is_null($this->_user)){
  243. curl_setopt($s, CURLOPT_USERPWD, $this->_user.':'.$this->_pass);
  244. }
  245. switch ($type) {
  246. case self::DELETE:
  247. curl_setopt($s, CURLOPT_URL, $url . '?' . http_build_query($params));
  248. curl_setopt($s, CURLOPT_CUSTOMREQUEST, self::DELETE);
  249. break;
  250. case self::PUT:
  251. curl_setopt($s, CURLOPT_URL, $url);
  252. curl_setopt($s, CURLOPT_CUSTOMREQUEST, self::PUT);
  253. curl_setopt($s, CURLOPT_HTTPHEADER, array('Content-Length: ' . strlen(http_build_query($params))));
  254. curl_setopt($s, CURLOPT_POSTFIELDS, http_build_query($params));
  255. break;
  256. case self::POST:
  257. curl_setopt($s, CURLOPT_URL, $url);
  258. curl_setopt($s, CURLOPT_POST, true);
  259. curl_setopt($s, CURLOPT_POSTFIELDS, $params);
  260. break;
  261. case self::GET:
  262. curl_setopt($s, CURLOPT_URL, $url . '?' . http_build_query($params));
  263. break;
  264. }
  265. curl_setopt($s, CURLOPT_RETURNTRANSFER, true);
  266. curl_setopt($s, CURLOPT_HTTPHEADER, $headers);
  267. $_out = curl_exec($s);
  268. $status = curl_getinfo($s, CURLINFO_HTTP_CODE);
  269. $err = curl_error($s); //jic
  270. curl_close($s);
  271. switch ($status) {
  272. case self::HTTP_OK:
  273. case self::HTTP_CREATED:
  274. case self::HTTP_ACEPTED:
  275. $out = $_out;
  276. break;
  277. default:
  278. if (!$this->_silentMode) {
  279. $_dout = json_decode($_out);
  280. if($_dout != NULL)
  281. {
  282. throw new Http_Exception("{$_dout->error->message}", $status);
  283. }else{
  284. error_log("Unknown http error: $_out, $err ($status)");
  285. throw new Http_Exception($err, $status);
  286. }
  287. }
  288. }
  289. return $out;
  290. }
  291. public function run()
  292. {
  293. if ($this->_connMultiple) {
  294. return $this->_runMultiple();
  295. } else {
  296. return $this->_run();
  297. }
  298. }
  299. private function _runMultiple()
  300. {
  301. $out= null;
  302. if (count($this->_append) > 0) {
  303. $arr = array();
  304. foreach ($this->_append as $_append) {
  305. $arr = array_merge($arr, $_append->_getRequests());
  306. }
  307. $this->_requests = $arr;
  308. $out = $this->_run();
  309. }
  310. return $out;
  311. }
  312. private function _run()
  313. {
  314. $headers = $this->_headers;
  315. $curly = $result = array();
  316. $mh = curl_multi_init();
  317. foreach ($this->_requests as $id => $reg) {
  318. $curly[$id] = curl_init();
  319. $type = $reg[0];
  320. $url = $reg[1];
  321. $params = $reg[2];
  322. if(!is_null($this->_user)){
  323. curl_setopt($curly[$id], CURLOPT_USERPWD, $this->_user.':'.$this->_pass);
  324. }
  325. switch ($type) {
  326. case self::DELETE:
  327. curl_setopt($curly[$id], CURLOPT_URL, $url . '?' . http_build_query($params));
  328. curl_setopt($curly[$id], CURLOPT_CUSTOMREQUEST, self::DELETE);
  329. break;
  330. case self::PUT:
  331. curl_setopt($curly[$id], CURLOPT_URL, $url);
  332. curl_setopt($curly[$id], CURLOPT_CUSTOMREQUEST, self::PUT);
  333. curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $params);
  334. break;
  335. case self::POST:
  336. curl_setopt($curly[$id], CURLOPT_URL, $url);
  337. curl_setopt($curly[$id], CURLOPT_POST, true);
  338. curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $params);
  339. break;
  340. case self::GET:
  341. curl_setopt($curly[$id], CURLOPT_URL, $url . '?' . http_build_query($params));
  342. break;
  343. }
  344. curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, true);
  345. curl_setopt($curly[$id], CURLOPT_HTTPHEADER, $headers);
  346. curl_multi_add_handle($mh, $curly[$id]);
  347. }
  348. $running = null;
  349. do {
  350. curl_multi_exec($mh, $running);
  351. sleep(0.2);
  352. } while($running > 0);
  353. foreach($curly as $id => $c) {
  354. $status = curl_getinfo($c, CURLINFO_HTTP_CODE);
  355. switch ($status) {
  356. case self::HTTP_OK:
  357. case self::HTTP_CREATED:
  358. case self::HTTP_ACEPTED:
  359. $result[$id] = curl_multi_getcontent($c);
  360. break;
  361. default:
  362. if (!$this->_silentMode) {
  363. $result[$id] = new Http_Multiple_Error($status, $type, $url, $params);
  364. }
  365. }
  366. curl_multi_remove_handle($mh, $c);
  367. }
  368. curl_multi_close($mh);
  369. return $result;
  370. }
  371. }