Skip to content

Commit 17f150e

Browse files
committed
Merge remote-tracking branch 'origin/2.0-wl10077' into 2.0
2 parents 1c50422 + ca83285 commit 17f150e

File tree

3 files changed

+136
-21
lines changed

3 files changed

+136
-21
lines changed

cdk/parser/tests/parser-t.cc

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,10 +1113,18 @@ TEST(Parser, uri)
11131113
"host",
11141114
URI_parts(none, none, "host", 0, none, false)
11151115
},
1116+
{
1117+
"[::1]",
1118+
URI_parts(none, none, "::1", 0, none, false)
1119+
},
11161120
{
11171121
"host:123",
11181122
URI_parts(none, none, "host", 123, none, false)
11191123
},
1124+
{
1125+
"[::1]:123",
1126+
URI_parts(none, none, "::1", 123, none, false)
1127+
},
11201128
{
11211129
"host:0",
11221130
URI_parts(none,none, "host", 0, none , false)
@@ -1125,6 +1133,10 @@ TEST(Parser, uri)
11251133
"host/path",
11261134
URI_parts(none , none, "host", 0, "path", false)
11271135
},
1136+
{
1137+
"[::1]/path",
1138+
URI_parts(none , none, "::1", 0, "path", false)
1139+
},
11281140
{
11291141
"host/",
11301142
URI_parts(none , none, "host", 0, "", false)
@@ -1133,6 +1145,10 @@ TEST(Parser, uri)
11331145
"user@host/path",
11341146
URI_parts("user" , none, "host", 0, "path", false)
11351147
},
1148+
{
1149+
"user@[::1]/path",
1150+
URI_parts("user" , none, "::1", 0, "path", false)
1151+
},
11361152
{
11371153
"user%40host%2Fpath",
11381154
URI_parts(none , none, "user@host/path", 0, none, false)
@@ -1145,10 +1161,18 @@ TEST(Parser, uri)
11451161
"user:pwd@host",
11461162
URI_parts("user" , "pwd", "host", 0, none, false)
11471163
},
1164+
{
1165+
"user:pwd@[::1]",
1166+
URI_parts("user" , "pwd", "::1", 0, none, false)
1167+
},
11481168
{
11491169
"user:pwd@host:123",
11501170
URI_parts("user" , "pwd", "host", 123, none, false)
11511171
},
1172+
{
1173+
"user:pwd@[::1]:123",
1174+
URI_parts("user" , "pwd", "::1", 123, none, false)
1175+
},
11521176
{
11531177
"user:pwd@host:123/",
11541178
URI_parts("user" , "pwd", "host", 123, "", false)
@@ -1157,6 +1181,10 @@ TEST(Parser, uri)
11571181
"user:pwd@host:123/foo?key=val",
11581182
URI_parts("user" , "pwd", "host", 123, "foo", true)
11591183
},
1184+
{
1185+
"user:pwd@[::1]:123/foo?key=val",
1186+
URI_parts("user" , "pwd", "::1", 123, "foo", true)
1187+
},
11601188
{
11611189
"user:pwd@host:123?key=val",
11621190
URI_parts("user" , "pwd", "host", 123, none, true)
@@ -1277,7 +1305,9 @@ TEST(Parser, uri)
12771305
"host/db?query#foo",
12781306
"host/db?a=[a,b,c&b",
12791307
"host/db?a=[a,b,c]foo=bar",
1280-
"host/db?a=[a,b=foo"
1308+
"host/db?a=[a,b=foo",
1309+
"[::1]:port:123",
1310+
"[::1"
12811311
//"host/db?l=[a,b&c]" TODO: should this fail?
12821312
// TODO: allowed chars in host/path component
12831313
};

cdk/parser/uri_parser.cc

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,13 @@ struct URI_parser::TokSet
263263
m_bits.set(tt2);
264264
}
265265

