diff options
| author | Jokler <jokler.contact@gmail.com> | 2018-03-12 16:02:51 +0100 |
|---|---|---|
| committer | Jokler <jokler.contact@gmail.com> | 2018-03-12 16:02:51 +0100 |
| commit | 909cabe9280722e43c5fb283f768051bb85e1890 (patch) | |
| tree | 506ac34b7e22cdb95568cef9e649ee64cb3b0fdb /src/utils.rs | |
| parent | 15e855ddecfdac31ddda26b12fcfd1a142a0ec21 (diff) | |
| parent | 8e40e919aca8b8592be43e2c5bbcc0717bf14a6b (diff) | |
| download | frippy-909cabe9280722e43c5fb283f768051bb85e1890.tar.gz frippy-909cabe9280722e43c5fb283f768051bb85e1890.zip | |
Merge branch 'dev'
Diffstat (limited to 'src/utils.rs')
| -rw-r--r-- | src/utils.rs | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..06156be --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,65 @@ +use std::str; +use std::io::{self, Read}; + +use reqwest::Client; +use reqwest::header::Connection; + +use failure::ResultExt; +use self::error::{DownloadError, ErrorKind}; + +/// Downloads the file and converts it to a String. +/// Any invalid bytes are converted to a replacement character. +/// +/// The error indicated either a failed download or that the DownloadLimit was reached +pub fn download(url: &str, max_kib: Option<usize>) -> Result<String, DownloadError> { + let mut response = Client::new() + .get(url) + .header(Connection::close()) + .send() + .context(ErrorKind::Connection)?; + + // 100 kibibyte buffer + let mut buf = [0; 100 * 1024]; + let mut written = 0; + let mut bytes = Vec::new(); + + // Read until we reach EOF or max_kib KiB + loop { + let len = match response.read(&mut buf) { + Ok(0) => break, + Ok(len) => len, + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, + Err(e) => Err(e).context(ErrorKind::Read)?, + }; + + bytes.extend_from_slice(&buf); + written += len; + + // Check if the file is too large to download + if let Some(max_kib) = max_kib { + if written > max_kib * 1024 { + Err(ErrorKind::DownloadLimit)?; + } + } + } + + Ok(String::from_utf8_lossy(&bytes).into_owned()) +} + +pub mod error { + #[derive(Copy, Clone, Eq, PartialEq, Debug, Fail, Error)] + #[error = "DownloadError"] + pub enum ErrorKind { + /// Connection Error + #[fail(display = "A connection error has occured")] + Connection, + + /// Read Error + #[fail(display = "A read error has occured")] + Read, + + /// Reached download limit error + #[fail(display = "Reached download limit")] + DownloadLimit, + } +} |
