libsubconverter/parser/explodes/
httpsub.rs

1use crate::utils::url::url_decode;
2use crate::{models::HTTP_DEFAULT_GROUP, Proxy};
3use url::Url;
4
5/// Parse an HTTP subscription link into a Proxy object
6/// Matches C++ explodeHTTPSub implementation
7pub fn explode_http_sub(link: &str, node: &mut Proxy) -> bool {
8    // Parse the URL
9    let url = match Url::parse(link) {
10        Ok(u) => u,
11        Err(_) => return false,
12    };
13
14    // Determine if TLS is enabled
15    let is_https = url.scheme() == "https";
16
17    // Initialize variables
18    let mut group = String::new();
19    let mut remarks = String::new();
20    let mut _server = String::new();
21    let mut _port = String::new();
22    let mut _username = String::new();
23    let mut password = String::new();
24
25    // Extract query parameters
26    for (key, value) in url.query_pairs() {
27        match key.as_ref() {
28            "remarks" => remarks = url_decode(&value),
29            "group" => group = url_decode(&value),
30            _ => {}
31        }
32    }
33
34    // Extract username and password
35    _username = url.username().to_string();
36    if let Some(pass) = url.password() {
37        password = pass.to_string();
38    }
39
40    // Extract hostname and port
41    if let Some(host) = url.host_str() {
42        _server = host.to_string();
43    } else {
44        return false;
45    }
46
47    if let Some(p) = url.port() {
48        _port = p.to_string();
49    } else {
50        _port = if is_https {
51            "443".to_string()
52        } else {
53            "80".to_string()
54        };
55    }
56
57    // Use default group if none specified
58    if group.is_empty() {
59        group = HTTP_DEFAULT_GROUP.to_string();
60    }
61
62    // Use server:port as remark if none specified
63    if remarks.is_empty() {
64        remarks = format!("{}:{}", _server, _port);
65    }
66
67    // Skip invalid port
68    if _port == "0" {
69        return false;
70    }
71
72    // Parse port to u16
73    let port_num = match _port.parse::<u16>() {
74        Ok(p) => p,
75        Err(_) => return false,
76    };
77
78    // Create the proxy object
79    *node = Proxy::http_construct(
80        &group, &remarks, &_server, port_num, &_username, &password, is_https, None, None, None, "",
81    );
82
83    true
84}