Parse a URI and extract the server connection information. * URI scheme is based on the the provisional specification[1] excluding support * for query parameters. Valid URIs are: * scheme: "redis://" * authority: [[ ":"] "@"] [ [":" ]] * path: ["/" [ ]] * * [1]: https://www.iana.org/assignments/uri-schemes/prov/redis */
| 232 | * |
| 233 | * [1]: https://www.iana.org/assignments/uri-schemes/prov/redis */ |
| 234 | static void parseRedisUri(const char *uri) { |
| 235 | |
| 236 | const char *scheme = "redis://"; |
| 237 | const char *tlsscheme = "rediss://"; |
| 238 | const char *curr = uri; |
| 239 | const char *end = uri + strlen(uri); |
| 240 | const char *userinfo, *username, *port, *host, *path; |
| 241 | |
| 242 | /* URI must start with a valid scheme. */ |
| 243 | if (!strncasecmp(tlsscheme, curr, strlen(tlsscheme))) { |
| 244 | #ifdef USE_OPENSSL |
| 245 | config.tls = 1; |
| 246 | curr += strlen(tlsscheme); |
| 247 | #else |
| 248 | fprintf(stderr,"rediss:// is only supported when redis-cli is compiled with OpenSSL\n"); |
| 249 | exit(1); |
| 250 | #endif |
| 251 | } else if (!strncasecmp(scheme, curr, strlen(scheme))) { |
| 252 | curr += strlen(scheme); |
| 253 | } else { |
| 254 | fprintf(stderr,"Invalid URI scheme\n"); |
| 255 | exit(1); |
| 256 | } |
| 257 | if (curr == end) return; |
| 258 | |
| 259 | /* Extract user info. */ |
| 260 | if ((userinfo = strchr(curr,'@'))) { |
| 261 | if ((username = strchr(curr, ':')) && username < userinfo) { |
| 262 | config.user = percentDecode(curr, username - curr); |
| 263 | curr = username + 1; |
| 264 | } |
| 265 | |
| 266 | config.auth = percentDecode(curr, userinfo - curr); |
| 267 | curr = userinfo + 1; |
| 268 | } |
| 269 | if (curr == end) return; |
| 270 | |
| 271 | /* Extract host and port. */ |
| 272 | path = strchr(curr, '/'); |
| 273 | if (*curr != '/') { |
| 274 | host = path ? path - 1 : end; |
| 275 | if ((port = strchr(curr, ':'))) { |
| 276 | config.hostport = atoi(port + 1); |
| 277 | host = port - 1; |
| 278 | } |
| 279 | config.hostip = sdsnewlen(curr, host - curr + 1); |
| 280 | } |
| 281 | curr = path ? path + 1 : end; |
| 282 | if (curr == end) return; |
| 283 | |
| 284 | /* Extract database number. */ |
| 285 | config.input_dbnum = atoi(curr); |
| 286 | } |
| 287 | |
| 288 | /* _serverAssert is needed by dict */ |
| 289 | void _serverAssert(const char *estr, const char *file, int line) { |
no test coverage detected