266+
TokSet(token_type tt1, token_type tt2, token_type tt3)
267+
{
268+
m_bits.set(tt1);
269+
m_bits.set(tt2);
270+
m_bits.set(tt3);
271+
}
272+
266273
bool has_token(token_type tt) const
267274
{
268275
return m_bits.test(tt);
@@ -294,21 +301,30 @@ void URI_parser::process(Processor &prc) const
294301
bool rescan = false;
295302
bool has_port = false;
296303

297-
self->consume_until(host, TokSet(T_AT, T_COLON));
298-
299-
if (self->consume_token(T_COLON))
304+
if (self->next_token_is(T_SQOPEN))
300305
{
301306
/*
307+
IPv6 adress found! Will be parsed on rescan
308+
*/
309+
rescan = true;
310+
}
311+
else
312+
{
313+
self->consume_until(host, TokSet(T_AT, T_COLON ));
314+
315+
if (self->consume_token(T_COLON))
316+
{
317+
/*
302318
We have seen "<???>:" and it still can be user followed
303319
by a password or host followed by a port.
304320
305321
We consume further tokens until @, or end of the authority
306322
part, whichever comes first.
307323
*/
308324

309-
self->consume_until(port, T_AT);
325+
self->consume_until(port, T_AT);
310326

311-
/*
327+
/*
312328
If we see @ now, then it means we were looking at user
313329
credentials so far (and they are stored in host and port,
314330
respectively). We report them and request re-scanning host/port
@@ -319,25 +335,26 @@ void URI_parser::process(Processor &prc) const
319335
the corresponding variables.
320336
*/
321337

322-
if (self->consume_token(T_AT))
323-
{
324-
// <user>:<pwd>@...
325-
prc.user(host);
326-
prc.password(port);
327-
rescan = true;
338+
if (self->consume_token(T_AT))
339+
{
340+
// <user>:<pwd>@...
341+
prc.user(host);
342+
prc.password(port);
343+
rescan = true;
344+
}
345+
else
346+
has_port = true;
328347
}
329-
else
330-
has_port = true;
331-
}
332-
else if (self->consume_token(T_AT))
333-
{
334-
/*
348+
else if (self->consume_token(T_AT))
349+
{
350+
/*
335351
No ':' seen but we see '@'. It means user without password and
336352
user is stored in host variable. We report it an request
337353
re-scanning of host/port info.
338354
*/
339-
prc.user(host);
340-
rescan = true;
355+
prc.user(host);
356+
rescan = true;
357+
}
341358
}
342359

343360
/*
@@ -350,7 +367,21 @@ void URI_parser::process(Processor &prc) const
350367
{
351368
host.clear();
352369
port.clear();
353-
self->consume_until(host, T_COLON);
370+
371+
if (self->consume_token(T_SQOPEN))
372+
{
373+
/*
374+
IPv6 address
375+
*/
376+
host.clear();
377+
self->consume_until(host, T_SQCLOSE);
378+
if (!self->consume_token(T_SQCLOSE))
379+
throw Error(this, L"Missing ']' while parsing IPv6 address");
380+
}
381+
else
382+
{
383+
self->consume_until(host, T_COLON );
384+
}
354385

355386
if (self->consume_token(T_COLON))
356387
{

devapi/tests/session-t.cc

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,3 +432,57 @@ TEST_F(Sess, ssl_session)
432432
}
433433

434434
}
435+
436+
TEST_F(Sess, ipv6)
437+
{
438+
439+
SKIP_IF_NO_XPLUGIN;
440+
441+
{
442+
mysqlx::XSession sess(SessionSettings::HOST, "::1",
443+
SessionSettings::PORT, get_port(),
444+
SessionSettings::USER, get_user(),
445+
SessionSettings::PWD, get_password() ? get_password() : nullptr ,
446+
SessionSettings::SSL_ENABLE, false);
447+
}
448+
449+
//Using URI
450+
451+
std::stringstream uri;
452+
453+
uri << "mysqlx://" << get_user();
454+
455+
if (get_password() && *get_password())
456+
uri << ":"<< get_password();
457+
458+
uri << "@" << "[::1]:" << get_port();
459+
460+
//URI without ssl_enable
461+
{
462+
mysqlx::XSession sess(uri.str());
463+
464+
SqlResult res = sess.bindToDefaultShard().sql("SHOW STATUS LIKE 'mysqlx_ssl_cipher'").execute();
465+
466+
auto row = res.fetchOne();
467+
cout << row[0] << ":" << row[1] << endl;
468+
469+
string cipher = row[1];
470+
471+
EXPECT_TRUE(cipher.empty());
472+
}
473+
474+
//Enable SSL
475+
uri << "/?ssl-enable";
476+
{
477+
mysqlx::XSession sess(uri.str());
478+
479+
SqlResult res = sess.bindToDefaultShard().sql("SHOW STATUS LIKE 'mysqlx_ssl_cipher'").execute();
480+
481+
auto row = res.fetchOne();
482+
cout << row[0] << ":" << row[1] << endl;
483+
484+
string cipher = row[1];
485+
486+
EXPECT_FALSE(cipher.empty());
487+
}
488+
}

0 commit comments

Comments
 (0)