mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 11:32:13 +00:00
Parse fragment from URL
This commit is contained in:
parent
506d6e427a
commit
6516ca6b11
@ -221,18 +221,35 @@ void CharString::copy_from(const char *p_cstr) {
|
||||
/* String */
|
||||
/*************************************************************************/
|
||||
|
||||
Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path) const {
|
||||
// Splits the URL into scheme, host, port, path. Strip credentials when present.
|
||||
Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path, String &r_fragment) const {
|
||||
// Splits the URL into scheme, host, port, path, fragment. Strip credentials when present.
|
||||
String base = *this;
|
||||
r_scheme = "";
|
||||
r_host = "";
|
||||
r_port = 0;
|
||||
r_path = "";
|
||||
r_fragment = "";
|
||||
|
||||
int pos = base.find("://");
|
||||
// Scheme
|
||||
if (pos != -1) {
|
||||
r_scheme = base.substr(0, pos + 3).to_lower();
|
||||
base = base.substr(pos + 3, base.length() - pos - 3);
|
||||
bool is_scheme_valid = true;
|
||||
for (int i = 0; i < pos; i++) {
|
||||
if (!is_ascii_alphanumeric_char(base[i]) && base[i] != '+' && base[i] != '-' && base[i] != '.') {
|
||||
is_scheme_valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_scheme_valid) {
|
||||
r_scheme = base.substr(0, pos + 3).to_lower();
|
||||
base = base.substr(pos + 3, base.length() - pos - 3);
|
||||
}
|
||||
}
|
||||
pos = base.find("#");
|
||||
// Fragment
|
||||
if (pos != -1) {
|
||||
r_fragment = base.substr(pos + 1);
|
||||
base = base.substr(0, pos);
|
||||
}
|
||||
pos = base.find("/");
|
||||
// Path
|
||||
|
@ -452,7 +452,7 @@ public:
|
||||
String c_escape_multiline() const;
|
||||
String c_unescape() const;
|
||||
String json_escape() const;
|
||||
Error parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path) const;
|
||||
Error parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path, String &r_fragment) const;
|
||||
|
||||
String property_name_encode() const;
|
||||
|
||||
|
@ -77,8 +77,8 @@ Error EditorDebuggerServerTCP::start(const String &p_uri) {
|
||||
|
||||
// Optionally override
|
||||
if (!p_uri.is_empty() && p_uri != "tcp://") {
|
||||
String scheme, path;
|
||||
Error err = p_uri.parse_url(scheme, bind_host, bind_port, path);
|
||||
String scheme, path, fragment;
|
||||
Error err = p_uri.parse_url(scheme, bind_host, bind_port, path, fragment);
|
||||
ERR_FAIL_COND_V(err != OK, ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_COND_V(!bind_host.is_valid_ip_address() && bind_host != "*", ERR_INVALID_PARAMETER);
|
||||
}
|
||||
|
@ -993,7 +993,8 @@ void EditorAssetLibrary::_request_image(ObjectID p_for, int p_asset_id, String p
|
||||
String url_host;
|
||||
int url_port;
|
||||
String url_path;
|
||||
Error err = trimmed_url.parse_url(url_scheme, url_host, url_port, url_path);
|
||||
String url_fragment;
|
||||
Error err = trimmed_url.parse_url(url_scheme, url_host, url_port, url_path, url_fragment);
|
||||
if (err != OK) {
|
||||
if (is_print_verbose_enabled()) {
|
||||
ERR_PRINT(vformat("Asset Library: Invalid image URL '%s' for asset # %d.", trimmed_url, p_asset_id));
|
||||
|
@ -77,8 +77,8 @@ Error EditorDebuggerServerWebSocket::start(const String &p_uri) {
|
||||
|
||||
// Optionally override
|
||||
if (!p_uri.is_empty() && p_uri != "ws://") {
|
||||
String scheme, path;
|
||||
Error err = p_uri.parse_url(scheme, bind_host, bind_port, path);
|
||||
String scheme, path, fragment;
|
||||
Error err = p_uri.parse_url(scheme, bind_host, bind_port, path, fragment);
|
||||
ERR_FAIL_COND_V(err != OK, ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_COND_V(!bind_host.is_valid_ip_address() && bind_host != "*", ERR_INVALID_PARAMETER);
|
||||
}
|
||||
|
@ -68,8 +68,9 @@ Error EMWSPeer::connect_to_url(const String &p_url, Ref<TLSOptions> p_tls_option
|
||||
String host;
|
||||
String path;
|
||||
String scheme;
|
||||
String fragment;
|
||||
int port = 0;
|
||||
Error err = p_url.parse_url(scheme, host, port, path);
|
||||
Error err = p_url.parse_url(scheme, host, port, path, fragment);
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Invalid URL: " + p_url);
|
||||
|
||||
if (scheme.is_empty()) {
|
||||
|
@ -482,8 +482,9 @@ Error WSLPeer::connect_to_url(const String &p_url, Ref<TLSOptions> p_options) {
|
||||
String host;
|
||||
String path;
|
||||
String scheme;
|
||||
String fragment;
|
||||
int port = 0;
|
||||
Error err = p_url.parse_url(scheme, host, port, path);
|
||||
Error err = p_url.parse_url(scheme, host, port, path, fragment);
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Invalid URL: " + p_url);
|
||||
if (scheme.is_empty()) {
|
||||
scheme = "ws://";
|
||||
|
@ -49,7 +49,8 @@ Error HTTPRequest::_parse_url(const String &p_url) {
|
||||
redirections = 0;
|
||||
|
||||
String scheme;
|
||||
Error err = p_url.parse_url(scheme, url, port, request_string);
|
||||
String fragment;
|
||||
Error err = p_url.parse_url(scheme, url, port, request_string, fragment);
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Error parsing URL: '%s'.", p_url));
|
||||
|
||||
if (scheme == "https://") {
|
||||
|
@ -1988,6 +1988,46 @@ TEST_CASE("[String] Variant ptr indexed set") {
|
||||
CHECK_EQ(s, String("azcd"));
|
||||
}
|
||||
|
||||
TEST_CASE("[String] parse_url") {
|
||||
String scheme, host, path, fragment;
|
||||
int port;
|
||||
|
||||
SUBCASE("Typical URL") {
|
||||
Error err = String("https://docs.godotengine.org/en/stable/").parse_url(scheme, host, port, path, fragment);
|
||||
REQUIRE(err == OK);
|
||||
CHECK_EQ(scheme, "https://");
|
||||
CHECK_EQ(host, "docs.godotengine.org");
|
||||
CHECK_EQ(port, 0);
|
||||
CHECK_EQ(path, "/en/stable/");
|
||||
CHECK_EQ(fragment, "");
|
||||
}
|
||||
|
||||
SUBCASE("All Elements") {
|
||||
Error err = String("https://www.example.com:8080/path/to/file.html#fragment").parse_url(scheme, host, port, path, fragment);
|
||||
REQUIRE(err == OK);
|
||||
CHECK_EQ(scheme, "https://");
|
||||
CHECK_EQ(host, "www.example.com");
|
||||
CHECK_EQ(port, 8080);
|
||||
CHECK_EQ(path, "/path/to/file.html");
|
||||
CHECK_EQ(fragment, "fragment");
|
||||
}
|
||||
|
||||
SUBCASE("Invalid Scheme") {
|
||||
Error err = String("http_://example.com").parse_url(scheme, host, port, path, fragment);
|
||||
REQUIRE(err == ERR_INVALID_PARAMETER); // Host being empty is an error.
|
||||
}
|
||||
|
||||
SUBCASE("Scheme vs Fragment") {
|
||||
Error err = String("google.com/#goto=http://redirect_url/").parse_url(scheme, host, port, path, fragment);
|
||||
REQUIRE(err == OK);
|
||||
CHECK_EQ(scheme, "");
|
||||
CHECK_EQ(host, "google.com");
|
||||
CHECK_EQ(port, 0);
|
||||
CHECK_EQ(path, "/");
|
||||
CHECK_EQ(fragment, "goto=http://redirect_url/");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("[Stress][String] Empty via ' == String()'") {
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
String str = "Hello World!";
|
||||
|
Loading…
Reference in New Issue
Block a user