diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index 6ede9dd8a..cf8eb39ac 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -595,6 +595,14 @@ typedef struct _cef_urlparts_t { /// cef_string_t port; + /// + // Origin contains just the scheme, host, and port from a URL. Equivalent to + // clearing any username and password, replacing the path with a slash, and + // clearing everything after that. This value will be empty for non-standard + // URLs. + /// + cef_string_t origin; + /// // Path component including the first slash following the host. /// diff --git a/include/internal/cef_types_wrappers.h b/include/internal/cef_types_wrappers.h index 160a73693..5aa689d6a 100644 --- a/include/internal/cef_types_wrappers.h +++ b/include/internal/cef_types_wrappers.h @@ -472,6 +472,7 @@ struct CefURLPartsTraits { cef_string_clear(&s->password); cef_string_clear(&s->host); cef_string_clear(&s->port); + cef_string_clear(&s->origin); cef_string_clear(&s->path); cef_string_clear(&s->query); } @@ -486,6 +487,7 @@ struct CefURLPartsTraits { copy); cef_string_set(src->host.str, src->host.length, &target->host, copy); cef_string_set(src->port.str, src->port.length, &target->port, copy); + cef_string_set(src->origin.str, src->origin.length, &target->origin, copy); cef_string_set(src->path.str, src->path.length, &target->path, copy); cef_string_set(src->query.str, src->query.length, &target->query, copy); } diff --git a/libcef/common/url_impl.cc b/libcef/common/url_impl.cc index dda4e3edd..fc35dae6c 100644 --- a/libcef/common/url_impl.cc +++ b/libcef/common/url_impl.cc @@ -18,6 +18,7 @@ bool CefParseURL(const CefString& url, CefString(&parts.username).FromString(gurl.username()); CefString(&parts.password).FromString(gurl.password()); CefString(&parts.host).FromString(gurl.host()); + CefString(&parts.origin).FromString(gurl.GetOrigin().spec()); CefString(&parts.port).FromString(gurl.port()); CefString(&parts.path).FromString(gurl.path()); CefString(&parts.query).FromString(gurl.query()); diff --git a/tests/unittests/url_unittest.cc b/tests/unittests/url_unittest.cc index 12918b68e..621a9e394 100644 --- a/tests/unittests/url_unittest.cc +++ b/tests/unittests/url_unittest.cc @@ -5,181 +5,215 @@ #include "include/cef_url.h" #include "testing/gtest/include/gtest/gtest.h" -TEST(URLTest, CreateURL) { - // Create the URL using the spec. - { - CefURLParts parts; - CefString url; - CefString(&parts.spec).FromASCII( - "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2"); - EXPECT_TRUE(CefCreateURL(parts, url)); - EXPECT_EQ(url, - "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2"); - } - - // Test that scheme and host are required. - { - CefURLParts parts; - CefString url; - CefString(&parts.scheme).FromASCII("http"); - EXPECT_FALSE(CefCreateURL(parts, url)); - } - { - CefURLParts parts; - CefString url; - CefString(&parts.host).FromASCII("www.example.com"); - EXPECT_FALSE(CefCreateURL(parts, url)); - } - - // Create the URL using scheme and host. - { - CefURLParts parts; - CefString url; - CefString(&parts.scheme).FromASCII("http"); - CefString(&parts.host).FromASCII("www.example.com"); - EXPECT_TRUE(CefCreateURL(parts, url)); - EXPECT_EQ(url, "http://www.example.com/"); - } - - // Create the URL using scheme, host and path. - { - CefURLParts parts; - CefString url; - CefString(&parts.scheme).FromASCII("http"); - CefString(&parts.host).FromASCII("www.example.com"); - CefString(&parts.path).FromASCII("/path/to.html"); - EXPECT_TRUE(CefCreateURL(parts, url)); - EXPECT_EQ(url, "http://www.example.com/path/to.html"); - } - - // Create the URL using scheme, host, path and query. - { - CefURLParts parts; - CefString url; - CefString(&parts.scheme).FromASCII("http"); - CefString(&parts.host).FromASCII("www.example.com"); - CefString(&parts.path).FromASCII("/path/to.html"); - CefString(&parts.query).FromASCII("foo=test&bar=test2"); - EXPECT_TRUE(CefCreateURL(parts, url)); - EXPECT_EQ(url, "http://www.example.com/path/to.html?foo=test&bar=test2"); - } - - // Create the URL using all the various components. - { - CefURLParts parts; - CefString url; - CefString(&parts.scheme).FromASCII("http"); - CefString(&parts.username).FromASCII("user"); - CefString(&parts.password).FromASCII("pass"); - CefString(&parts.host).FromASCII("www.example.com"); - CefString(&parts.port).FromASCII("88"); - CefString(&parts.path).FromASCII("/path/to.html"); - CefString(&parts.query).FromASCII("foo=test&bar=test2"); - EXPECT_TRUE(CefCreateURL(parts, url)); - EXPECT_EQ(url, - "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2"); - } +// Create the URL using the spec. +TEST(URLTest, CreateURLSpec) { + CefURLParts parts; + CefString url; + CefString(&parts.spec).FromASCII( + "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2"); + EXPECT_TRUE(CefCreateURL(parts, url)); + EXPECT_STREQ( + "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2", + url.ToString().c_str()); } -TEST(URLTest, ParseURL) { - // Parse the URL using scheme and host. - { - CefURLParts parts; - CefString url; - url.FromASCII("http://www.example.com"); - EXPECT_TRUE(CefParseURL(url, parts)); +// Test that host is required. +TEST(URLTest, CreateURLHostRequired) { + CefURLParts parts; + CefString url; + CefString(&parts.scheme).FromASCII("http"); + EXPECT_FALSE(CefCreateURL(parts, url)); +} - CefString spec(&parts.spec); - EXPECT_EQ(spec, "http://www.example.com/"); - EXPECT_EQ(parts.username.length, (size_t)0); - EXPECT_EQ(parts.password.length, (size_t)0); - CefString scheme(&parts.scheme); - EXPECT_EQ(scheme, "http"); - CefString host(&parts.host); - EXPECT_EQ(host, "www.example.com"); - EXPECT_EQ(parts.port.length, (size_t)0); - CefString path(&parts.path); - EXPECT_EQ(path, "/"); - EXPECT_EQ(parts.query.length, (size_t)0); - } +// Test that scheme is required. +TEST(URLTest, CreateURLSchemeRequired) { + CefURLParts parts; + CefString url; + CefString(&parts.host).FromASCII("www.example.com"); + EXPECT_FALSE(CefCreateURL(parts, url)); +} - // Parse the URL using scheme, host and path. - { - CefURLParts parts; - CefString url; - url.FromASCII("http://www.example.com/path/to.html"); - EXPECT_TRUE(CefParseURL(url, parts)); +// Create the URL using scheme and host. +TEST(URLTest, CreateURLSchemeHost) { + CefURLParts parts; + CefString url; + CefString(&parts.scheme).FromASCII("http"); + CefString(&parts.host).FromASCII("www.example.com"); + EXPECT_TRUE(CefCreateURL(parts, url)); + EXPECT_STREQ("http://www.example.com/", url.ToString().c_str()); +} - CefString spec(&parts.spec); - EXPECT_EQ(spec, "http://www.example.com/path/to.html"); - EXPECT_EQ(parts.username.length, (size_t)0); - EXPECT_EQ(parts.password.length, (size_t)0); - CefString scheme(&parts.scheme); - EXPECT_EQ(scheme, "http"); - CefString host(&parts.host); - EXPECT_EQ(host, "www.example.com"); - EXPECT_EQ(parts.port.length, (size_t)0); - CefString path(&parts.path); - EXPECT_EQ(path, "/path/to.html"); - EXPECT_EQ(parts.query.length, (size_t)0); - } +// Create the URL using scheme, host and path. +TEST(URLTest, CreateURLSchemeHostPath) { + CefURLParts parts; + CefString url; + CefString(&parts.scheme).FromASCII("http"); + CefString(&parts.host).FromASCII("www.example.com"); + CefString(&parts.path).FromASCII("/path/to.html"); + EXPECT_TRUE(CefCreateURL(parts, url)); + EXPECT_STREQ("http://www.example.com/path/to.html", url.ToString().c_str()); +} - // Parse the URL using scheme, host, path and query. - { - CefURLParts parts; - CefString url; - url.FromASCII("http://www.example.com/path/to.html?foo=test&bar=test2"); - EXPECT_TRUE(CefParseURL(url, parts)); +// Create the URL using scheme, host, path and query. +TEST(URLTest, CreateURLSchemeHostPathQuery) { + CefURLParts parts; + CefString url; + CefString(&parts.scheme).FromASCII("http"); + CefString(&parts.host).FromASCII("www.example.com"); + CefString(&parts.path).FromASCII("/path/to.html"); + CefString(&parts.query).FromASCII("foo=test&bar=test2"); + EXPECT_TRUE(CefCreateURL(parts, url)); + EXPECT_STREQ("http://www.example.com/path/to.html?foo=test&bar=test2", + url.ToString().c_str()); +} - CefString spec(&parts.spec); - EXPECT_EQ(spec, "http://www.example.com/path/to.html?foo=test&bar=test2"); - EXPECT_EQ(parts.username.length, (size_t)0); - EXPECT_EQ(parts.password.length, (size_t)0); - CefString scheme(&parts.scheme); - EXPECT_EQ(scheme, "http"); - CefString host(&parts.host); - EXPECT_EQ(host, "www.example.com"); - EXPECT_EQ(parts.port.length, (size_t)0); - CefString path(&parts.path); - EXPECT_EQ(path, "/path/to.html"); - CefString query(&parts.query); - EXPECT_EQ(query, "foo=test&bar=test2"); - } +// Create the URL using all the various components. +TEST(URLTest, CreateURLAll) { + CefURLParts parts; + CefString url; + CefString(&parts.scheme).FromASCII("http"); + CefString(&parts.username).FromASCII("user"); + CefString(&parts.password).FromASCII("pass"); + CefString(&parts.host).FromASCII("www.example.com"); + CefString(&parts.port).FromASCII("88"); + CefString(&parts.path).FromASCII("/path/to.html"); + CefString(&parts.query).FromASCII("foo=test&bar=test2"); + EXPECT_TRUE(CefCreateURL(parts, url)); + EXPECT_STREQ( + "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2", + url.ToString().c_str()); +} - // Parse the URL using all the various components. - { - CefURLParts parts; - CefString url; - url.FromASCII( - "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2"); - EXPECT_TRUE(CefParseURL(url, parts)); +// Parse the URL using scheme and host. +TEST(URLTest, ParseURLSchemeHost) { + CefURLParts parts; + CefString url; + url.FromASCII("http://www.example.com"); + EXPECT_TRUE(CefParseURL(url, parts)); - CefString spec(&parts.spec); - EXPECT_EQ(spec, - "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2"); - CefString scheme(&parts.scheme); - EXPECT_EQ(scheme, "http"); - CefString username(&parts.username); - EXPECT_EQ(username, "user"); - CefString password(&parts.password); - EXPECT_EQ(password, "pass"); - CefString host(&parts.host); - EXPECT_EQ(host, "www.example.com"); - CefString port(&parts.port); - EXPECT_EQ(port, "88"); - CefString path(&parts.path); - EXPECT_EQ(path, "/path/to.html"); - CefString query(&parts.query); - EXPECT_EQ(query, "foo=test&bar=test2"); - } + CefString spec(&parts.spec); + EXPECT_STREQ("http://www.example.com/", spec.ToString().c_str()); + EXPECT_EQ(0U, parts.username.length); + EXPECT_EQ(0U, parts.password.length); + CefString scheme(&parts.scheme); + EXPECT_STREQ("http", scheme.ToString().c_str()); + CefString host(&parts.host); + EXPECT_STREQ("www.example.com", host.ToString().c_str()); + EXPECT_EQ(0U, parts.port.length); + CefString origin(&parts.origin); + EXPECT_STREQ(origin.ToString().c_str(), "http://www.example.com/"); + CefString path(&parts.path); + EXPECT_STREQ("/", path.ToString().c_str()); + EXPECT_EQ(0U, parts.query.length); +} - // Parse an invalid URL. - { - CefURLParts parts; - CefString url; - url.FromASCII("www.example.com"); - EXPECT_FALSE(CefParseURL(url, parts)); - } +// Parse the URL using scheme, host and path. +TEST(URLTest, ParseURLSchemeHostPath) { + CefURLParts parts; + CefString url; + url.FromASCII("http://www.example.com/path/to.html"); + EXPECT_TRUE(CefParseURL(url, parts)); + + CefString spec(&parts.spec); + EXPECT_STREQ("http://www.example.com/path/to.html", + spec.ToString().c_str()); + EXPECT_EQ(0U, parts.username.length); + EXPECT_EQ(0U, parts.password.length); + CefString scheme(&parts.scheme); + EXPECT_STREQ("http", scheme.ToString().c_str()); + CefString host(&parts.host); + EXPECT_STREQ("www.example.com", host.ToString().c_str()); + EXPECT_EQ(0U, parts.port.length); + CefString origin(&parts.origin); + EXPECT_STREQ(origin.ToString().c_str(), "http://www.example.com/"); + CefString path(&parts.path); + EXPECT_STREQ("/path/to.html", path.ToString().c_str()); + EXPECT_EQ(0U, parts.query.length); +} + +// Parse the URL using scheme, host, path and query. +TEST(URLTest, ParseURLSchemeHostPathQuery) { + CefURLParts parts; + CefString url; + url.FromASCII("http://www.example.com/path/to.html?foo=test&bar=test2"); + EXPECT_TRUE(CefParseURL(url, parts)); + + CefString spec(&parts.spec); + EXPECT_STREQ("http://www.example.com/path/to.html?foo=test&bar=test2", + spec.ToString().c_str()); + EXPECT_EQ(0U, parts.username.length); + EXPECT_EQ(0U, parts.password.length); + CefString scheme(&parts.scheme); + EXPECT_STREQ("http", scheme.ToString().c_str()); + CefString host(&parts.host); + EXPECT_STREQ("www.example.com", host.ToString().c_str()); + EXPECT_EQ(0U, parts.port.length); + CefString origin(&parts.origin); + EXPECT_STREQ(origin.ToString().c_str(), "http://www.example.com/"); + CefString path(&parts.path); + EXPECT_STREQ("/path/to.html", path.ToString().c_str()); + CefString query(&parts.query); + EXPECT_STREQ("foo=test&bar=test2", query.ToString().c_str()); +} + +// Parse the URL using all the various components. +TEST(URLTest, ParseURLAll) { + CefURLParts parts; + CefString url; + url.FromASCII( + "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2"); + EXPECT_TRUE(CefParseURL(url, parts)); + + CefString spec(&parts.spec); + EXPECT_STREQ( + "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2", + spec.ToString().c_str()); + CefString scheme(&parts.scheme); + EXPECT_STREQ("http", scheme.ToString().c_str()); + CefString username(&parts.username); + EXPECT_STREQ("user", username.ToString().c_str()); + CefString password(&parts.password); + EXPECT_STREQ("pass", password.ToString().c_str()); + CefString host(&parts.host); + EXPECT_STREQ("www.example.com", host.ToString().c_str()); + CefString port(&parts.port); + EXPECT_STREQ("88", port.ToString().c_str()); + CefString origin(&parts.origin); + EXPECT_STREQ(origin.ToString().c_str(), "http://www.example.com:88/"); + CefString path(&parts.path); + EXPECT_STREQ("/path/to.html", path.ToString().c_str()); + CefString query(&parts.query); + EXPECT_STREQ("foo=test&bar=test2", query.ToString().c_str()); +} + +// Parse an invalid URL. +TEST(URLTest, ParseURLInvalid) { + CefURLParts parts; + CefString url; + url.FromASCII("www.example.com"); + EXPECT_FALSE(CefParseURL(url, parts)); +} + +// Parse a non-standard scheme. +TEST(URLTest, ParseURLNonStandard) { + CefURLParts parts; + CefString url; + url.FromASCII("custom:something%20else?foo"); + EXPECT_TRUE(CefParseURL(url, parts)); + + CefString spec(&parts.spec); + EXPECT_STREQ("custom:something%20else?foo", spec.ToString().c_str()); + EXPECT_EQ(0U, parts.username.length); + EXPECT_EQ(0U, parts.password.length); + CefString scheme(&parts.scheme); + EXPECT_STREQ("custom", scheme.ToString().c_str()); + EXPECT_EQ(0U, parts.host.length); + EXPECT_EQ(0U, parts.port.length); + EXPECT_EQ(0U, parts.origin.length); + CefString path(&parts.path); + EXPECT_STREQ("something%20else", path.ToString().c_str()); + CefString query(&parts.query); + EXPECT_STREQ("foo", query.ToString().c_str()); } TEST(URLTest, GetMimeType) {