Merge pull request #15808 from civicrm/5.20
[civicrm-core.git] / CRM / Cxn / CiviCxnHttp.php
CommitLineData
5063e355
TO
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 */
10class 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 /**
041ecc95 20 * Singleton object.
21 *
5063e355 22 * @param bool $fresh
041ecc95 23 *
5063e355 24 * @return CRM_Cxn_CiviCxnHttp
041ecc95 25 * @throws \CRM_Core_Exception
5063e355
TO
26 */
27 public static function singleton($fresh = FALSE) {
28 if (self::$singleton === NULL || $fresh) {
be2fb01f 29 $cache = CRM_Utils_Cache::create([
a4704404 30 'name' => 'CiviCxnHttp',
be2fb01f 31 'type' => Civi::settings()->get('debug_enabled') ? 'ArrayCache' : ['SqlGroup', 'ArrayCache'],
a4704404 32 'prefetch' => FALSE,
be2fb01f 33 ]);
5063e355
TO
34
35 self::$singleton = new CRM_Cxn_CiviCxnHttp($cache);
36 }
37 return self::$singleton;
38 }
39
40 /**
041ecc95 41 * The cache data store.
42 *
43 * @param CRM_Utils_Cache_Interface|null $cache
5063e355
TO
44 */
45 public function __construct($cache) {
46 $this->cache = $cache;
47 }
48
49 /**
041ecc95 50 * Send.
51 *
5063e355
TO
52 * @param string $verb
53 * @param string $url
54 * @param string $blob
55 * @param array $headers
56 * Array of headers (e.g. "Content-type" => "text/plain").
57 * @return array
58 * array($headers, $blob, $code)
59 */
be2fb01f 60 public function send($verb, $url, $blob, $headers = []) {
5063e355
TO
61 $lowVerb = strtolower($verb);
62
63 if ($lowVerb === 'get' && $this->cache) {
dc73faee 64 $cachePath = 'get_' . md5($url);
5063e355
TO
65 $cacheLine = $this->cache->get($cachePath);
66 if ($cacheLine && $cacheLine['expires'] > CRM_Utils_Time::getTimeRaw()) {
67 return $cacheLine['data'];
68 }
69 }
70
71 $result = parent::send($verb, $url, $blob, $headers);
72
73 if ($lowVerb === 'get' && $this->cache) {
74 $expires = CRM_Utils_Http::parseExpiration($result[0]);
75 if ($expires !== NULL) {
dc73faee 76 $cachePath = 'get_' . md5($url);
be2fb01f 77 $cacheLine = [
5063e355
TO
78 'url' => $url,
79 'expires' => $expires,
80 'data' => $result,
be2fb01f 81 ];
5063e355
TO
82 $this->cache->set($cachePath, $cacheLine);
83 }
84 }
85
86 return $result;
87 }
88
f2ac86d1 89 /**
90 * Create stream options.
91 *
92 * @param string $verb
93 * @param string $url
94 * @param string $blob
95 * @param array $headers
96 *
97 * @return array
98 * @throws \Exception
99 */
5063e355
TO
100 protected function createStreamOpts($verb, $url, $blob, $headers) {
101 $result = parent::createStreamOpts($verb, $url, $blob, $headers);
102
be2fb01f 103 $caConfig = CA_Config_Stream::probe([
aaffa79f 104 'verify_peer' => (bool) Civi::settings()->get('verifySSL'),
be2fb01f 105 ]);
5063e355
TO
106 if ($caConfig->isEnableSSL()) {
107 $result['ssl'] = $caConfig->toStreamOptions();
108 }
109 if (!$caConfig->isEnableSSL() && preg_match('/^https:/', $url)) {
110 CRM_Core_Error::fatal('Cannot fetch document - system does not support SSL');
111 }
112
113 return $result;
114 }
115
8e2819ad 116 /**
041ecc95 117 * Get cache.
118 *
8e2819ad
TO
119 * @return \CRM_Utils_Cache_Interface|null
120 */
121 public function getCache() {
122 return $this->cache;
123 }
124
5063e355 125}