From 48e34b8c98c480beb4ceb6cff4c9e72352af892a Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Sat, 26 Apr 2025 22:36:47 +0200 Subject: [PATCH] Move request sending to client sub module --- crates/lune-std-net/src/client/mod.rs | 80 ++++++++++++++++++++++ crates/lune-std-net/src/lib.rs | 5 +- crates/lune-std-net/src/shared/request.rs | 81 ++--------------------- 3 files changed, 89 insertions(+), 77 deletions(-) diff --git a/crates/lune-std-net/src/client/mod.rs b/crates/lune-std-net/src/client/mod.rs index dec0006..683e3e6 100644 --- a/crates/lune-std-net/src/client/mod.rs +++ b/crates/lune-std-net/src/client/mod.rs @@ -1,2 +1,82 @@ +use hyper::{ + body::{Bytes, Incoming}, + client::conn::http1::handshake, + header::LOCATION, + Method, Request as HyperRequest, Response as HyperResponse, Uri, +}; + +use mlua::prelude::*; + +use crate::{ + client::stream::HttpRequestStream, + shared::{ + hyper::{HyperExecutor, HyperIo}, + request::Request, + response::Response, + }, +}; + pub mod config; pub mod stream; + +const MAX_REDIRECTS: usize = 10; + +/** + Sends the request and returns the final response. + + This will follow any redirects returned by the server, + modifying the request method and body as necessary. +*/ +pub async fn send_request(mut request: Request, lua: Lua) -> LuaResult { + loop { + let stream = HttpRequestStream::connect(request.inner.uri()).await?; + + let (mut sender, conn) = handshake(HyperIo::from(stream)).await.into_lua_err()?; + + HyperExecutor::execute(lua.clone(), conn); + + let incoming = sender + .send_request(request.as_full()) + .await + .into_lua_err()?; + + if let Some((new_method, new_uri)) = check_redirect(&request.inner, &incoming) { + if request.redirects >= MAX_REDIRECTS { + return Err(LuaError::external("Too many redirects")); + } + + if new_method == Method::GET { + *request.inner.body_mut() = Bytes::new(); + } + + *request.inner.method_mut() = new_method; + *request.inner.uri_mut() = new_uri; + + request.redirects += 1; + + continue; + } + + break Response::from_incoming(incoming, request.decompress).await; + } +} + +fn check_redirect( + request: &HyperRequest, + response: &HyperResponse, +) -> Option<(Method, Uri)> { + if !response.status().is_redirection() { + return None; + } + + let location = response.headers().get(LOCATION)?; + let location = location.to_str().ok()?; + let location = location.parse().ok()?; + + let method = match response.status().as_u16() { + 301..=303 => Method::GET, + _ => request.method().clone(), + }; + + Some((method, location)) +} diff --git a/crates/lune-std-net/src/lib.rs b/crates/lune-std-net/src/lib.rs index dbdaefd..e3e12b5 100644 --- a/crates/lune-std-net/src/lib.rs +++ b/crates/lune-std-net/src/lib.rs @@ -39,7 +39,6 @@ pub fn module(lua: Lua) -> LuaResult { } async fn net_request(lua: Lua, config: RequestConfig) -> LuaResult { - Request::from_config(config, lua.clone())? - .send(lua.clone()) - .await + let request = Request::from_config(config, lua.clone())?; + self::client::send_request(request, lua.clone()).await } diff --git a/crates/lune-std-net/src/shared/request.rs b/crates/lune-std-net/src/shared/request.rs index 213449a..033831c 100644 --- a/crates/lune-std-net/src/shared/request.rs +++ b/crates/lune-std-net/src/shared/request.rs @@ -2,32 +2,22 @@ use http_body_util::Full; use url::Url; use hyper::{ - body::{Bytes, Incoming}, - client::conn::http1::handshake, - header::{HeaderName, HeaderValue, LOCATION, USER_AGENT}, - HeaderMap, Method, Request as HyperRequest, Response as HyperResponse, Uri, + body::Bytes, + header::{HeaderName, HeaderValue, USER_AGENT}, + HeaderMap, Request as HyperRequest, }; use mlua::prelude::*; -use crate::{ - client::{config::RequestConfig, stream::HttpRequestStream}, - shared::{ - headers::create_user_agent_header, - hyper::{HyperExecutor, HyperIo}, - response::Response, - }, -}; - -const MAX_REDIRECTS: usize = 10; +use crate::{client::config::RequestConfig, shared::headers::create_user_agent_header}; #[derive(Debug, Clone)] pub struct Request { // NOTE: We use Bytes instead of Full to avoid // needing async when getting a reference to the body - inner: HyperRequest, - redirects: usize, - decompress: bool, + pub(crate) inner: HyperRequest, + pub(crate) redirects: usize, + pub(crate) decompress: bool, } impl Request { @@ -100,43 +90,6 @@ impl Request { let body = Full::new(self.inner.body().clone()); builder.body(body).expect("request was valid") } - - /** - Sends the request and returns the final response. - - This will follow any redirects returned by the server, - modifying the request method and body as necessary. - */ - pub async fn send(mut self, lua: Lua) -> LuaResult { - loop { - let stream = HttpRequestStream::connect(self.inner.uri()).await?; - - let (mut sender, conn) = handshake(HyperIo::from(stream)).await.into_lua_err()?; - - HyperExecutor::execute(lua.clone(), conn); - - let incoming = sender.send_request(self.as_full()).await.into_lua_err()?; - - if let Some((new_method, new_uri)) = check_redirect(&self.inner, &incoming) { - if self.redirects >= MAX_REDIRECTS { - return Err(LuaError::external("Too many redirects")); - } - - if new_method == Method::GET { - *self.inner.body_mut() = Bytes::new(); - } - - *self.inner.method_mut() = new_method; - *self.inner.uri_mut() = new_uri; - - self.redirects += 1; - - continue; - } - - break Response::from_incoming(incoming, self.decompress).await; - } - } } fn add_default_headers(lua: &Lua, headers: &mut HeaderMap) -> LuaResult<()> { @@ -148,23 +101,3 @@ fn add_default_headers(lua: &Lua, headers: &mut HeaderMap) -> LuaResult<()> { Ok(()) } - -fn check_redirect( - request: &HyperRequest, - response: &HyperResponse, -) -> Option<(Method, Uri)> { - if !response.status().is_redirection() { - return None; - } - - let location = response.headers().get(LOCATION)?; - let location = location.to_str().ok()?; - let location = location.parse().ok()?; - - let method = match response.status().as_u16() { - 301..=303 => Method::GET, - _ => request.method().clone(), - }; - - Some((method, location)) -}