mirror of
https://github.com/lune-org/lune.git
synced 2025-05-04 10:43:57 +01:00
Use tryfrom trait to convert from config to request or response
This commit is contained in:
parent
64d49de3be
commit
85ba4e66fe
4 changed files with 93 additions and 95 deletions
|
@ -1,10 +1,10 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use bstr::{BString, ByteSlice};
|
use bstr::{BString, ByteSlice};
|
||||||
use hyper::Method;
|
use hyper::{header::USER_AGENT, Method};
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::shared::headers::table_to_hash_map;
|
use crate::shared::headers::{create_user_agent_header, table_to_hash_map};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RequestConfigOptions {
|
pub struct RequestConfigOptions {
|
||||||
|
@ -86,7 +86,7 @@ impl FromLua for RequestConfig {
|
||||||
Err(_) => HashMap::new(),
|
Err(_) => HashMap::new(),
|
||||||
};
|
};
|
||||||
// Extract headers
|
// Extract headers
|
||||||
let headers = match tab.get::<LuaTable>("headers") {
|
let mut headers = match tab.get::<LuaTable>("headers") {
|
||||||
Ok(tab) => table_to_hash_map(tab, "headers")?,
|
Ok(tab) => table_to_hash_map(tab, "headers")?,
|
||||||
Err(_) => HashMap::new(),
|
Err(_) => HashMap::new(),
|
||||||
};
|
};
|
||||||
|
@ -118,6 +118,9 @@ impl FromLua for RequestConfig {
|
||||||
Err(_) => RequestConfigOptions::default(),
|
Err(_) => RequestConfigOptions::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Finally, add any default headers, if applicable
|
||||||
|
add_default_headers(lua, &mut headers)?;
|
||||||
|
|
||||||
// All good, validated and we got what we need
|
// All good, validated and we got what we need
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
url,
|
url,
|
||||||
|
@ -140,3 +143,12 @@ impl FromLua for RequestConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_default_headers(lua: &Lua, headers: &mut HashMap<String, Vec<String>>) -> LuaResult<()> {
|
||||||
|
if !headers.contains_key(USER_AGENT.as_str()) {
|
||||||
|
let ua = create_user_agent_header(lua)?;
|
||||||
|
headers.insert(USER_AGENT.to_string(), vec![ua]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -43,6 +43,5 @@ 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> {
|
||||||
let request = Request::from_config(config, lua.clone())?;
|
self::client::send_request(Request::try_from(config)?, lua).await
|
||||||
self::client::send_request(request, lua.clone()).await
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use url::Url;
|
||||||
|
|
||||||
use hyper::{
|
use hyper::{
|
||||||
body::{Body as _, Bytes, Incoming},
|
body::{Body as _, Bytes, Incoming},
|
||||||
header::{HeaderName, HeaderValue, USER_AGENT},
|
header::{HeaderName, HeaderValue},
|
||||||
HeaderMap, Method, Request as HyperRequest,
|
HeaderMap, Method, Request as HyperRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
client::config::RequestConfig,
|
client::config::RequestConfig,
|
||||||
shared::headers::{create_user_agent_header, hash_map_to_table, header_map_to_table},
|
shared::headers::{hash_map_to_table, header_map_to_table},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -27,57 +27,6 @@ pub struct Request {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Request {
|
impl Request {
|
||||||
/**
|
|
||||||
Creates a new request that is ready to be sent from a request configuration.
|
|
||||||
*/
|
|
||||||
pub fn from_config(config: RequestConfig, lua: Lua) -> LuaResult<Self> {
|
|
||||||
// 1. Parse the URL and make sure it is valid
|
|
||||||
let mut url = Url::parse(&config.url).into_lua_err()?;
|
|
||||||
|
|
||||||
// 2. Append any query pairs passed as a table
|
|
||||||
{
|
|
||||||
let mut query = url.query_pairs_mut();
|
|
||||||
for (key, values) in config.query {
|
|
||||||
for value in values {
|
|
||||||
query.append_pair(&key, &value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Create the inner request builder
|
|
||||||
let mut builder = HyperRequest::builder()
|
|
||||||
.method(config.method)
|
|
||||||
.uri(url.as_str());
|
|
||||||
|
|
||||||
// 4. Append any headers passed as a table - builder
|
|
||||||
// headers may be None if builder is already invalid
|
|
||||||
if let Some(headers) = builder.headers_mut() {
|
|
||||||
for (key, values) in config.headers {
|
|
||||||
let key = HeaderName::from_bytes(key.as_bytes()).into_lua_err()?;
|
|
||||||
for value in values {
|
|
||||||
let value = HeaderValue::from_str(&value).into_lua_err()?;
|
|
||||||
headers.insert(key.clone(), value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. Convert request body bytes to the proper Body
|
|
||||||
// type that Hyper expects, if we got any bytes
|
|
||||||
let body = config.body.map(Bytes::from).unwrap_or_default();
|
|
||||||
|
|
||||||
// 6. Finally, attach the body, verifying that the request
|
|
||||||
// is valid, and attach a user agent if not already set
|
|
||||||
let mut inner = builder.body(body).into_lua_err()?;
|
|
||||||
|
|
||||||
add_default_headers(&lua, inner.headers_mut())?;
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
inner,
|
|
||||||
redirects: 0,
|
|
||||||
decompress: config.options.decompress,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a new request from a raw incoming request.
|
Creates a new request from a raw incoming request.
|
||||||
*/
|
*/
|
||||||
|
@ -173,14 +122,52 @@ impl Request {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_default_headers(lua: &Lua, headers: &mut HeaderMap) -> LuaResult<()> {
|
impl TryFrom<RequestConfig> for Request {
|
||||||
if !headers.contains_key(USER_AGENT) {
|
type Error = LuaError;
|
||||||
let ua = create_user_agent_header(lua)?;
|
fn try_from(config: RequestConfig) -> Result<Self, Self::Error> {
|
||||||
let ua = HeaderValue::from_str(&ua).into_lua_err()?;
|
// 1. Parse the URL and make sure it is valid
|
||||||
headers.insert(USER_AGENT, ua);
|
let mut url = Url::parse(&config.url).into_lua_err()?;
|
||||||
|
|
||||||
|
// 2. Append any query pairs passed as a table
|
||||||
|
{
|
||||||
|
let mut query = url.query_pairs_mut();
|
||||||
|
for (key, values) in config.query {
|
||||||
|
for value in values {
|
||||||
|
query.append_pair(&key, &value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
// 3. Create the inner request builder
|
||||||
|
let mut builder = HyperRequest::builder()
|
||||||
|
.method(config.method)
|
||||||
|
.uri(url.as_str());
|
||||||
|
|
||||||
|
// 4. Append any headers passed as a table - builder
|
||||||
|
// headers may be None if builder is already invalid
|
||||||
|
if let Some(headers) = builder.headers_mut() {
|
||||||
|
for (key, values) in config.headers {
|
||||||
|
let key = HeaderName::from_bytes(key.as_bytes()).into_lua_err()?;
|
||||||
|
for value in values {
|
||||||
|
let value = HeaderValue::from_str(&value).into_lua_err()?;
|
||||||
|
headers.insert(key.clone(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Convert request body bytes to the proper Body
|
||||||
|
// type that Hyper expects, if we got any bytes
|
||||||
|
let body = config.body.map(Bytes::from).unwrap_or_default();
|
||||||
|
|
||||||
|
// 6. Finally, attach the body, verifying that the request is valid
|
||||||
|
let inner = builder.body(body).into_lua_err()?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
inner,
|
||||||
|
redirects: 0,
|
||||||
|
decompress: config.options.decompress,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LuaUserData for Request {
|
impl LuaUserData for Request {
|
||||||
|
|
|
@ -20,36 +20,6 @@ pub struct Response {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Response {
|
impl Response {
|
||||||
/**
|
|
||||||
Creates a new response that is ready to be sent from a response configuration.
|
|
||||||
*/
|
|
||||||
pub fn from_config(config: ResponseConfig, _lua: Lua) -> LuaResult<Self> {
|
|
||||||
// 1. Create the inner response builder
|
|
||||||
let mut builder = HyperResponse::builder().status(config.status);
|
|
||||||
|
|
||||||
// 2. Append any headers passed as a table - builder
|
|
||||||
// headers may be None if builder is already invalid
|
|
||||||
if let Some(headers) = builder.headers_mut() {
|
|
||||||
for (key, values) in config.headers {
|
|
||||||
let key = HeaderName::from_bytes(key.as_bytes()).into_lua_err()?;
|
|
||||||
for value in values {
|
|
||||||
let value = HeaderValue::from_str(&value).into_lua_err()?;
|
|
||||||
headers.insert(key.clone(), value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Convert response body bytes to the proper Body
|
|
||||||
// type that Hyper expects, if we got any bytes
|
|
||||||
let body = config.body.map(Bytes::from).unwrap_or_default();
|
|
||||||
|
|
||||||
// 4. Finally, attach the body, verifying that the response is valid
|
|
||||||
Ok(Self {
|
|
||||||
inner: builder.body(body).into_lua_err()?,
|
|
||||||
decompressed: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a new response from a raw incoming response.
|
Creates a new response from a raw incoming response.
|
||||||
*/
|
*/
|
||||||
|
@ -133,6 +103,36 @@ impl Response {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<ResponseConfig> for Response {
|
||||||
|
type Error = LuaError;
|
||||||
|
fn try_from(config: ResponseConfig) -> Result<Self, Self::Error> {
|
||||||
|
// 1. Create the inner response builder
|
||||||
|
let mut builder = HyperResponse::builder().status(config.status);
|
||||||
|
|
||||||
|
// 2. Append any headers passed as a table - builder
|
||||||
|
// headers may be None if builder is already invalid
|
||||||
|
if let Some(headers) = builder.headers_mut() {
|
||||||
|
for (key, values) in config.headers {
|
||||||
|
let key = HeaderName::from_bytes(key.as_bytes()).into_lua_err()?;
|
||||||
|
for value in values {
|
||||||
|
let value = HeaderValue::from_str(&value).into_lua_err()?;
|
||||||
|
headers.insert(key.clone(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Convert response body bytes to the proper Body
|
||||||
|
// type that Hyper expects, if we got any bytes
|
||||||
|
let body = config.body.map(Bytes::from).unwrap_or_default();
|
||||||
|
|
||||||
|
// 4. Finally, attach the body, verifying that the response is valid
|
||||||
|
Ok(Self {
|
||||||
|
inner: builder.body(body).into_lua_err()?,
|
||||||
|
decompressed: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl LuaUserData for Response {
|
impl LuaUserData for Response {
|
||||||
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
|
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
|
||||||
fields.add_field_method_get("ok", |_, this| Ok(this.status_ok()));
|
fields.add_field_method_get("ok", |_, this| Ok(this.status_ok()));
|
||||||
|
|
Loading…
Add table
Reference in a new issue