liftinstall/src/http.rs

101 lines
2.5 KiB
Rust
Raw Normal View History

2018-08-03 11:52:31 +00:00
//! http.rs
//!
//! A simple wrapper around Hyper's HTTP client.
use reqwest::header::CONTENT_LENGTH;
2018-01-30 04:53:28 +00:00
use std::io::Read;
2018-08-07 12:26:53 +00:00
use std::time::Duration;
Update config files for v7 (#12) * platform: fix build on Linux and update web-view * deps: replace xz-decom with xz2 and update deps * platform: fix regression... ... that prevents the build on Windows * linux: implement platform-dependent functions * travis: add macos and windows CI * travis: use official Rust Docker image * Update Cargo.lock for new version * Break apart REST into separate services This cleans up locking, ensures consistent futures for all endpoints and enhances code re-use. * Clean up codebase, fixing minor errors * Update packages, use async client for downloading config While this has a hell of a lot more boilerplate, this is quite a bit cleaner. * Add explicit 'dyn's as per Rust nightly requirements * Migrate self updating functions to own module * Migrate assets to server module * Use patched web-view to fix dialogs, remove nfd * Implement basic dark mode * Revert window.close usage * ui: split files and use Webpack * frontend: ui: include prebuilt assets... ... and update rust side stuff * build: integrate webpack building into build.rs * Polish Vue UI split * Add instructions for node + yarn * native: fix uninstall self-destruction behavior...... by not showing the command prompt window and fork-spawning the cmd * native: deal with Unicode issues in native APIs * native: further improve Unicode support on Windows * travis: add cache and fix issues * ui: use Buefy components to... ... beautify the UI * ui: makes error message selectable * Make launcher mode behaviour more robust * Fix error display on launcher pages * Correctly handle exit on error * Bump installer version
2019-07-05 01:23:16 +00:00
use reqwest::async::Client as AsyncClient;
2018-08-07 12:26:53 +00:00
use reqwest::Client;
use reqwest::StatusCode;
2018-08-07 12:26:53 +00:00
2018-10-01 01:27:31 +00:00
/// Asserts that a URL is valid HTTPS, else returns an error.
pub fn assert_ssl(url: &str) -> Result<(), String> {
if url.starts_with("https://") {
Ok(())
} else {
Update config files for v7 (#12) * platform: fix build on Linux and update web-view * deps: replace xz-decom with xz2 and update deps * platform: fix regression... ... that prevents the build on Windows * linux: implement platform-dependent functions * travis: add macos and windows CI * travis: use official Rust Docker image * Update Cargo.lock for new version * Break apart REST into separate services This cleans up locking, ensures consistent futures for all endpoints and enhances code re-use. * Clean up codebase, fixing minor errors * Update packages, use async client for downloading config While this has a hell of a lot more boilerplate, this is quite a bit cleaner. * Add explicit 'dyn's as per Rust nightly requirements * Migrate self updating functions to own module * Migrate assets to server module * Use patched web-view to fix dialogs, remove nfd * Implement basic dark mode * Revert window.close usage * ui: split files and use Webpack * frontend: ui: include prebuilt assets... ... and update rust side stuff * build: integrate webpack building into build.rs * Polish Vue UI split * Add instructions for node + yarn * native: fix uninstall self-destruction behavior...... by not showing the command prompt window and fork-spawning the cmd * native: deal with Unicode issues in native APIs * native: further improve Unicode support on Windows * travis: add cache and fix issues * ui: use Buefy components to... ... beautify the UI * ui: makes error message selectable * Make launcher mode behaviour more robust * Fix error display on launcher pages * Correctly handle exit on error * Bump installer version
2019-07-05 01:23:16 +00:00
Err("Specified URL was not https".to_string())
2018-10-01 01:27:31 +00:00
}
}
2018-08-07 12:26:53 +00:00
/// Builds a customised HTTP client.
pub fn build_client() -> Result<Client, String> {
Client::builder()
2018-08-09 05:21:50 +00:00
.timeout(Duration::from_secs(8))
2018-08-07 12:26:53 +00:00
.build()
2018-10-01 01:27:31 +00:00
.map_err(|x| format!("Unable to build client: {:?}", x))
2018-08-07 12:26:53 +00:00
}
2018-01-30 04:53:28 +00:00
Update config files for v7 (#12) * platform: fix build on Linux and update web-view * deps: replace xz-decom with xz2 and update deps * platform: fix regression... ... that prevents the build on Windows * linux: implement platform-dependent functions * travis: add macos and windows CI * travis: use official Rust Docker image * Update Cargo.lock for new version * Break apart REST into separate services This cleans up locking, ensures consistent futures for all endpoints and enhances code re-use. * Clean up codebase, fixing minor errors * Update packages, use async client for downloading config While this has a hell of a lot more boilerplate, this is quite a bit cleaner. * Add explicit 'dyn's as per Rust nightly requirements * Migrate self updating functions to own module * Migrate assets to server module * Use patched web-view to fix dialogs, remove nfd * Implement basic dark mode * Revert window.close usage * ui: split files and use Webpack * frontend: ui: include prebuilt assets... ... and update rust side stuff * build: integrate webpack building into build.rs * Polish Vue UI split * Add instructions for node + yarn * native: fix uninstall self-destruction behavior...... by not showing the command prompt window and fork-spawning the cmd * native: deal with Unicode issues in native APIs * native: further improve Unicode support on Windows * travis: add cache and fix issues * ui: use Buefy components to... ... beautify the UI * ui: makes error message selectable * Make launcher mode behaviour more robust * Fix error display on launcher pages * Correctly handle exit on error * Bump installer version
2019-07-05 01:23:16 +00:00
/// Builds a customised async HTTP client.
pub fn build_async_client() -> Result<AsyncClient, String> {
AsyncClient::builder()
.timeout(Duration::from_secs(8))
.build()
.map_err(|x| format!("Unable to build client: {:?}", x))
2018-08-07 05:34:57 +00:00
}
2018-01-30 04:53:28 +00:00
/// Streams a file from a HTTP server.
pub fn stream_file<F>(
url: &str,
authorization: Option<String>,
mut callback: F,
) -> Result<(), String>
2018-01-30 04:54:44 +00:00
where
F: FnMut(Vec<u8>, u64) -> (),
2018-01-30 04:54:44 +00:00
{
2018-10-01 01:27:31 +00:00
assert_ssl(url)?;
let mut client = build_client()?.get(url);
if let Some(auth) = authorization {
client = client.header("Authorization", format!("Bearer {}", auth));
}
let mut client = client
.send()
.map_err(|x| format!("Failed to GET resource: {:?}", x))?;
match client.status() {
StatusCode::OK => {}
StatusCode::TOO_MANY_REQUESTS => {
return Err(
"Your token has exceeded the number of daily allowable IP addresses. \
Please wait 24 hours and try again."
.to_string(),
);
}
x => {
return Err(format!("Bad status code: {:?}.", x));
}
}
2018-01-30 04:53:28 +00:00
let size = match client.headers().get(CONTENT_LENGTH) {
Some(ref v) => v
.to_str()
.map_err(|x| format!("Content length header was invalid: {:?}", x))?
.parse()
.map_err(|x| format!("Failed to parse content length: {:?}", x))?,
None => 0,
2018-01-30 04:53:28 +00:00
};
let mut buf = [0 as u8; 8192];
loop {
let len = client
.read(&mut buf)
.map_err(|x| format!("Failed to read resource: {:?}", x))?;
2018-01-30 04:53:28 +00:00
if len == 0 {
break;
}
2018-01-30 04:54:44 +00:00
let buf_copy = &buf[0..len];
2018-01-30 04:53:28 +00:00
let buf_copy = buf_copy.to_vec();
callback(buf_copy, size);
}
Ok(())
}