PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/php/ProxyClasses.php

https://github.com/phpmaps/election-results
PHP | 633 lines | 495 code | 93 blank | 45 comment | 58 complexity | 775fd53f99683fffcd66cde9d229918a MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. <?php
  2. define("LOG_TO_FILE", 0);
  3. define("LOG_TO_CLIENT", 1);
  4. define("LOG_TO_CLIENT_AND_FILE", 2);
  5. /**
  6. * The ProxClasses file contains three simple classes 1) RestRequest 2) ProxyLog 3) RestRequest
  7. */
  8. /**
  9. *
  10. * Proxy is designed to take in request from client and handle it according to the configuration options
  11. * found in the proxy.php file
  12. *
  13. * PHP version 5.3.6
  14. */
  15. class Proxy {
  16. public $_files = array ();
  17. public $_post = array ();
  18. public $_get = array ();
  19. public $_allowedMimeTypes = array();
  20. public $_queryString;
  21. public $_tempPath;
  22. public $_allowedDomains = array();
  23. public $_requireMatch = true;
  24. public $_defaultUrl;
  25. public $_useGet;
  26. public $_errorReporting;
  27. public $_logPath;
  28. public $_logErrors;
  29. public $_logLevel;
  30. public $log;
  31. public function __construct(array $options = null) {
  32. if (is_array($options)) {
  33. $this->setOptions($options);
  34. }
  35. $this->postConstruct();
  36. $this->initLogging();
  37. }
  38. public function __set($name, $value)
  39. {
  40. $method = 'set' . $name;
  41. if (('mapper' == $name) || !method_exists($this, $method)) {
  42. throw new Exception('Invalid proxy property. (line 50)');
  43. }
  44. $this->$method($value);
  45. }
  46. public function __get($name)
  47. {
  48. $method = 'get' . $name;
  49. if (('mapper' == $name) || !method_exists($this, $method)) {
  50. throw new Exception('Invalid proxy property. (line 59)');
  51. }
  52. return $this->$method();
  53. }
  54. public function getQueryString() {
  55. return $this->_queryString;
  56. }
  57. public function setQueryString($queryString) {
  58. $this->_queryString = $queryString;
  59. return $this;
  60. }
  61. public function getAllowedDomains() {
  62. return $this->_allowedDomains;
  63. }
  64. public function setAllowedDomains($allowedDomains) {
  65. $this->_allowedDomains = $allowedDomains;
  66. return $this;
  67. }
  68. public function getAllowedMimeTypes() {
  69. return $this->_allowedMimeTypes;
  70. }
  71. public function setAllowedMimeTypes($allowedMimeTypes) {
  72. $this->_allowedMimeTypes = $allowedMimeTypes;
  73. return $this;
  74. }
  75. public function getUseGet() {
  76. return $this->_useGet;
  77. }
  78. public function setUseGet($useGet) {
  79. $this->_useGet = $useGet;
  80. return $this;
  81. }
  82. public function getErrorReporting() {
  83. return $this->_errorReporting;
  84. }
  85. public function setErrorReporting() {
  86. $this->_errorReporting = $errorReporting;
  87. return $this;
  88. }
  89. public function getLogErrors() {
  90. return $this->_logErrors;
  91. }
  92. public function setLogErrors($logErrors) {
  93. $this->_logErrors = $logErrors;
  94. return $this;
  95. }
  96. public function getLogLevel() {
  97. return $this->_logLevel;
  98. }
  99. public function setLogLevel($logLevel) {
  100. $this->_logLevel = $logLevel;
  101. return $this;
  102. }
  103. public function getLogPath() {
  104. return $this->_logPath;
  105. }
  106. public function setLogPath($logPath) {
  107. $this->_logPath = $logPath;
  108. return $this;
  109. }
  110. public function getDefaultUrl() {
  111. return $this->_defaultUrl;
  112. }
  113. public function setDefaultUrl($defaultUrl) {
  114. $this->_defaultUrl = $defaultUrl;
  115. return $this;
  116. }
  117. public function getTempPath() {
  118. return $this->_tempPath;
  119. }
  120. public function setTempPath($tempPath) {
  121. $this->_tempPath = $tempPath;
  122. return $this;
  123. }
  124. public function getRequireMatch() {
  125. return $this->_requireMatch;
  126. }
  127. public function setRequireMatch($requireMatch) {
  128. $this->_requireMatch = $requireMatch;
  129. return $this;
  130. }
  131. public function getGet() {
  132. return $this->_get;
  133. }
  134. public function setGet($get) {
  135. $this->_get = $get;
  136. return $this;
  137. }
  138. public function getFiles() {
  139. return $this->_files;
  140. }
  141. public function setFiles($files) {
  142. $this->_files = $files;
  143. return $this;
  144. }
  145. public function getPost() {
  146. return $this->_post;
  147. }
  148. public function setPost($post) {
  149. $this->_post = $post;
  150. return $this;
  151. }
  152. public function setOptions(array $options)
  153. {
  154. $methods = get_class_methods($this);
  155. foreach ($options as $key => $value) {
  156. if ($key == "errorReporting") {
  157. $this->setOptions($value);
  158. continue;
  159. }
  160. $method = 'set' . ucfirst($key);
  161. if (in_array($method, $methods)) {
  162. $this->$method($value);
  163. }
  164. }
  165. return $this;
  166. }
  167. public function postConstruct() {
  168. if(!isset($this->_allowedDomains) || empty($this->_allowedDomains)){
  169. $this->_allowedDomains = array("url" => $this->_defaultUrl, "mustMatch" => true, "token" =>"");
  170. }else{
  171. array_push($this->_allowedDomains, array("url" => $this->_defaultUrl, "mustMatch" => true, "token" =>""));
  172. }
  173. if(!isset($this->_queryString) || empty($this->_queryString)){
  174. $this->setQueryString($this->_defaultUrl);
  175. }
  176. }
  177. public function initLogging() {
  178. $this->log = new ProxyLog($this->_logPath, $this->_logLevel);
  179. }
  180. /**
  181. * Delegate method will POST values or files to a specified server and returns the server's response.
  182. * To call this method, ProxyPost::_queryString must be set with a URL as string which supports Esri Web API proxy pattern.
  183. * Delegate retuns an associative array. Potential keys within this array are: status, type, response.
  184. *
  185. * @var bool
  186. * @return <array>
  187. */
  188. public function delegate() {
  189. if ($this->_requireMatch) {
  190. $pos = $this->is_url_allowed ();
  191. }
  192. if (isset ( $this->_files ) && ! empty ( $this->_files )) {
  193. $upload_path = $this->getTempPath ();
  194. foreach ( $this->_files as $key => $value ) {
  195. if ($value ["error"] == UPLOAD_ERR_OK) {
  196. $file = $upload_path . $value ["name"];
  197. move_uploaded_file ( $value ["tmp_name"], $file );
  198. $t ['file'] = '@' . $upload_path . $value ["name"];
  199. $t = array_merge ( $t, $this->_post );
  200. $restRequest = new RestRequest ( array ("url" => $this->_queryString, "method" => 'FILE', "requestBody" => null, "file" => $t, "log" => $this->log));
  201. $restRequest->executeFile ();
  202. unlink($file);
  203. } else {
  204. $this->log->report("Unknown error happened when moving file.");
  205. }
  206. }
  207. } else {
  208. if($this->_useGet) {
  209. $parts = preg_split("/\?/", $this->_queryString);
  210. if (count($parts) <= 1) {
  211. $needle = '&'; // http://en.wikipedia.org/wiki/Percent-encoding (observed PHP does odd things with & character)
  212. $haystack = $parts[0];
  213. $pos = strpos($haystack,$needle);
  214. if($pos >= 1) {
  215. $this->log->report("URL contains no question mark and contains invalid character.");
  216. }
  217. }
  218. $restRequest = new RestRequest ( array ("url" => $this->_queryString, "method" => 'GET', "requestBody" => null, "log" => $this->log ));
  219. $restRequest->execute ();
  220. }else{
  221. $restRequest = new RestRequest ( array ("url" => $this->_queryString, "method" => 'POST', "requestBody" => $this->getPost (), "log" => $this->log));
  222. $restRequest->execute ();
  223. }
  224. }
  225. return $this->executeComplete ( $restRequest );
  226. }
  227. public function is_url_allowed() {
  228. $pos = false;
  229. $parts = preg_split("/\?/", $this->_queryString);
  230. $requestedUrl = $parts[0];
  231. for($i = 0, $len = count ( $this->_allowedDomains ); $i < $len; $i ++) {
  232. $value = $this->_allowedDomains [$i];
  233. $allowedDomain = $value['url'];
  234. if ($value ['mustMatch']) {
  235. if (stripos ( $requestedUrl, $allowedDomain ) === 0) {
  236. $pos = $i;
  237. break;
  238. }
  239. if ((strcasecmp ( $requestedUrl, $allowedDomain ) == 0)) {
  240. $pos = $i;
  241. break;
  242. }
  243. } else {
  244. //mustMatch is false
  245. $pos = $i;
  246. }
  247. }
  248. if ($pos === false) {
  249. header ( 'Status: 403', true, 403 );
  250. $this->log->report("Target URL is not allowed!");
  251. } else {
  252. $token = $this->_allowedDomains [$pos] ['token'];
  253. if ($token) {
  254. $this->_queryString .= (stripos ( $this->_queryString, "?" ) !== false ? '&' : '?') . 'token=' . $token;
  255. }
  256. }
  257. return $pos;
  258. }
  259. public function executeComplete($restRequest) {
  260. $responseInfo = $restRequest->getResponseInfo ();
  261. return array ("status" => $responseInfo ['http_code'], "type" => $responseInfo ['content_type'], "response" => $restRequest->getResponseBody () );
  262. }
  263. }
  264. /**
  265. * RestRequest class handles all communication to REST Services
  266. *
  267. * PHP version 5.3.6
  268. * @category Logging
  269. * @package ProxyLog
  270. * @version v10 $Revision: 05-20-12 19:27:56 A $
  271. * @link http://www.esri.com
  272. * @see proxy.php (example usage)
  273. * @since 05-20-12 19:27:56
  274. * @deprecated File deprecated in Release v10.1
  275. */
  276. class ProxyLog
  277. {
  278. public $_timeFormat = 'm-d-y H:i:s - ';
  279. public $_eol = "\r\n";
  280. public $_indent = " ";
  281. public $_logPath;
  282. public $_logLevel;
  283. public function __construct($logPath = null, $logLevel = null)
  284. {
  285. $this->_logPath = $logPath;
  286. $this->_logLevel = $logLevel;
  287. }
  288. public function getTime()
  289. {
  290. return date($this->_timeFormat);
  291. }
  292. public function fileLog($error_message)
  293. {
  294. if(isset($this->_logPath)) {
  295. try {
  296. $fh = null;
  297. if (file_exists($this->_logPath)) {
  298. if (is_writable($this->_logPath)) {
  299. $fh = fopen($this->_logPath, 'a');
  300. fwrite($fh, $this->_eol);
  301. fwrite($fh, $this->getTime());
  302. fwrite($fh, $this->_indent);
  303. fwrite($fh, $error_message);
  304. }
  305. } else {
  306. $fh = fopen($this->_logPath, 'w');
  307. fwrite($fh, $this->getTime());
  308. fwrite($fh, $this->_indent);
  309. fwrite($fh, "Proxy log created.");
  310. fwrite($fh, $this->_eol);
  311. fwrite($fh, $this->getTime());
  312. fwrite($fh, $this->_indent);
  313. fwrite($fh, $error_message);
  314. }
  315. fclose($fh);
  316. } catch (Exception $e) {
  317. throw new Exception('Logging error occured. (line 375)');
  318. }
  319. }else{
  320. if($this->_logLevel == 1 || $this->_logLevel == 2) {
  321. throw new Exception('Logging error occured. ' . $error_message . ' (line 379)');
  322. }
  323. }
  324. }
  325. public function clientLog($error_message)
  326. {
  327. exit($error_message);
  328. }
  329. public function report($error_message)
  330. {
  331. if ($this->_logLevel == 0) {
  332. $this->fileLog($error_message);
  333. } elseif ($this->_logLevel == 1) {
  334. $this->clientLog($error_message);
  335. } elseif ($this->_logLevel == 2) {
  336. $this->fileLog($error_message);
  337. $this->clientLog($error_message);
  338. }
  339. }
  340. }
  341. /**
  342. * RestRequest class handles all communication to REST Services
  343. *
  344. * PHP version 5.3.6
  345. * @category Communication
  346. * @package RestRequest
  347. * @version v10 $Revision: 05-20-12 19:27:56 A $
  348. * @link http://www.esri.com
  349. * @see proxy.php (example usage)
  350. * @since 05-20-12 19:27:56
  351. * @deprecated File deprecated in Release v10.1
  352. */
  353. class RestRequest {
  354. public $_url;
  355. public $_method;
  356. public $_requestBody;
  357. public $_file;
  358. public $_requestLength;
  359. public $_responseBody;
  360. public $_responseInfo;
  361. public $log;
  362. public function __construct(array $options = null) {
  363. if (is_array($options)) {
  364. $this->setOptions($options);
  365. }
  366. if ($this->_requestBody !== null) {
  367. $this->buildPostBody ();
  368. }
  369. }
  370. public function __set($name, $value)
  371. {
  372. $method = 'set' . $name;
  373. if (('mapper' == $name) || !method_exists($this, $method)) {
  374. throw new Exception('Error occured before logging was enabled. (line 440)');
  375. }
  376. $this->$method($value);
  377. }
  378. public function __get($name)
  379. {
  380. $method = 'get' . $name;
  381. if (('mapper' == $name) || !method_exists($this, $method)) {
  382. throw new Exception('Error occured before logging was enabled. (line 449)');
  383. }
  384. return $this->$method();
  385. }
  386. public function getRequestBody() {
  387. return $this->_requestBody;
  388. }
  389. public function setRequestBody($requestBody) {
  390. $this->_requestBody = $requestBody;
  391. return $this;
  392. }
  393. public function getLog() {
  394. return $this->log;
  395. }
  396. public function setLog($log) {
  397. $this->log = $log;
  398. return $this;
  399. }
  400. public function getResponseBody() {
  401. return $this->_responseBody;
  402. }
  403. public function setResponseBody($responseBody) {
  404. $this->_responseBody = $responseBody;
  405. return $this;
  406. }
  407. public function getResponseInfo() {
  408. return $this->_responseInfo;
  409. }
  410. public function setResponseInfo($responseInfo) {
  411. $this->_responseInfo = $responseInfo;
  412. return $this;
  413. }
  414. public function getUrl() {
  415. return $this->_url;
  416. }
  417. public function setUrl($url) {
  418. $this->_url = $url;
  419. return $this;
  420. }
  421. public function getMethod() {
  422. return $this->_method;
  423. }
  424. public function setMethod($method) {
  425. $this->_method = $method;
  426. return $this;
  427. }
  428. public function getFile() {
  429. return $this->_file;
  430. }
  431. public function setFile($file) {
  432. $this->_file = $file;
  433. return $this;
  434. }
  435. public function getRequestLength() {
  436. return $this->_requestLength;
  437. }
  438. public function setRequestLength($requestLength) {
  439. $this->_requestLength = $requestLength;
  440. return $this;
  441. }
  442. public function setOptions(array $options)
  443. {
  444. $methods = get_class_methods($this);
  445. foreach ($options as $key => $value) {
  446. $method = 'set' . ucfirst($key);
  447. if (in_array($method, $methods)) {
  448. $this->$method($value);
  449. }
  450. }
  451. return $this;
  452. }
  453. public function buildPostBody($data = null) {
  454. $data = ($data !== null) ? $data : $this->_requestBody;
  455. if (! is_array ( $data )) {
  456. $this->log->report("Invalid data input recieved.");
  457. }
  458. $data = http_build_query ( $data, '', '&' );
  459. $this->_requestBody = $data;
  460. }
  461. public function execute() {
  462. $curl = curl_init ();
  463. try {
  464. switch (strtoupper ( $this->_method )) {
  465. case 'GET' :
  466. $this->executeGet ( $curl );
  467. break;
  468. case 'FILE' :
  469. $this->executeFile ( $curl );
  470. break;
  471. case 'POST' :
  472. $this->executePost ( $curl );
  473. break;
  474. case 'PUT' :
  475. $this->executePut ( $curl );
  476. break;
  477. case 'DELETE' :
  478. $this->executeDelete ( $curl );
  479. break;
  480. default :
  481. $this->log->report('Current method (' . $this->_method . ') is an invalid REST method.');
  482. }
  483. } catch ( InvalidArgumentException $e ) {
  484. curl_close ( $curl );
  485. $this->log->report($e);
  486. } catch ( Exception $e ) {
  487. curl_close ( $curl );
  488. $this->log->report($e);
  489. }
  490. }
  491. protected function setCurlOpts(&$curl) {
  492. curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, false ); // Weak setting not designed for production. http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/
  493. curl_setopt ( $curl, CURLOPT_URL, $this->_url );
  494. curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, true );
  495. curl_setopt ( $curl, CURLOPT_FOLLOWLOCATION, 1 );
  496. }
  497. protected function doExecute(&$curl) {
  498. $this->setCurlOpts ( $curl );
  499. $this->_responseBody = curl_exec ( $curl );
  500. $this->_responseInfo = curl_getinfo ( $curl );
  501. curl_close ( $curl );
  502. }
  503. public function executeFile() {
  504. $curl = curl_init ();
  505. curl_setopt ( $curl, CURLOPT_POST, 1 );
  506. curl_setopt ( $curl, CURLOPT_POSTFIELDS, $this->_file );
  507. $this->doExecute ( $curl );
  508. }
  509. protected function executePost($curl) {
  510. if (! is_string ( $this->_requestBody )) {
  511. $this->buildPostBody ();
  512. }
  513. curl_setopt ( $curl, CURLOPT_POST, 1 );
  514. curl_setopt ( $curl, CURLOPT_POSTFIELDS, $this->_requestBody );
  515. $this->doExecute ( $curl );
  516. }
  517. protected function executePut($curl) {
  518. if (! is_string ( $this->_requestBody )) {
  519. $this->buildPostBody ();
  520. }
  521. $this->_requestLength = strlen ( $this->_requestBody );
  522. $fh = fopen ( 'php://memory', 'rw' );
  523. fwrite ( $fh, $this->_requestBody );
  524. rewind ( $fh );
  525. curl_setopt ( $curl, CURLOPT_INFILE, $fh );
  526. curl_setopt ( $curl, CURLOPT_INFILESIZE, $this->_requestLength );
  527. curl_setopt ( $curl, CURLOPT_PUT, true );
  528. $this->doExecute ( $curl );
  529. fclose ( $fh );
  530. }
  531. protected function executeDelete($curl) {
  532. curl_setopt ( $curl, CURLOPT_CUSTOMREQUEST, 'DELETE' );
  533. $this->doExecute ( $curl );
  534. }
  535. protected function executeGet($curl) {
  536. $this->doExecute ( $curl );
  537. }
  538. }