Skip to content

Commit a9a6d8f

Browse files
committed
Update & Fixes
- Added buffer support to net & serde apis. - Fixed luau types - Fixed repl bugs.
1 parent 9bf3136 commit a9a6d8f

File tree

13 files changed

+217
-42
lines changed

13 files changed

+217
-42
lines changed

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
### Added
11+
- Added buffer support for `@net/server` body response. If a buffer is returned, it will be sent as the response body, works with `{ body = buffer, statusCode = 200 }`.
12+
13+
Example:
14+
```lua
15+
local net = require("@net/net")
16+
17+
net.serve({
18+
port = 8080,
19+
request = function(req)
20+
return buffer.fromstring("Hello World!")
21+
end
22+
})
23+
```
24+
- Added buffer support for `@net/serde` in compress/decompress. If a buffer is passed, it will return a new buffer.
25+
26+
Example:
27+
```lua
28+
local serde = require("@net/serde")
29+
30+
local compressed_buffer = serde.gzip.compress(buffer.fromstring("Zune"))
31+
print(compressed_buffer) -- <buffer: 0x12343567>
32+
```
33+
34+
### Changed
35+
- Updated backend luau module.
36+
37+
### Fixed
38+
- Fixed Inaccurate luau types for `@zcore/net`.
39+
- Fixed REPL not working after an error is thrown.
40+
1041
## `0.2.0` - August 30, 2024
1142

1243
### Added

