mirror of
https://github.com/NetworkCats/rustyip.git
synced 2026-11-13 16:17:46 +00:00
feat: add IPV4_DOMAIN config for dual-stack IP detection
This commit is contained in:
+9
-1
@@ -13,9 +13,17 @@ DB_UPDATE_INTERVAL_HOURS=24
|
||||
# Site domain name (used for display/metadata)
|
||||
SITE_DOMAIN=localhost
|
||||
|
||||
# IPv4-only domain for dual-stack detection (e.g., noipv6.org)
|
||||
# Leave empty to disable IPv4 detection for IPv6 users
|
||||
IPV4_DOMAIN=
|
||||
|
||||
# Enable development mode (uses 1.1.1.1 as fallback when CF-Connecting-IP is absent)
|
||||
DEV_MODE=false
|
||||
|
||||
# Path to the TLS certificate directory for HAproxy
|
||||
# Path to the TLS certificate directory for HAProxy (main domain)
|
||||
# The directory must contain origin.pem (combined cert + key)
|
||||
CERT_PATH=./haproxy/certs
|
||||
|
||||
# Path to the TLS certificate directory for the IPv4-only domain
|
||||
# The directory must contain origin.pem (combined cert + key)
|
||||
IPV4_CERT_PATH=./haproxy/certs-ipv4
|
||||
|
||||
@@ -6,6 +6,7 @@ services:
|
||||
volumes:
|
||||
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
|
||||
- ${CERT_PATH:-./haproxy/certs}:/etc/haproxy/certs:ro
|
||||
- ${IPV4_CERT_PATH:-./haproxy/certs-ipv4}:/etc/haproxy/certs-ipv4:ro
|
||||
depends_on:
|
||||
app:
|
||||
condition: service_healthy
|
||||
@@ -21,6 +22,7 @@ services:
|
||||
- DB_UPDATE_URL=${DB_UPDATE_URL:-https://github.com/NetworkCats/Merged-IP-Data/releases/latest/download/Merged-IP.mmdb}
|
||||
- DB_UPDATE_INTERVAL_HOURS=${DB_UPDATE_INTERVAL_HOURS:-24}
|
||||
- SITE_DOMAIN=${SITE_DOMAIN:-localhost}
|
||||
- IPV4_DOMAIN=${IPV4_DOMAIN:-}
|
||||
volumes:
|
||||
- db_data:/data
|
||||
healthcheck:
|
||||
|
||||
@@ -7,6 +7,7 @@ pub struct Config {
|
||||
pub db_update_url: String,
|
||||
pub db_update_interval_hours: u64,
|
||||
pub site_domain: String,
|
||||
pub ipv4_domain: String,
|
||||
pub dev_mode: bool,
|
||||
}
|
||||
|
||||
@@ -31,6 +32,8 @@ impl Config {
|
||||
|
||||
let site_domain = env::var("SITE_DOMAIN").unwrap_or_else(|_| "localhost".to_string());
|
||||
|
||||
let ipv4_domain = env::var("IPV4_DOMAIN").unwrap_or_default();
|
||||
|
||||
let dev_mode = env::var("DEV_MODE")
|
||||
.unwrap_or_default()
|
||||
.eq_ignore_ascii_case("true");
|
||||
@@ -41,6 +44,7 @@ impl Config {
|
||||
db_update_url,
|
||||
db_update_interval_hours,
|
||||
site_domain,
|
||||
ipv4_domain,
|
||||
dev_mode,
|
||||
}
|
||||
}
|
||||
@@ -67,6 +71,7 @@ mod tests {
|
||||
"DB_UPDATE_URL",
|
||||
"DB_UPDATE_INTERVAL_HOURS",
|
||||
"SITE_DOMAIN",
|
||||
"IPV4_DOMAIN",
|
||||
"DEV_MODE",
|
||||
];
|
||||
|
||||
@@ -98,6 +103,7 @@ mod tests {
|
||||
assert!(config.db_update_url.contains("Merged-IP.mmdb"));
|
||||
assert_eq!(config.db_update_interval_hours, 24);
|
||||
assert_eq!(config.site_domain, "localhost");
|
||||
assert!(config.ipv4_domain.is_empty());
|
||||
assert!(!config.dev_mode);
|
||||
}
|
||||
|
||||
@@ -181,6 +187,22 @@ mod tests {
|
||||
unsafe { remove_var("SITE_DOMAIN") };
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_ipv4_domain() {
|
||||
let _guard = lock_env();
|
||||
// SAFETY: ENV_LOCK is held.
|
||||
unsafe {
|
||||
clear_config_vars();
|
||||
set_var("IPV4_DOMAIN", "noipv6.org");
|
||||
}
|
||||
|
||||
let config = Config::from_env();
|
||||
assert_eq!(config.ipv4_domain, "noipv6.org");
|
||||
|
||||
// SAFETY: ENV_LOCK is held.
|
||||
unsafe { remove_var("IPV4_DOMAIN") };
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dev_mode_enabled() {
|
||||
let _guard = lock_env();
|
||||
|
||||
@@ -25,6 +25,7 @@ const DEV_FALLBACK_IP: IpAddr = IpAddr::V4(std::net::Ipv4Addr::new(1, 1, 1, 1));
|
||||
pub struct AppState {
|
||||
pub db: SharedDb,
|
||||
pub site_domain: Arc<str>,
|
||||
pub ipv4_domain: Arc<str>,
|
||||
pub dev_mode: bool,
|
||||
pub openapi_json: Arc<str>,
|
||||
}
|
||||
@@ -36,6 +37,7 @@ struct IndexTemplate {
|
||||
query: String,
|
||||
is_query: bool,
|
||||
site_domain: Arc<str>,
|
||||
ipv4_domain: Arc<str>,
|
||||
css_version: u64,
|
||||
js_version: u64,
|
||||
asn: String,
|
||||
@@ -571,6 +573,7 @@ pub async fn root(
|
||||
query: query.ip.unwrap_or_default(),
|
||||
is_query,
|
||||
site_domain: state.site_domain.clone(),
|
||||
ipv4_domain: state.ipv4_domain.clone(),
|
||||
css_version: static_assets::asset_version("style.css"),
|
||||
js_version: static_assets::asset_version("script.js"),
|
||||
asn: format_asn(&info),
|
||||
|
||||
@@ -39,11 +39,13 @@ async fn main() {
|
||||
let cancel = CancellationToken::new();
|
||||
|
||||
let site_domain: std::sync::Arc<str> = config.site_domain.into();
|
||||
let ipv4_domain: std::sync::Arc<str> = config.ipv4_domain.into();
|
||||
let openapi_json = handlers::build_openapi_json(&site_domain);
|
||||
|
||||
let state = handlers::AppState {
|
||||
db: shared_db.clone(),
|
||||
site_domain,
|
||||
ipv4_domain,
|
||||
dev_mode: config.dev_mode,
|
||||
openapi_json,
|
||||
};
|
||||
|
||||
@@ -26,9 +26,11 @@ fn build_test_app_with_dev_mode(dev_mode: bool) -> axum::Router {
|
||||
let shared_db = db::new_shared(reader);
|
||||
let site_domain: std::sync::Arc<str> = "test.example.com".into();
|
||||
let openapi_json = build_openapi_json(&site_domain);
|
||||
let ipv4_domain: std::sync::Arc<str> = "noipv6.test.example.com".into();
|
||||
let state = AppState {
|
||||
db: shared_db,
|
||||
site_domain,
|
||||
ipv4_domain,
|
||||
dev_mode,
|
||||
openapi_json,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user