Skip to content

Commit e254013

Browse files
committed
Merge pull request #1114
2 parents 9c5f9ab + 895fcf4 commit e254013

File tree

3 files changed

+181
-10
lines changed

3 files changed

+181
-10
lines changed

php_phongo.c

Lines changed: 129 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474

7575
#define PHONGO_DEBUG_INI "mongodb.debug"
7676
#define PHONGO_DEBUG_INI_DEFAULT ""
77+
#define PHONGO_METADATA_SEPARATOR " / "
78+
#define PHONGO_METADATA_SEPARATOR_LEN (sizeof(PHONGO_METADATA_SEPARATOR) - 1)
7779

7880
ZEND_DECLARE_MODULE_GLOBALS(mongodb)
7981
#if defined(ZTS) && defined(COMPILE_DL_MONGODB)
@@ -2459,7 +2461,130 @@ static char* php_phongo_manager_make_client_hash(const char* uri_string, zval* o
24592461
return hash;
24602462
}
24612463

2462-
static mongoc_client_t* php_phongo_make_mongo_client(const mongoc_uri_t* uri) /* {{{ */
2464+
static bool php_phongo_extract_handshake_data(zval* driver, const char* key, char** value, size_t* value_len)
2465+
{
2466+
zval* zvalue;
2467+
2468+
if (!php_array_exists(driver, key)) {
2469+
*value = NULL;
2470+
*value_len = 0;
2471+
2472+
return true;
2473+
}
2474+
2475+
zvalue = php_array_fetch(driver, key);
2476+
2477+
if (Z_TYPE_P(zvalue) != IS_STRING) {
2478+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"%s\" handshake option to be a string, %s given", key, PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zvalue));
2479+
return false;
2480+
}
2481+
2482+
*value = estrdup(Z_STRVAL_P(zvalue));
2483+
*value_len = Z_STRLEN_P(zvalue);
2484+
2485+
return true;
2486+
}
2487+
2488+
static char* php_phongo_concat_handshake_data(const char* default_value, const char* custom_value, size_t custom_value_len)
2489+
{
2490+
char* ret;
2491+
/* Length of the returned value needs to include the trailing null byte */
2492+
size_t ret_len = strlen(default_value) + 1;
2493+
2494+
if (custom_value) {
2495+
/* Increase the length by that of the custom value as well as one byte for the separator */
2496+
ret_len += custom_value_len + PHONGO_METADATA_SEPARATOR_LEN;
2497+
}
2498+
2499+
ret = ecalloc(sizeof(char*), ret_len);
2500+
2501+
if (custom_value) {
2502+
snprintf(ret, ret_len, "%s%s%s", default_value, PHONGO_METADATA_SEPARATOR, custom_value);
2503+
} else {
2504+
snprintf(ret, ret_len, "%s", default_value);
2505+
}
2506+
2507+
return ret;
2508+
}
2509+
2510+
static void php_phongo_handshake_data_append(const char* name, size_t name_len, const char* version, size_t version_len, const char* platform, size_t platform_len)
2511+
{
2512+
char* php_version_string;
2513+
size_t php_version_string_len;
2514+
char* driver_name;
2515+
char* driver_version;
2516+
char* full_platform;
2517+
2518+
php_version_string_len = strlen(PHP_VERSION);
2519+
php_version_string = ecalloc(sizeof(char*), 4 + php_version_string_len);
2520+
snprintf(php_version_string, 4 + php_version_string_len, "PHP %s", php_version_string);
2521+
2522+
driver_name = php_phongo_concat_handshake_data("ext-mongodb:PHP", name, name_len);
2523+
driver_version = php_phongo_concat_handshake_data(PHP_MONGODB_VERSION, version, version_len);
2524+
full_platform = php_phongo_concat_handshake_data(php_version_string, platform, platform_len);
2525+
2526+
MONGOC_DEBUG(
2527+
"Setting driver handshake data: name %s, version %s, platform %s",
2528+
driver_name,
2529+
driver_version,
2530+
full_platform);
2531+
2532+
mongoc_handshake_data_append(driver_name, driver_version, full_platform);
2533+
2534+
efree(php_version_string);
2535+
efree(driver_name);
2536+
efree(driver_version);
2537+
efree(full_platform);
2538+
}
2539+
2540+
static void php_phongo_set_handshake_data(zval* driverOptions)
2541+
{
2542+
char* name = NULL;
2543+
size_t name_len = 0;
2544+
char* version = NULL;
2545+
size_t version_len = 0;
2546+
char* platform = NULL;
2547+
size_t platform_len = 0;
2548+
2549+
if (driverOptions && php_array_existsc(driverOptions, "driver")) {
2550+
zval* driver = php_array_fetchc(driverOptions, "driver");
2551+
2552+
if (Z_TYPE_P(driver) != IS_ARRAY) {
2553+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"driver\" driver option to be an array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(driver));
2554+
return;
2555+
}
2556+
2557+
if (!php_phongo_extract_handshake_data(driver, "name", &name, &name_len)) {
2558+
/* Exception already thrown */
2559+
goto cleanup;
2560+
}
2561+
2562+
if (!php_phongo_extract_handshake_data(driver, "version", &version, &version_len)) {
2563+
/* Exception already thrown */
2564+
goto cleanup;
2565+
}
2566+
2567+
if (!php_phongo_extract_handshake_data(driver, "platform", &platform, &platform_len)) {
2568+
/* Exception already thrown */
2569+
goto cleanup;
2570+
}
2571+
}
2572+
2573+
php_phongo_handshake_data_append(name, name_len, version, version_len, platform, platform_len);
2574+
2575+
cleanup:
2576+
if (name) {
2577+
efree(name);
2578+
}
2579+
if (version) {
2580+
efree(version);
2581+
}
2582+
if (platform) {
2583+
efree(platform);
2584+
}
2585+
}
2586+
2587+
static mongoc_client_t* php_phongo_make_mongo_client(const mongoc_uri_t* uri, zval* driverOptions) /* {{{ */
24632588
{
24642589
const char *mongoc_version, *bson_version;
24652590

@@ -2485,6 +2610,8 @@ static mongoc_client_t* php_phongo_make_mongo_client(const mongoc_uri_t* uri) /*
24852610
bson_version,
24862611
PHP_VERSION);
24872612

2613+
php_phongo_set_handshake_data(driverOptions);
2614+
24882615
return mongoc_client_new_from_uri(uri);
24892616
} /* }}} */
24902617

@@ -3081,7 +3208,7 @@ void phongo_manager_init(php_phongo_manager_t* manager, const char* uri_string,
30813208
}
30823209
#endif
30833210

3084-
manager->client = php_phongo_make_mongo_client(uri);
3211+
manager->client = php_phongo_make_mongo_client(uri, driverOptions);
30853212
mongoc_client_set_error_api(manager->client, MONGOC_ERROR_API_VERSION_2);
30863213

30873214
if (!manager->client) {
@@ -3326,21 +3453,13 @@ static zend_class_entry* php_phongo_fetch_internal_class(const char* class_name,
33263453
/* {{{ PHP_MINIT_FUNCTION */
33273454
PHP_MINIT_FUNCTION(mongodb)
33283455
{
3329-
char* php_version_string;
3330-
33313456
(void) type; /* We don't care if we are loaded via dl() or extension= */
33323457

33333458
REGISTER_INI_ENTRIES();
33343459

33353460
/* Initialize libmongoc */
33363461
mongoc_init();
33373462

3338-
/* Set handshake options */
3339-
php_version_string = malloc(4 + sizeof(PHP_VERSION) + 1);
3340-
snprintf(php_version_string, 4 + sizeof(PHP_VERSION) + 1, "PHP %s", PHP_VERSION);
3341-
mongoc_handshake_data_append("ext-mongodb:PHP", PHP_MONGODB_VERSION, php_version_string);
3342-
free(php_version_string);
3343-
33443463
/* Initialize libbson */
33453464
bson_mem_set_vtable(&MONGODB_G(bsonMemVTable));
33463465

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
MongoDB\Driver\Manager: Pass custom handshake data
3+
--INI--
4+
mongodb.debug=stderr
5+
--FILE--
6+
<?php
7+
8+
$manager = new MongoDB\Driver\Manager(null, [], ['driver' => ['name' => 'test', 'version' => '0.1', 'platform' => 'mine']]);
9+
$manager = new MongoDB\Driver\Manager(null, [], ['driver' => ['name' => 'test']]);
10+
11+
?>
12+
===DONE===
13+
<?php exit(0); ?>
14+
--EXPECTF--
15+
%A[%s] PHONGO: DEBUG > Setting driver handshake data: name ext-mongodb:PHP / test, version %s / 0.1, platform PHP %s / mine
16+
%A[%s] PHONGO: DEBUG > Setting driver handshake data: name ext-mongodb:PHP / test, version %s, platform PHP %s
17+
%A===DONE===%A
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
MongoDB\Driver\Manager::__construct(): Invalid handshake data
3+
--FILE--
4+
<?php
5+
require_once __DIR__ . "/../utils/basic.inc";
6+
7+
$tests = [
8+
(object) [],
9+
'string',
10+
['name' => []],
11+
['version' => []],
12+
['platform' => []],
13+
];
14+
15+
foreach ($tests as $driver) {
16+
echo throws(function () use ($driver) {
17+
$manager = new MongoDB\Driver\Manager(null, [], ['driver' => $driver]);
18+
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
19+
}
20+
21+
?>
22+
===DONE===
23+
<?php exit(0); ?>
24+
--EXPECT--
25+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
26+
Expected "driver" driver option to be an array, stdClass given
27+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
28+
Expected "driver" driver option to be an array, string given
29+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
30+
Expected "name" handshake option to be a string, array given
31+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
32+
Expected "version" handshake option to be a string, array given
33+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
34+
Expected "platform" handshake option to be a string, array given
35+
===DONE===

0 commit comments

Comments
 (0)