Add support for query pairs in net.request params

This commit is contained in:
Filip Tibell 2023-02-23 11:31:42 +01:00
parent 26c880c7a0
commit 9fd6f66686
No known key found for this signature in database
5 changed files with 80 additions and 3 deletions

View file

@ -170,14 +170,16 @@ type NetMethod = "GET" | "POST" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "PATCH
This is a dictionary that may contain one or more of the following values: This is a dictionary that may contain one or more of the following values:
* `url` - The URL to request. This is always required * `url` - The URL to send a request to. This is always required
* `method` - The HTTP method verb, such as `"GET"`, `"POST"`, `"PATCH"`, `"PUT"`, or `"DELETE"`. Defaults to `"GET"` * `method` - The HTTP method verb, such as `"GET"`, `"POST"`, `"PATCH"`, `"PUT"`, or `"DELETE"`. Defaults to `"GET"`
* `query` - A table of key-value pairs representing query parameters in the request path
* `headers` - A table of key-value pairs representing headers * `headers` - A table of key-value pairs representing headers
* `body` - The request body * `body` - The request body
]=] ]=]
export type NetFetchParams = { export type NetFetchParams = {
url: string, url: string,
method: NetMethod?, method: NetMethod?,
query: { [string]: string }?,
headers: { [string]: string }?, headers: { [string]: string }?,
body: string?, body: string?,
} }

View file

@ -59,6 +59,9 @@ async fn net_request<'a>(lua: &'static Lua, config: RequestConfig<'a>) -> LuaRes
// Create and send the request // Create and send the request
let client: NetClient = lua.named_registry_value("net.client")?; let client: NetClient = lua.named_registry_value("net.client")?;
let mut request = client.request(config.method, &config.url); let mut request = client.request(config.method, &config.url);
for (query, value) in config.query {
request = request.query(&[(query.to_str()?, value.to_str()?)]);
}
for (header, value) in config.headers { for (header, value) in config.headers {
request = request.header(header.to_str()?, value.to_str()?); request = request.header(header.to_str()?, value.to_str()?);
} }

View file

@ -9,6 +9,7 @@ use reqwest::Method;
pub struct RequestConfig<'a> { pub struct RequestConfig<'a> {
pub url: String, pub url: String,
pub method: Method, pub method: Method,
pub query: HashMap<LuaString<'a>, LuaString<'a>>,
pub headers: HashMap<LuaString<'a>, LuaString<'a>>, pub headers: HashMap<LuaString<'a>, LuaString<'a>>,
pub body: Option<Vec<u8>>, pub body: Option<Vec<u8>>,
} }
@ -20,6 +21,7 @@ impl<'lua> FromLua<'lua> for RequestConfig<'lua> {
return Ok(Self { return Ok(Self {
url: s.to_string_lossy().to_string(), url: s.to_string_lossy().to_string(),
method: Method::GET, method: Method::GET,
query: HashMap::new(),
headers: HashMap::new(), headers: HashMap::new(),
body: None, body: None,
}); });
@ -38,6 +40,18 @@ impl<'lua> FromLua<'lua> for RequestConfig<'lua> {
Ok(config_method) => config_method.to_string_lossy().trim().to_ascii_uppercase(), Ok(config_method) => config_method.to_string_lossy().trim().to_ascii_uppercase(),
Err(_) => "GET".to_string(), Err(_) => "GET".to_string(),
}; };
// Extract query
let query = match tab.raw_get::<_, LuaTable>("query") {
Ok(config_headers) => {
let mut lua_headers = HashMap::new();
for pair in config_headers.pairs::<LuaString, LuaString>() {
let (key, value) = pair?.to_owned();
lua_headers.insert(key, value);
}
lua_headers
}
Err(_) => HashMap::new(),
};
// Extract headers // Extract headers
let headers = match tab.raw_get::<_, LuaTable>("headers") { let headers = match tab.raw_get::<_, LuaTable>("headers") {
Ok(config_headers) => { Ok(config_headers) => {
@ -74,6 +88,7 @@ impl<'lua> FromLua<'lua> for RequestConfig<'lua> {
return Ok(Self { return Ok(Self {
url, url,
method, method,
query,
headers, headers,
body, body,
}); });

View file

@ -46,6 +46,7 @@ create_tests! {
fs_move: "fs/move", fs_move: "fs/move",
net_request_codes: "net/request/codes", net_request_codes: "net/request/codes",
net_request_methods: "net/request/methods", net_request_methods: "net/request/methods",
net_request_query: "net/request/query",
net_request_redirect: "net/request/redirect", net_request_redirect: "net/request/redirect",
net_json_decode: "net/json/decode", net_json_decode: "net/json/decode",
net_json_encode: "net/json/encode", net_json_encode: "net/json/encode",
@ -61,8 +62,8 @@ create_tests! {
require_nested: "globals/require/tests/nested", require_nested: "globals/require/tests/nested",
require_parents: "globals/require/tests/parents", require_parents: "globals/require/tests/parents",
require_siblings: "globals/require/tests/siblings", require_siblings: "globals/require/tests/siblings",
// TODO: Uncomment this test, it is commented out // TODO: Uncomment this test, it is commented out right
// right now to let CI pass so we make a release // now to let CI pass so that we can make a new release
// global_coroutine: "globals/coroutine", // global_coroutine: "globals/coroutine",
global_pcall: "globals/pcall", global_pcall: "globals/pcall",
global_type: "globals/type", global_type: "globals/type",

View file

@ -0,0 +1,56 @@
local QUERY: { [string]: string } = {
Key = "Value",
Hello = "World",
SpaceEmoji = " 🚀 ",
}
-- Make a request with some basic query params as well
-- as a special non-ascii one that needs url encoding
local response = net.request({
url = "https://httpbin.org/anything",
query = QUERY,
})
assert(
response.ok,
"Request failed with status "
.. tostring(response.statusCode)
.. " "
.. tostring(response.statusMessage)
)
-- We should get a json response here with an "args" table which is our query
local success, json = pcall(net.jsonDecode, response.body)
assert(success, "Failed to decode json response\n" .. tostring(json))
local args = if type(json.args) == "table" then json.args else nil
assert(args ~= nil, "Response body did not contain an args table")
-- The args table should then have the *exact* same contents as our query
for key, value in QUERY do
local received = args[key]
if received == nil then
error(string.format("Response body did not contain query parameter '%s'", key))
elseif typeof(received) ~= typeof(value) then
error(
string.format(
"Response body contained query parameter '%s' but it was of type '%s', expected '%s'",
key,
typeof(received),
typeof(value)
)
)
elseif received ~= value then
error(
string.format(
"Response body contained query parameter '%s' but it had the value '%s', expected '%s'",
key,
received,
value
)
)
end
end