mirror of
https://github.com/lune-org/lune.git
synced 2025-04-20 03:43:49 +01:00
Add net.serve address
property
This commit is contained in:
parent
eef3d2d6fa
commit
8ba4055e13
4 changed files with 57 additions and 19 deletions
|
@ -60,6 +60,7 @@ impl FromLua<'_> for RequestConfig {
|
||||||
fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> {
|
fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> {
|
||||||
// If we just got a string we assume its a GET request to a given url
|
// If we just got a string we assume its a GET request to a given url
|
||||||
if let LuaValue::String(s) = value {
|
if let LuaValue::String(s) = value {
|
||||||
|
println!("{:?}", s);
|
||||||
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,
|
||||||
|
@ -140,9 +141,11 @@ impl FromLua<'_> for RequestConfig {
|
||||||
|
|
||||||
// Net serve config
|
// Net serve config
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct ServeConfig<'a> {
|
pub struct ServeConfig<'a> {
|
||||||
pub handle_request: LuaFunction<'a>,
|
pub handle_request: LuaFunction<'a>,
|
||||||
pub handle_web_socket: Option<LuaFunction<'a>>,
|
pub handle_web_socket: Option<LuaFunction<'a>>,
|
||||||
|
pub address: Option<LuaString<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua> FromLua<'lua> for ServeConfig<'lua> {
|
impl<'lua> FromLua<'lua> for ServeConfig<'lua> {
|
||||||
|
@ -152,11 +155,13 @@ impl<'lua> FromLua<'lua> for ServeConfig<'lua> {
|
||||||
return Ok(ServeConfig {
|
return Ok(ServeConfig {
|
||||||
handle_request: f.clone(),
|
handle_request: f.clone(),
|
||||||
handle_web_socket: None,
|
handle_web_socket: None,
|
||||||
|
address: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
LuaValue::Table(t) => {
|
LuaValue::Table(t) => {
|
||||||
let handle_request: Option<LuaFunction> = t.raw_get("handleRequest")?;
|
let handle_request: Option<LuaFunction> = t.raw_get("handleRequest")?;
|
||||||
let handle_web_socket: Option<LuaFunction> = t.raw_get("handleWebSocket")?;
|
let handle_web_socket: Option<LuaFunction> = t.raw_get("handleWebSocket")?;
|
||||||
|
let address: Option<LuaString> = t.raw_get("address")?;
|
||||||
if handle_request.is_some() || handle_web_socket.is_some() {
|
if handle_request.is_some() || handle_web_socket.is_some() {
|
||||||
return Ok(ServeConfig {
|
return Ok(ServeConfig {
|
||||||
handle_request: handle_request.unwrap_or_else(|| {
|
handle_request: handle_request.unwrap_or_else(|| {
|
||||||
|
@ -174,6 +179,7 @@ impl<'lua> FromLua<'lua> for ServeConfig<'lua> {
|
||||||
.expect("Failed to create default http responder function")
|
.expect("Failed to create default http responder function")
|
||||||
}),
|
}),
|
||||||
handle_web_socket,
|
handle_web_socket,
|
||||||
|
address,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Some("Missing handleRequest and / or handleWebSocket".to_string())
|
Some("Missing handleRequest and / or handleWebSocket".to_string())
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use hyper::header::CONTENT_ENCODING;
|
use hyper::header::CONTENT_ENCODING;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
use crate::lune::{scheduler::Scheduler, util::TableBuilder};
|
use crate::lune::{scheduler::Scheduler, util::TableBuilder};
|
||||||
|
|
||||||
use self::{server::create_server, util::header_map_to_table};
|
use self::{
|
||||||
|
server::{bind_to_addr, create_server},
|
||||||
|
util::header_map_to_table,
|
||||||
|
};
|
||||||
|
|
||||||
use super::serde::{
|
use super::serde::{
|
||||||
compress_decompress::{decompress, CompressDecompressFormat},
|
compress_decompress::{decompress, CompressDecompressFormat},
|
||||||
|
@ -21,7 +27,6 @@ mod websocket;
|
||||||
|
|
||||||
use client::{NetClient, NetClientBuilder};
|
use client::{NetClient, NetClientBuilder};
|
||||||
use config::{RequestConfig, ServeConfig};
|
use config::{RequestConfig, ServeConfig};
|
||||||
use server::bind_to_localhost;
|
|
||||||
use websocket::NetWebSocket;
|
use websocket::NetWebSocket;
|
||||||
|
|
||||||
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
|
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
|
||||||
|
@ -64,6 +69,8 @@ async fn net_request<'lua>(lua: &'lua Lua, config: RequestConfig) -> LuaResult<L
|
||||||
where
|
where
|
||||||
'lua: 'static, // FIXME: Get rid of static lifetime bound here
|
'lua: 'static, // FIXME: Get rid of static lifetime bound here
|
||||||
{
|
{
|
||||||
|
println!("net_request config {:?}", config);
|
||||||
|
|
||||||
// Create and send the request
|
// Create and send the request
|
||||||
let client = NetClient::from_registry(lua);
|
let client = NetClient::from_registry(lua);
|
||||||
let mut request = client.request(config.method, &config.url);
|
let mut request = client.request(config.method, &config.url);
|
||||||
|
@ -133,11 +140,28 @@ async fn net_serve<'lua>(
|
||||||
where
|
where
|
||||||
'lua: 'static, // FIXME: Get rid of static lifetime bound here
|
'lua: 'static, // FIXME: Get rid of static lifetime bound here
|
||||||
{
|
{
|
||||||
|
println!("port {:?}", port);
|
||||||
|
|
||||||
let sched = lua
|
let sched = lua
|
||||||
.app_data_ref::<&Scheduler>()
|
.app_data_ref::<&Scheduler>()
|
||||||
.expect("Lua struct is missing scheduler");
|
.expect("Lua struct is missing scheduler");
|
||||||
|
|
||||||
let builder = bind_to_localhost(port)?;
|
println!("config {:?}", config);
|
||||||
|
|
||||||
|
let address_pattern = Regex::new(r"(?:.*:\/\/)?([\d\.]+)(?::\d+)?").unwrap();
|
||||||
|
|
||||||
|
let address = match &config.address {
|
||||||
|
Some(addr) => {
|
||||||
|
let caps = address_pattern.captures(addr.to_str()?).unwrap();
|
||||||
|
println!("captures {:?}", &caps);
|
||||||
|
caps[1].parse::<Ipv4Addr>()?
|
||||||
|
}
|
||||||
|
None => Ipv4Addr::new(127, 0, 0, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("address {:?}", address);
|
||||||
|
|
||||||
|
let builder = bind_to_addr(address, port)?;
|
||||||
|
|
||||||
create_server(lua, &sched, config, builder)
|
create_server(lua, &sched, config, builder)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
use std::{collections::HashMap, convert::Infallible, net::SocketAddr, sync::Arc};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
convert::Infallible,
|
||||||
|
net::{Ipv4Addr, SocketAddr},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
use hyper::{
|
use hyper::{
|
||||||
server::{conn::AddrIncoming, Builder},
|
server::{conn::AddrIncoming, Builder},
|
||||||
|
@ -20,12 +25,15 @@ use super::{
|
||||||
websocket::NetWebSocket,
|
websocket::NetWebSocket,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(super) fn bind_to_localhost(port: u16) -> LuaResult<Builder<AddrIncoming>> {
|
pub(super) fn bind_to_addr(address: Ipv4Addr, port: u16) -> LuaResult<Builder<AddrIncoming>> {
|
||||||
let addr = SocketAddr::from(([127, 0, 0, 1], port));
|
let addr = SocketAddr::from((address, port));
|
||||||
|
|
||||||
|
println!("attempting to bind to {:?}", addr);
|
||||||
|
|
||||||
match Server::try_bind(&addr) {
|
match Server::try_bind(&addr) {
|
||||||
Ok(b) => Ok(b),
|
Ok(b) => Ok(b),
|
||||||
Err(e) => Err(LuaError::external(format!(
|
Err(e) => Err(LuaError::external(format!(
|
||||||
"Failed to bind to localhost on port {port}\n{}",
|
"Failed to bind to {addr}\n{}",
|
||||||
e.to_string()
|
e.to_string()
|
||||||
.replace("error creating server listener: ", "> ")
|
.replace("error creating server listener: ", "> ")
|
||||||
))),
|
))),
|
||||||
|
|
|
@ -5,12 +5,12 @@ local task = require("@lune/task")
|
||||||
|
|
||||||
local PORT = 8080
|
local PORT = 8080
|
||||||
local URL = `http://127.0.0.1:{PORT}`
|
local URL = `http://127.0.0.1:{PORT}`
|
||||||
local URL_EXTERNAL = `http://0.0.0.0:{PORT}`
|
local URL_EXTERNAL = `http://0.0.0.0`
|
||||||
local RESPONSE = "Hello, lune!"
|
local RESPONSE = "Hello, lune!"
|
||||||
|
|
||||||
-- A server should never be running before testing
|
-- A server should never be running before testing
|
||||||
local isRunning = pcall(net.request, URL)
|
local isRunning = pcall(net.request, URL)
|
||||||
assert(not isRunning, `A server is already running at {URL}`)
|
assert(not isRunning, `a server is already running at {URL}`)
|
||||||
|
|
||||||
-- Serve should not block the thread from continuing
|
-- Serve should not block the thread from continuing
|
||||||
|
|
||||||
|
@ -21,8 +21,6 @@ local thread = task.delay(1, function()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local handle = net.serve(PORT, function(request)
|
local handle = net.serve(PORT, function(request)
|
||||||
-- print("Request:", request)
|
|
||||||
-- print("Responding with", RESPONSE)
|
|
||||||
assert(request.path == "/some/path")
|
assert(request.path == "/some/path")
|
||||||
assert(request.query.key == "param2")
|
assert(request.query.key == "param2")
|
||||||
assert(request.query.key2 == "param3")
|
assert(request.query.key2 == "param3")
|
||||||
|
@ -84,13 +82,15 @@ assert(
|
||||||
)
|
)
|
||||||
|
|
||||||
-- Serve should be able to bind to other IP addresses
|
-- Serve should be able to bind to other IP addresses
|
||||||
handle = net.serve(URL_EXTERNAL, function(request)
|
local handle2 = net.serve(PORT, {
|
||||||
assert(request.path == "/some/path")
|
address = URL_EXTERNAL,
|
||||||
assert(request.query.key == "param2")
|
handleRequest = function(request)
|
||||||
assert(request.query.key2 == "param3")
|
return `Response from {URL_EXTERNAL}:{PORT}`
|
||||||
return RESPONSE
|
end,
|
||||||
end)
|
})
|
||||||
|
|
||||||
-- And any requests to that IP should succeed
|
-- And any requests to that IP should succeed
|
||||||
response = net.request(URL_EXTERNAL .. "/some/path?key=param1&key=param2&key2=param3").body
|
local response3 = net.request(`{URL_EXTERNAL}:{PORT}`).body
|
||||||
assert(response == RESPONSE, "Invalid response from server")
|
assert(response3 ~= nil, "Invalid response from server")
|
||||||
|
|
||||||
|
handle2.stop()
|
||||||
|
|
Loading…
Add table
Reference in a new issue