Skip to content

Commit a840f06

Browse files
committed
Merge pull request #366 from puppyofkosh/CDRIVER-1392
CDRIVER-1392 appname in connection string
1 parent 071f842 commit a840f06

9 files changed

+255
-4
lines changed

src/mongoc/mongoc-client-pool.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ mongoc_client_pool_new (const mongoc_uri_t *uri)
8383
mongoc_client_pool_t *pool;
8484
const bson_t *b;
8585
bson_iter_t iter;
86+
#ifdef MONGOC_EXPERIMENTAL_FEATURES
87+
const char *appname;
88+
#endif
89+
8690

8791
ENTRY;
8892

@@ -122,6 +126,14 @@ mongoc_client_pool_new (const mongoc_uri_t *uri)
122126
}
123127
}
124128

129+
#ifdef MONGOC_EXPERIMENTAL_FEATURES
130+
appname = mongoc_uri_get_option_as_utf8 (pool->uri, "appname", NULL);
131+
if (appname) {
132+
/* the appname should have already been validated */
133+
BSON_ASSERT (mongoc_client_pool_set_appname (pool, appname));
134+
}
135+
#endif
136+
125137
mongoc_counter_client_pools_active_inc();
126138

127139
RETURN(pool);

src/mongoc/mongoc-client.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,9 @@ _mongoc_client_new_from_uri (const mongoc_uri_t *uri, mongoc_topology_t *topolog
723723
const mongoc_read_prefs_t *read_prefs;
724724
const mongoc_read_concern_t *read_concern;
725725
const mongoc_write_concern_t *write_concern;
726+
#ifdef MONGOC_EXPERIMENTAL_FEATURES
727+
const char *appname;
728+
#endif
726729

727730
BSON_ASSERT (uri);
728731

@@ -750,6 +753,14 @@ _mongoc_client_new_from_uri (const mongoc_uri_t *uri, mongoc_topology_t *topolog
750753
read_prefs = mongoc_uri_get_read_prefs_t (client->uri);
751754
client->read_prefs = mongoc_read_prefs_copy (read_prefs);
752755

756+
#ifdef MONGOC_EXPERIMENTAL_FEATURES
757+
appname = mongoc_uri_get_option_as_utf8 (client->uri, "appname", NULL);
758+
if (appname && client->topology->single_threaded) {
759+
/* the appname should have already been validated */
760+
BSON_ASSERT (mongoc_client_set_appname (client, appname));
761+
}
762+
#endif
763+
753764
mongoc_cluster_init (&client->cluster, client->uri, client);
754765

755766
#ifdef MONGOC_ENABLE_SSL

src/mongoc/mongoc-metadata-private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ bool _mongoc_metadata_build_doc_with_application (bson_t *doc,
6060
const char *application);
6161
void _mongoc_metadata_freeze (void);
6262
mongoc_metadata_t *_mongoc_metadata_get (void);
63+
bool _mongoc_metadata_appname_is_valid (const char *appname);
6364
BSON_END_DECLS
6465

6566
#endif

src/mongoc/mongoc-metadata.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,9 @@ _mongoc_metadata_get (void)
314314
{
315315
return &gMongocMetadata;
316316
}
317+
318+
bool
319+
_mongoc_metadata_appname_is_valid (const char *appname)
320+
{
321+
return strlen (appname) <= MONGOC_METADATA_APPNAME_MAX;
322+
}

src/mongoc/mongoc-topology-scanner.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ bool
763763
_mongoc_topology_scanner_set_appname (mongoc_topology_scanner_t *ts,
764764
const char *appname)
765765
{
766-
if (strlen (appname) > MONGOC_METADATA_APPNAME_MAX) {
766+
if (!_mongoc_metadata_appname_is_valid (appname)) {
767767
return false;
768768
}
769769

src/mongoc/mongoc-uri.c

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "mongoc-host-list.h"
2929
#include "mongoc-host-list-private.h"
3030
#include "mongoc-log.h"
31+
#include "mongoc-metadata-private.h"
3132
#include "mongoc-socket.h"
3233
#include "mongoc-uri-private.h"
3334
#include "mongoc-read-concern-private.h"
@@ -634,10 +635,15 @@ mongoc_uri_parse_option (mongoc_uri_t *uri,
634635
mongoc_read_concern_set_level (uri->read_concern, value);
635636
} else if (!strcasecmp(key, "authmechanismproperties")) {
636637
if (!mongoc_uri_parse_auth_mechanism_properties(uri, value)) {
637-
bson_free(key);
638-
bson_free(value);
639-
return false;
638+
goto CLEANUP;
639+
}
640+
#ifdef MONGOC_EXPERIMENTAL_FEATURES
641+
} else if (!strcasecmp (key, "appname")) {
642+
if (!mongoc_uri_set_appname (uri, value)) {
643+
MONGOC_WARNING ("appname is invalid [appname=%s]", value);
644+
goto CLEANUP;
640645
}
646+
#endif
641647
} else {
642648
bson_append_utf8(&uri->options, key, -1, value, -1);
643649
}
@@ -1114,6 +1120,37 @@ mongoc_uri_set_auth_source (mongoc_uri_t *uri, const char *value)
11141120
return true;
11151121
}
11161122

1123+
1124+
#ifdef MONGOC_EXPERIMENTAL_FEATURES
1125+
const char *
1126+
mongoc_uri_get_appname (const mongoc_uri_t *uri)
1127+
{
1128+
BSON_ASSERT (uri);
1129+
1130+
return mongoc_uri_get_option_as_utf8 (uri, "appname", NULL);
1131+
}
1132+
1133+
1134+
bool
1135+
mongoc_uri_set_appname (mongoc_uri_t *uri,
1136+
const char *value)
1137+
{
1138+
BSON_ASSERT (value);
1139+
1140+
if (!bson_utf8_validate (value, strlen (value), false)) {
1141+
return false;
1142+
}
1143+
1144+
if (!_mongoc_metadata_appname_is_valid (value)) {
1145+
return false;
1146+
}
1147+
1148+
mongoc_uri_bson_append_or_replace_key (&uri->options, "appname", value);
1149+
1150+
return true;
1151+
}
1152+
#endif
1153+
11171154
const bson_t *
11181155
mongoc_uri_get_options (const mongoc_uri_t *uri)
11191156
{

src/mongoc/mongoc-uri.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "mongoc-read-prefs.h"
2828
#include "mongoc-read-concern.h"
2929
#include "mongoc-write-concern.h"
30+
#include "mongoc-config.h"
3031

3132

3233
#ifndef MONGOC_DEFAULT_PORT
@@ -87,6 +88,11 @@ const bson_t *mongoc_uri_get_credentials (const mongoc_
8788
const char *mongoc_uri_get_auth_source (const mongoc_uri_t *uri);
8889
bool mongoc_uri_set_auth_source (mongoc_uri_t *uri,
8990
const char *value);
91+
#ifdef MONGOC_EXPERIMENTAL_FEATURES
92+
const char *mongoc_uri_get_appname (const mongoc_uri_t *uri);
93+
bool mongoc_uri_set_appname (mongoc_uri_t *uri,
94+
const char *value);
95+
#endif
9096
const char *mongoc_uri_get_auth_mechanism (const mongoc_uri_t *uri);
9197
bool mongoc_uri_get_mechanism_properties (const mongoc_uri_t *uri,
9298
bson_t *properties);

tests/test-mongoc-client.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,6 +1981,93 @@ test_client_sends_metadata_pooled (void)
19811981
{
19821982
_test_client_sends_metadata (true);
19831983
}
1984+
1985+
static void
1986+
test_client_appname (bool pooled,
1987+
bool use_uri)
1988+
{
1989+
mock_server_t *server;
1990+
request_t *request;
1991+
mongoc_uri_t *uri;
1992+
future_t *future;
1993+
mongoc_client_t *client;
1994+
mongoc_client_pool_t *pool;
1995+
const char *const server_reply = "{'ok': 1, 'ismaster': true}";
1996+
const int heartbeat_ms = 500;
1997+
1998+
server = mock_server_new ();
1999+
mock_server_run (server);
2000+
uri = mongoc_uri_copy (mock_server_get_uri (server));
2001+
mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", heartbeat_ms);
2002+
2003+
if (use_uri) {
2004+
mongoc_uri_set_option_as_utf8 (uri, "appname", "testapp");
2005+
}
2006+
2007+
if (pooled) {
2008+
pool = mongoc_client_pool_new (uri);
2009+
if (!use_uri) {
2010+
ASSERT (mongoc_client_pool_set_appname (pool, "testapp"));
2011+
}
2012+
client = mongoc_client_pool_pop (pool);
2013+
} else {
2014+
client = mongoc_client_new_from_uri (uri);
2015+
if (!use_uri) {
2016+
ASSERT (mongoc_client_set_appname (client, "testapp"));
2017+
}
2018+
future = _force_ismaster_with_ping (client, heartbeat_ms);
2019+
}
2020+
2021+
request = mock_server_receives_command (
2022+
server, "admin", MONGOC_QUERY_SLAVE_OK,
2023+
"{'isMaster': 1,"
2024+
" 'client': {"
2025+
" 'application': {"
2026+
" 'name': 'testapp'}}}");
2027+
2028+
mock_server_replies_simple (request, server_reply);
2029+
if (!pooled) {
2030+
_respond_to_ping (future, server);
2031+
}
2032+
2033+
request_destroy (request);
2034+
2035+
/* cleanup */
2036+
if (pooled) {
2037+
mongoc_client_pool_push (pool, client);
2038+
mongoc_client_pool_destroy (pool);
2039+
} else {
2040+
mongoc_client_destroy (client);
2041+
}
2042+
2043+
mongoc_uri_destroy (uri);
2044+
mock_server_destroy (server);
2045+
}
2046+
2047+
static void
2048+
test_client_appname_single_uri (void)
2049+
{
2050+
test_client_appname (false, true);
2051+
}
2052+
2053+
static void
2054+
test_client_appname_single_no_uri (void)
2055+
{
2056+
test_client_appname (false, false);
2057+
}
2058+
2059+
static void
2060+
test_client_appname_pooled_uri (void)
2061+
{
2062+
test_client_appname (true, true);
2063+
}
2064+
2065+
static void
2066+
test_client_appname_pooled_no_uri (void)
2067+
{
2068+
test_client_appname (true, false);
2069+
}
2070+
19842071
#endif
19852072

19862073
void
@@ -2038,6 +2125,14 @@ test_client_install (TestSuite *suite)
20382125
test_client_sends_metadata_single);
20392126
TestSuite_Add (suite, "/Client/sends_metadata_pooled",
20402127
test_client_sends_metadata_pooled);
2128+
TestSuite_Add (suite, "/Client/appname_single_uri",
2129+
test_client_appname_single_uri);
2130+
TestSuite_Add (suite, "/Client/appname_single_no_uri",
2131+
test_client_appname_single_no_uri);
2132+
TestSuite_Add (suite, "/Client/appname_pooled_uri",
2133+
test_client_appname_pooled_uri);
2134+
TestSuite_Add (suite, "/Client/appname_pooled_no_uri",
2135+
test_client_appname_pooled_no_uri);
20412136
#endif
20422137

20432138
#ifdef TODO_CDRIVER_689

tests/test-mongoc-metadata.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,73 @@ _reset_metadata (void)
4040
_mongoc_metadata_init ();
4141
}
4242

43+
static void
44+
test_mongoc_metadata_appname_in_uri (void)
45+
{
46+
char long_string[MONGOC_METADATA_APPNAME_MAX + 2];
47+
char *uri_str;
48+
const char *good_uri = "mongodb://host/?appname=mongodump";
49+
mongoc_uri_t *uri;
50+
const char *appname = "mongodump";
51+
52+
memset (long_string, 'a', MONGOC_METADATA_APPNAME_MAX + 1);
53+
long_string[MONGOC_METADATA_APPNAME_MAX + 1] = '\0';
54+
55+
/* Shouldn't be able to set with appname really long */
56+
capture_logs (true);
57+
uri_str = bson_strdup_printf ("mongodb://a/?appname=%s", long_string);
58+
ASSERT (!mongoc_client_new (uri_str));
59+
capture_logs (false);
60+
61+
uri = mongoc_uri_new (good_uri);
62+
ASSERT (uri);
63+
appname = mongoc_uri_get_appname (uri);
64+
ASSERT (appname);
65+
ASSERT (!strcmp (appname, appname));
66+
mongoc_uri_destroy (uri);
67+
68+
uri = mongoc_uri_new (NULL);
69+
ASSERT (uri);
70+
ASSERT (!mongoc_uri_set_appname (uri, long_string));
71+
ASSERT (mongoc_uri_set_appname (uri, appname));
72+
appname = mongoc_uri_get_appname (uri);
73+
ASSERT (appname);
74+
ASSERT (!strcmp (appname, appname));
75+
mongoc_uri_destroy (uri);
76+
77+
bson_free (uri_str);
78+
}
79+
80+
static void
81+
test_mongoc_metadata_appname_frozen_single (void)
82+
{
83+
mongoc_client_t *client;
84+
const char *good_uri = "mongodb://host/?appname=mongodump";
85+
86+
client = mongoc_client_new (good_uri);
87+
88+
/* Shouldn't be able to set appname again */
89+
ASSERT (!mongoc_client_set_appname (client, "a"));
90+
91+
mongoc_client_destroy (client);
92+
}
93+
94+
static void
95+
test_mongoc_metadata_appname_frozen_pooled (void)
96+
{
97+
mongoc_client_pool_t *pool;
98+
const char *good_uri = "mongodb://host/?appname=mongodump";
99+
mongoc_uri_t *uri;
100+
101+
uri = mongoc_uri_new (good_uri);
102+
103+
pool = mongoc_client_pool_new (uri);
104+
ASSERT (!mongoc_client_pool_set_appname (pool, "test"));
105+
106+
mongoc_client_pool_destroy (pool);
107+
mongoc_uri_destroy (uri);
108+
}
109+
43110
static void
44111
test_mongoc_metadata_append_success (void)
45112
{
@@ -71,6 +138,7 @@ test_mongoc_metadata_append_success (void)
71138
mock_server_run (server);
72139
uri = mongoc_uri_copy (mock_server_get_uri (server));
73140
mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", 500);
141+
mongoc_uri_set_option_as_utf8 (uri, "appname", "testapp");
74142
pool = mongoc_client_pool_new (uri);
75143

76144
/* Force topology scanner to start */
@@ -86,6 +154,14 @@ test_mongoc_metadata_append_success (void)
86154
ASSERT (bson_iter_init_find (&iter, request_doc, METADATA_FIELD));
87155
ASSERT (bson_iter_recurse (&iter, &md_iter));
88156

157+
ASSERT (bson_iter_find (&md_iter, "application"));
158+
ASSERT (BSON_ITER_HOLDS_DOCUMENT (&md_iter));
159+
ASSERT (bson_iter_recurse (&md_iter, &inner_iter));
160+
ASSERT (bson_iter_find (&inner_iter, "name"));
161+
val = bson_iter_utf8 (&inner_iter, NULL);
162+
ASSERT (val);
163+
ASSERT (!strcmp (val, "testapp"));
164+
89165
/* Make sure driver.name and driver.version and platform are all right */
90166
ASSERT (bson_iter_find (&md_iter, "driver"));
91167
ASSERT (BSON_ITER_HOLDS_DOCUMENT (&md_iter));
@@ -321,6 +397,13 @@ test_mongoc_metadata_cannot_send (void)
321397
void
322398
test_metadata_install (TestSuite *suite)
323399
{
400+
TestSuite_Add (suite, "/ClientMetadata/appname_in_uri",
401+
test_mongoc_metadata_appname_in_uri);
402+
TestSuite_Add (suite, "/ClientMetadata/appname_frozen_single",
403+
test_mongoc_metadata_appname_frozen_single);
404+
TestSuite_Add (suite, "/ClientMetadata/appname_frozen_pooled",
405+
test_mongoc_metadata_appname_frozen_pooled);
406+
324407
TestSuite_Add (suite, "/ClientMetadata/success",
325408
test_mongoc_metadata_append_success);
326409
TestSuite_Add (suite, "/ClientMetadata/failure",

0 commit comments

Comments
 (0)