Merge pull request #15314 from jitendrapurohit/dev-1255
[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 * Singleton object.
21 *
22 * @param bool $fresh
23 *
24 * @return CRM_Cxn_CiviCxnHttp
25 * @throws \CRM_Core_Exception
26 */
27 public static function singleton($fresh = FALSE) {
28 if (self::$singleton === NULL || $fresh) {
29 $cache = CRM_Utils_Cache::create([
30 'name' => 'CiviCxnHttp',
31 'type' => Civi::settings()->get('debug_enabled') ? 'ArrayCache' : ['SqlGroup', 'ArrayCache'],
32 'prefetch' => FALSE,
33 ]);
34
35 self::$singleton = new CRM_Cxn_CiviCxnHttp($cache);
36 }
37 return self::$singleton;
38 }
39
40 /**
41 * The cache data store.
42 *
43 * @param CRM_Utils_Cache_Interface|null $cache
44 */
45 public function __construct($cache) {
46 $this->cache = $cache;
47 }
48
49 /**
50 * Send.
51 *
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 */
60 public function send($verb, $url, $blob, $headers = []) {
61 $lowVerb = strtolower($verb);
62
63 if ($lowVerb === 'get' && $this->cache) {
64 $cachePath = 'get_' . md5($url);
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) {
76 $cachePath = 'get_' . md5($url);
77 $cacheLine = [
78 'url' => $url,
79 'expires' => $expires,
80 'data' => $result,
81 ];
82 $this->cache->set($cachePath, $cacheLine);
83 }
84 }
85
86 return $result;
87 }
88
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 */
100 protected function createStreamOpts($verb, $url, $blob, $headers) {
101 $result = parent::createStreamOpts($verb, $url, $blob, $headers);
102
103 $caConfig = CA_Config_Stream::probe([
104 'verify_peer' => (bool) Civi::settings()->get('verifySSL'),
105 ]);
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
116 /**
117 * Get cache.
118 *
119 * @return \CRM_Utils_Cache_Interface|null
120 */
121 public function getCache() {
122 return $this->cache;
123 }
124
125 }