build.zig.zon

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.{
22
.name = "Zune",
3-
.version = "0.2.0",
3+
.version = "0.2.1",
44
.minimum_zig_version = "0.13.0",
55
.dependencies = .{
66
.json = .{
@@ -16,8 +16,8 @@
1616
.hash = "1220d6bbca59a59f16bda33b69e140d90bad313d11c07c0e2ab16076c59355845112",
1717
},
1818
.luau = .{
19-
.url = "https://codeload.github.com/SnorlaxAssist/zig-luau/tar.gz/fc385b1db1f68de1a5e242ed2fee77add1e47dd9",
20-
.hash = "1220cd16498a29dadde7dee091b703904963b2781997dacfd34f08dbe62177473637",
19+
.url = "https://codeload.github.com/SnorlaxAssist/zig-luau/tar.gz/a5168544a2f32ad281a7594143c7fd13cb57f6d0",
20+
.hash = "1220fb671beaead95894ebbd2fee934cf5473f7d2ebe91cf8e784235c93d1f19d2a7",
2121
},
2222
},
2323
.paths = .{

src/commands/repl/lib.zig

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,10 @@ fn Execute(allocator: std.mem.Allocator, args: []const []const u8) !void {
4747
.mode = .Run,
4848
});
4949

50-
const ML = L.newThread();
51-
52-
ML.sandboxThread();
53-
5450
const path = try std.fs.cwd().realpathAlloc(allocator, ".");
5551
defer allocator.free(path);
5652

57-
Engine.setLuaFileContext(ML, path);
53+
Engine.setLuaFileContext(L, path);
5854

5955
var stdin = std.io.getStdIn();
6056
var in_reader = stdin.reader();
@@ -128,6 +124,8 @@ fn Execute(allocator: std.mem.Allocator, args: []const []const u8) !void {
128124

129125
history.save(buffer.items);
130126

127+
const ML = L.newThread();
128+
131129
if (Engine.loadModule(ML, "CLI", buffer.items, null)) {
132130
Engine.runAsync(ML, &scheduler) catch ML.pop(1);
133131
} else |err| switch (err) {
@@ -138,6 +136,8 @@ fn Execute(allocator: std.mem.Allocator, args: []const []const u8) !void {
138136
else => return err,
139137
}
140138

139+
L.pop(1); // drop: thread
140+
141141
history.reset();
142142

143143
buffer.clearAndFree();

src/core/standard/net/httpserver.zig

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -342,20 +342,32 @@ pub fn responseResumed(responsePtr: *NetStreamData, L: *Luau, scheduler: *Schedu
342342
}
343343
}
344344

345-
if (L.getField(-3, "body") != .string) {
345+
const bodyType = L.getField(-3, "body");
346+
if (bodyType != .string and bodyType != .buffer) {
346347
std.debug.print("Field 'body' must be a string", .{});
347348
stream.writeAll(HTTP_500) catch return;
348349
return;
349350
}
350-
const body = L.checkString(-1);
351+
const body = if (bodyType == .buffer) L.checkBuffer(-1) else L.checkString(-1);
351352

352353
const response = if (headersString.items.len > 0)
353-
std.fmt.allocPrint(allocator, "HTTP/1.1 {d} {s}\r\n{s}Content-Length: {d}\r\n\r\n{s}", .{ statusCode, std.http.Status.phrase(@enumFromInt(statusCode)).?, headersString.items, body.len, body }) catch |err| {
354+
std.fmt.allocPrint(allocator, "HTTP/1.1 {d} {s}\r\n{s}Content-Length: {d}\r\n\r\n{s}", .{
355+
statusCode,
356+
std.http.Status.phrase(@enumFromInt(statusCode)).?,
357+
headersString.items,
358+
body.len,
359+
body,
360+
}) catch |err| {
354361
std.debug.print("Error formatting response: {}\n", .{err});
355362
return;
356363
}
357364
else
358-
std.fmt.allocPrint(allocator, "HTTP/1.1 {d} {s}\r\nContent-Length: {d}\r\n\r\n{s}", .{ statusCode, std.http.Status.phrase(@enumFromInt(statusCode)).?, body.len, body }) catch |err| {
365+
std.fmt.allocPrint(allocator, "HTTP/1.1 {d} {s}\r\nContent-Length: {d}\r\n\r\n{s}", .{
366+
statusCode,
367+
std.http.Status.phrase(@enumFromInt(statusCode)).?,
368+
body.len,
369+
body,
370+
}) catch |err| {
359371
std.debug.print("Error formatting response: {}\n", .{err});
360372
return;
361373
};
@@ -366,8 +378,8 @@ pub fn responseResumed(responsePtr: *NetStreamData, L: *Luau, scheduler: *Schedu
366378
return;
367379
};
368380
},
369-
.string => {
370-
const content = L.checkString(-1);
381+
.string, .buffer => |t| {
382+
const content = if (t == .buffer) L.checkBuffer(-1) else L.checkString(-1);
371383
const response = std.fmt.allocPrint(allocator, "HTTP/1.1 200 OK\r\nContent-Length: {d}\r\n\r\n{s}", .{ content.len, content }) catch |err| {
372384
std.debug.print("Error formatting response: {}\n", .{err});
373385
return;
@@ -380,7 +392,7 @@ pub fn responseResumed(responsePtr: *NetStreamData, L: *Luau, scheduler: *Schedu
380392
},
381393
else => {
382394
L.pop(1);
383-
std.debug.print("Serve response must be a table", .{});
395+
std.debug.print("Serve response must be a table or string", .{});
384396
stream.writeAll(HTTP_500) catch return;
385397
return;
386398
},

src/core/standard/serde/gzip.zig

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ const Luau = luau.Luau;
99
pub fn lua_compress(L: *Luau) !i32 {
1010
const allocator = L.allocator();
1111

12-
const string = L.checkString(1);
12+
const is_buffer = L.typeOf(1) == .buffer;
13+
14+
const string = if (is_buffer) L.checkBuffer(1) else L.checkString(1);
1315
const options = L.typeOf(2);
1416

1517
var level: u4 = 12;
@@ -36,15 +38,16 @@ pub fn lua_compress(L: *Luau) !i32 {
3638
.level = @enumFromInt(level),
3739
});
3840

39-
L.pushLString(buf.items);
41+
if (is_buffer) try L.pushBuffer(buf.items) else L.pushLString(buf.items);
4042

4143
return 1;
4244
}
4345

4446
pub fn lua_decompress(L: *Luau) !i32 {
4547
const allocator = L.allocator();
4648

47-
const string = L.checkString(1);
49+
const is_buffer = L.typeOf(1) == .buffer;
50+
const string = if (is_buffer) L.checkBuffer(1) else L.checkString(1);
4851

4952
var buf = std.ArrayList(u8).init(allocator);
5053
defer buf.deinit();
@@ -53,7 +56,7 @@ pub fn lua_decompress(L: *Luau) !i32 {
5356

5457
try std.compress.gzip.decompress(stream.reader(), buf.writer());
5558

56-
L.pushLString(buf.items);
59+
if (is_buffer) try L.pushBuffer(buf.items) else L.pushLString(buf.items);
5760

5861
return 1;
5962
}

src/core/standard/serde/lz4.zig

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ const Luau = luau.Luau;
1212
pub fn lua_compress(L: *Luau) !i32 {
1313
const allocator = L.allocator();
1414

15-
const string = L.checkString(1);
15+
const is_buffer = L.typeOf(1) == .buffer;
16+
17+
const string = if (is_buffer) L.checkBuffer(1) else L.checkString(1);
1618
const options = L.typeOf(2);
1719

1820
var level: u32 = 4;
@@ -47,15 +49,17 @@ pub fn lua_compress(L: *Luau) !i32 {
4749
@memcpy(out[0..4], header[0..4]);
4850
@memcpy(out[4..][0..buf.items.len], buf.items[0..]);
4951

50-
L.pushLString(out);
52+
if (is_buffer) try L.pushBuffer(out) else L.pushLString(out);
5153

5254
return 1;
5355
}
5456

5557
pub fn lua_decompress(L: *Luau) !i32 {
5658
const allocator = L.allocator();
5759

58-
const string = L.checkString(1);
60+
const is_buffer = L.typeOf(1) == .buffer;
61+
62+
const string = if (is_buffer) L.checkBuffer(1) else L.checkString(1);
5963

6064
if (string.len < 4) L.raiseErrorStr("InvalidHeader", .{});
6165

@@ -67,7 +71,7 @@ pub fn lua_decompress(L: *Luau) !i32 {
6771
const decompressed = try decoder.decompress(string[4..], sizeHint);
6872
defer allocator.free(decompressed);
6973

70-
L.pushLString(decompressed);
74+
if (is_buffer) try L.pushBuffer(decompressed) else L.pushLString(decompressed);
7175

7276
return 1;
7377
}

src/core/standard/serde/zlib.zig

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ const Luau = luau.Luau;
99
pub fn lua_compress(L: *Luau) !i32 {
1010
const allocator = L.allocator();
1111

12-
const string = L.checkString(1);
12+
const is_buffer = L.typeOf(1) == .buffer;
13+
14+
const string = if (is_buffer) L.checkBuffer(1) else L.checkString(1);
1315
const options = L.typeOf(2);
1416

1517
var level: u4 = 12;
@@ -35,15 +37,18 @@ pub fn lua_compress(L: *Luau) !i32 {
3537
try std.compress.zlib.compress(stream.reader(), buf.writer(), .{
3638
.level = @enumFromInt(level),
3739
});
38-
L.pushLString(buf.items);
40+
41+
if (is_buffer) try L.pushBuffer(buf.items) else L.pushLString(buf.items);
3942

4043
return 1;
4144
}
4245

4346
pub fn lua_decompress(L: *Luau) !i32 {
4447
const allocator = L.allocator();
4548

46-
const string = L.checkString(1);
49+
const is_buffer = L.typeOf(1) == .buffer;
50+
51+
const string = if (is_buffer) L.checkBuffer(1) else L.checkString(1);
4752

4853
var buf = std.ArrayList(u8).init(allocator);
4954
defer buf.deinit();
@@ -52,7 +57,7 @@ pub fn lua_decompress(L: *Luau) !i32 {
5257

5358
try std.compress.zlib.decompress(stream.reader(), buf.writer());
5459

55-
L.pushLString(buf.items);
60+
if (is_buffer) try L.pushBuffer(buf.items) else L.pushLString(buf.items);
5661

5762
return 1;
5863
}

src/types/core/net.luau

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1+
export type WebSocket = NetWebSocket;
2+
export type ServerHandle = NetServerHandle;
3+
export type ClientWebSocket = NetClientWebSocket;
4+
15
export type ServerRequest = {
26
method : string,
37
path : string,
48
headers : {[string] : string},
59
body : string,
610
};
711

8-
export type ServerResponse = string | {
9-
status : number,
10-
headers : {[string] : string},
11-
body : string,
12+
export type ServerResponse = {
13+
statusCode : number,
14+
headers : {[string] : string}?,
15+
body : buffer | string,
1216
}
1317

1418
export type ServerWebSocketHandlers = {
@@ -24,19 +28,19 @@ export type ServerWebSocketHandlers = {
2428
2529
*`WebSocket` class will keep the same reference per connection*.
2630
]]
27-
open : ((websocket: NetWebSocket) -> ())?,
31+
open : ((websocket: WebSocket) -> ())?,
2832
--[[
2933
A function event for when a websocket receives a message.
3034
3135
*`WebSocket` class will keep the same reference per connection*.
3236
]]
33-
message : ((websocket: NetWebSocket, message: string) -> ())?,
37+
message : ((websocket: WebSocket, message: string) -> ())?,
3438
--[[
3539
A function event for when a websocket is closed.
3640
3741
*`WebSocket` class will keep the same reference per connection*.
3842
]]
39-
close : ((websocket: NetWebSocket) -> ())?,
43+
close : ((websocket: WebSocket) -> ())?,
4044
};
4145

4246
export type ServeOptions = {
@@ -62,7 +66,7 @@ export type ServeOptions = {
6266
--[[
6367
The function to handle requests.
6468
]]
65-
request : (request: ServerRequest) -> ServerResponse,
69+
request : (request: ServerRequest) -> buffer | string | ServerResponse,
6670

6771
--[[
6872
Functions to handle websockets.
@@ -104,9 +108,9 @@ local network = {};
104108
105109
@param options The options for the server.
106110
@return boolean Whether the server started successfully.
107-
@return string | NetServerHandle The error message, or the server handle.
111+
@return string | ServerHandle The error message, or the server handle.
108112
]]
109-
network.serve = (nil :: any) :: (options: ServeOptions) -> (boolean, string | NetServerHandle);
113+
network.serve = (nil :: any) :: (options: ServeOptions) -> (boolean, string | ServerHandle);
110114

111115
--[[
112116
Makes a request to the specified host.
@@ -130,8 +134,8 @@ network.request = (nil :: any) :: (host: string, options: RequestOptions?) -> (b
130134
@param host The host to connect to.
131135
@param protocols The protocols to use.
132136
@return boolean Whether the connection was successful.
133-
@return NetClientWebSocket
137+
@return ClientWebSocket
134138
]]
135-
network.websocket = (nil :: any) :: (host: string, protocols: {string}?) -> (boolean, string | NetClientWebSocket);
139+
network.websocket = (nil :: any) :: (host: string, protocols: {string}?) -> (boolean, string | ClientWebSocket);
136140

137141
return network;

src/types/core/serde.luau

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,15 @@ export type GenericCompressor = {
3939
--[[
4040
Compresses a string.
4141
]]
42-
compress : (raw: string, options: GenericCompressionOptions?) -> string,
42+
compress :
43+
& ((raw: string, options: GenericCompressionOptions?) -> string)
44+
& ((raw: buffer, options: GenericCompressionOptions?) -> buffer),
4345
--[[
4446
Decompresses a string.
4547
]]
46-
decompress : (compressed: string) -> string,
48+
decompress :
49+
& (compressed: string) -> string
50+
& (compressed: buffer) -> buffer,
4751
};
4852

4953
local serde = {}

0 commit comments

Comments
 (0)