bool mongoc_uri_set_option_as_bool (mongoc_uri_t *uri, const char *option, bool value) { const bson_t *options; bson_iter_t iter; BSON_ASSERT (option); if (!mongoc_uri_option_is_bool (option)) { return false; } if ((options = mongoc_uri_get_options (uri)) && bson_iter_init_find_case (&iter, options, option)) { if (BSON_ITER_HOLDS_BOOL (&iter)) { bson_iter_overwrite_bool (&iter, value); return true; } else { return false; } } bson_append_bool(&uri->options, option, -1, value); return true; }
void _mongoc_sasl_set_properties (mongoc_sasl_t *sasl, const mongoc_uri_t *uri) { const bson_t *options; bson_iter_t iter; bson_t properties; const char *service_name = NULL; bool canonicalize = false; _mongoc_sasl_set_pass(sasl, mongoc_uri_get_password(uri)); _mongoc_sasl_set_user(sasl, mongoc_uri_get_username(uri)); options = mongoc_uri_get_options (uri); if (!mongoc_uri_get_mechanism_properties (uri, &properties)) { bson_init (&properties); } if (bson_iter_init_find_case ( &iter, options, MONGOC_URI_GSSAPISERVICENAME) && BSON_ITER_HOLDS_UTF8 (&iter)) { service_name = bson_iter_utf8 (&iter, NULL); } if (bson_iter_init_find_case (&iter, &properties, "SERVICE_NAME") && BSON_ITER_HOLDS_UTF8 (&iter)) { /* newer "authMechanismProperties" URI syntax takes precedence */ service_name = bson_iter_utf8 (&iter, NULL); } _mongoc_sasl_set_service_name (sasl, service_name); /* * Driver Authentication Spec: "Drivers MAY allow the user to request * canonicalization of the hostname. This might be required when the hosts * report different hostnames than what is used in the kerberos database. * The default is "false". * * Some underlying GSSAPI layers will do this for us, but can be disabled in * their config (krb.conf). * * See CDRIVER-323 for more information. */ if (bson_iter_init_find_case ( &iter, options, MONGOC_URI_CANONICALIZEHOSTNAME) && BSON_ITER_HOLDS_BOOL (&iter)) { canonicalize = bson_iter_bool (&iter); } if (bson_iter_init_find_case ( &iter, &properties, "CANONICALIZE_HOST_NAME") && BSON_ITER_HOLDS_UTF8 (&iter)) { /* newer "authMechanismProperties" URI syntax takes precedence */ canonicalize = !strcasecmp (bson_iter_utf8 (&iter, NULL), "true"); } sasl->canonicalize_host_name = canonicalize; bson_destroy (&properties); }
mongoc_client_pool_t * mongoc_client_pool_new (const mongoc_uri_t *uri) { mongoc_topology_t *topology; mongoc_client_pool_t *pool; const bson_t *b; bson_iter_t iter; ENTRY; BSON_ASSERT (uri); #ifndef MONGOC_ENABLE_SSL if (mongoc_uri_get_ssl (uri)) { MONGOC_ERROR ("Can't create SSL client pool," " SSL not enabled in this build."); return NULL; } #endif pool = (mongoc_client_pool_t *)bson_malloc0(sizeof *pool); mongoc_mutex_init(&pool->mutex); _mongoc_queue_init(&pool->queue); pool->uri = mongoc_uri_copy(uri); pool->min_pool_size = 0; pool->max_pool_size = 100; pool->size = 0; pool->topology_scanner_started = false; topology = mongoc_topology_new(uri, false); pool->topology = topology; mongoc_client_metadata_init (&pool->topology->scanner->ismaster_metadata); pool->error_api_version = MONGOC_ERROR_API_VERSION_LEGACY; b = mongoc_uri_get_options(pool->uri); if (bson_iter_init_find_case(&iter, b, "minpoolsize")) { if (BSON_ITER_HOLDS_INT32(&iter)) { pool->min_pool_size = BSON_MAX(0, bson_iter_int32(&iter)); } } if (bson_iter_init_find_case(&iter, b, "maxpoolsize")) { if (BSON_ITER_HOLDS_INT32(&iter)) { pool->max_pool_size = BSON_MAX(1, bson_iter_int32(&iter)); } } mongoc_counter_client_pools_active_inc(); RETURN(pool); }
mongoc_client_t * mongoc_client_new (const char *uri_string) { const mongoc_write_concern_t *write_concern; mongoc_client_t *client; mongoc_uri_t *uri; const bson_t *options; bson_iter_t iter; bool has_ssl = false; if (!uri_string) { uri_string = "mongodb://127.0.0.1/"; } if (!(uri = mongoc_uri_new(uri_string))) { return NULL; } options = mongoc_uri_get_options (uri); if (bson_iter_init_find (&iter, options, "ssl") && BSON_ITER_HOLDS_BOOL (&iter) && bson_iter_bool (&iter)) { has_ssl = true; } client = bson_malloc0(sizeof *client); client->uri = uri; client->request_id = rand (); client->initiator = mongoc_client_default_stream_initiator; client->initiator_data = client; write_concern = mongoc_uri_get_write_concern (uri); client->write_concern = mongoc_write_concern_copy (write_concern); client->read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); _mongoc_cluster_init (&client->cluster, client->uri, client); #ifdef MONGOC_ENABLE_SSL if (has_ssl) { mongoc_client_set_ssl_opts (client, mongoc_ssl_opt_get_default ()); } #endif mongoc_counter_clients_active_inc (); return client; }
const char* mongoc_uri_get_option_as_utf8 (const mongoc_uri_t *uri, const char *option, const char *fallback) { const bson_t *options; bson_iter_t iter; if ((options = mongoc_uri_get_options (uri)) && bson_iter_init_find_case (&iter, options, option) && BSON_ITER_HOLDS_UTF8 (&iter)) { return bson_iter_utf8 (&iter, NULL); } return fallback; }
bool mongoc_uri_get_option_as_bool (const mongoc_uri_t *uri, const char *option, bool fallback) { const bson_t *options; bson_iter_t iter; if ((options = mongoc_uri_get_options (uri)) && bson_iter_init_find_case (&iter, options, option) && BSON_ITER_HOLDS_BOOL (&iter)) { return bson_iter_bool (&iter); } return fallback; }
int32_t mongoc_uri_get_option_as_int32(const mongoc_uri_t *uri, const char *option, int32_t fallback) { const bson_t *options; bson_iter_t iter; int32_t retval = fallback; if ((options = mongoc_uri_get_options (uri)) && bson_iter_init_find_case (&iter, options, option) && BSON_ITER_HOLDS_INT32 (&iter)) { if (!(retval = bson_iter_int32(&iter))) { retval = fallback; } } return retval; }
mongoc_client_t * _mongoc_client_new_from_uri (const mongoc_uri_t *uri, mongoc_topology_t *topology) { mongoc_client_t *client; const mongoc_read_prefs_t *read_prefs; const mongoc_write_concern_t *write_concern; #ifdef MONGOC_ENABLE_SSL const bson_t *options; bson_iter_t iter; #endif BSON_ASSERT (uri); client = (mongoc_client_t *)bson_malloc0(sizeof *client); client->uri = mongoc_uri_copy (uri); client->request_id = rand (); client->initiator = mongoc_client_default_stream_initiator; client->initiator_data = client; client->topology = topology; write_concern = mongoc_uri_get_write_concern (client->uri); client->write_concern = mongoc_write_concern_copy (write_concern); read_prefs = mongoc_uri_get_read_prefs_t (client->uri); client->read_prefs = mongoc_read_prefs_copy (read_prefs); mongoc_cluster_init (&client->cluster, client->uri, client); #ifdef MONGOC_ENABLE_SSL options = mongoc_uri_get_options (client->uri); if (bson_iter_init_find (&iter, options, "ssl") && BSON_ITER_HOLDS_BOOL (&iter) && bson_iter_bool (&iter)) { mongoc_client_set_ssl_opts (client, mongoc_ssl_opt_get_default ()); } #endif mongoc_counter_clients_active_inc (); return client; }
mongoc_client_pool_t * mongoc_client_pool_new (const mongoc_uri_t *uri) { mongoc_topology_t *topology; mongoc_client_pool_t *pool; const bson_t *b; bson_iter_t iter; ENTRY; BSON_ASSERT (uri); pool = (mongoc_client_pool_t *)bson_malloc0(sizeof *pool); mongoc_mutex_init(&pool->mutex); _mongoc_queue_init(&pool->queue); pool->uri = mongoc_uri_copy(uri); pool->min_pool_size = 0; pool->max_pool_size = 100; pool->size = 0; topology = mongoc_topology_new(uri, false); pool->topology = topology; b = mongoc_uri_get_options(pool->uri); if (bson_iter_init_find_case(&iter, b, "minpoolsize")) { if (BSON_ITER_HOLDS_INT32(&iter)) { pool->min_pool_size = BSON_MAX(0, bson_iter_int32(&iter)); } } if (bson_iter_init_find_case(&iter, b, "maxpoolsize")) { if (BSON_ITER_HOLDS_INT32(&iter)) { pool->max_pool_size = BSON_MAX(1, bson_iter_int32(&iter)); } } mongoc_counter_client_pools_active_inc(); RETURN(pool); }
static mongoc_stream_t * mongoc_client_connect_tcp (const mongoc_uri_t *uri, const mongoc_host_list_t *host, bson_error_t *error) { mongoc_socket_t *sock = NULL; struct addrinfo hints; struct addrinfo *result, *rp; int32_t connecttimeoutms = MONGOC_DEFAULT_CONNECTTIMEOUTMS; int64_t expire_at; const bson_t *options; bson_iter_t iter; char portstr [8]; int s; ENTRY; bson_return_val_if_fail (uri, NULL); bson_return_val_if_fail (host, NULL); if ((options = mongoc_uri_get_options (uri)) && bson_iter_init_find (&iter, options, "connecttimeoutms") && BSON_ITER_HOLDS_INT32 (&iter)) { if (!(connecttimeoutms = bson_iter_int32(&iter))) { connecttimeoutms = MONGOC_DEFAULT_CONNECTTIMEOUTMS; } } BSON_ASSERT (connecttimeoutms); expire_at = bson_get_monotonic_time () + (connecttimeoutms * 1000L); bson_snprintf (portstr, sizeof portstr, "%hu", host->port); memset (&hints, 0, sizeof hints); hints.ai_family = host->family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; hints.ai_protocol = 0; s = getaddrinfo (host->host, portstr, &hints, &result); if (s != 0) { mongoc_counter_dns_failure_inc (); bson_set_error(error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_NAME_RESOLUTION, "Failed to resolve %s", host->host); RETURN (NULL); } mongoc_counter_dns_success_inc (); for (rp = result; rp; rp = rp->ai_next) { /* * Create a new non-blocking socket. */ if (!(sock = mongoc_socket_new (rp->ai_family, rp->ai_socktype, rp->ai_protocol))) { continue; } /* * Try to connect to the peer. */ if (0 != mongoc_socket_connect (sock, rp->ai_addr, (socklen_t)rp->ai_addrlen, expire_at)) { char errmsg_buf[32]; const char * errmsg; errmsg = bson_strerror_r (mongoc_socket_errno (sock), errmsg_buf, sizeof errmsg_buf); MONGOC_WARNING ("Failed to connect, error: %d, %s\n", mongoc_socket_errno(sock), errmsg); mongoc_socket_destroy (sock); sock = NULL; continue; } break; } if (!sock) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "Failed to connect to target host: %s", host->host_and_port); freeaddrinfo (result); RETURN (NULL); } freeaddrinfo (result); return mongoc_stream_socket_new (sock); }
static mongoc_stream_t * mongoc_client_default_stream_initiator (const mongoc_uri_t *uri, const mongoc_host_list_t *host, void *user_data, bson_error_t *error) { mongoc_stream_t *base_stream = NULL; #ifdef MONGOC_ENABLE_SSL mongoc_client_t *client = user_data; const bson_t *options; bson_iter_t iter; const char *mechanism; #endif bson_return_val_if_fail (uri, NULL); bson_return_val_if_fail (host, NULL); #ifndef MONGOC_ENABLE_SSL if (mongoc_uri_get_ssl (uri)) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER, "SSL is not enabled in this build of mongo-c-driver."); return NULL; } #endif switch (host->family) { #if defined(AF_INET6) case AF_INET6: #endif case AF_INET: base_stream = mongoc_client_connect_tcp (uri, host, error); break; case AF_UNIX: base_stream = mongoc_client_connect_unix (uri, host, error); break; default: bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_INVALID_TYPE, "Invalid address family: 0x%02x", host->family); break; } #ifdef MONGOC_ENABLE_SSL if (base_stream) { options = mongoc_uri_get_options (uri); mechanism = mongoc_uri_get_auth_mechanism (uri); if ((bson_iter_init_find_case (&iter, options, "ssl") && bson_iter_as_bool (&iter)) || (mechanism && (0 == strcmp (mechanism, "MONGODB-X509")))) { base_stream = mongoc_stream_tls_new (base_stream, &client->ssl_opts, true); if (!base_stream) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed initialize TLS state."); return NULL; } if (!mongoc_stream_tls_do_handshake (base_stream, -1) || !mongoc_stream_tls_check_cert (base_stream, host->host)) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to handshake and validate TLS certificate."); mongoc_stream_destroy (base_stream); base_stream = NULL; return NULL; } } } #endif return base_stream ? mongoc_stream_buffered_new (base_stream, 1024) : NULL; }
static void test_mongoc_uri_new (void) { const mongoc_host_list_t *hosts; const bson_t *options; const bson_t *credentials; bson_t properties; mongoc_uri_t *uri; bson_iter_t iter; bson_iter_t child; /* bad uris */ ASSERT(!mongoc_uri_new("mongodb://")); ASSERT(!mongoc_uri_new("mongodb://::")); ASSERT(!mongoc_uri_new("mongodb://*****:*****@localhost:27017/foo/?authSource=abcd"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "christian"); ASSERT_CMPSTR(mongoc_uri_get_password(uri), "secret"); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "abcd"); mongoc_uri_destroy(uri); /* should use the default auth source and mechanism */ uri = mongoc_uri_new("mongodb://*****:*****@localhost:27017"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "admin"); ASSERT(!mongoc_uri_get_auth_mechanism(uri)); mongoc_uri_destroy(uri); /* should use the db when no authSource is specified */ uri = mongoc_uri_new("mongodb://*****:*****@localhost/foo"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "foo"); mongoc_uri_destroy(uri); /* should recognize an empty password */ uri = mongoc_uri_new("mongodb://samantha:@localhost"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "samantha"); ASSERT_CMPSTR(mongoc_uri_get_password(uri), ""); mongoc_uri_destroy(uri); /* should recognize no password */ uri = mongoc_uri_new("mongodb://christian@localhost:27017"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "christian"); ASSERT(!mongoc_uri_get_password(uri)); mongoc_uri_destroy(uri); /* should recognize a url escaped character in the username */ uri = mongoc_uri_new("mongodb://christian%40realm:pwd@localhost:27017"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "christian@realm"); mongoc_uri_destroy(uri); /* while you shouldn't do this, lets test for it */ uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017/db%2ename"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_database(uri), "db.name"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017/db%2Ename"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_database(uri), "db.name"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017/?abcd=%20"); ASSERT(uri); options = mongoc_uri_get_options(uri); ASSERT(options); ASSERT(bson_iter_init_find(&iter, options, "abcd")); ASSERT(BSON_ITER_HOLDS_UTF8(&iter)); ASSERT_CMPSTR(bson_iter_utf8(&iter, NULL), " "); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@[::6]:27017/?abcd=%20"); ASSERT(uri); options = mongoc_uri_get_options(uri); ASSERT(options); ASSERT(bson_iter_init_find(&iter, options, "abcd")); ASSERT(BSON_ITER_HOLDS_UTF8(&iter)); ASSERT_CMPSTR(bson_iter_utf8(&iter, NULL), " "); mongoc_uri_destroy(uri); /* GSSAPI-specific options */ /* should recognize the GSSAPI mechanism, and use $external as source */ uri = mongoc_uri_new("mongodb://user%40DOMAIN.COM:password@localhost/?authMechanism=GSSAPI"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_mechanism(uri), "GSSAPI"); /*ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "$external");*/ mongoc_uri_destroy(uri); /* use $external as source when db is specified */ uri = mongoc_uri_new("mongodb://user%40DOMAIN.COM:password@localhost/foo/?authMechanism=GSSAPI"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "$external"); mongoc_uri_destroy(uri); /* should not accept authSource other than $external */ ASSERT(!mongoc_uri_new("mongodb://user%40DOMAIN.COM:password@localhost/foo/?authMechanism=GSSAPI&authSource=bar")); /* should accept authMechanismProperties */ uri = mongoc_uri_new("mongodb://user%40DOMAIN.COM:password@localhost/?authMechanism=GSSAPI" "&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true"); ASSERT(uri); credentials = mongoc_uri_get_credentials(uri); ASSERT(credentials); ASSERT(mongoc_uri_get_mechanism_properties(uri, &properties)); assert (bson_iter_init_find_case (&iter, &properties, "SERVICE_NAME") && BSON_ITER_HOLDS_UTF8 (&iter) && (0 == strcmp (bson_iter_utf8 (&iter, NULL), "other"))); assert (bson_iter_init_find_case (&iter, &properties, "CANONICALIZE_HOST_NAME") && BSON_ITER_HOLDS_UTF8 (&iter) && (0 == strcmp (bson_iter_utf8 (&iter, NULL), "true"))); mongoc_uri_destroy(uri); /* reverse order of arguments to ensure parsing still succeeds */ uri = mongoc_uri_new("mongodb://user@localhost/" "?authMechanismProperties=SERVICE_NAME:other" "&authMechanism=GSSAPI"); ASSERT(uri); mongoc_uri_destroy(uri); /* deprecated gssapiServiceName option */ uri = mongoc_uri_new("mongodb://christian%40realm.cc@localhost:27017/?authMechanism=GSSAPI&gssapiServiceName=blah"); ASSERT(uri); options = mongoc_uri_get_options(uri); ASSERT(options); assert (0 == strcmp (mongoc_uri_get_auth_mechanism (uri), "GSSAPI")); assert (0 == strcmp (mongoc_uri_get_username (uri), "*****@*****.**")); assert (bson_iter_init_find_case (&iter, options, "gssapiServiceName") && BSON_ITER_HOLDS_UTF8 (&iter) && (0 == strcmp (bson_iter_utf8 (&iter, NULL), "blah"))); mongoc_uri_destroy(uri); /* MONGODB-CR */ /* should recognize this mechanism */ uri = mongoc_uri_new("mongodb://user@localhost/?authMechanism=MONGODB-CR"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_mechanism(uri), "MONGODB-CR"); mongoc_uri_destroy(uri); /* X509 */ /* should recognize this mechanism, and use $external as the source */ uri = mongoc_uri_new("mongodb://user@localhost/?authMechanism=MONGODB-X509"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_mechanism(uri), "MONGODB-X509"); /*ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "$external");*/ mongoc_uri_destroy(uri); /* use $external as source when db is specified */ uri = mongoc_uri_new("mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality" "%2CST%3DmyState%2CC%3DmyCountry@localhost/foo/?authMechanism=MONGODB-X509"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "$external"); mongoc_uri_destroy(uri); /* should not accept authSource other than $external */ ASSERT(!mongoc_uri_new("mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality" "%2CST%3DmyState%2CC%3DmyCountry@localhost/foo/?authMechanism=MONGODB-X509&authSource=bar")); /* should recognize the encoded username */ uri = mongoc_uri_new("mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality" "%2CST%3DmyState%2CC%3DmyCountry@localhost/?authMechanism=MONGODB-X509"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry"); mongoc_uri_destroy(uri); /* PLAIN */ /* should recognize this mechanism */ uri = mongoc_uri_new("mongodb://user@localhost/?authMechanism=PLAIN"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_mechanism(uri), "PLAIN"); mongoc_uri_destroy(uri); /* SCRAM-SHA1 */ /* should recognize this mechanism */ uri = mongoc_uri_new("mongodb://user@localhost/?authMechanism=SCRAM-SHA1"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_mechanism(uri), "SCRAM-SHA1"); mongoc_uri_destroy(uri); }
static void test_mongoc_uri_new (void) { const mongoc_host_list_t *hosts; const bson_t *options; mongoc_uri_t *uri; bson_iter_t iter; bson_iter_t child; ASSERT(!mongoc_uri_new("mongodb://")); ASSERT(!mongoc_uri_new("mongodb://::")); ASSERT(!mongoc_uri_new("mongodb://*****:*****@localhost:27017?authSource=abcd"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "christian"); ASSERT_CMPSTR(mongoc_uri_get_password(uri), "secret"); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "abcd"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://*****:*****@localhost:27017"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "admin"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian@localhost:27017"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "christian"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "christian@realm"); mongoc_uri_destroy(uri); /* while you shouldn't do this, lets test for it */ uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017/db%2ename"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_database(uri), "db.name"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017/db%2Ename"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_database(uri), "db.name"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017/?abcd=%20"); ASSERT(uri); options = mongoc_uri_get_options(uri); ASSERT(options); ASSERT(bson_iter_init_find(&iter, options, "abcd")); ASSERT(BSON_ITER_HOLDS_UTF8(&iter)); ASSERT_CMPSTR(bson_iter_utf8(&iter, NULL), " "); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm.cc@localhost:27017/?authmechanism=GSSAPI&gssapiservicename=blah"); ASSERT(uri); options = mongoc_uri_get_options(uri); ASSERT(options); assert (0 == strcmp (mongoc_uri_get_auth_mechanism (uri), "GSSAPI")); assert (0 == strcmp (mongoc_uri_get_username (uri), "*****@*****.**")); assert (bson_iter_init_find_case (&iter, options, "gssapiservicename") && BSON_ITER_HOLDS_UTF8 (&iter) && (0 == strcmp (bson_iter_utf8 (&iter, NULL), "blah"))); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@[::6]:27017/?abcd=%20"); ASSERT(uri); options = mongoc_uri_get_options(uri); ASSERT(options); ASSERT(bson_iter_init_find(&iter, options, "abcd")); ASSERT(BSON_ITER_HOLDS_UTF8(&iter)); ASSERT_CMPSTR(bson_iter_utf8(&iter, NULL), " "); mongoc_uri_destroy(uri); }