| 2158 | } |
| 2159 | |
| 2160 | inline std::string encode_url(const std::string &s) { |
| 2161 | std::string result; |
| 2162 | result.reserve(s.size()); |
| 2163 | |
| 2164 | for (size_t i = 0; s[i]; i++) { |
| 2165 | switch (s[i]) { |
| 2166 | case ' ': result += "%20"; break; |
| 2167 | case '+': result += "%2B"; break; |
| 2168 | case '\r': result += "%0D"; break; |
| 2169 | case '\n': result += "%0A"; break; |
| 2170 | case '\'': result += "%27"; break; |
| 2171 | case ',': result += "%2C"; break; |
| 2172 | // case ':': result += "%3A"; break; // ok? probably... |
| 2173 | case ';': result += "%3B"; break; |
| 2174 | default: |
| 2175 | auto c = static_cast<uint8_t>(s[i]); |
| 2176 | if (c >= 0x80) { |
| 2177 | result += '%'; |
| 2178 | char hex[4]; |
| 2179 | auto len = snprintf(hex, sizeof(hex) - 1, "%02X", c); |
| 2180 | assert(len == 2); |
| 2181 | result.append(hex, static_cast<size_t>(len)); |
| 2182 | } else { |
| 2183 | result += s[i]; |
| 2184 | } |
| 2185 | break; |
| 2186 | } |
| 2187 | } |
| 2188 | |
| 2189 | return result; |
| 2190 | } |
| 2191 | |
| 2192 | inline std::string decode_url(const std::string &s, |
| 2193 | bool convert_plus_to_space) { |
no test coverage detected