Merge pull request #6987 from xurizaemon/CRM-17212
[civicrm-core.git] / CRM / Cxn / CiviCxnHttp.php
1 <?php
2
3 /**
4 * Class CRM_Cxn_CiviCxnHttp
5 *
6 * This extends the PhpHttp client used by CiviConnect and adds:
7 * - Force-cache support for GET requests
8 * - Compliance with SSL policy
9 */
10 class CRM_Cxn_CiviCxnHttp extends \Civi\Cxn\Rpc\Http\PhpHttp {
11
12 protected static $singleton = NULL;
13
14 /**
15 * @var CRM_Utils_Cache_Interface|null
16 */
17 protected $cache;
18
19 /**
20 * @param bool $fresh
21 * @return CRM_Cxn_CiviCxnHttp
22 */
23 public static function singleton($fresh = FALSE) {
24 if (self::$singleton === NULL || $fresh) {
25 $cache = CRM_Utils_Cache::create(array(
26 'name' => 'CiviCxnHttp',
27 'type' => Civi::settings()->get('debug_enabled') ? 'ArrayCache' : array('SqlGroup', 'ArrayCache'),
28 'prefetch' => FALSE,
29 ));
30
31 self::$singleton = new CRM_Cxn_CiviCxnHttp($cache);
32 }
33 return self::$singleton;
34 }
35
36 /**
37 * @param CRM_Utils_Cache_Interface|NULL $cache
38 * The cache data store.
39 */
40 public function __construct($cache) {
41 $this->cache = $cache;
42 }
43
44 /**
45 * @param string $verb
46 * @param string $url
47 * @param string $blob
48 * @param array $headers
49 * Array of headers (e.g. "Content-type" => "text/plain").
50 * @return array
51 * array($headers, $blob, $code)
52 */
53 public function send($verb, $url, $blob, $headers = array()) {
54 $lowVerb = strtolower($verb);
55
56 if ($lowVerb === 'get' && $this->cache) {
57 $cachePath = 'get/' . md5($url);
58 $cacheLine = $this->cache->get($cachePath);
59 if ($cacheLine && $cacheLine['expires'] > CRM_Utils_Time::getTimeRaw()) {
60 return $cacheLine['data'];
61 }
62 }
63
64 $result = parent::send($verb, $url, $blob, $headers);
65
66 if ($lowVerb === 'get' && $this->cache) {
67 $expires = CRM_Utils_Http::parseExpiration($result[0]);
68 if ($expires !== NULL) {
69 $cachePath = 'get/' . md5($url);
70 $cacheLine = array(
71 'url' => $url,
72 'expires' => $expires,
73 'data' => $result,
74 );
75 $this->cache->set($cachePath, $cacheLine);
76 }
77 }
78
79 return $result;
80 }
81
82 protected function createStreamOpts($verb, $url, $blob, $headers) {
83 $result = parent::createStreamOpts($verb, $url, $blob, $headers);
84
85 $caConfig = CA_Config_Stream::probe(array(
86 'verify_peer' => (bool) CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'verifySSL'),
87 ));
88 if ($caConfig->isEnableSSL()) {
89 $result['ssl'] = $caConfig->toStreamOptions();
90 }
91 if (!$caConfig->isEnableSSL() && preg_match('/^https:/', $url)) {
92 CRM_Core_Error::fatal('Cannot fetch document - system does not support SSL');
93 }
94
95 return $result;
96 }
97
98 }