summaryrefslogtreecommitdiffstats
path: root/src/launcher/request.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/launcher/request.rs')
-rw-r--r--src/launcher/request.rs139
1 files changed, 0 insertions, 139 deletions
diff --git a/src/launcher/request.rs b/src/launcher/request.rs
deleted file mode 100644
index df89a8b..0000000
--- a/src/launcher/request.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-use std::error::Error;
-use std::fmt::Display;
-use std::future::Future;
-use std::pin::Pin;
-use std::task::{Context, Poll};
-use curl::easy::{Easy};
-use tokio::sync::oneshot;
-use tokio::sync::oneshot::Receiver;
-use tokio::task;
-use crate::launcher::constants::USER_AGENT;
-
-// yeah this is basically reqwest but bad (I did not want to rely on both reqwest and curl)
-
-#[derive(Clone, Copy)]
-enum FetchState {
- Primed,
- Running,
- Complete
-}
-
-pub struct EasyFetch {
- easy: Option<Easy>,
- state: FetchState,
- response: Option<Receiver<Result<FetchResult, curl::Error>>>
-}
-
-impl EasyFetch {
- fn new(easy: Easy) -> Self {
- EasyFetch {
- easy: Some(easy),
- state: FetchState::Primed,
- response: None
- }
- }
-
- pub fn get(url: &str) -> Self {
- let mut easy = Easy::new();
- easy.useragent(USER_AGENT).expect("couldn't set user agent");
- easy.get(true).expect("couldn't set request method");
- easy.url(url).expect("couldn't set url");
-
- Self::new(easy)
- }
-}
-
-#[derive(Debug)]
-pub struct FetchResult {
- easy: Easy,
- response_code: u32,
- data: Vec<u8>,
-}
-
-#[derive(Debug)]
-pub struct FetchResponseError(u32);
-
-impl FetchResponseError {
- pub fn get_code(&self) -> u32 {
- self.0
- }
-}
-
-impl Display for FetchResponseError {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "http response: {}", self.0)
- }
-}
-
-impl Error for FetchResponseError {}
-
-impl FetchResult {
- pub fn get_response_code(&self) -> u32 {
- self.response_code
- }
-
- pub fn get_data(&self) -> &[u8] {
- &self.data
- }
-
- pub fn get_data_string(&self) -> String {
- String::from_utf8_lossy(&self.data).to_string()
- }
-
- pub fn error_for_status(self) -> Result<Self, FetchResponseError> {
- if self.response_code / 100 == 2 {
- Ok(self)
- } else {
- Err(FetchResponseError(self.response_code))
- }
- }
-}
-
-impl Future for EasyFetch {
- type Output = Result<FetchResult, curl::Error>;
-
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let self_ref = self.get_mut();
-
- match &self_ref.state {
- FetchState::Primed => {
- self_ref.state = FetchState::Running;
- let mut easy = self_ref.easy.take().unwrap();
- let waker = cx.waker().clone();
-
- let (tx, rx) = oneshot::channel::<Result<FetchResult, curl::Error>>();
- self_ref.response.replace(rx);
-
- task::spawn_blocking(move || {
- let mut out_data: Vec<u8> = Vec::new();
- let mut transfer = easy.transfer();
-
- transfer.write_function(|data| {
- out_data.extend_from_slice(data);
- Ok(data.len())
- }).expect("infallible curl operation failed");
-
- let res = transfer.perform();
- drop(transfer); // have to explicitly drop to release borrow on "easy"
-
- out_data.shrink_to_fit();
-
- tx.send(res.map(|_| FetchResult {
- response_code: easy.response_code().expect("querying response code should not fail"),
- data: out_data,
- easy
- })).expect("curl fetch reader hangup (this shouldn't happen)");
- waker.wake();
- });
-
- Poll::Pending
- },
- FetchState::Running => {
- self_ref.state = FetchState::Complete;
- Poll::Ready(self_ref.response.take().unwrap().try_recv()
- .expect("curl fetch writer hangup or not ready (this shouldn't happen)"))
- },
- FetchState::Complete => panic!("fetch polled after completion")
- }
- }
-} \ No newline at end of file