Skip to content

Commit fe8d16e

Browse files
committed
Add the ZMQCert class
The ZMQCert class wraps the CZMQ zcert API. Instances of the ZMQCert class can: * have their public and private text inspected, either as 32-byte binary strings or Z85 armoured strings * be tested for equality * be cloned * store and retrieve metadata * have their public and private test saved to and loaded from disk be applied to a ZMQSocket
1 parent fb0dbc7 commit fe8d16e

11 files changed

+723
-13
lines changed

config.m4

+26-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ PHP_ARG_WITH(zmq, whether to enable 0MQ support,
44
PHP_ARG_ENABLE(zmq_pthreads, whether to enable support for php threads extension,
55
[ --enable-zmq-pthreads whether to enable support for php threads extension], no, no)
66

7+
PHP_ARG_WITH(czmq, whether to enable CZMQ support,
8+
[ --with-czmq[=DIR] Enable CZMQ support. DIR is the prefix to CZMQ installation directory.], no, no)
9+
710
if test "$PHP_ZMQ" != "no"; then
811

912
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
@@ -43,6 +46,29 @@ if test "$PHP_ZMQ" != "no"; then
4346
AC_MSG_ERROR(Unable to find libzmq installation)
4447
fi
4548

49+
if test "$PHP_CZMQ" != "no"; then
50+
if test "x$PHP_CZMQ" != "xyes"; then
51+
export PKG_CONFIG_PATH="${PHP_CZMQ}/${PHP_LIBDIR}/pkgconfig"
52+
fi
53+
54+
AC_MSG_CHECKING(for CZMQ)
55+
if $PKG_CONFIG --exists libczmq; then
56+
PHP_CZMQ_VERSION=`$PKG_CONFIG libczmq --modversion`
57+
PHP_CZMQ_PREFIX=`$PKG_CONFIG libczmq --variable=prefix`
58+
AC_MSG_RESULT([found version $PHP_CZMQ_VERSION in $PHP_CZMQ_PREFIX])
59+
60+
PHP_CZMQ_LIBS=`$PKG_CONFIG libczmq --libs`
61+
PHP_CZMQ_INCS=`$PKG_CONFIG libczmq --cflags`
62+
63+
PHP_EVAL_LIBLINE($PHP_CZMQ_LIBS, ZMQ_SHARED_LIBADD)
64+
PHP_EVAL_INCLINE($PHP_CZMQ_INCS)
65+
66+
AC_DEFINE([HAVE_CZMQ], [], [CZMQ was found])
67+
else
68+
AC_MSG_RESULT([no])
69+
fi
70+
fi
71+
4672
AC_CHECK_HEADERS([stdint.h],[php_zmq_have_stdint=yes; break;])
4773
if test $php_zmq_have_stdint != "yes"; then
4874
AC_MSG_ERROR(Unable to find stdint.h)
@@ -60,4 +86,3 @@ if test "$PHP_ZMQ" != "no"; then
6086
PHP_NEW_EXTENSION(zmq, zmq.c zmq_pollset.c zmq_device.c zmq_sockopt.c zmq_fd_stream.c zmq_clock.c, $ext_shared)
6187
PKG_CONFIG_PATH="$ORIG_PKG_CONFIG_PATH"
6288
fi
63-

package.xml

+7
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@
9090
<file name="035-capture.phpt" role="test" />
9191
<file name="036-device.phpt" role="test" />
9292
<file name="037-device-deprecated.phpt" role="test" />
93+
<file name="038-cert-construct.phpt" role="test" />
94+
<file name="039-cert-equals.phpt" role="test" />
95+
<file name="040-cert-clone.phpt" role="test" />
96+
<file name="041-cert-meta.phpt" role="test" />
97+
<file name="042-cert-save.phpt" role="test" />
98+
<file name="043-cert-load.phpt" role="test" />
99+
<file name="046-cert-apply.phpt" role="test" />
93100
<file name="bug_gh_43.phpt" role="test" />
94101
<file name="bug_gh_49.phpt" role="test" />
95102
<file name="bug_gh_50.phpt" role="test" />

php_zmq_private.h

+13
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@
3737

3838
#include <zmq.h>
3939

40+
#ifdef HAVE_CZMQ
41+
# include <czmq.h>
42+
# if CZMQ_VERSION_MAJOR >= 2
43+
# define HAVE_CZMQ_2
44+
# endif
45+
#endif
46+
4047
#ifdef PHP_WIN32
4148
# include "win32/php_stdint.h"
4249
#else
@@ -263,5 +270,11 @@ ZEND_BEGIN_MODULE_GLOBALS(php_zmq)
263270
php_zmq_clock_ctx_t *clock_ctx;
264271
ZEND_END_MODULE_GLOBALS(php_zmq)
265272

273+
#ifdef HAVE_CZMQ_2
274+
typedef struct _php_zmq_cert {
275+
zend_object zend_object;
276+
zcert_t *zcert;
277+
} php_zmq_cert;
278+
#endif
266279

267280
#endif /* _PHP_ZMQ_PRIVATE_H_ */

tests/038-cert-construct.phpt

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Test a ZMQCert can be constructed.
3+
--SKIPIF--
4+
<?php
5+
require_once __DIR__ . '/skipif.inc';
6+
7+
if (!class_exists('ZMQCert')) {
8+
die('skip');
9+
}
10+
--FILE--
11+
<?php
12+
13+
$cert = new ZMQCert();
14+
var_dump((bool)$cert);
15+
16+
date_default_timezone_set('Europe/London');
17+
$dateTime = new DateTime();
18+
19+
try {
20+
$cert = new ZMQCert($dateTime);
21+
} catch (ZMQCertException $e) {
22+
var_dump($e->getMessage());
23+
}
24+
--EXPECT--
25+
bool(true)
26+
string(69) "ZMQCert::__construct() expects parameter 1 to be string, object given"

tests/039-cert-equals.phpt

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Test two ZMQCerts can be tested for equality.
3+
--SKIPIF--
4+
<?php
5+
6+
require_once __DIR__ . '/skipif.inc';
7+
8+
if (!class_exists('ZMQCert')) {
9+
die('skip');
10+
}
11+
--FILE--
12+
<?php
13+
14+
$cert = new ZMQCert();
15+
$newCert = new ZMQCert();
16+
17+
var_dump($cert->equals($cert));
18+
var_dump($newCert->equals($cert));
19+
--EXPECT--
20+
bool(true)
21+
bool(false)

tests/040-cert-clone.phpt

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
Test a ZMQCert can be cloned.
3+
--SKIPIF--
4+
<?php
5+
6+
require_once __DIR__ . '/skipif.inc';
7+
8+
if (!class_exists('ZMQCert')) {
9+
die('skip');
10+
}
11+
--FILE--
12+
<?php
13+
14+
$cert = new ZMQCert();
15+
$clonedCert = clone $cert;
16+
17+
var_dump($cert->equals($clonedCert));
18+
--EXPECT--
19+
bool(true)

tests/041-cert-meta.phpt

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
--TEST--
2+
Test a ZMQCert can get and set metadata.
3+
--SKIPIF--
4+
<?php
5+
6+
require_once __DIR__ . '/skipif.inc';
7+
8+
if (!class_exists('ZMQCert')) {
9+
die('skip');
10+
}
11+
--FILE--
12+
<?php
13+
14+
$cert = new ZMQCert();
15+
var_dump($cert->getMeta('foo'));
16+
var_dump($cert->getMetaKeys());
17+
18+
$cert->setMeta('foo', 'bar');
19+
var_dump($cert->getMeta('foo'));
20+
var_dump($cert->getMetaKeys());
21+
22+
$cert->setMeta('baz', 'qux');
23+
var_dump($cert->getMetaKeys());
24+
25+
// If the parameters are incorrect, then it should still return the metadata
26+
// keys.
27+
var_dump($cert->getMetaKeys(123));
28+
--EXPECT--
29+
NULL
30+
array(0) {
31+
}
32+
string(3) "bar"
33+
array(1) {
34+
[0]=>
35+
string(3) "foo"
36+
}
37+
array(2) {
38+
[0]=>
39+
string(3) "baz"
40+
[1]=>
41+
string(3) "foo"
42+
}
43+
array(2) {
44+
[0]=>
45+
string(3) "baz"
46+
[1]=>
47+
string(3) "foo"
48+
}

tests/042-cert-save.phpt

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
--TEST--
2+
Test a ZMQCert can be saved.
3+
--SKIPIF--
4+
<?php
5+
6+
require_once __DIR__ . '/skipif.inc';
7+
8+
if (!class_exists('ZMQCert')) {
9+
die('skip');
10+
}
11+
--FILE--
12+
<?php
13+
14+
define('BASE_CERT_DIR', __DIR__ . '/certs');
15+
mkdir(BASE_CERT_DIR);
16+
17+
// #save
18+
$certPath = BASE_CERT_DIR . '/cert';
19+
20+
$cert = new ZMQCert();
21+
$cert->save($certPath);
22+
var_dump(is_file($certPath));
23+
var_dump(is_file($certPath . '_secret'));
24+
25+
unlink($certPath);
26+
unlink($certPath . '_secret');
27+
28+
try {
29+
$cert->save('/path/to/cert');
30+
} catch (ZMQCertException $e) {
31+
var_dump($e->getMessage());
32+
}
33+
34+
// #savePublic
35+
$certPath = BASE_CERT_DIR . '/cert_public';
36+
37+
$cert = new ZMQCert();
38+
$cert->savePublic($certPath);
39+
var_dump(is_file($certPath));
40+
41+
unlink($certPath);
42+
43+
try {
44+
$cert->savePublic('/path/to/cert_public');
45+
} catch (ZMQCertException $e) {
46+
var_dump($e->getMessage());
47+
}
48+
49+
// #saveSecret
50+
$certPath = BASE_CERT_DIR . '/cert_secret';
51+
$cert->saveSecret($certPath);
52+
var_dump(is_file($certPath));
53+
54+
unlink($certPath);
55+
56+
try {
57+
$cert->saveSecret('/path/to/cert_secret');
58+
} catch (ZMQCertException $e) {
59+
var_dump($e->getMessage());
60+
}
61+
62+
rmdir(BASE_CERT_DIR);
63+
--EXPECT--
64+
bool(true)
65+
bool(true)
66+
string(47) "Failed to save the certificate to /path/to/cert"
67+
bool(true)
68+
string(61) "Failed to save the public certificate to /path/to/cert_public"
69+
bool(true)
70+
string(61) "Failed to save the secret certificate to /path/to/cert_secret"

tests/043-cert-load.phpt

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Test a ZMQCert can be loaded.
3+
--SKIPIF--
4+
<?php
5+
6+
require_once __DIR__ . '/skipif.inc';
7+
8+
if (! class_exists('ZMQCert')) {
9+
die('skip');
10+
}
11+
--FILE--
12+
<?php
13+
14+
define('BASE_CERT_DIR', __DIR__ . '/certs');
15+
mkdir(BASE_CERT_DIR);
16+
17+
$certPath = BASE_CERT_DIR . '/cert';
18+
$cert = new ZMQCert();
19+
$cert->save($certPath);
20+
21+
$certCloneEquivalent = new ZMQCert($certPath);
22+
var_dump($certCloneEquivalent->equals($cert));
23+
24+
unlink($certPath);
25+
unlink($certPath . '_secret');
26+
27+
try {
28+
new ZMQCert('/path/to/cert');
29+
} catch (ZMQCertException $e) {
30+
var_dump($e->getMessage());
31+
}
32+
33+
rmdir(BASE_CERT_DIR);
34+
--EXPECT--
35+
bool(true)
36+
string(49) "Failed to load the certificate from /path/to/cert"

tests/046-cert-apply.phpt

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Test a ZMQCert can be applied to a ZMQSocket.
3+
--SKIPIF--
4+
<?php
5+
6+
require_once __DIR__ . '/skipif.inc';
7+
8+
if (!class_exists('ZMQCert')) {
9+
die('skip');
10+
}
11+
--FILE--
12+
<?php
13+
14+
$context = new ZMQContext();
15+
$socket = $context->getSocket(ZMQ::SOCKET_REQ);
16+
$cert = new ZMQCert();
17+
$cert->apply($socket);
18+
--EXPECT--

0 commit comments

Comments
 (0)