Skip to content

Commit c762233

Browse files
authored
Merge branch 'master' into fetch-with-include
2 parents 254cca3 + ee2a5fa commit c762233

26 files changed

+664
-3
lines changed

.github/workflows/ci.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ jobs:
2626
strategy:
2727
matrix:
2828
include:
29-
- name: PHP 8.1
30-
PHP_VERSION: 8.1
3129
- name: PHP 8.2
3230
PHP_VERSION: 8.2
31+
- name: PHP 8.1
32+
PHP_VERSION: 8.1
3333
fail-fast: false
34+
name: Test ${{ matrix.name }}
3435
steps:
3536
- uses: actions/checkout@v3
3637
- name: Use Node.js

README.md

+10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ A library that gives you access to the powerful Parse Server backend from your P
2424

2525
## Table of Contents <!-- omit in toc -->
2626

27+
- [Compatibility](#compatibility)
2728
- [Installation](#installation)
2829
- [Install with Composer](#install-with-composer)
2930
- [Install with Git](#install-with-git)
@@ -64,6 +65,15 @@ A library that gives you access to the powerful Parse Server backend from your P
6465
- [Logs](#logs)
6566
- [Contributing / Testing](#contributing--testing)
6667

68+
## Compatibility
69+
70+
The Parse PHP SDK is continuously tested with the most recent releases of PHP to ensure compatibility. We follow the [PHP Long Term Support plan](https://www.php.net/supported-versions.php) and only test against versions that are officially supported and have not reached their end-of-life date.
71+
72+
| Version | End-of-Life | Compatible |
73+
|---------|-------------|------------|
74+
| PHP 8.2 | Dec 2024 | ✅ Yes |
75+
| PHP 8.1 | Nov 2023 | ✅ Yes |
76+
6777
## Installation
6878
There are various ways to install and use this sdk. We'll elaborate on a couple here.
6979
Note that the Parse PHP SDK requires PHP 5.4 or newer. It can also run on HHVM (recommended 3.0 or newer).

src/Parse/HttpClients/ParseCurlHttpClient.php

+12
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,18 @@ public function setCAFile($caFile)
306306
$this->parseCurl->setOption(CURLOPT_CAINFO, $caFile);
307307
}
308308

309+
/**
310+
* Sets multiple curl options
311+
* https://www.php.net/manual/en/function.curl-setopt.php
312+
*
313+
* @param array $options Array of options to set
314+
* @throws ParseException
315+
*/
316+
public function setHttpOptions($options)
317+
{
318+
$this->parseCurl->setOptionsArray($options);
319+
}
320+
309321
/**
310322
* Gets the error code
311323
*

src/Parse/HttpClients/ParseHttpable.php

+7
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ public function setTimeout($timeout);
6363
*/
6464
public function setCAFile($caFile);
6565

66+
/**
67+
* Sets http options to pass to the http client
68+
*
69+
* @param string $httpOptions Options to set
70+
*/
71+
public function setHttpOptions($httpOptions);
72+
6673
/**
6774
* Gets the error code
6875
*

src/Parse/HttpClients/ParseStreamHttpClient.php

+25
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ class ParseStreamHttpClient implements ParseHttpable
7878
*/
7979
private $caFile;
8080

81+
/**
82+
* Options to pass to the stream context.
83+
*
84+
* @var array
85+
*/
86+
private $httpOptions;
87+
8188
/**
8289
* Optional timeout for this request
8390
*
@@ -195,6 +202,12 @@ public function send($url, $method = 'GET', $data = array())
195202
$this->options['ssl']['cafile'] = $this->caFile;
196203
}
197204

205+
if (isset($this->httpOptions)) {
206+
foreach ($this->httpOptions as $key => $value) {
207+
$this->options[$key] = $value;
208+
}
209+
}
210+
198211
// add additional options for this request
199212
$this->options['http'] = array(
200213
'method' => $method,
@@ -264,6 +277,7 @@ public function send($url, $method = 'GET', $data = array())
264277

265278
// clear options
266279
$this->options = array();
280+
$this->httpOptions = array();
267281

268282
// flush our existing headers
269283
$this->headers = array();
@@ -348,6 +362,17 @@ public function setCAFile($caFile)
348362
$this->caFile = $caFile;
349363
}
350364

365+
/**
366+
* Sets http options to pass to the stream context
367+
* https://www.php.net/manual/en/context.php
368+
*
369+
* @param array $httpOptions options to set
370+
*/
371+
public function setHttpOptions($httpOptions)
372+
{
373+
$this->httpOptions = $httpOptions;
374+
}
375+
351376
/**
352377
* Sets the request timeout
353378
*

src/Parse/ParseClient.php

+25
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ final class ParseClient
103103
*/
104104
private static $caFile;
105105

106+
/**
107+
* Options to pass to the http client.
108+
*
109+
* @var array
110+
*/
111+
private static $httpOptions;
112+
106113
/**
107114
* Constant for version string to include with requests.
108115
*
@@ -301,6 +308,21 @@ public static function setCAFile($caFile)
301308
self::$caFile = $caFile;
302309
}
303310

311+
/**
312+
* Sets http options to pass to the http client
313+
* For curl
314+
* https://www.php.net/manual/en/function.curl-setopt.php
315+
*
316+
* For stream context
317+
* https://www.php.net/manual/en/context.php
318+
*
319+
* @param array $httpOptions options to set
320+
*/
321+
public static function setHttpOptions($httpOptions)
322+
{
323+
self::$httpOptions = $httpOptions;
324+
}
325+
304326
/**
305327
* ParseClient::_encode, internal method for encoding object values.
306328
*
@@ -452,6 +474,9 @@ private static function getPreparedHttpClient()
452474
// set CA file
453475
$httpClient->setCAFile(self::$caFile);
454476
}
477+
if (isset(self::$httpOptions)) {
478+
$httpClient->setHttpOptions(self::$httpOptions);
479+
}
455480

456481
return $httpClient;
457482
}

tests/Parse/Helper.php

+6
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,10 @@ public static function print($text)
105105
{
106106
fwrite(STDOUT, $text . "\n");
107107
}
108+
109+
public static function printArray($array)
110+
{
111+
print_r($array);
112+
ob_end_flush();
113+
}
108114
}

tests/Parse/ParseClientTest.php

+53
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
use PHPUnit\Framework\TestCase;
1818

19+
defined('CURLOPT_PINNEDPUBLICKEY') || define('CURLOPT_PINNEDPUBLICKEY', 10230);
20+
1921
class ParseClientTest extends TestCase
2022
{
2123
public static function setUpBeforeClass() : void
@@ -35,6 +37,9 @@ public function tearDown() : void
3537

3638
// unset CA file
3739
ParseClient::setCAFile(null);
40+
41+
// unset http options
42+
ParseClient::setHttpOptions(null);
3843
}
3944

4045
/**
@@ -667,4 +672,52 @@ public function testCheckBadServer()
667672
$this->assertTrue(isset($health['error_message']));
668673
}
669674
}
675+
676+
/**
677+
* @group test-http-options
678+
*/
679+
public function testCurlHttpOptions()
680+
{
681+
if (function_exists('curl_init')) {
682+
ParseClient::setHttpClient(new ParseCurlHttpClient());
683+
ParseClient::setServerURL('https://localhost:1338', 'parse');
684+
ParseClient::setHttpOptions([
685+
CURLOPT_SSL_VERIFYPEER => false,
686+
CURLOPT_PINNEDPUBLICKEY => 'sha256//Oz+R70/uIv0irdBWc7RNPyCGeZNbN+CBiPLjJxXWigg=',
687+
CURLOPT_SSLCERT => dirname(__DIR__).'/keys/client.crt',
688+
CURLOPT_SSLKEY => dirname(__DIR__).'/keys/client.key',
689+
]);
690+
$health = ParseClient::getServerHealth();
691+
692+
$this->assertNotNull($health);
693+
$this->assertEquals($health['status'], 200);
694+
$this->assertEquals($health['response']['status'], 'ok');
695+
Helper::setServerURL();
696+
}
697+
}
698+
699+
/**
700+
* @group test-http-options
701+
*/
702+
public function testStreamHttpOptions()
703+
{
704+
ParseClient::setHttpClient(new ParseStreamHttpClient());
705+
ParseClient::setServerURL('https://localhost:1338', 'parse');
706+
ParseClient::setHttpOptions([
707+
'ssl' => [
708+
'verify_peer' => false,
709+
'verify_peer_name' => false,
710+
'allow_self_signed' => true,
711+
'local_cert' => dirname(__DIR__).'/keys/client.crt',
712+
'local_pk' => dirname(__DIR__).'/keys/client.key',
713+
'peer_fingerprint' => '29F36676EFA0CA18B5B571C6144580044CB289C2',
714+
]
715+
]);
716+
$health = ParseClient::getServerHealth();
717+
718+
$this->assertNotNull($health);
719+
$this->assertEquals($health['status'], 200);
720+
$this->assertEquals($health['response']['status'], 'ok');
721+
Helper::setServerURL();
722+
}
670723
}

tests/gencerts.sh

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/bin/bash
2+
# https://gist.github.com/ryankurte/bc0d8cff6e73a6bb1950
3+
# https://curl.se/libcurl/c/CURLOPT_PINNEDPUBLICKEY.html
4+
# ./gencerts.sh parseca localhost parsephp keys/
5+
# ./gencerts.sh parseca client parsephp keys/
6+
7+
set -e
8+
9+
if [ "$#" -ne 3 ] && [ "$#" -ne 4 ]; then
10+
echo "Usage: $0 CA NAME ORG"
11+
echo "CA - name of fake CA"
12+
echo "NAME - name of fake client"
13+
echo "ORG - organisation for both"
14+
echo "[DIR] - directory for cert output"
15+
exit
16+
fi
17+
18+
CA=$1
19+
NAME=$2
20+
ORG=$3
21+
22+
if [ -z "$4" ]; then
23+
DIR=./
24+
else
25+
DIR=$4
26+
fi
27+
28+
if [ ! -d "$DIR" ]; then
29+
mkdir -p $DIR
30+
fi
31+
32+
LENGTH=4096
33+
DAYS=1000
34+
35+
SUBJECT=/C=NZ/ST=AKL/L=Auckland/O=$ORG
36+
37+
if [ ! -f "$DIR/$CA.key" ]; then
38+
39+
echo Generating CA
40+
openssl genrsa -out $DIR/$CA.key $LENGTH
41+
42+
echo Signing CA
43+
openssl req -x509 -new -nodes -key $DIR/$CA.key -sha256 -days 1024 -out $DIR/$CA.crt -subj $SUBJECT/CN=$CA
44+
45+
openssl x509 -in $DIR/$CA.crt -out $DIR/$CA.pem -text
46+
openssl x509 -sha1 -noout -in $DIR/$CA.pem -fingerprint | sed 's/SHA1 Fingerprint=//g' >> $DIR/$CA.fp
47+
48+
else
49+
echo Located existing CA
50+
fi
51+
52+
if [ ! -f "$DIR/$NAME.key" ]; then
53+
54+
echo Generating keys
55+
openssl genrsa -out $DIR/$NAME.key $LENGTH
56+
57+
echo Generating CSR
58+
openssl req -new -out $DIR/$NAME.csr -key $DIR/$NAME.key -subj $SUBJECT/CN=$NAME
59+
60+
echo Signing cert
61+
openssl x509 -req -days $DAYS -in $DIR/$NAME.csr -out $DIR/$NAME.crt -CA $DIR/$CA.crt -CAkey $DIR/$CA.key -CAcreateserial
62+
63+
echo Generating PEM
64+
openssl x509 -in $DIR/$NAME.crt -out $DIR/$NAME.pem -text
65+
66+
openssl x509 -sha1 -noout -in $DIR/$NAME.pem -fingerprint | sed 's/SHA1 Fingerprint=//g' > $DIR/$NAME.fp
67+
68+
echo Cleaning Up
69+
rm $DIR/*.csr
70+
71+
else
72+
echo Located existing client certificate
73+
fi
74+
75+
echo Done

tests/keys/client.crt

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIFITCCAwkCCQDEwoQengRnzDANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJO
3+
WjEMMAoGA1UECAwDQUtMMREwDwYDVQQHDAhBdWNrbGFuZDERMA8GA1UECgwIcGFy
4+
c2VwaHAxEDAOBgNVBAMMB3BhcnNlY2EwHhcNMjMwNTEyMjA0MzAzWhcNMjYwMjA1
5+
MjA0MzAzWjBSMQswCQYDVQQGEwJOWjEMMAoGA1UECAwDQUtMMREwDwYDVQQHDAhB
6+
dWNrbGFuZDERMA8GA1UECgwIcGFyc2VwaHAxDzANBgNVBAMMBmNsaWVudDCCAiIw
7+
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMlKDLogZSNxm5S4h97XM8A1+MsP
8+
RaK15g8ebVEP7OGrwX1bvLVis0U/ixwHs0mqjQ9tbuefMZyiRgdds+8tpRCCuqGo
9+
dwSk8YMmOlrF5xIpBT2cXJLhGvDyY0F0RLFZYBoioTYFth4i91DkzhmBaL6vjyB7
10+
dXduR1JQbzTpQHkhofPziQsNtinf8qBqLbH1dFaqwUUEgtsKJyaPlxJR21TF3Fv+
11+
2K/fmoyzP6Er7eUSCvJRRH1hCwzHxl7GqTKyQeaS1RLdrHYqZmSeiJpxwl8uSdBs
12+
x4y8wG4lhRdantCCANlTwLd7zPiuIu+RBP276o2+02K8my9N2STZUgHXefSoNx4M
13+
alYujKBUV+2qmhR9H2HlUB/C/h5Sb8PSlfWyD/bo3+agyw/1+9rfMUYCmiEtdik7
14+
amoBaahoqAHL8S3K19L0ytWkgFejSMzn+i4VDifnwupXHifDL7CPDX0vevFNDvC7
15+
HMLkBWmkNaTduDL5P3ximtIXE7akhK+ufiNoO3KLItenCENxCzUdNdDHguei2U5E
16+
vhTyaTmIIrkUGxQ+aVDXRF2njAeQNMdTjsCAiiSN1corYX8RXvNo8QZQUEaHG42u
17+
O6Yolsw8EZotbpExo1jbiDlI2pVIuwJdtaDCucPN/X6uZ8odGQ0LUeyTBYda/1OG
18+
VIQzPZnxSHzqPzuZAgMBAAEwDQYJKoZIhvcNAQELBQADggIBAHOLgs6FLIv+Vvpx
19+
fNtwabgOI2JxkFwaAujwWJS10tmczJp9qZilOlVBBhDFRBwBKqAaanHKCYkEfP6u
20+
dgC8RMOOYOb0gk6Tj3+zhvM4Qz+n8Cn2fA2+EtFXTKyMfJHuG/zddTLep2Phh9c9
21+
t5s/8aHAuqM9RGiA66V7mJiR9G5E8cNpyHniCh8Z11kABPMzAy92LyEGUlRwCrWx
22+
fCwItnzY2/7J8IW20rPIpb0EWmYHhxkUUzu7APQgvJpAUTdhmVKb9GLCUyY+oICE
23+
1WrnV9OQiqYVGFQkry9FXyKbsLVM6b6ar8DIXpYTYnd11sqFdiUUo4oItYYrO/1O
24+
0Bt0PX6hWYjR4r7ZT23KWAHZdlU4EFfrLJeZ6HDeYttJF68x9s8RZGgVU9Xlb/7X
25+
KGRVyCWI7aWzvI1lBVAnc7b7B9LrIkdHnYDt/ettmRvI/zZRBh73T7EPOQB7bEzP
26+
M8BXfAr/+qa2ToBWNd9AJrw7rg+OWGD801iXqsREyLr15nRIR12mGdKuyMkfghk1
27+
9J1Sd0fkfB2ci7Rn3afRdKksGuADQ2fvYihw0lALOPzSq/FYRqZBzwv9Qmw43CKd
28+
euEPcCfT7VYY47lmfFfKBcVv8d7NiJZRGkIUYUxS/UAsrLiBCgRkaUACcbLok7sJ
29+
jrdaTDx4EZu93dmJbEozNO6dRiLb
30+
-----END CERTIFICATE-----

tests/keys/client.der

1.29 KB
Binary file not shown.

tests/keys/client.fp

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
D7:10:BE:24:E6:85:A2:F8:79:F8:36:EF:42:A0:EC:B3:EC:93:C2:FB

0 commit comments

Comments
 (0)