| 68 | } |
| 69 | |
| 70 | Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path, String &r_fragment) const { |
| 71 | String base = *this; |
| 72 | r_scheme = ""; |
| 73 | r_host = ""; |
| 74 | r_port = 0; |
| 75 | r_path = ""; |
| 76 | r_fragment = ""; |
| 77 | |
| 78 | int pos = base.find("://"); |
| 79 | // Scheme |
| 80 | if (pos != -1) { |
| 81 | bool is_scheme_valid = true; |
| 82 | for (int i = 0; i < pos; i++) { |
| 83 | if (!is_ascii_alphanumeric_char(base[i]) && base[i] != '+' && base[i] != '-' && base[i] != '.') { |
| 84 | is_scheme_valid = false; |
| 85 | break; |
| 86 | } |
| 87 | } |
| 88 | if (is_scheme_valid) { |
| 89 | r_scheme = base.substr(0, pos + 3).to_lower(); |
| 90 | base = base.substr(pos + 3); |
| 91 | } |
| 92 | } |
| 93 | pos = base.find_char('#'); |
| 94 | // Fragment |
| 95 | if (pos != -1) { |
| 96 | r_fragment = base.substr(pos + 1); |
| 97 | base = base.substr(0, pos); |
| 98 | } |
| 99 | pos = base.find_char('/'); |
| 100 | // Path |
| 101 | if (pos != -1) { |
| 102 | r_path = base.substr(pos); |
| 103 | base = base.substr(0, pos); |
| 104 | } |
| 105 | // Host |
| 106 | pos = base.find_char('@'); |
| 107 | if (pos != -1) { |
| 108 | // Strip credentials |
| 109 | base = base.substr(pos + 1); |
| 110 | } |
| 111 | if (base.begins_with("[")) { |
| 112 | // Literal IPv6 |
| 113 | pos = base.rfind_char(']'); |
| 114 | if (pos == -1) { |
| 115 | return ERR_INVALID_PARAMETER; |
| 116 | } |
| 117 | r_host = base.substr(1, pos - 1); |
| 118 | base = base.substr(pos + 1); |
| 119 | } else { |
| 120 | // Anything else |
| 121 | if (base.get_slice_count(":") > 2) { |
| 122 | return ERR_INVALID_PARAMETER; |
| 123 | } |
| 124 | pos = base.rfind_char(':'); |
| 125 | if (pos == -1) { |
| 126 | r_host = base; |
| 127 | base = ""; |
no test coverage detected