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
7880ZEND_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 */
33273454PHP_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
0 commit comments