1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use std::net::{SocketAddr, TcpStream};
use std::time::Duration;
use simple_error::SimpleError;
const DEFAULT_TIMEOUT: u64 = 3;
fn connect(addr: &SocketAddr, timeout: Option<Duration>) -> Result<bool, SimpleError> {
let duration = match timeout {
Some(tout) => tout,
_ => Duration::new(DEFAULT_TIMEOUT, 0),
};
match TcpStream::connect_timeout(addr, duration) {
Ok(_) => Ok(true),
Err(e) => Err(SimpleError::from(e)),
}
}
pub fn online(timeout: Option<Duration>) -> Result<bool, SimpleError> {
let addr = SocketAddr::from(([216, 58, 201, 174], 80));
match connect(&addr, timeout) {
Ok(_) => Ok(true),
Err(e) => match e.as_str() {
"Network is unreachable (os error 101)" => Ok(false),
"connection timed out" => {
let addr_fallback = SocketAddr::from(([2, 22, 126, 57], 80));
match connect(&addr_fallback, timeout) {
Ok(_) => Ok(true),
Err(err) => match err.as_str() {
"connection timed out" => Ok(false),
_ => Err(err),
},
}
}
_ => Err(e),
},
}
}
#[cfg(test)]
mod connect {
use std::time::Duration;
use super::connect;
use std::net::SocketAddr;
#[test]
fn should_work_no_parameters() {
let addr = SocketAddr::from(([8, 8, 8, 8], 53));
assert_eq!(connect(&addr, None), Ok(true));
}
#[test]
fn should_work_timeout() {
let addr = SocketAddr::from(([8, 8, 8, 8], 53));
let timeout = Duration::new(6, 0);
assert_eq!(connect(&addr, Some(timeout)), Ok(true));
}
#[test]
#[should_panic(expected = "connection timed out")]
fn should_fail_unreachable() {
let addr = SocketAddr::from(([8, 8, 8, 8], 8888));
connect(&addr, None).unwrap();
}
#[test]
#[should_panic(expected = "connection timed out")]
fn should_fail_unreachable_timeout() {
let addr = SocketAddr::from(([8, 8, 8, 8], 8888));
let timeout = Duration::new(6, 0);
connect(&addr, Some(timeout)).unwrap();
}
}