Advertisement
Guest User

Untitled

a guest
Mar 7th, 2017
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 41.94 KB | None | 0 0
  1. <?php
  2.  
  3. namespace MikeBrantRestClientLib;
  4.  
  5. /**
  6. * @desc Class for executing RESTful service calls using a fluent interface.
  7. */
  8. class RestClient
  9. {
  10. /**
  11. * Flag to determine if basic authentication is to be used.
  12. *
  13. * @var boolean
  14. */
  15. protected $useBasicAuth = false;
  16.  
  17. /**
  18. * User Name for HTTP Basic Auth
  19. *
  20. * @var string
  21. */
  22. protected $basicAuthUsername = null;
  23.  
  24. /**
  25. * Password for HTTP Basic Auth
  26. *
  27. * @var string
  28. */
  29. protected $basicAuthPassword = null;
  30.  
  31. /**
  32. * Flag to determine if SSL is used
  33. *
  34. * @var boolean
  35. */
  36. protected $useSsl = false;
  37.  
  38. /**
  39. * Flag to determine is we are to run in test mode where host's SSL cert is not verified
  40. *
  41. * @var boolean
  42. */
  43. protected $useSslTestMode = false;
  44.  
  45. /**
  46. * Integer value representing number of seconds to set for curl timeout option. Defaults to 30 seconds.
  47. *
  48. * @var integer
  49. */
  50. protected $timeout = 30;
  51.  
  52. /**
  53. * Variable to store remote host name
  54. *
  55. * @var string
  56. */
  57. protected $remoteHost = null;
  58.  
  59. /**
  60. * Variable to hold setting to determine if redirects are followed
  61. *
  62. * @var boolean
  63. */
  64. protected $followRedirects = false;
  65.  
  66. /**
  67. * Variable to hold value for maximum number of redirects to follow for cases when redirect are being followed.
  68. * Default value of 0 will allow for following of unlimited redirects.
  69. *
  70. * @var integer
  71. */
  72. protected $maxRedirects = 0;
  73.  
  74. /**
  75. * Variable which can hold a URI base for all actions
  76. *
  77. * @var string
  78. */
  79. protected $uriBase = '/';
  80.  
  81. /**
  82. * Stores curl handle
  83. *
  84. * @var mixed
  85. */
  86. private $curl = null;
  87.  
  88. /**
  89. * Variable to store request URL that is formed before a request is made
  90. *
  91. * @var string
  92. */
  93. private $requestUrl = null;
  94.  
  95. /**
  96. * Array containing headers to be used for request
  97. *
  98. * @var array
  99. */
  100. private $headers = array();
  101.  
  102. /**
  103. * Variable to store the request header as sent
  104. *
  105. * @var string
  106. */
  107.  
  108. /**
  109. * Variable to store CurlHttpResponse result from curl call
  110. *
  111. * @var CurlHttpResponse
  112. */
  113. private $response = null;
  114.  
  115. /**
  116. * Constructor method. Currently there is no instantiation logic.
  117. *
  118. * @return void
  119. */
  120. public function __construct() {}
  121.  
  122. /**
  123. * Method to execute GET on server
  124. *
  125. * @param string $action
  126. * @return CurlHttpResponse
  127. * @throws InvalidArgumentException
  128. * @throws Exception
  129. */
  130. public function get($action) {
  131. $this->validateAction($action);
  132. $this->curlSetup();
  133. $this->setRequestUrl($action);
  134. curl_setopt($this->curl, CURLOPT_HTTPGET, true);
  135. // execute call. Can throw Exception.
  136. $this->curlExec();
  137.  
  138. return $this->response;
  139. }
  140.  
  141. /**
  142. * Method to exexute POST on server
  143. *
  144. * @param mixed $action
  145. * @param mixed $data
  146. * @return CurlHttpResponse
  147. * @throws InvalidArgumentException
  148. * @throws Exception
  149. */
  150. public function post($action, $data) {
  151. $this->validateAction($action);
  152. $this->validateData($data);
  153. $this->curlSetup();
  154. $this->setRequestUrl($action);
  155. $this->setRequestData($data);
  156. curl_setopt($this->curl, CURLOPT_POST, true);
  157. // execute call. Can throw Exception.
  158. $this->curlExec();
  159.  
  160. return $this->response;
  161. }
  162.  
  163. /**
  164. * Method to execute PUT on server
  165. *
  166. * @param string $action
  167. * @param mixed $data
  168. * @return CurlHttpResponse
  169. * @throws InvalidArgumentException
  170. * @throws Exception
  171. */
  172. public function put($action, $data) {
  173. $this->validateAction($action);
  174. $this->validateData($data);
  175. $this->curlSetup();
  176. $this->setRequestUrl($action);
  177. $this->setRequestData($data);
  178. curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'PUT');
  179. // execute call. Can throw Exception.
  180. $this->curlExec();
  181.  
  182. return $this->response;
  183. }
  184.  
  185. /**
  186. * Method to execute DELETE on server
  187. *
  188. * @param string $action
  189. * @return CurlHttpResponse
  190. * @throws InvalidArgumentException
  191. * @throws Exception
  192. */
  193. public function delete($action) {
  194. $this->validateAction($action);
  195. $this->curlSetup();
  196. $this->setRequestUrl($action);
  197. curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
  198. // execute call. Can throw Exception.
  199. $this->curlExec();
  200.  
  201. return $this->response;
  202. }
  203.  
  204. /**
  205. * Method to execute HEAD on server
  206. *
  207. * @param string $action
  208. * @return CurlHttpResponse
  209. * @throws InvalidArgumentException
  210. * @throws Exception
  211. */
  212. public function head($action) {
  213. $this->validateAction($action);
  214. $this->curlSetup();
  215. $this->setRequestUrl($action);
  216. curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
  217. curl_setopt($this->curl, CURLOPT_NOBODY, true);
  218. // execute call. Can throw Exception.
  219. $this->curlExec();
  220.  
  221. return $this->response;
  222. }
  223.  
  224. /**
  225. * Sets host name of remote server
  226. *
  227. * @param string $host
  228. * @return RestClient
  229. * @throws InvalidArgumentException
  230. */
  231. public function setRemoteHost($host) {
  232. if(empty($host)) {
  233. throw new InvalidArgumentException('Host name not provided.');
  234. } else if(!is_string($host)) {
  235. throw new InvalidArgumentException('Non-string host name provided.');
  236. }
  237.  
  238. // remove any http(s):// at beginning of host name
  239. $httpsPattern = '#https://#i';
  240. $httpPattern = '#http://#i';
  241. if (1 === preg_match($httpsPattern, $host)) {
  242. // this needs to be SSL request
  243. $this->setUseSsl(true);
  244. $host = str_ireplace('https://', '', $host);
  245. } else if (1 === preg_match($httpPattern, $host)) {
  246. $host = str_ireplace('http://', '', $host);
  247. }
  248.  
  249. // remove trailing slash in host name
  250. $host = rtrim($host, '/');
  251.  
  252. // look for common SSL port values in host name to see if SSL is needed
  253. $portPatterns = array(
  254. '/:443$/',
  255. '/:8443$/',
  256. );
  257. foreach ($portPatterns as $pattern) {
  258. if (1 === preg_match($pattern, $host)) {
  259. $this->setUseSsl(true);
  260. }
  261. }
  262.  
  263. $this->remoteHost = $host;
  264.  
  265. return $this;
  266. }
  267.  
  268. /**
  269. * Sets URI base for the instance
  270. *
  271. * @param string $uriBase
  272. * @return RestClient
  273. * @throws InvalidArgumentException
  274. */
  275. public function setUriBase($uriBase) {
  276. if(empty($uriBase)) {
  277. throw new InvalidArgumentException('URI base not provided.');
  278. } else if(!is_string($uriBase)) {
  279. throw new InvalidArgumentException('Non-string URI base provided.');
  280. }
  281.  
  282. // make sure we always have forward slash at beginning and end of uriBase
  283. $uriBase = '/' . ltrim($uriBase, '/');
  284. $uriBase = rtrim($uriBase, '/') . '/';
  285. $this->uriBase = $uriBase;
  286.  
  287. return $this;
  288. }
  289.  
  290. /**
  291. * Sets whether SSL is to be used
  292. *
  293. * @param boolean $value
  294. * @return RestClient
  295. * @throws InvalidArgumentException
  296. */
  297. public function setUseSsl($value) {
  298. if (!is_bool($value)) {
  299. throw new InvalidArgumentException('Non-boolean value passed as parameter.');
  300. }
  301. $this->useSsl = $value;
  302.  
  303. return $this;
  304. }
  305.  
  306. /**
  307. * Sets whether SSL Test Mode is to be used
  308. *
  309. * @param boolean $value
  310. * @return RestClient
  311. * @throws InvalidArgumentException
  312. */
  313. public function setUseSslTestMode($value) {
  314. if (!is_bool($value)) {
  315. throw new InvalidArgumentException('Non-boolean value passed as parameter.');
  316. }
  317. $this->useSslTestMode = $value;
  318.  
  319. return $this;
  320. }
  321. /**
  322. * Sets basic authentication credentials
  323. *
  324. * @param string $user
  325. * @param string $password
  326. * @return RestClient
  327. * @throws InvalidArgumentException
  328. */
  329. public function setBasicAuthCredentials($user, $password) {
  330. if (empty($user)) {
  331. throw new InvalidArgumentException('User name not provided when trying to set basic authentication credentials.');
  332. }
  333. if (empty($password)) {
  334. throw new InvalidArgumentException('Password not provided when trying to set basic authentication credentials.');
  335. }
  336.  
  337. $this->useBasicAuth = true;
  338. $this->basicAuthUsername = $user;
  339. $this->basicAuthPassword = $password;
  340.  
  341. return $this;
  342. }
  343.  
  344. /**
  345. * Sets HTTP headers from an associative array where key is header name and value is the header value
  346. *
  347. * @param array $headers
  348. * @return RestClient
  349. */
  350. public function setHeaders(array $headers) {
  351. if(empty($headers)) {
  352. throw new InvalidArgumentException('Empty array passed when triyng to set headers');
  353. }
  354. $this->headers = $headers;
  355.  
  356. return $this;
  357. }
  358.  
  359. /**
  360. * Sets maximum timeout for curl requests
  361. *
  362. * @param integer $seconds
  363. * @return RestClient
  364. * @throws InvalidArgumentException
  365. */
  366. public function setTimeout($seconds) {
  367. if(!is_integer($seconds) || $seconds < 0) {
  368. throw new InvalidArgumentException('A non-negative integer value must be passed when trying to set timeout');
  369. }
  370. $this->timeout = $seconds;
  371.  
  372. return $this;
  373. }
  374.  
  375. /**
  376. * Sets flag on whether to follow 3XX redirects.
  377. *
  378. * @param boolean $follow
  379. * @return RestClient
  380. * @throws InvalidArgumentException
  381. */
  382. public function setFollowRedirects($follow) {
  383. if(!is_bool($follow)) {
  384. throw new InvalidArgumentException('Non-boolean value passed as parameter.');
  385. }
  386. $this->followRedirects = $follow;
  387.  
  388. return $this;
  389. }
  390.  
  391. /**
  392. * Sets maximum number of redirects to follow. A value of 0 represents no redirect limit. Also sets followRedirects property to true .
  393. *
  394. * @param integer $redirects
  395. * @return RestClient
  396. * @throws InvalidArgumentException
  397. */
  398. public function setMaxRedirects($redirects) {
  399. if(!is_integer($redirects) || $redirects < 0) {
  400. throw new InvalidArgumentException('A non-negative integer value must be passed when trying to set max redirects.');
  401. }
  402. $this->maxRedirects = $redirects;
  403. $this->setFollowRedirects(true);
  404.  
  405. return $this;
  406. }
  407.  
  408. /**
  409. * Get remote host setting
  410. *
  411. * @return string
  412. */
  413. public function getRemoteHost() {
  414. return $this->remoteHost;
  415. }
  416.  
  417. /**
  418. * Get URI Base setting
  419. *
  420. * @return string
  421. */
  422. public function getUriBase() {
  423. return $this->uriBase;
  424. }
  425.  
  426. /**
  427. * Get boolean setting indicating whether SSL is to be used
  428. *
  429. * @return boolean
  430. */
  431. public function isUsingSsl() {
  432. return $this->useSsl;
  433. }
  434.  
  435. /**
  436. * Get boolean setting indicating whether SSL test mode is enabled
  437. *
  438. * @return boolean
  439. */
  440. public function isUsingSslTestMode() {
  441. return $this->useSslTestMode;
  442. }
  443.  
  444. /**
  445. * Get timeout setting
  446. *
  447. * @return integer
  448. */
  449. public function getTimeout() {
  450. return $this->timeout;
  451. }
  452.  
  453. /**
  454. * Get follow redirects setting
  455. *
  456. * @return boolean
  457. */
  458. public function isFollowingRedirects() {
  459. return $this->followRedirects;
  460. }
  461.  
  462. /**
  463. * Get max redirects setting
  464. *
  465. * @return integer
  466. */
  467. public function getMaxRedirects() {
  468. return $this->maxRedirects;
  469. }
  470.  
  471. /**
  472. * Method to initialize curl handle in object
  473. *
  474. * @return void
  475. * @throws Exception
  476. */
  477. private function curlSetup() {
  478. // reset all request/response properties
  479. $this->resetRequestResponseProperties();
  480.  
  481. // initialize curl. Throws Exception on failure.
  482. $this->curl = $this->curlInit();
  483. }
  484.  
  485. /**
  486. * Method to initilize a curl handle
  487. *
  488. * @return resource
  489. * @throws Exception
  490. */
  491. protected function curlInit() {
  492. // initialize curl
  493. $curl = curl_init();
  494. if($curl === false) {
  495. throw new Exception('curl failed to initialize.');
  496. }
  497. // set timeout
  498. curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout);
  499.  
  500. // set basic HTTP authentication settings
  501. if (true === $this->useBasicAuth) {
  502. curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
  503. curl_setopt($curl, CURLOPT_USERPWD, $this->basicAuthUsername . ':' . $this->basicAuthPassword);
  504. }
  505.  
  506. // set headers
  507. if (!empty($this->headers)) {
  508. $headers = array();
  509. foreach ($this->headers as $key=>$val) {
  510. $headers[] = $key . ': ' . $val;
  511. }
  512. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  513. }
  514.  
  515. // if not in production environment, we want to ignore SSL validation
  516. if (true === $this->useSsl && true === $this->useSslTestMode) {
  517. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  518. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
  519. }
  520.  
  521. // set option to add request header information to curl_getinfo output
  522. curl_setopt($curl, CURLINFO_HEADER_OUT, true);
  523.  
  524. // set option to return content body
  525. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  526.  
  527. // set redirect options
  528. if (true === $this->followRedirects) {
  529. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
  530. if ($this->maxRedirects > 0) {
  531. curl_setopt($curl, CURLOPT_MAXREDIRS, $this->maxRedirects);
  532. }
  533. }
  534.  
  535. return $curl;
  536. }
  537.  
  538. /**
  539. * Method to to teardown curl fixtures at end of request
  540. *
  541. * @return void
  542. */
  543. private function curlTeardown() {
  544. $this->curlClose($this->curl);
  545. $this->curl = null;
  546. }
  547.  
  548. /**
  549. * Method to close curl handle
  550. *
  551. * @return void
  552. */
  553. protected function curlClose($curl) {
  554. curl_close($curl);
  555. }
  556.  
  557. /**
  558. * Method to execute curl call
  559. *
  560. * @return void
  561. * @throws Exception
  562. */
  563. private function curlExec() {
  564. $curlResult = curl_exec($this->curl);
  565. if($curlResult === false) {
  566. // our curl call failed for some reason
  567. $curlError = curl_error($this->curl);
  568. $this->curlTeardown();
  569. throw new Exception('curl call failed with message: "' . $curlError. '"');
  570. }
  571.  
  572. // return CurlHttpResponse
  573. try {
  574. $this->response = new CurlHttpResponse($curlResult, curl_getinfo($this->curl));
  575. } catch (InvalidArgumentException $e) {
  576. throw new Exception(
  577. 'Unable to instantiate CurlHttpResponse. Message: "' . $e->getMessage() . '"',
  578. $e->getCode(),
  579. $e
  580. );
  581. } finally {
  582. $this->curlTeardown();
  583. }
  584. }
  585.  
  586. /**
  587. * Method to reset all properties specific to a particular request/response sequence.
  588. *
  589. * @return void
  590. */
  591. protected function resetRequestResponseProperties() {
  592. $this->requestUrl = null;
  593. $this->response = null;
  594. }
  595.  
  596. /**
  597. * Method to set the url on curl handle based on passed action
  598. *
  599. * @param string $action
  600. * @return void
  601. */
  602. protected function setRequestUrl($action) {
  603. $url = $this->buildUrl($action);
  604. $this->requestUrl = $url;
  605. curl_setopt($this->curl, CURLOPT_URL, $url);
  606. }
  607.  
  608. /**
  609. * Method to build URL based on class settings and passed action
  610. *
  611. * @param string $action
  612. * @return string
  613. */
  614. protected function buildUrl($action) {
  615. $url = 'http://';
  616. if (true === $this->useSsl) {
  617. $url = 'https://';
  618. }
  619. $url = $url . $this->remoteHost . $this->uriBase . $action;
  620. return $url;
  621. }
  622.  
  623. /**
  624. * Method to set data to be sent along with POST/PUT requests
  625. *
  626. * @param mixed $data
  627. * @return void
  628. */
  629. protected function setRequestData($data) {
  630. $this->requestData = $data;
  631. curl_setopt($this->curl, CURLOPT_POSTFIELDS, $data);
  632. }
  633.  
  634. /**
  635. * Method to provide common validation for action parameters
  636. *
  637. * @param string $action
  638. * @return void
  639. * @throws InvalidArgumentException
  640. */
  641. protected function validateAction($action) {
  642. if(!is_string($action)) {
  643. throw new InvalidArgumentException('A non-string value was passed for action parameter');
  644. }
  645. }
  646.  
  647. /**
  648. * Method to provide common validation for data parameters
  649. *
  650. * @param mixed $data
  651. * @return void
  652. * @throws InvalidArgumentException
  653. */
  654. protected function validateData($data) {
  655. if(empty($data)) {
  656. throw new InvalidArgumentException('An empty value was passed for data parameter');
  657. }
  658. }
  659. }
  660.  
  661. <?php
  662.  
  663. namespace MikeBrantRestClientLib;
  664.  
  665. use PHPUnitFrameworkTestCase;
  666.  
  667. /**
  668. * Mock for curl_init global function
  669. *
  670. * @return mixed
  671. */
  672. function curl_init() {
  673. if (!is_null(RestClientTest::$curlInitResponse)) {
  674. return RestClientTest::$curlInitResponse;
  675. }
  676. return curl_init();
  677. }
  678.  
  679. /**
  680. * Mock for curl_exec global function
  681. *
  682. * @param resource curl handle
  683. * @return mixed
  684. */
  685. function curl_exec($curl) {
  686. if (!is_null(RestClientTest::$curlExecResponse)) {
  687. return RestClientTest::$curlExecResponse;
  688. }
  689. return curl_exec($curl);
  690. }
  691.  
  692. /**
  693. * Mock for curl_error global function
  694. *
  695. * @param resource curl handle
  696. * @return mixed
  697. */
  698. function curl_error($curl) {
  699. if (!is_null(RestClientTest::$curlErrorResponse)) {
  700. return RestClientTest::$curlErrorResponse;
  701. }
  702. return curl_error($curl);
  703. }
  704.  
  705. /**
  706. * This is hacky workaround for avoiding double definition of this global method override
  707. * when running full test suite on this library.
  708. */
  709. if(!function_exists('MikeBrantRestClientLibcurl_getinfo')) {
  710.  
  711. /**
  712. * Mock for curl_getinfo function
  713. *
  714. * @param resource curl handle
  715. * @return mixed
  716. */
  717. function curl_getinfo($curl) {
  718. $backtrace = debug_backtrace();
  719. $testClass = $backtrace[1]['class'] . 'Test';
  720. if (!is_null($testClass::$curlGetinfoResponse)) {
  721. return $testClass::$curlGetinfoResponse;
  722. }
  723. return curl_getinfo($curl);
  724. }
  725. }
  726.  
  727. class RestClientTest extends TestCase
  728. {
  729. public static $curlInitResponse = null;
  730.  
  731. public static $curlExecResponse = null;
  732.  
  733. public static $curlErrorResponse = null;
  734.  
  735. public static $curlGetinfoResponse = null;
  736.  
  737. protected $client = null;
  738.  
  739. protected $curlExecMockResponse = 'Test Response';
  740.  
  741. protected $curlGetinfoMockResponse = array(
  742. 'url' => 'http://google.com/',
  743. 'content_type' => 'text/html; charset=UTF-8',
  744. 'http_code' => 200,
  745. 'header_size' => 321,
  746. 'request_size' => 49,
  747. 'filetime' => -1,
  748. 'ssl_verify_result' => 0,
  749. 'redirect_count' => 0,
  750. 'total_time' => 1.123264,
  751. 'namelookup_time' => 1.045272,
  752. 'connect_time' => 1.070183,
  753. 'pretransfer_time' => 1.071139,
  754. 'size_upload' => 0,
  755. 'size_download' => 219,
  756. 'speed_download' => 194,
  757. 'speed_upload' => 0,
  758. 'download_content_length' => 219,
  759. 'upload_content_length' => -1,
  760. 'starttransfer_time' => 1.122377,
  761. 'redirect_time' => 0,
  762. 'redirect_url' => 'http://www.google.com/',
  763. 'primary_ip' => '216.58.194.142',
  764. 'certinfo' => array(),
  765. 'primary_port' => 80,
  766. 'local_ip' => '192.168.1.74',
  767. 'local_port' => 59733,
  768. 'request_header' => "GET / HTTP/1.1nHost: google.comnAccept: */*",
  769. );
  770.  
  771. protected function setUp() {
  772. self::$curlInitResponse = null;
  773. self::$curlExecResponse = null;
  774. self::$curlErrorResponse = null;
  775. self::$curlGetinfoResponse = null;
  776. $this->client = new RestClient();
  777. }
  778.  
  779. protected function tearDown() {
  780. $this->client = null;
  781. }
  782.  
  783. public function notStringProvider() {
  784. return array(
  785. array(null),
  786. array(new stdClass()),
  787. array(1),
  788. array(0),
  789. array(true),
  790. array(false),
  791. array(array())
  792. );
  793. }
  794.  
  795. public function emptyProvider() {
  796. return array(
  797. array(null),
  798. array(''),
  799. array(0),
  800. array(0.0),
  801. array(false),
  802. array('0'),
  803. array(array())
  804. );
  805. }
  806.  
  807. public function notStringAndEmptyProvider() {
  808. return array(
  809. array(null),
  810. array(''),
  811. array(new stdClass()),
  812. array(1),
  813. array(0),
  814. array(0.0),
  815. array('0'),
  816. array(true),
  817. array(false),
  818. array(array())
  819. );
  820. }
  821.  
  822. public function hostProvider() {
  823. return array(
  824. array('somedomain.com', 'somedomain.com', false),
  825. array('somedomain.com/', 'somedomain.com', false),
  826. array('https://somedomain.com', 'somedomain.com', true),
  827. array('http://somedomain.com', 'somedomain.com', false),
  828. array('somedomain.com:80', 'somedomain.com:80', false),
  829. array('somedomain.com:443', 'somedomain.com:443', true),
  830. array('somedomain.com:8443', 'somedomain.com:8443', true)
  831. );
  832. }
  833.  
  834. public function notBooleanProvider() {
  835. return array(
  836. array(null),
  837. array(''),
  838. array('string'),
  839. array('true'),
  840. array('false'),
  841. array(1),
  842. array(0),
  843. array('1'),
  844. array('0'),
  845. array(0.0),
  846. array(new stdClass()),
  847. array(array())
  848. );
  849. }
  850.  
  851. public function uriBaseProvider() {
  852. return array(
  853. array('test', '/test/'),
  854. array('/test', '/test/'),
  855. array('test/', '/test/'),
  856. array('/test/', '/test/')
  857. );
  858. }
  859.  
  860. public function notZeroOrPositiveIntegerProvider() {
  861. return array(
  862. array(-1),
  863. array(null),
  864. array(''),
  865. array(new stdClass()),
  866. array(1.0),
  867. array('1'),
  868. array(array())
  869. );
  870. }
  871.  
  872. public function headersProvider() {
  873. return array(
  874. array(
  875. array(
  876. 'header1' => 'header1 value',
  877. 'header2' => 'header2 value'
  878. )
  879. )
  880. );
  881. }
  882.  
  883. public function curlExecExceptionProvider() {
  884. return array(
  885. array(false, $this->curlGetinfoMockResponse),
  886. array('test', array())
  887. );
  888. }
  889.  
  890. public function buildUrlProvider() {
  891. return array(
  892. array(true, 'google.com', 'base', 'action', 'https://google.com/base/action'),
  893. array(false, 'google.com', 'base', 'action', 'http://google.com/base/action')
  894. );
  895. }
  896.  
  897. /**
  898. * @dataProvider notStringProvider
  899. * @expectedException InvalidArgumentException
  900. * @covers MikeBrantRestClientLibRestClient::validateAction
  901. */
  902. public function testValidateActionThrowsExceptions($action) {
  903. $this->client->get($action);
  904. }
  905.  
  906. /**
  907. * @dataProvider emptyProvider
  908. * @expectedException InvalidArgumentException
  909. * @covers MikeBrantRestClientLibRestClient::validateData
  910. */
  911. public function testValidateDataThrowsExceptions($data) {
  912. $this->client->post('', $data);
  913. }
  914.  
  915. /**
  916. * @dataProvider notStringAndEmptyProvider
  917. * @expectedException InvalidArgumentException
  918. * @covers MikeBrantRestClientLibRestClient::setRemoteHost
  919. */
  920. public function testSetRemoteHostThrowsExceptions($host) {
  921. $this->client->setRemoteHost($host);
  922. }
  923.  
  924. /**
  925. * @dataProvider hostProvider
  926. * @covers MikeBrantRestClientLibRestClient::setRemoteHost
  927. * @covers MikeBrantRestClientLibRestClient::getRemoteHost
  928. */
  929. public function testSetRemoteHost($hostInput, $hostOutput, $useSslSet) {
  930. $this->client->setRemoteHost($hostInput);
  931. $this->assertEquals($hostOutput, $this->client->getRemoteHost());
  932. $this->assertEquals($useSslSet, $this->client->isUsingSsl());
  933. }
  934.  
  935. /**
  936. * @dataProvider notStringAndEmptyProvider
  937. * @expectedException InvalidArgumentException
  938. * @covers MikeBrantRestClientLibRestClient::setUriBase
  939. */
  940. public function testSetUriBaseThrowsExceptions($string) {
  941. $this->client->setUriBase($string);
  942. }
  943.  
  944. /**
  945. * @dataProvider uriBaseProvider
  946. * @covers MikeBrantRestClientLibRestClient::setUriBase
  947. * @covers MikeBrantRestClientLibRestClient::getUriBase
  948. */
  949. public function testSetUriBase($stringInput, $stringOutput) {
  950. $this->client->setUriBase($stringInput);
  951. $this->assertEquals($stringOutput, $this->client->getUriBase());
  952. }
  953.  
  954. /**
  955. * @dataProvider notBooleanProvider
  956. * @expectedException InvalidArgumentException
  957. * @covers MikeBrantRestClientLibRestClient::setUseSsl
  958. */
  959. public function testSetUseSslThrowsExceptions($boolean) {
  960. $this->client->setUseSsl($boolean);
  961. }
  962.  
  963. /**
  964. * @covers MikeBrantRestClientLibRestClient::setUseSsl
  965. * @covers MikeBrantRestClientLibRestClient::isUsingSsl
  966. */
  967. public function testSetUseSsl() {
  968. $this->client->setUseSsl(true);
  969. $this->assertTrue($this->client->isUsingSsl());
  970. $this->client->setUseSsl(false);
  971. $this->assertFalse($this->client->isUsingSsl());
  972. }
  973.  
  974. /**
  975. * @dataProvider notBooleanProvider
  976. * @expectedException InvalidArgumentException
  977. * @covers MikeBrantRestClientLibRestClient::setUseSslTestMode
  978. */
  979. public function testSetUseSslTestModeThrowsExceptions($boolean) {
  980. $this->client->setUseSslTestMode($boolean);
  981. }
  982.  
  983. /**
  984. * @covers MikeBrantRestClientLibRestClient::setUseSslTestMode
  985. * @covers MikeBrantRestClientLibRestClient::isUsingSslTestMode
  986. */
  987. public function testSetUseSslTestMode() {
  988. $this->client->setUseSslTestMode(true);
  989. $this->assertTrue($this->client->isUsingSslTestMode());
  990. $this->client->setUseSslTestMode(false);
  991. $this->assertFalse($this->client->isUsingSslTestMode());
  992. }
  993.  
  994. /**
  995. * @dataProvider emptyProvider
  996. * @expectedException InvalidArgumentException
  997. * @covers MikeBrantRestClientLibRestClient::setBasicAuthCredentials
  998. */
  999. public function testSetBasicAuthCredentialsThrowsExceptionOnEmptyUser($user) {
  1000. $this->client->setBasicAuthCredentials($user, 'password');
  1001. }
  1002.  
  1003. /**
  1004. * @dataProvider emptyProvider
  1005. * @expectedException InvalidArgumentException
  1006. * @covers MikeBrantRestClientLibRestClient::setBasicAuthCredentials
  1007. */
  1008. public function testSetBasicAuthCredentialsThrowsExceptionOnEmptyPassword($password) {
  1009. $this->client->setBasicAuthCredentials('user', $password);
  1010. }
  1011.  
  1012. /**
  1013. * @covers MikeBrantRestClientLibRestClient::setBasicAuthCredentials
  1014. */
  1015. public function testSetBasicAuthCredentials() {
  1016. $this->client->setBasicAuthCredentials('user', 'password');
  1017. $this->assertAttributeEquals('user', 'basicAuthUsername', $this->client);
  1018. $this->assertAttributeEquals('password', 'basicAuthPassword', $this->client);
  1019. $this->assertAttributeEquals(true, 'useBasicAuth', $this->client);
  1020. }
  1021.  
  1022. /**
  1023. * @expectedException InvalidArgumentException
  1024. * @covers MikeBrantRestClientLibRestClient::setHeaders
  1025. */
  1026. public function testSetHeadersThrowsExceptionOnEmptyArray() {
  1027. $this->client->setHeaders(array());
  1028. }
  1029.  
  1030. /**
  1031. * @dataProvider headersProvider
  1032. * @covers MikeBrantRestClientLibRestClient::setHeaders
  1033. */
  1034. public function testSetHeaders($headers) {
  1035. $this->client->setHeaders($headers);
  1036. $this->assertAttributeEquals($headers, 'headers', $this->client);
  1037. }
  1038.  
  1039. /**
  1040. * @dataProvider notZeroOrPositiveIntegerProvider
  1041. * @expectedException InvalidArgumentException
  1042. * @covers MikeBrantRestClientLibRestClient::setTimeout
  1043. */
  1044. public function testSetTimeoutThrowsExceptions($int) {
  1045. $this->client->setTimeout($int);
  1046. }
  1047.  
  1048. /**
  1049. * @covers MikeBrantRestClientLibRestClient::setTimeout
  1050. * @covers MikeBrantRestClientLibRestClient::getTimeout
  1051. */
  1052. public function testSetTimeout() {
  1053. $this->client->setTimeout(30);
  1054. $this->assertEquals(30, $this->client->getTimeout());
  1055. $this->client->setTimeout(0);
  1056. $this->assertEquals(0, $this->client->getTimeout());
  1057. }
  1058.  
  1059. /**
  1060. * @dataProvider notBooleanProvider
  1061. * @expectedException InvalidArgumentException
  1062. * @covers MikeBrantRestClientLibRestClient::setFollowRedirects
  1063. */
  1064. public function testSetFollowRedirectsThrowsExceptions($boolean) {
  1065. $this->client->setFollowRedirects($boolean);
  1066. }
  1067.  
  1068. /**
  1069. * @covers MikeBrantRestClientLibRestClient::setFollowRedirects
  1070. * @covers MikeBrantRestClientLibRestClient::isFollowingRedirects
  1071. */
  1072. public function testSetFollowRedirects() {
  1073. $this->client->setFollowRedirects(true);
  1074. $this->assertTrue($this->client->isFollowingRedirects());
  1075. $this->client->setFollowRedirects(false);
  1076. $this->assertFalse($this->client->isFollowingRedirects());
  1077. }
  1078.  
  1079. /**
  1080. * @dataProvider notZeroOrPositiveIntegerProvider
  1081. * @expectedException InvalidArgumentException
  1082. * @covers MikeBrantRestClientLibRestClient::setMaxRedirects
  1083. */
  1084. public function testSetMaxRedirectsThrowsExceptions($int) {
  1085. $this->client->setMaxRedirects($int);
  1086. }
  1087.  
  1088. /**
  1089. * @covers MikeBrantRestClientLibRestClient::setMaxRedirects
  1090. * @covers MikeBrantRestClientLibRestClient::getMaxRedirects
  1091. */
  1092. public function testSetMaxRedirects() {
  1093. $this->client->setMaxRedirects(1);
  1094. $this->assertEquals(1, $this->client->getMaxRedirects());
  1095. $this->assertTrue($this->client->isFollowingRedirects());
  1096. $this->client->setMaxRedirects(0);
  1097. $this->assertEquals(0, $this->client->getMaxRedirects());
  1098. $this->assertTrue($this->client->isFollowingRedirects());
  1099. }
  1100.  
  1101. /**
  1102. * @expectedException Exception
  1103. * @covers MikeBrantRestClientLibRestClient::curlInit
  1104. */
  1105. public function testCurlInitThrowsException() {
  1106. self::$curlInitResponse = false;
  1107. $this->client->get('action');
  1108. }
  1109.  
  1110. /**
  1111. * @dataProvider curlExecExceptionProvider
  1112. * @expectedException Exception
  1113. * @covers MikeBrantRestClientLibRestClient::curlExec
  1114. */
  1115. public function testCurlExecThrowsException($response, $getinfo) {
  1116. self::$curlExecResponse = $response;
  1117. self::$curlErrorResponse = 'test error';
  1118. self::$curlGetinfoResponse = $getinfo;
  1119. $this->client->get('action');
  1120. }
  1121.  
  1122. /**
  1123. * @dataProvider buildUrlProvider
  1124. * @covers MikeBrantRestClientLibRestClient::get
  1125. * @covers MikeBrantRestClientLibRestClient::validateAction
  1126. * @covers MikeBrantRestClientLibRestClient::buildUrl
  1127. * @covers MikeBrantRestClientLibRestClient::curlSetup
  1128. * @covers MikeBrantRestClientLibRestClient::resetRequestResponseProperties
  1129. * @covers MikeBrantRestClientLibRestClient::curlInit
  1130. * @covers MikeBrantRestClientLibRestClient::setRequestUrl
  1131. * @covers MikeBrantRestClientLibRestClient::curlExec
  1132. * @covers MikeBrantRestClientLibRestClient::curlTeardown
  1133. * @covers MikeBrantRestClientLibRestClient::curlClose
  1134. */
  1135. public function testGet($useSsl, $host, $uriBase, $action, $expectedUrl) {
  1136. self::$curlExecResponse = $this->curlExecMockResponse;
  1137. self::$curlGetinfoResponse = $this->curlGetinfoMockResponse;
  1138. $this->client->setBasicAuthCredentials('user', 'password')
  1139. ->setHeaders(array('header' => 'header value'))
  1140. ->setUseSsl($useSsl)
  1141. ->setUseSslTestMode(true)
  1142. ->setFollowRedirects(true)
  1143. ->setMaxRedirects(1)
  1144. ->setremoteHost($host)
  1145. ->setUriBase($uriBase);
  1146. $response = $this->client->get($action);
  1147. $this->assertInstanceOf(CurlHttpResponse::class, $response);
  1148. $this->assertAttributeEquals(null, 'curl', $this->client);
  1149. }
  1150.  
  1151. /**
  1152. * @covers MikeBrantRestClientLibRestClient::post
  1153. * @covers MikeBrantRestClientLibRestClient::validateData
  1154. * @covers MikeBrantRestClientLibRestClient::setRequestData
  1155. */
  1156. public function testPost() {
  1157. self::$curlExecResponse = $this->curlExecMockResponse;
  1158. self::$curlGetinfoResponse = $this->curlGetinfoMockResponse;
  1159. $response = $this->client->post('', 'test post data');
  1160. $this->assertInstanceOf(CurlHttpResponse::class, $response);
  1161. $this->assertAttributeEquals(null, 'curl', $this->client);
  1162. }
  1163.  
  1164. /**
  1165. * @covers MikeBrantRestClientLibRestClient::put
  1166. */
  1167. public function testPut() {
  1168. self::$curlExecResponse = $this->curlExecMockResponse;
  1169. self::$curlGetinfoResponse = $this->curlGetinfoMockResponse;
  1170. $response = $this->client->put('', 'test put data');
  1171. $this->assertInstanceOf(CurlHttpResponse::class, $response);
  1172. $this->assertAttributeEquals(null, 'curl', $this->client);
  1173. }
  1174.  
  1175. /**
  1176. * @covers MikeBrantRestClientLibRestClient::delete
  1177. */
  1178. public function testDelete() {
  1179. self::$curlExecResponse = $this->curlExecMockResponse;
  1180. self::$curlGetinfoResponse = $this->curlGetinfoMockResponse;
  1181. $response = $this->client->delete('');
  1182. $this->assertInstanceOf(CurlHttpResponse::class, $response);
  1183. $this->assertAttributeEquals(null, 'curl', $this->client);
  1184. }
  1185.  
  1186. /**
  1187. * @covers MikeBrantRestClientLibRestClient::head
  1188. */
  1189. public function testHead() {
  1190. self::$curlExecResponse = '';
  1191. self::$curlGetinfoResponse = $this->curlGetinfoMockResponse;
  1192. $response = $this->client->head('');
  1193. $this->assertInstanceOf(CurlHttpResponse::class, $response);
  1194. $this->assertAttributeEquals(null, 'curl', $this->client);
  1195. }
  1196. }
  1197.  
  1198. <?php
  1199.  
  1200. namespace MikeBrantRestClientLib;
  1201.  
  1202. /**
  1203. * @desc Class representing HTTP response as returned from curl call.
  1204. */
  1205. class CurlHttpResponse
  1206. {
  1207. /**
  1208. * Variable to store response body
  1209. */
  1210. protected $body = null;
  1211.  
  1212. /**
  1213. * Variable to store HTTP repsonse code
  1214. *
  1215. * @var integer
  1216. */
  1217. protected $httpCode = null;
  1218.  
  1219. /**
  1220. * Variable to store response content type header
  1221. *
  1222. * @var string
  1223. */
  1224. protected $contentType = null;
  1225.  
  1226. /**
  1227. * Variable to store URL used in request as reported via curl_getinfo().
  1228. *
  1229. * @var string
  1230. */
  1231. protected $requestUrl = null;
  1232.  
  1233. /**
  1234. * Variable to store header used in request as reported via curl_getinfo().
  1235. *
  1236. * @var string
  1237. */
  1238. protected $requestHeader = null;
  1239.  
  1240. /**
  1241. * Variable to store curl getinfo array.
  1242. * See documentation at http://php.net/manual/en/function.curl-getinfo.php for expected array format.
  1243. *
  1244. * @var array
  1245. */
  1246. protected $curlGetinfo = null;
  1247.  
  1248. /**
  1249. * Constructor method.
  1250. *
  1251. * @param mixed $responseBody Response body as returned from a curl request.
  1252. * @param array $curlGetinto Array returned form curl_getinfo() function call for request.
  1253. * @return void
  1254. * @throws InvalidArgumentException
  1255. */
  1256. public function __construct($responseBody, array $curlGetinfo) {
  1257. $this->validateGetinfoArray($curlGetinfo);
  1258. $this->body = $responseBody;
  1259. $this->httpCode = $curlGetinfo['http_code'];
  1260. $this->contentType = $curlGetinfo['content_type'];
  1261. $this->requestUrl = $curlGetinfo['url'];
  1262. $this->requestHeader = $curlGetinfo['request_header'];
  1263. $this->curlGetinfo = $curlGetinfo;
  1264. }
  1265.  
  1266. /**
  1267. * Returns response body for request
  1268. *
  1269. * @return mixed
  1270. */
  1271. public function getBody() {
  1272. return $this->body;
  1273. }
  1274.  
  1275. /**
  1276. * Returns HTTP response code for request
  1277. *
  1278. * @return integer
  1279. */
  1280. public function getHttpCode() {
  1281. return $this->httpCode;
  1282. }
  1283.  
  1284. /**
  1285. * Returns URL used in request as reported via curl_getinfo().
  1286. *
  1287. * @return string
  1288. */
  1289. public function getRequestUrl() {
  1290. return $this->requestUrl;
  1291. }
  1292.  
  1293. /**
  1294. * Returns header used in request as reported via curl_getinfo().
  1295. *
  1296. * @return string
  1297. */
  1298. public function getRequestHeader() {
  1299. return $this->requestHeader;
  1300. }
  1301.  
  1302. /**
  1303. * Returns curl getinfo array.
  1304. * See documentation at http://php.net/manual/en/function.curl-getinfo.php for expected array format.
  1305. *
  1306. * @return array
  1307. */
  1308. public function getCurlGetinfo() {
  1309. return $this->curlGetinfo;
  1310. }
  1311.  
  1312. /**
  1313. * Method to perform minimal validation of input array as having keys expected to be returned from
  1314. * curl_getinfo().
  1315. *
  1316. * @throws InvalidArgumentException
  1317. */
  1318. protected function validateGetinfoArray(array $getinfo) {
  1319. if(empty($getinfo)) {
  1320. throw new InvalidArgumentException('Empty array passed. Valid curl_getinfo() result array expected.');
  1321. }
  1322. if(!isset($getinfo['http_code']) || !is_integer($getinfo['http_code'])) {
  1323. throw new InvalidArgumentException('curl_getinfo() response array expects integer value at http_code key.');
  1324. }
  1325. if(!isset($getinfo['content_type']) || !is_string($getinfo['content_type'])) {
  1326. throw new InvalidArgumentException('curl_getinfo() response array expects string value at content_type key.');
  1327. }
  1328. if(!isset($getinfo['url']) || !is_string($getinfo['url'])) {
  1329. throw new InvalidArgumentException('curl_getinfo() response array expects string value at url key.');
  1330. }
  1331. if(!isset($getinfo['request_header']) || !is_string($getinfo['request_header'])) {
  1332. throw new InvalidArgumentException('curl_getinfo() response array expects string value at request_header key.');
  1333. }
  1334. }
  1335. }
  1336.  
  1337. <?php
  1338.  
  1339. namespace MikeBrantRestClientLib;
  1340.  
  1341. use PHPUnitFrameworkTestCase;
  1342.  
  1343. class CurlHttpResponseTest extends TestCase
  1344. {
  1345. protected $curlExecMockResponse = 'Test Response';
  1346.  
  1347. protected $curlGetinfoMockResponse = array(
  1348. 'url' => 'http://google.com/',
  1349. 'content_type' => 'text/html; charset=UTF-8',
  1350. 'http_code' => 200,
  1351. 'header_size' => 321,
  1352. 'request_size' => 49,
  1353. 'filetime' => -1,
  1354. 'ssl_verify_result' => 0,
  1355. 'redirect_count' => 0,
  1356. 'total_time' => 1.123264,
  1357. 'namelookup_time' => 1.045272,
  1358. 'connect_time' => 1.070183,
  1359. 'pretransfer_time' => 1.071139,
  1360. 'size_upload' => 0,
  1361. 'size_download' => 219,
  1362. 'speed_download' => 194,
  1363. 'speed_upload' => 0,
  1364. 'download_content_length' => 219,
  1365. 'upload_content_length' => -1,
  1366. 'starttransfer_time' => 1.122377,
  1367. 'redirect_time' => 0,
  1368. 'redirect_url' => 'http://www.google.com/',
  1369. 'primary_ip' => '216.58.194.142',
  1370. 'certinfo' => array(),
  1371. 'primary_port' => 80,
  1372. 'local_ip' => '192.168.1.74',
  1373. 'local_port' => 59733,
  1374. 'request_header' => "GET / HTTP/1.1nHost: google.comnAccept: */*",
  1375. );
  1376.  
  1377. public function invalidGetinfoProvider() {
  1378. return array(
  1379. array(
  1380. array()
  1381. ),
  1382. array(
  1383. array('no keys')
  1384. ),
  1385. array(
  1386. array(
  1387. 'http_code' => 'not integer'
  1388. )
  1389. ),
  1390. array(
  1391. array(
  1392. 'http_code' => 200
  1393. )
  1394. ),
  1395. array(
  1396. array(
  1397. 'http_code' => 200,
  1398. 'content_type' => false
  1399. )
  1400. ),
  1401. array(
  1402. array(
  1403. 'http_code' => 200,
  1404. 'content_type' => 'text/html'
  1405. )
  1406. ),
  1407. array(
  1408. array(
  1409. 'http_code' => 200,
  1410. 'content_type' => 'text/html',
  1411. 'url' => false
  1412. )
  1413. ),
  1414. array(
  1415. array(
  1416. 'http_code' => 200,
  1417. 'content_type' => 'text/html',
  1418. 'url' => 'htttp://somedomain.com'
  1419. )
  1420. ),
  1421. array(
  1422. array(
  1423. 'http_code' => 200,
  1424. 'content_type' => 'text/html',
  1425. 'url' => 'htttp://somedomain.com',
  1426. 'request_header' => false
  1427. )
  1428. )
  1429. );
  1430. }
  1431.  
  1432. /**
  1433. * @dataProvider invalidGetinfoProvider
  1434. * @expectedException InvalidArgumentException
  1435. * @covers MikeBrantRestClientLibCurlHttpResponse::validateGetinfoArray
  1436. */
  1437. public function testValidateGetinfoArrayThrowsExceptions($getinfo) {
  1438. $response = new CurlHttpResponse('test', $getinfo);
  1439. }
  1440.  
  1441. /**
  1442. * @covers MikeBrantRestClientLibCurlHttpResponse::__construct
  1443. * @covers MikeBrantRestClientLibCurlHttpResponse::validateGetinfoArray
  1444. * @covers MikeBrantRestClientLibCurlHttpResponse::getBody
  1445. * @covers MikeBrantRestClientLibCurlHttpResponse::getHttpCode
  1446. * @covers MikeBrantRestClientLibCurlHttpResponse::getRequestUrl
  1447. * @covers MikeBrantRestClientLibCurlHttpResponse::getRequestHeader
  1448. * @covers MikeBrantRestClientLibCurlHttpResponse::getCurlGetinfo
  1449. */
  1450. public function testConstructor() {
  1451. $response = new CurlHttpResponse($this->curlExecMockResponse, $this->curlGetinfoMockResponse);
  1452. $this->assertEquals($this->curlExecMockResponse, $response->getBody());
  1453. $this->assertEquals($this->curlGetinfoMockResponse['http_code'], $response->getHttpCode());
  1454. $this->assertEquals($this->curlGetinfoMockResponse['url'], $response->getRequestUrl());
  1455. $this->assertEquals($this->curlGetinfoMockResponse['request_header'], $response->getRequestHeader());
  1456. $this->assertEquals($this->curlGetinfoMockResponse, $response->getCurlGetinfo());
  1457. }
  1458. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement