diff options
| author | 2025-01-11 01:50:48 -0600 | |
|---|---|---|
| committer | 2025-01-11 01:50:48 -0600 | |
| commit | 9f1a7c45dcee1268f6b222dd2fac4ec083a34d9a (patch) | |
| tree | ee47b18270a1f4df74b2951a86cad5e7d36ce003 /src/launcher/request.rs | |
| parent | untested moment (remove reqwest) (diff) | |
re-add reqwest (mistakes were made)
Diffstat (limited to 'src/launcher/request.rs')
| -rw-r--r-- | src/launcher/request.rs | 139 |
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 |
