Skip to content

Commit 771a69b

Browse files
author
Willem Stuursma
committed
Update bundled cacert.pem file. Follows Mozilla's recommendations on invalid certificates. Always use certificate bundle, ignore old installed bundles. Enable HTTP Keep-Alive to enhance performance of multiple API calls
1 parent 9657b89 commit 771a69b

File tree

2 files changed

+892
-555
lines changed

2 files changed

+892
-555
lines changed

src/Mollie/API/Client.php

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Mollie_API_Client
3434
/**
3535
* Version of our client.
3636
*/
37-
const CLIENT_VERSION = "1.1.6";
37+
const CLIENT_VERSION = "1.1.7";
3838

3939
/**
4040
* Endpoint of the remote API.
@@ -93,6 +93,15 @@ class Mollie_API_Client
9393
*/
9494
protected $version_strings = array();
9595

96+
/**
97+
* This property will contain a cURL handle, which we will keep around to enable the re-use of of the TCP
98+
* connection. This saves re-negotiating the TLS handshake and setting up the new TCP connections when performing
99+
* multiple API calls.
100+
*
101+
* @var resource
102+
*/
103+
protected $ch;
104+
96105
public function __construct ()
97106
{
98107
$this->payments = new Mollie_API_Resource_Payments($this);
@@ -171,13 +180,27 @@ public function performHttpCall ($http_method, $api_method, $http_body = NULL)
171180
throw new Mollie_API_Exception("You have not set an API key. Please use setApiKey() to set the API key.");
172181
}
173182

174-
$url = $this->api_endpoint . "/" . self::API_VERSION . "/" . $api_method;
183+
if (empty($this->ch))
184+
{
185+
/*
186+
* Initialize a cURL handle.
187+
*/
188+
$this->ch = curl_init();
189+
}
190+
else
191+
{
192+
/*
193+
* Re-use the same cURL handle.
194+
*/
195+
curl_reset($this->ch);
196+
}
175197

176-
$ch = curl_init($url);
198+
$url = $this->api_endpoint . "/" . self::API_VERSION . "/" . $api_method;
177199

178-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
179-
curl_setopt($ch, CURLOPT_ENCODING, "");
180-
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
200+
curl_setopt($this->ch, CURLOPT_URL, $url);
201+
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, TRUE);
202+
curl_setopt($this->ch, CURLOPT_ENCODING, "");
203+
curl_setopt($this->ch, CURLOPT_TIMEOUT, 10);
181204

182205
$user_agent = join(' ', $this->version_strings);
183206

@@ -188,33 +211,30 @@ public function performHttpCall ($http_method, $api_method, $http_body = NULL)
188211
"X-Mollie-Client-Info: " . php_uname(),
189212
);
190213

191-
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $http_method);
214+
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $http_method);
192215

193216
if ($http_body !== NULL)
194217
{
195218
$request_headers[] = "Content-Type: application/json";
196-
curl_setopt($ch, CURLOPT_POST, 1);
197-
curl_setopt($ch, CURLOPT_POSTFIELDS, $http_body);
219+
curl_setopt($this->ch, CURLOPT_POST, 1);
220+
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $http_body);
198221
}
199222

200-
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
201-
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
202-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
223+
curl_setopt($this->ch, CURLOPT_HTTPHEADER, $request_headers);
224+
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 2);
225+
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, TRUE);
203226

204-
$body = curl_exec($ch);
227+
/*
228+
* On some servers, the list of installed certificates is outdated or not present at all (the ca-bundle.crt
229+
* is not installed). So we tell cURL which certificates we trust.
230+
*/
231+
curl_setopt($this->ch, CURLOPT_CAINFO, realpath(dirname(__FILE__) . "/cacert.pem"));
205232

206-
if (curl_errno($ch) == CURLE_SSL_CACERT || curl_errno($ch) == CURLE_SSL_PEER_CERTIFICATE || curl_errno($ch) == 77 /* CURLE_SSL_CACERT_BADFILE (constant not defined in PHP though) */)
207-
{
208-
/*
209-
* On some servers, the list of installed certificates is outdated or not present at all (the ca-bundle.crt
210-
* is not installed). So we tell cURL which certificates we trust. Then we retry the requests.
211-
*/
212-
$request_headers[] = "X-Mollie-Debug: used shipped root certificates";
213-
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
214-
curl_setopt($ch, CURLOPT_CAINFO, realpath(dirname(__FILE__) . "/cacert.pem"));
215-
$body = curl_exec($ch);
233+
$body = curl_exec($this->ch);
216234

217-
if (strpos(curl_error($ch), "error setting certificate verify locations") !== FALSE)
235+
if (curl_errno($this->ch) == CURLE_SSL_CACERT || curl_errno($this->ch) == CURLE_SSL_PEER_CERTIFICATE || curl_errno($this->ch) == 77 /* CURLE_SSL_CACERT_BADFILE (constant not defined in PHP though) */)
236+
{
237+
if (strpos(curl_error($this->ch), "error setting certificate verify locations") !== FALSE)
218238
{
219239
/*
220240
* Error setting CA-file. Could be missing, or there is a bug in OpenSSL with too long paths.
@@ -224,28 +244,39 @@ public function performHttpCall ($http_method, $api_method, $http_body = NULL)
224244
*/
225245
array_shift($request_headers);
226246
$request_headers[] = "X-Mollie-Debug: unable to use shipped root certificaties, no peer validation.";
227-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
228-
$body = curl_exec($ch);
247+
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, FALSE);
248+
$body = curl_exec($this->ch);
229249
}
230250
}
231251

232-
if (strpos(curl_error($ch), "certificate subject name 'mollie.nl' does not match target host") !== FALSE)
252+
if (strpos(curl_error($this->ch), "certificate subject name 'mollie.nl' does not match target host") !== FALSE)
233253
{
234254
/*
235255
* On some servers, the wildcard SSL certificate is not processed correctly. This happens with OpenSSL 0.9.7
236256
* from 2003.
237257
*/
238258
$request_headers[] = "X-Mollie-Debug: old OpenSSL found";
239-
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
240-
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
241-
$body = curl_exec($ch);
259+
curl_setopt($this->ch, CURLOPT_HTTPHEADER, $request_headers);
260+
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
261+
$body = curl_exec($this->ch);
242262
}
243263

244-
if (curl_errno($ch))
264+
if (curl_errno($this->ch))
245265
{
246-
throw new Mollie_API_Exception("Unable to communicate with Mollie (".curl_errno($ch)."): " . curl_error($ch) . ".");
266+
throw new Mollie_API_Exception("Unable to communicate with Mollie (".curl_errno($this->ch)."): " . curl_error($this->ch) . ".");
247267
}
248268

249269
return $body;
250270
}
271+
272+
/**
273+
* Destroy cURL handle if is still exist.
274+
*/
275+
public function __destruct ()
276+
{
277+
if (is_resource($this->ch))
278+
{
279+
curl_close($this->ch);
280+
}
281+
}
251282
}

0 commit comments

Comments
 (0)