Refactor application structure and simplify implementation
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
use base64::{engine::general_purpose, Engine};
|
||||
use proxywarden_lib::models::redact_subscription_url;
|
||||
use proxywarden_lib::subscription::{
|
||||
self, parse_subscription_body, parse_user_info, SubscriptionFetchIdentity,
|
||||
SubscriptionFetchPolicy,
|
||||
self, parse_subscription_body, parse_user_info, validate_resolved_subscription_addresses,
|
||||
SubscriptionFetchIdentity, SubscriptionFetchPolicy,
|
||||
};
|
||||
use std::io::{Read, Write};
|
||||
use std::net::TcpListener;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener};
|
||||
use std::time::Duration;
|
||||
|
||||
#[test]
|
||||
@@ -27,6 +27,29 @@ fn parses_singbox_json_config_servers() {
|
||||
assert_eq!(parsed.servers[1].server_port, 8443);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn server_ids_are_opaque_and_distinguish_credentials_on_same_endpoint() {
|
||||
let parsed = parse_subscription_body(
|
||||
r#"{
|
||||
"outbounds": [
|
||||
{ "type": "vless", "tag": "same", "server": "edge.example.test", "server_port": 443, "uuid": "11111111-1111-1111-1111-111111111111" },
|
||||
{ "type": "vless", "tag": "same", "server": "edge.example.test", "server_port": 443, "uuid": "22222222-2222-2222-2222-222222222222" }
|
||||
]
|
||||
}"#,
|
||||
)
|
||||
.expect("duplicate endpoint subscription should parse");
|
||||
|
||||
assert_ne!(parsed.servers[0].id, parsed.servers[1].id);
|
||||
assert!(parsed
|
||||
.servers
|
||||
.iter()
|
||||
.all(|server| server.id.starts_with("pw-")));
|
||||
assert!(parsed
|
||||
.servers
|
||||
.iter()
|
||||
.all(|server| !server.id.contains("11111111")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_base64_vless_link_list() {
|
||||
let link = sample_vless_link("nl-1");
|
||||
@@ -42,6 +65,45 @@ fn parses_base64_vless_link_list() {
|
||||
assert_eq!(outbound["packet_encoding"], "xudp");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_trojan_shadowsocks_and_vmess_link_formats() {
|
||||
let vmess_payload = serde_json::json!({
|
||||
"v": "2",
|
||||
"ps": "VMess NL",
|
||||
"add": "vmess.example.test",
|
||||
"port": "443",
|
||||
"id": "33333333-3333-3333-3333-333333333333",
|
||||
"scy": "auto",
|
||||
"net": "ws",
|
||||
"host": "cdn.example.test",
|
||||
"path": "/ws",
|
||||
"tls": "tls",
|
||||
"sni": "vmess.example.test"
|
||||
});
|
||||
let vmess_link = format!(
|
||||
"vmess://{}",
|
||||
general_purpose::STANDARD_NO_PAD.encode(vmess_payload.to_string())
|
||||
);
|
||||
let body = format!(
|
||||
"trojan://secret@trojan.example.test:443?sni=edge.example.test#Trojan%20DE\nss://aes-256-gcm:password@ss.example.test:8388#SS%20US\n{vmess_link}"
|
||||
);
|
||||
|
||||
let parsed = parse_subscription_body(&body).expect("supported link formats should parse");
|
||||
|
||||
assert_eq!(parsed.servers.len(), 3);
|
||||
assert_eq!(parsed.servers[0].server_type, "trojan");
|
||||
assert_eq!(parsed.servers[0].tag, "Trojan DE");
|
||||
assert_eq!(
|
||||
parsed.config["outbounds"][0]["tls"]["server_name"],
|
||||
"edge.example.test"
|
||||
);
|
||||
assert_eq!(parsed.servers[1].server_type, "shadowsocks");
|
||||
assert_eq!(parsed.config["outbounds"][1]["method"], "aes-256-gcm");
|
||||
assert_eq!(parsed.servers[2].server_type, "vmess");
|
||||
assert_eq!(parsed.config["outbounds"][2]["transport"]["type"], "ws");
|
||||
assert_eq!(parsed.config["outbounds"][2]["tls"]["enabled"], true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decodes_percent_encoded_vless_fragment_tag() {
|
||||
let link = sample_vless_link(
|
||||
@@ -111,6 +173,25 @@ fn rejects_unsafe_local_subscription_urls_before_network() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_dns_results_containing_private_or_metadata_addresses() {
|
||||
for ip in [
|
||||
IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
||||
IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)),
|
||||
IpAddr::V4(Ipv4Addr::new(169, 254, 169, 254)),
|
||||
] {
|
||||
let error = validate_resolved_subscription_addresses(&[SocketAddr::new(ip, 443)])
|
||||
.expect_err("unsafe resolved address should be blocked");
|
||||
assert!(error.message.contains("resolves to"));
|
||||
}
|
||||
|
||||
validate_resolved_subscription_addresses(&[SocketAddr::new(
|
||||
IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)),
|
||||
443,
|
||||
)])
|
||||
.expect("public resolved address should be accepted");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fetch_subscription_sends_device_hwid_header_when_identity_is_set() {
|
||||
let listener = TcpListener::bind("127.0.0.1:0").expect("bind local test listener");
|
||||
|
||||
Reference in New Issue
Block a user