diff --git a/src/protocol/protocol.c b/src/protocol/protocol.c index d7d2e71af..78921f572 100644 --- a/src/protocol/protocol.c +++ b/src/protocol/protocol.c @@ -52,34 +52,35 @@ struct protocol_backend { unsigned int need_slash_after_host:1; unsigned int free_syntax:1; unsigned int need_ssl:1; + unsigned int keep_double_slashes:1; }; static const struct protocol_backend protocol_backends[] = { - { "about", 0, about_protocol_handler, 0, 0, 1, 0 }, - { "bittorrent", 0, bittorrent_protocol_handler, 0, 0, 1, 0 }, - { "data", 0, data_protocol_handler, 0, 0, 1, 0 }, - { "file", 0, file_protocol_handler, 1, 0, 0, 0 }, - { "finger", 79, finger_protocol_handler, 1, 1, 0, 0 }, - { "fsp", 21, fsp_protocol_handler, 1, 1, 0, 0 }, - { "ftp", 21, ftp_protocol_handler, 1, 1, 0, 0 }, - { "gopher", 70, gopher_protocol_handler, 1, 1, 0, 0 }, - { "http", 80, http_protocol_handler, 1, 1, 0, 0 }, - { "https", 443, https_protocol_handler, 1, 1, 0, 1 }, - { "javascript", 0, NULL, 0, 0, 1, 0 }, - { "news", 0, news_protocol_handler, 0, 0, 1, 0 }, - { "nntp", 119, nntp_protocol_handler, 1, 1, 0, 0 }, - { "nntps", 563, nntp_protocol_handler, 1, 1, 0, 1 }, - { "proxy", 3128, proxy_protocol_handler, 1, 1, 0, 0 }, - { "smb", 139, smb_protocol_handler, 1, 1, 0, 0 }, - { "snews", 0, news_protocol_handler, 0, 0, 1, 0 }, + { "about", 0, about_protocol_handler, 0, 0, 1, 0, 1 }, + { "bittorrent", 0, bittorrent_protocol_handler, 0, 0, 1, 0, 1 }, + { "data", 0, data_protocol_handler, 0, 0, 1, 0, 1 }, + { "file", 0, file_protocol_handler, 1, 0, 0, 0, 0 }, + { "finger", 79, finger_protocol_handler, 1, 1, 0, 0, 1 }, + { "fsp", 21, fsp_protocol_handler, 1, 1, 0, 0, 1 }, + { "ftp", 21, ftp_protocol_handler, 1, 1, 0, 0, 0 }, + { "gopher", 70, gopher_protocol_handler, 1, 1, 0, 0, 1 }, + { "http", 80, http_protocol_handler, 1, 1, 0, 0, 1 }, + { "https", 443, https_protocol_handler, 1, 1, 0, 1, 1 }, + { "javascript", 0, NULL, 0, 0, 1, 0, 1 }, + { "news", 0, news_protocol_handler, 0, 0, 1, 0, 1 }, + { "nntp", 119, nntp_protocol_handler, 1, 1, 0, 0, 0 }, + { "nntps", 563, nntp_protocol_handler, 1, 1, 0, 1, 0 }, + { "proxy", 3128, proxy_protocol_handler, 1, 1, 0, 0, 1 }, + { "smb", 139, smb_protocol_handler, 1, 1, 0, 0, 1 }, + { "snews", 0, news_protocol_handler, 0, 0, 1, 0, 1 }, /* Keep these last! */ - { NULL, 0, NULL, 0, 0, 1, 0 }, + { NULL, 0, NULL, 0, 0, 1, 0, 1 }, - { "user", 0, NULL, 0, 0, 0, 0 }, + { "user", 0, NULL, 0, 0, 0, 0, 1 }, /* Internal protocol for mapping to protocol.user.* handlers. Placed * last because it's checked first and else should be ignored. */ - { "custom", 0, NULL, 0, 0, 1, 0 }, + { "custom", 0, NULL, 0, 0, 1, 0, 1 }, }; @@ -174,6 +175,14 @@ get_protocol_need_slash_after_host(enum protocol protocol) return protocol_backends[protocol].need_slash_after_host; } +int +get_protocol_keep_double_slashes(enum protocol protocol) +{ + assert(VALID_PROTOCOL(protocol)); + if_assert_failed return 0; + return protocol_backends[protocol].keep_double_slashes; +} + int get_protocol_free_syntax(enum protocol protocol) { diff --git a/src/protocol/protocol.h b/src/protocol/protocol.h index c39e794c8..c02e67166 100644 --- a/src/protocol/protocol.h +++ b/src/protocol/protocol.h @@ -44,6 +44,7 @@ typedef void (protocol_external_handler_T)(struct session *, struct uri *); int get_protocol_port(enum protocol protocol); int get_protocol_need_slashes(enum protocol protocol); +int get_protocol_keep_double_slashes(enum protocol protocol); int get_protocol_need_slash_after_host(enum protocol protocol); int get_protocol_free_syntax(enum protocol protocol); int get_protocol_need_ssl(enum protocol protocol); diff --git a/src/protocol/uri.c b/src/protocol/uri.c index 33316ebfc..9da2e9ee9 100644 --- a/src/protocol/uri.c +++ b/src/protocol/uri.c @@ -673,7 +673,7 @@ normalize_uri(struct uri *uri, unsigned char *uristring) { unsigned char *parse_string = uristring; unsigned char *src, *dest, *path; - int need_slash = 0; + int need_slash = 0, keep_dslash = 1; int parse = (uri == NULL); struct uri uri_struct; @@ -701,8 +701,10 @@ normalize_uri(struct uri *uri, unsigned char *uristring) if (get_protocol_free_syntax(uri->protocol)) return uristring; - if (uri->protocol != PROTOCOL_UNKNOWN) + if (uri->protocol != PROTOCOL_UNKNOWN) { need_slash = get_protocol_need_slash_after_host(uri->protocol); + keep_dslash = get_protocol_keep_double_slashes(uri->protocol); + } path = uri->data - need_slash; dest = src = path; @@ -766,8 +768,7 @@ normalize_uri(struct uri *uri, unsigned char *uristring) continue; } - } else if (is_uri_dir_sep(uri, src[1]) && - uri->protocol == PROTOCOL_FILE) { + } else if (is_uri_dir_sep(uri, src[1]) && !keep_dslash) { /* // - ignore first '/'. */ src += 1; continue;