mirror of
https://github.com/lune-org/lune.git
synced 2025-05-04 10:43:57 +01:00
Move request sending to client sub module
This commit is contained in:
parent
c92d086123
commit
48e34b8c98
3 changed files with 89 additions and 77 deletions
|
@ -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 config;
|
||||||
pub mod stream;
|
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<Response> {
|
||||||
|
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<Bytes>,
|
||||||
|
response: &HyperResponse<Incoming>,
|
||||||
|
) -> 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))
|
||||||
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ pub fn module(lua: Lua) -> LuaResult<LuaTable> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn net_request(lua: Lua, config: RequestConfig) -> LuaResult<Response> {
|
async fn net_request(lua: Lua, config: RequestConfig) -> LuaResult<Response> {
|
||||||
Request::from_config(config, lua.clone())?
|
let request = Request::from_config(config, lua.clone())?;
|
||||||
.send(lua.clone())
|
self::client::send_request(request, lua.clone()).await
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,32 +2,22 @@ use http_body_util::Full;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use hyper::{
|
use hyper::{
|
||||||
body::{Bytes, Incoming},
|
body::Bytes,
|
||||||
client::conn::http1::handshake,
|
header::{HeaderName, HeaderValue, USER_AGENT},
|
||||||
header::{HeaderName, HeaderValue, LOCATION, USER_AGENT},
|
HeaderMap, Request as HyperRequest,
|
||||||
HeaderMap, Method, Request as HyperRequest, Response as HyperResponse, Uri,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{client::config::RequestConfig, shared::headers::create_user_agent_header};
|
||||||
client::{config::RequestConfig, stream::HttpRequestStream},
|
|
||||||
shared::{
|
|
||||||
headers::create_user_agent_header,
|
|
||||||
hyper::{HyperExecutor, HyperIo},
|
|
||||||
response::Response,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const MAX_REDIRECTS: usize = 10;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
// NOTE: We use Bytes instead of Full<Bytes> to avoid
|
// NOTE: We use Bytes instead of Full<Bytes> to avoid
|
||||||
// needing async when getting a reference to the body
|
// needing async when getting a reference to the body
|
||||||
inner: HyperRequest<Bytes>,
|
pub(crate) inner: HyperRequest<Bytes>,
|
||||||
redirects: usize,
|
pub(crate) redirects: usize,
|
||||||
decompress: bool,
|
pub(crate) decompress: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Request {
|
impl Request {
|
||||||
|
@ -100,43 +90,6 @@ impl Request {
|
||||||
let body = Full::new(self.inner.body().clone());
|
let body = Full::new(self.inner.body().clone());
|
||||||
builder.body(body).expect("request was valid")
|
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<Response> {
|
|
||||||
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<()> {
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_redirect(
|
|
||||||
request: &HyperRequest<Bytes>,
|
|
||||||
response: &HyperResponse<Incoming>,
|
|
||||||
) -> 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))
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue