From 03c773fd7928a8afa39c0515e97a5cdc0436d95b Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Thu, 18 Apr 2024 20:54:21 +0200 Subject: [PATCH 1/4] Fix headers in net.serve being raw bytes instead of strings --- src/lune/builtins/net/server/request.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/lune/builtins/net/server/request.rs b/src/lune/builtins/net/server/request.rs index dde529f..bab7a5d 100644 --- a/src/lune/builtins/net/server/request.rs +++ b/src/lune/builtins/net/server/request.rs @@ -18,21 +18,30 @@ impl LuaRequest { let path = self.head.uri.path().to_string(); let body = lua.create_string(&self.body)?; - let query: HashMap = self + let query: HashMap = self .head .uri .query() .unwrap_or_default() .split('&') .filter_map(|q| q.split_once('=')) - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(); - let headers: HashMap> = self + .map(|(k, v)| { + let k = lua.create_string(k)?; + let v = lua.create_string(v)?; + Ok((k, v)) + }) + .collect::>()?; + + let headers: HashMap = self .head .headers .iter() - .map(|(k, v)| (k.as_str().to_string(), v.as_bytes().to_vec())) - .collect(); + .map(|(k, v)| { + let k = lua.create_string(k.as_str())?; + let v = lua.create_string(v.as_bytes())?; + Ok((k, v)) + }) + .collect::>()?; TableBuilder::new(lua)? .with_value("method", method)? From 4a28499aaa1d9669636ffc6b0da2cd7c7549533d Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Thu, 18 Apr 2024 20:56:40 +0200 Subject: [PATCH 2/4] Fix net.serve no longer accepting ipv6 --- src/lune/builtins/net/config.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lune/builtins/net/config.rs b/src/lune/builtins/net/config.rs index 5d02d2b..d801c47 100644 --- a/src/lune/builtins/net/config.rs +++ b/src/lune/builtins/net/config.rs @@ -1,4 +1,7 @@ -use std::{collections::HashMap, net::Ipv4Addr}; +use std::{ + collections::HashMap, + net::{IpAddr, Ipv4Addr}, +}; use mlua::prelude::*; @@ -6,7 +9,7 @@ use reqwest::Method; use super::util::table_to_hash_map; -const DEFAULT_IP_ADDRESS: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1); +const DEFAULT_IP_ADDRESS: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); const WEB_SOCKET_UPDGRADE_REQUEST_HANDLER: &str = r#" return { @@ -155,7 +158,7 @@ impl FromLua<'_> for RequestConfig { #[derive(Debug)] pub struct ServeConfig<'a> { - pub address: Ipv4Addr, + pub address: IpAddr, pub handle_request: LuaFunction<'a>, pub handle_web_socket: Option>, } @@ -175,7 +178,7 @@ impl<'lua> FromLua<'lua> for ServeConfig<'lua> { let handle_request: Option = t.get("handleRequest")?; let handle_web_socket: Option = t.get("handleWebSocket")?; if handle_request.is_some() || handle_web_socket.is_some() { - let address: Ipv4Addr = match &address { + let address: IpAddr = match &address { Some(addr) => { let addr_str = addr.to_str()?; From 753897222ab8b02101d483d3d88384b6a992771d Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Thu, 18 Apr 2024 22:10:08 +0200 Subject: [PATCH 3/4] Implement stdio.readToEnd API --- src/lune/builtins/stdio/mod.rs | 18 +++++++++++++++++- types/stdio.luau | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/lune/builtins/stdio/mod.rs b/src/lune/builtins/stdio/mod.rs index 14927f2..f851bc7 100644 --- a/src/lune/builtins/stdio/mod.rs +++ b/src/lune/builtins/stdio/mod.rs @@ -2,7 +2,7 @@ use mlua::prelude::*; use dialoguer::{theme::ColorfulTheme, Confirm, Input, MultiSelect, Select}; use mlua_luau_scheduler::LuaSpawnExt; -use tokio::io::{self, AsyncWriteExt}; +use tokio::io::{self, AsyncReadExt, AsyncWriteExt}; use crate::lune::util::{ formatting::{ @@ -21,6 +21,7 @@ pub fn create(lua: &Lua) -> LuaResult> { .with_function("format", stdio_format)? .with_async_function("write", stdio_write)? .with_async_function("ewrite", stdio_ewrite)? + .with_async_function("readToEnd", stdio_read_to_end)? .with_async_function("prompt", stdio_prompt)? .build_readonly() } @@ -53,6 +54,21 @@ async fn stdio_ewrite(_: &Lua, s: LuaString<'_>) -> LuaResult<()> { Ok(()) } +/* + FUTURE: Figure out how to expose some kind of "readLine" function using a buffered reader. + + This is a bit tricky since we would want to be able to use **both** readLine and readToEnd + in the same script, doing something like readLine, readLine, readToEnd from lua, and + having that capture the first two lines and then read the rest of the input. +*/ + +async fn stdio_read_to_end(lua: &Lua, _: ()) -> LuaResult { + let mut input = Vec::new(); + let mut stdin = io::stdin(); + stdin.read_to_end(&mut input).await?; + lua.create_string(&input) +} + async fn stdio_prompt(lua: &Lua, options: PromptOptions) -> LuaResult { lua.spawn_blocking(move || prompt(options)) .await diff --git a/types/stdio.luau b/types/stdio.luau index 3c5198e..70a73e0 100644 --- a/types/stdio.luau +++ b/types/stdio.luau @@ -58,6 +58,11 @@ end stdio.write("World! ") stdio.write("All on the same line") stdio.ewrite("\nAnd some error text, too") + + -- Reading from stdin, either line-by-line or the entire input + local firstLine = stdio.readLine() + local secondLine = stdio.readLine() + local remaining = stdio.readToEnd() ``` ]=] local stdio = {} @@ -143,4 +148,16 @@ function stdio.write(s: string) end ]=] function stdio.ewrite(s: string) end +--[=[ + @within Stdio + @tag must_use + + Reads the entire input from stdin. + + @return The input from stdin +]=] +function stdio.readToEnd(): string + return nil :: any +end + return stdio From fa7f6c6f5101f6a28beedf29104709fa4054e613 Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Thu, 18 Apr 2024 22:14:54 +0200 Subject: [PATCH 4/4] Fix doc example for new stdio API --- types/stdio.luau | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/types/stdio.luau b/types/stdio.luau index 70a73e0..e6e88a4 100644 --- a/types/stdio.luau +++ b/types/stdio.luau @@ -59,10 +59,8 @@ end stdio.write("All on the same line") stdio.ewrite("\nAnd some error text, too") - -- Reading from stdin, either line-by-line or the entire input - local firstLine = stdio.readLine() - local secondLine = stdio.readLine() - local remaining = stdio.readToEnd() + -- Reading the entire input from stdin + local input = stdio.readToEnd() ``` ]=] local stdio = {}