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
use std::net::{TcpListener, TcpStream};
use std::io::{copy, Result, Error, ErrorKind};
use std::fs::{self, File};
use std::path::Path;
use std::thread;
use Network;
pub struct Handle {
url: String,
listener: TcpListener,
}
impl Handle {
pub fn url(&self) -> String {
self.url.clone()
}
}
impl Drop for Handle {
fn drop(&mut self) {
drop(self.listener.set_nonblocking(true))
}
}
#[cfg(unix)]
fn fix_permissions<P: AsRef<Path>>(path: P) -> Result<()> {
use std::os::unix::fs::PermissionsExt;
let mut perm = fs::metadata(&path)?.permissions();
perm.set_mode(0o700);
fs::set_permissions(&path, perm)
}
#[cfg(windows)]
fn fix_permissions<P: AsRef<Path>>(_: P) -> Result<()> { Ok(()) }
impl Network {
pub fn upload<P: AsRef<Path>>(&self, path: P) -> Result<Handle> {
let path = path.as_ref().to_owned();
if !path.is_file() {
return Err(Error::new(ErrorKind::NotFound, "file not found"));
}
let listener = TcpListener::bind("0.0.0.0:0")?;
let port = listener.local_addr()?.port();
let interrupt = listener.try_clone()?;
thread::spawn(move || {
while let Ok((mut stream, _)) = listener.accept() {
let mut file = File::open(&path).unwrap();
thread::spawn(move || {
if let Err(err) = copy(&mut file, &mut stream) {
error!("while uploading file: {}", err);
}
});
}
});
Ok(Handle {
url: format!("tcp://{}:{}", self.hostname, port),
listener: interrupt,
})
}
pub fn download<P: AsRef<Path>>(&self, url: &str, path: P) -> Result<()> {
if !url.starts_with("tcp://") {
return Err(Error::new(ErrorKind::InvalidInput,
"url doesn't start with tcp://'"));
}
let addr = &url[6..];
let mut stream = TcpStream::connect(addr)?;
let mut file = File::create(&path)?;
fix_permissions(&path)?;
debug!("downloading file from tcp://{} to {:?}", addr, path.as_ref());
copy(&mut stream, &mut file)?;
Ok(())
}
}