1
use crate::error::{Error, Result};
2
use serde::Deserialize;
3
use std::path::Path;
4

            
5
18
pub(crate) fn load_from_json<T: for<'a> Deserialize<'a>, P: AsRef<Path>>(path: P) -> Result<T> {
6
18
    let path = path.as_ref().canonicalize().map_err(|e| Error::Io {
7
        source: e,
8
        path: path.as_ref().to_owned(),
9
18
    })?;
10
18
    let bytes = std::fs::read(&path).map_err(|e| Error::Io {
11
        source: e,
12
        path: path.clone(),
13
18
    })?;
14
18
    serde_json::from_slice(&bytes).map_err(|e| Error::Serde {
15
        source: e,
16
        path: Some(path),
17
18
    })
18
18
}
19

            
20
// check the provided values for a website for sanity
21
13
pub(crate) fn check_websites(value: &str) -> bool {
22
13
    for v in value.split_whitespace() {
23
13
        let url = match url::Url::parse(v) {
24
2
            Ok(url) => url,
25
11
            Err(_) => match url::Url::parse(&format!("https://{}", v)) {
26
11
                Ok(url) => url,
27
                Err(_) => return false,
28
            },
29
        };
30
13
        match url.host() {
31
8
            Some(url::Host::Domain(host)) => {
32
8
                // the hostname should have a dot (.) to be useful
33
8
                if !host.contains('.') {
34
1
                    return false;
35
7
                }
36
            }
37
5
            Some(url::Host::Ipv4(ip)) => {
38
5
                if ip.is_private()
39
4
                    || ip.is_link_local()
40
3
                    || ip.is_loopback()
41
2
                    || ip.is_multicast()
42
1
                    || ip.is_documentation()
43
1
                    || ip.is_unspecified()
44
                {
45
5
                    return false;
46
                }
47
            }
48
            Some(url::Host::Ipv6(ip)) => {
49
                if ip.is_loopback() || ip.is_multicast() || ip.is_unspecified() {
50
                    return false;
51
                }
52
            }
53
            None => {
54
                return false;
55
            }
56
        }
57
    }
58
7
    true
59
13
}
60

            
61
#[test]
62
1
fn test_check_websites() {
63
1
    assert!(check_websites(""));
64
1
    assert!(check_websites("https://nlnet.nl"));
65
1
    assert!(check_websites("https://nlnet.nl\tros.nl"));
66
1
    assert!(check_websites("nlnet.nl"));
67
1
    assert!(!check_websites("YbxuoyIq"));
68
1
    assert!(!check_websites("127.0.0.1"));
69
1
    assert!(!check_websites("0.0.0.0"));
70
1
    assert!(!check_websites("10.0.0.1"));
71
1
    assert!(!check_websites("169.254.10.65"));
72
1
    assert!(!check_websites("224.254.10.65"));
73
1
}