PageRenderTime 39ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/php/src/Proxy.php

https://github.com/znarf/nvo
PHP | 255 lines | 113 code | 26 blank | 116 comment | 20 complexity | 7de9252a94f11d67bf429ea47b59ce0d MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /**
  3. * Copyright (c) 2008 Netvibes (http://www.netvibes.org/).
  4. *
  5. * This file is part of Netvibes Widget Platform.
  6. *
  7. * Netvibes Widget Platform is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * Netvibes Widget Platform is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with Netvibes Widget Platform. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. require_once 'Zend/Json.php';
  21. require_once 'Zend/Http/Client.php';
  22. /**
  23. * Proxy to handle Ajax calls.
  24. */
  25. class Proxy
  26. {
  27. /**
  28. * HTTP Request User Agent.
  29. */
  30. const USER_AGENT = 'Netvibes Exposition Proxy';
  31. /**
  32. * Response body.
  33. *
  34. * @var string
  35. */
  36. public $body = null;
  37. /**
  38. * Target URL.
  39. *
  40. * @var string
  41. */
  42. private $_url = null;
  43. /**
  44. * HTTP Client.
  45. *
  46. * @var Zend_Http_Client
  47. */
  48. private $_client = null;
  49. /**
  50. * HTTP Response.
  51. *
  52. * @var Zend_Http_Response
  53. */
  54. private $_response = null;
  55. /**
  56. * HTTP method.
  57. *
  58. * @var string
  59. */
  60. private $_method = 'GET';
  61. /**
  62. * Reponse type.
  63. *
  64. * @var string
  65. */
  66. private $_type = 'text';
  67. /**
  68. * JavaScript callback function.
  69. *
  70. * @var array
  71. */
  72. private $_callback = null;
  73. /**
  74. * Mime types to be used in responses headers.
  75. *
  76. * @var array
  77. */
  78. private $_mimeTypes = array(
  79. 'xml' => 'text/xml',
  80. 'html' => 'text/html',
  81. 'feed' => 'application/json',
  82. 'json' => 'application/json',
  83. 'text' => 'text/plain'
  84. );
  85. /**
  86. * Cache key.
  87. *
  88. * @var string
  89. */
  90. private $_key = null;
  91. /**
  92. * Cache object.
  93. *
  94. * @var Zend_Cache
  95. */
  96. private $_cache = null;
  97. /**
  98. * Cache lifetime.
  99. *
  100. * @var integer
  101. */
  102. private $_cachetime = 0;
  103. /**
  104. * Constructor.
  105. *
  106. * @param string $url
  107. * @param array $options
  108. */
  109. public function __construct($url, $options = array())
  110. {
  111. if (empty($url)) {
  112. throw new Exception('No URL has been set');
  113. }
  114. $this->_url = $url;
  115. $this->_key = 'ajax_' . md5($this->_url);
  116. foreach ($options as $name => $value) {
  117. if ($name == 'type') {
  118. $this->_type = $value;
  119. } else if ($name == 'cachetime') {
  120. $this->_cachetime = $value;
  121. }
  122. }
  123. $options = array(
  124. 'useragent' => self::USER_AGENT,
  125. 'timeout' => '60',
  126. 'maxredirects' => 5
  127. );
  128. $this->_client = new Zend_Http_Client($this->_url, $options);
  129. $registry = Zend_Registry::getInstance();
  130. $this->_cache = $registry['cache'];
  131. }
  132. /**
  133. * Sets the HTTP client options.
  134. *
  135. * @param array $options
  136. */
  137. public function setHttpClientOptions($options)
  138. {
  139. foreach ($options as $name => $value) {
  140. $setter = 'set' . ucfirst($name);
  141. if ($setter == 'setAuth') {
  142. $this->_client->$setter($value['username'], $value['password'], Zend_Http_Client::AUTH_BASIC);
  143. } else {
  144. $this->_client->$setter($value);
  145. }
  146. }
  147. }
  148. /**
  149. * Checks if the result is cachable.
  150. *
  151. * @return True if the result is cachable, otherwise false.
  152. */
  153. public function isCachable()
  154. {
  155. return ($this->_method == 'GET' && $this->_response->getStatus() == 200);
  156. }
  157. /**
  158. * Retrieves the response body.
  159. *
  160. * @return The response body
  161. */
  162. public function getBody()
  163. {
  164. $cache = $this->getCache();
  165. if ($cache) {
  166. $body = $cache->load($this->_key . '_body');
  167. }
  168. if (empty($body)) {
  169. try {
  170. $this->_response = $this->_client->request();
  171. } catch (Zend_Http_Client_Exception $e) {
  172. error_log("Http exception via AjaxProxy on " . $this->_url);
  173. return null;
  174. }
  175. if ($this->_response->getStatus() == 503) { // Service unavailable
  176. header('HTTP/1.1 ' . $this->_response->getStatus() . ' ' . $this->_response->getMessage());
  177. exit;
  178. }
  179. $body = $this->_response->getBody();
  180. if ($cache && $this->isCachable() && strlen($body) < 200000) {
  181. $cache->save($body, $this->_key . '_body');
  182. }
  183. }
  184. return $body;
  185. }
  186. /**
  187. * Sends the Ajax reponse.
  188. */
  189. public function sendResponse()
  190. {
  191. $body = $this->getBody();
  192. // experimental, encode utf8 automatically
  193. if (!$this->isUtf8Encoded($body)) {
  194. $body = utf8_encode($body);
  195. }
  196. $mimeType = $this->_mimeTypes[$this->_type];
  197. header("Content-Type: $mimeType");
  198. echo $body;
  199. }
  200. /**
  201. * Detects if a string is UTF-8 encoded.
  202. * @see http://us2.php.net/mb_detect_encoding
  203. *
  204. * @param string $string
  205. * @return boolean True is the string is UTF-8 encoded, otherwise false.
  206. */
  207. public static function isUtf8Encoded($string)
  208. {
  209. $match = preg_match('%(?:
  210. [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
  211. |\xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
  212. |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
  213. |\xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
  214. |\xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
  215. |[\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
  216. |\xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
  217. )+%xs', $string);
  218. return ($match > 0);
  219. }
  220. /**
  221. * Retrieves the cache instance.
  222. *
  223. * @return Zend_Cache
  224. */
  225. public function getCache()
  226. {
  227. return $this->_cache;
  228. }
  229. }