Repository: valkey-io/valkey
File: src/cli_common.c (C)

Code before:
/* Parse a URI and extract the server connection information.
 * URI scheme is based on the provisional specification[1] excluding support
 * for query parameters. Valid URIs are:
 *   scheme:    "valkey://"
 *   authority: [[<username> ":"] <password> "@"] [<hostname> [":" <port>]]
 *   path:      ["/" [<db>]]
 *
 *  [1]: https://www.iana.org/assignments/uri-schemes/prov/redis */
void parseRedisUri(const char *uri, const char* tool_name, cliConnInfo *connInfo, int *tls_flag) {
#ifdef USE_OPENSSL
    UNUSED(tool_name);
#else
    UNUSED(tls_flag);
#endif

    const char *curr = uri;
    const char *end = uri + strlen(uri);
    const char *userinfo, *username, *port, *host, *path;

    /* URI must start with a valid scheme. */
    if (!strncasecmp(TLS_SCHEME_VALKEY, curr, strlen(TLS_SCHEME_VALKEY)) ||
        !strncasecmp(TLS_SCHEME_PRE_VALKEY, curr, strlen(TLS_SCHEME_PRE_VALKEY))) {
#ifdef USE_OPENSSL
        *tls_flag = 1;
        char *del = strstr(curr, SCHEME_PREFIX_DELIM);
        curr += (del - curr) + strlen(SCHEME_PREFIX_DELIM);
#else
        char *curr_scheme = strtok(curr, SCHEME_PREFIX_DELIM);
        fprintf(stderr,"%s:// is only supported when %s is compiled with OpenSSL\n", curr_scheme, tool_name);
        exit(1);
#endif
    } else if (!strncasecmp(SCHEME_VALKEY, curr, strlen(SCHEME_VALKEY)) ||
               !strncasecmp(SCHEME_PRE_VALKEY, curr, strlen(SCHEME_PRE_VALKEY))) {
        char *del = strstr(curr, SCHEME_PREFIX_DELIM);
        curr += (del - curr) + strlen(SCHEME_PREFIX_DELIM);
    } else {
        fprintf(stderr,"Invalid URI scheme\n");
        exit(1);
    }
    if (curr == end) return;

    /* Extract user info. */
    if ((userinfo = strchr(curr,'@'))) {
        if ((username = strchr(curr, ':')) && username < userinfo) {
            connInfo->user = percentDecode(curr, username - curr);
            curr = username + 1;
        }

        connInfo->auth = percentDecode(curr, userinfo - curr);
        curr = userinfo + 1;
    }

Review comment (refactor):
I don't think we need a macro for `"://"`. It unnecessary abstraction that just makes it harder to follow the code. I think we should just use `"://"`. It's shorter and easier to read.

Code after:
void parseRedisUri(const char *uri, const char* tool_name, cliConnInfo *connInfo, int *tls_flag) {
#ifdef USE_OPENSSL
    UNUSED(tool_name);
#else
    UNUSED(tls_flag);
#endif

    const char *scheme = "valkey://";
    const char *tlsscheme = "valkeys://";
    /* We need to support redis:// and rediss:// too for compatibility. */
    const char *redisScheme = "redis://";
    const char *redisTlsscheme = "rediss://";
    const char *curr = uri;
    const char *end = uri + strlen(uri);
    const char *userinfo, *username, *port, *host, *path;

    /* URI must start with a valid scheme. */
    if (!strncasecmp(tlsscheme, curr, strlen(tlsscheme)) ||
        !strncasecmp(redisTlsscheme, curr, strlen(redisTlsscheme))) {
#ifdef USE_OPENSSL
        *tls_flag = 1;
        char *del = strstr(curr, "://");
        curr += (del - curr) + 3;
#else
        char *copy = strdup(curr);
        char *curr_scheme = strtok(copy, "://");
        fprintf(stderr,"%s:// is only supported when %s is compiled with OpenSSL\n", curr_scheme, tool_name);
        free(copy);
        exit(1);
#endif
    } else if (!strncasecmp(scheme, curr, strlen(scheme)) ||
               !strncasecmp(redisScheme, curr, strlen(redisScheme))) {
        char *del = strstr(curr, "://");
        curr += (del - curr) + 3;
    } else {
        fprintf(stderr,"Invalid URI scheme\n");
        exit(1);
    }
    if (curr == end) return;

    /* Extract user info. */
    if ((userinfo = strchr(curr,'@'))) {
        if ((username = strchr(curr, ':')) && username < userinfo) {
            connInfo->user = percentDecode(curr, username - curr);
            curr = username + 1;
        }

        connInfo->auth = percentDecode(curr, userinfo - curr);
        curr = userinfo + 1;
    }
    if (curr == end) return;