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
use std::net::{Ipv4Addr, SocketAddr, UdpSocket};
use std::str;
mod parser;
pub struct ResponseHeaders {
pub server: String,
pub location: String,
}
fn create_socket(add: &str) -> UdpSocket {
match UdpSocket::bind(add) {
Ok(s) => return s,
Err(e) => panic!("couldn't bind socket: {}", e)
};
}
pub struct SimpleServiceDiscoveryClient {
socket: UdpSocket,
}
impl SimpleServiceDiscoveryClient {
fn broadcast_search(&self) {
let payload = "\
M-SEARCH * HTTP/1.1\n\
Host: 239.255.255.250:1900\n\
Man: \"ssdp:discover\"\n\
ST: ssdp:all\n\
MX: 5";
match self.socket.send_to(payload.as_bytes(), SocketAddr::from(([239, 255, 255, 250], 1900))) {
Ok(_) => {
}
Err(error) => {
println!("woops {}", error)
}
}
}
fn join_multicast_v4(&self, multiaddr: &Ipv4Addr) {
self.socket.join_multicast_v4(multiaddr, &Ipv4Addr::new(0, 0, 0, 0)).expect("to join multicast");
}
fn listen(&self, mut f: impl FnMut(&ResponseHeaders)) {
let mut buf = [0; 9000];
loop {
match self.socket.recv_from(&mut buf) {
Ok((_smt, _src)) => {
let body = str::from_utf8(&buf).unwrap_or("").trim();
let lines = body.split("\r\n");
let mut server= String::new();
let mut location= String::new();
for line in lines {
match parser::extract(line, "Server: ") {
Some(result) => {
server = result
}
None => {}
}
match parser::extract(line, "Location: ") {
Some(result) => {
location = result
}
None => {}
}
}
let response_headers = ResponseHeaders {server, location };
f(&response_headers);
},
Err(e) => {
println!("couldn't recieve a datagram: {}", e);
}
}
}
}
}
pub fn create_client() -> SimpleServiceDiscoveryClient {
let client = SimpleServiceDiscoveryClient {
socket: create_socket("0.0.0.0:1900")
};
return client;
}
pub fn listen(f: impl FnMut(&ResponseHeaders)) {
let client = create_client();
client.broadcast_search();
client.join_multicast_v4(&Ipv4Addr::new(239, 255, 255, 250));
client.listen(f);
}