mirror of
https://codeberg.org/icewind/nextcloud-config-parser.git
synced 2026-06-03 08:34:13 +02:00
fix tls redis parsing
This commit is contained in:
parent
88b64b402d
commit
83ba84fa2d
7 changed files with 137 additions and 51 deletions
49
src/lib.rs
49
src/lib.rs
|
|
@ -5,6 +5,7 @@ use itertools::Either;
|
|||
use miette::Diagnostic;
|
||||
use std::iter::once;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use thiserror::Error;
|
||||
|
||||
pub use nc::{parse, parse_glob};
|
||||
|
|
@ -32,12 +33,40 @@ impl RedisConfig {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq, Ord, Eq)]
|
||||
pub enum RedisConnectionAddr {
|
||||
Tcp { host: String, port: u16 },
|
||||
Tcp { host: String, port: u16, tls: bool },
|
||||
Unix { path: PathBuf },
|
||||
}
|
||||
|
||||
impl RedisConnectionAddr {
|
||||
fn parse(mut host: &str, port: Option<u16>, tls: bool) -> Self {
|
||||
if host.starts_with("/") {
|
||||
RedisConnectionAddr::Unix { path: host.into() }
|
||||
} else {
|
||||
let tls = if host.starts_with("tls://") || host.starts_with("rediss://") {
|
||||
host = host.split_once("://").unwrap().1;
|
||||
true
|
||||
} else {
|
||||
tls
|
||||
};
|
||||
if host == "localhost" {
|
||||
host = "127.0.0.1";
|
||||
}
|
||||
let (host, port, _) = if let Some(port) = port {
|
||||
(host, Some(port), None)
|
||||
} else {
|
||||
split_host(host)
|
||||
};
|
||||
RedisConnectionAddr::Tcp {
|
||||
host: host.into(),
|
||||
port: port.unwrap_or(6379),
|
||||
tls,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RedisClusterConnectionInfo {
|
||||
pub addr: Vec<RedisConnectionAddr>,
|
||||
|
|
@ -321,3 +350,19 @@ impl Database {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn split_host(host: &str) -> (&str, Option<u16>, Option<&str>) {
|
||||
if host.starts_with('/') {
|
||||
return ("localhost", None, Some(host));
|
||||
}
|
||||
let mut parts = host.split(':');
|
||||
let host = parts.next().unwrap();
|
||||
match parts
|
||||
.next()
|
||||
.map(|port_or_socket| u16::from_str(port_or_socket).map_err(|_| port_or_socket))
|
||||
{
|
||||
Some(Ok(port)) => (host, Some(port), None),
|
||||
Some(Err(socket)) => (host, None, Some(socket)),
|
||||
None => (host, None, None),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
54
src/nc.rs
54
src/nc.rs
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
Config, Database, DbConnect, DbError, Error, NotAConfigError, PhpParseError,
|
||||
split_host, Config, Database, DbConnect, DbError, Error, NotAConfigError, PhpParseError,
|
||||
RedisClusterConnectionInfo, RedisConnectionInfo, RedisTlsParams, Result, SslOptions,
|
||||
};
|
||||
use crate::{RedisConfig, RedisConnectionAddr};
|
||||
|
|
@ -279,22 +279,6 @@ fn parse_db_options(parsed: &Value) -> Result<Database> {
|
|||
}
|
||||
}
|
||||
|
||||
fn split_host(host: &str) -> (&str, Option<u16>, Option<&str>) {
|
||||
if host.starts_with('/') {
|
||||
return ("localhost", None, Some(host));
|
||||
}
|
||||
let mut parts = host.split(':');
|
||||
let host = parts.next().unwrap();
|
||||
match parts
|
||||
.next()
|
||||
.map(|port_or_socket| u16::from_str(port_or_socket).map_err(|_| port_or_socket))
|
||||
{
|
||||
Some(Ok(port)) => (host, Some(port), None),
|
||||
Some(Err(socket)) => (host, None, Some(socket)),
|
||||
None => (host, None, None),
|
||||
}
|
||||
}
|
||||
|
||||
enum RedisAddress {
|
||||
Single(RedisConnectionAddr),
|
||||
Cluster(Vec<RedisConnectionAddr>),
|
||||
|
|
@ -304,36 +288,24 @@ fn parse_redis_options(parsed: &Value) -> RedisConfig {
|
|||
let (redis_options, address) = if parsed["redis.cluster"].is_array() {
|
||||
let redis_options = &parsed["redis.cluster"];
|
||||
let seeds = redis_options["seeds"].values();
|
||||
let addresses = seeds
|
||||
let mut addresses = seeds
|
||||
.filter_map(|seed| seed.as_str())
|
||||
.map(split_host)
|
||||
.filter_map(|(host, port, _)| {
|
||||
Some(RedisConnectionAddr::Tcp {
|
||||
host: host.into(),
|
||||
port: port?,
|
||||
})
|
||||
.map(|seed| {
|
||||
RedisConnectionAddr::parse(seed, None, redis_options["ssl_context"].is_array())
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
addresses.sort();
|
||||
(redis_options, RedisAddress::Cluster(addresses))
|
||||
} else {
|
||||
let redis_options = &parsed["redis"];
|
||||
let mut host = redis_options["host"].as_str().unwrap_or("127.0.0.1");
|
||||
let address = if host.starts_with('/') {
|
||||
RedisAddress::Single(RedisConnectionAddr::Unix { path: host.into() })
|
||||
} else {
|
||||
if host == "localhost" {
|
||||
host = "127.0.0.1";
|
||||
}
|
||||
let (host, port, _) = if let Some(port) = redis_options["port"].as_int() {
|
||||
(host, Some(port as u16), None)
|
||||
} else {
|
||||
split_host(host)
|
||||
};
|
||||
RedisAddress::Single(RedisConnectionAddr::Tcp {
|
||||
host: host.into(),
|
||||
port: port.unwrap_or(6379),
|
||||
})
|
||||
};
|
||||
let host = redis_options["host"].as_str().unwrap_or("127.0.0.1");
|
||||
let address = RedisAddress::Single(RedisConnectionAddr::parse(
|
||||
host,
|
||||
redis_options["port"]
|
||||
.as_int()
|
||||
.and_then(|port| u16::try_from(port).ok()),
|
||||
redis_options["ssl_context"].is_array(),
|
||||
));
|
||||
(redis_options, address)
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue