package io.vertx.redis.client.impl;
import io.vertx.core.net.SocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public final class RedisURI {
private static final String DEFAULT_HOST = "localhost";
private static final int DEFAULT_PORT = 6379;
private final String connectionString;
private final SocketAddress socketAddress;
private final String user;
private final String password;
private final Integer select;
private final boolean ssl;
private final boolean unix;
private final Map<String, String> params;
public RedisURI(String connectionString) {
this.connectionString = connectionString;
try {
final URI uri = new URI(connectionString);
final String host = uri.getHost() == null ? DEFAULT_HOST : uri.getHost();
final int port = uri.getPort() == -1 ? DEFAULT_PORT : uri.getPort();
final String path = (uri.getPath() == null || uri.getPath().isEmpty()) ? "/" : uri.getPath();
params = parseQuery(uri);
switch (uri.getScheme()) {
case "rediss":
ssl = true;
unix = false;
socketAddress = SocketAddress.inetSocketAddress(port, host);
if (path.length() > 1) {
select = Integer.parseInt(uri.getPath().substring(1));
} else if (params.containsKey("db")) {
select = Integer.parseInt(params.get("db"));
} else {
select = null;
}
break;
case "redis":
ssl = false;
unix = false;
socketAddress = SocketAddress.inetSocketAddress(port, host);
if (path.length() > 1) {
select = Integer.parseInt(uri.getPath().substring(1));
} else if (params.containsKey("db")) {
select = Integer.parseInt(params.get("db"));
} else {
select = null;
}
break;
case "unix":
ssl = false;
unix = true;
socketAddress = SocketAddress.domainSocketAddress(path);
if (params.containsKey("db")) {
select = Integer.parseInt(params.get("db"));
} else {
select = null;
}
break;
default:
throw new IllegalArgumentException("Unsupported Redis connection string scheme [" + uri.getScheme() + "]");
}
String userInfo = uri.getUserInfo();
if (userInfo != null) {
int sep = userInfo.lastIndexOf(':');
if (sep != -1) {
if (sep > 0) {
user = userInfo.substring(0, sep);
} else {
user = params.getOrDefault("user", null);
}
password = userInfo.substring(sep + 1);
} else {
user = params.getOrDefault("user", null);
password = params.getOrDefault("password", null);
}
} else {
user = params.getOrDefault("user", null);
password = params.getOrDefault("password", null);
}
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Failed to parse the connection string", e);
}
}
private static Map<String, String> parseQuery(URI uri) {
if (uri.getQuery() != null) {
final Map<String, String> query = new HashMap<>();
for (String kv : uri.getQuery().split("&")) {
int eq = kv.indexOf('=');
if (eq != -1) {
query.put(kv.substring(0, eq), kv.substring(eq + 1));
}
}
return query;
}
return Collections.emptyMap();
}
public SocketAddress socketAddress() {
return socketAddress;
}
public String user() {
return user;
}
public String password() {
return password;
}
public Integer select() {
return select;
}
public boolean ssl() {
return ssl;
}
public boolean unix() {
return unix;
}
public String param(String key) {
return params.get(key);
}
public String userinfo() {
if (user == null && password == null) {
return "";
}
return
(user == null ? "" : user) +
":" +
(password == null ? "" : password) +
"@";
}
public String protocol() {
if (unix) {
return "unix";
} else {
if (ssl) {
return "rediss";
} else {
return "redis";
}
}
}
@Override
public String toString() {
return connectionString;
}
}