/* from RFC 6694 */
"about:blank",
/* from RFC 6733 */
-#if 0 // these don't comply with RFC 3986
"aaa://host.example.com;transport=tcp",
"aaa://host.example.com:6666;transport=tcp",
"aaa://host.example.com;protocol=diameter",
"aaa://host.example.com:6666;protocol=diameter",
"aaa://host.example.com:6666;transport=tcp;protocol=diameter",
"aaa://host.example.com:1813;transport=udp;protocol=radius",
-#endif
/* from RFC 6787 */
"session:request1@form-level.store",
"session:help@root-level.store",
test_end();
}
+static void test_uri_aaa(void)
+{
+ test_begin("uri aaa");
+
+ const char *uri = "aaa://host.example.com:6666;transport=tcp;protocol=diameter";
+ struct uri_parser parser;
+ uri_parser_init(&parser, pool_datastack_create(), uri);
+ parser.semicolon_params = TRUE;
+
+ const char *scheme;
+ struct uri_authority auth;
+ const char *query;
+ int ret;
+ ret = uri_parse_scheme(&parser, &scheme);
+ test_assert(ret > 0);
+ test_assert_strcmp(scheme, "aaa");
+ ret = uri_parse_slashslash_host_authority(&parser, &auth);
+ test_assert(ret > 0);
+ test_assert_strcmp(auth.host.name, "host.example.com");
+ test_assert_ucmp(auth.port, ==, 6666);
+ ret = uri_parse_query(&parser, &query);
+ test_assert(ret > 0);
+ test_assert_strcmp(query, "transport=tcp;protocol=diameter");
+ test_end();
+}
+
void test_uri(void)
{
test_uri_valid();
test_uri_invalid();
test_uri_rfc();
test_uri_escape();
+ test_uri_aaa();
}
switch (*parser->cur) {
case ':': case '/': case '?': case '#':
break;
+ case ';':
+ if (parser->semicolon_params)
+ break;
+ /* fall-through */
default:
if (parser->parse_prefix)
break;
switch (*parser->cur) {
case '/': case '?': case '#':
break;
+ case ';':
+ if (parser->semicolon_params)
+ break;
+ /* fall-through */
default:
if (parser->parse_prefix)
break;
query = *( pchar / "/" / "?" )
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
*/
- if (parser->cur >= parser->end || *parser->cur != '?')
+ if (parser->cur >= parser->end ||
+ (!parser->semicolon_params && *parser->cur != '?') ||
+ (parser->semicolon_params && *parser->cur != ';'))
return 0;
parser->cur++;
*/
/* scheme ":" */
- if ((flags & URI_PARSE_SCHEME_EXTERNAL) == 0 &&
- (ret = uri_parse_scheme(parser, NULL)) <= 0) {
- if (ret == 0)
- parser->error = "Missing scheme";
- return -1;
+ if ((flags & URI_PARSE_SCHEME_EXTERNAL) == 0) {
+ const char *scheme;
+ if ((ret = uri_parse_scheme(parser, &scheme)) <= 0) {
+ if (ret == 0)
+ parser->error = "Missing scheme";
+ return -1;
+ }
+ if (strcmp(scheme, "aaa") == 0 ||
+ (flags & URI_PARSE_SEMICOLON_PARAMS) != 0)
+ parser->semicolon_params = TRUE;
}
/* "//" authority */
URI_PARSE_SCHEME_EXTERNAL = BIT(0),
/* Allow '#fragment' part in URI */
URI_PARSE_ALLOW_FRAGMENT_PART = BIT(1),
+ /* Allow ';param' after host - violates RFC3986 */
+ URI_PARSE_SEMICOLON_PARAMS = BIT(2),
};
struct uri_host {
bool allow_pct_nul:1;
bool parse_prefix:1;
+ bool semicolon_params:1;
};
static inline const char *uri_char_sanitize(unsigned char c)