diff --git a/.oms b/.oms new file mode 100644 index 0000000..4788567 --- /dev/null +++ b/.oms @@ -0,0 +1 @@ +PROJECT=rene.zap diff --git a/examples/app/basic.zig b/examples/app/basic.zig index d59b062..bd98350 100644 --- a/examples/app/basic.zig +++ b/examples/app/basic.zig @@ -57,7 +57,7 @@ const SimpleEndpoint = struct { .{ context.db_connection, e.some_data, arena.ptr, thread_id }, ); try r.sendBody(response_text); - std.Thread.sleep(std.time.ns_per_ms * 300); + std.posix.nanosleep(0, std.time.ns_per_ms * 300); } }; diff --git a/examples/cookies/cookies.zig b/examples/cookies/cookies.zig index 148c951..d66b822 100644 --- a/examples/cookies/cookies.zig +++ b/examples/cookies/cookies.zig @@ -16,8 +16,8 @@ pub const std_options: std.Options = .{ }; // We send ourselves a request with a cookie -fn makeRequest(a: std.mem.Allocator, url: []const u8) !void { - var http_client: std.http.Client = .{ .allocator = a }; +fn makeRequest(a: std.mem.Allocator, io: std.Io, url: []const u8) !void { + var http_client: std.http.Client = .{ .allocator = a, .io = io }; defer http_client.deinit(); _ = try http_client.fetch(.{ @@ -29,8 +29,8 @@ fn makeRequest(a: std.mem.Allocator, url: []const u8) !void { }); } -fn makeRequestThread(a: std.mem.Allocator, url: []const u8) !std.Thread { - return try std.Thread.spawn(.{}, makeRequest, .{ a, url }); +fn makeRequestThread(a: std.mem.Allocator, io: std.Io, url: []const u8) !std.Thread { + return try std.Thread.spawn(.{}, makeRequest, .{ a, io, url }); } // here we go @@ -118,7 +118,11 @@ pub fn main() !void { try listener.listen(); std.log.info("\n\nTerminate with CTRL+C", .{}); - const thread = try makeRequestThread(allocator, "http://127.0.0.1:3000"); + var threaded = std.Io.Threaded.init(allocator); + defer threaded.deinit(); + const io = threaded.io(); + + const thread = try makeRequestThread(allocator, io, "http://127.0.0.1:3000"); defer thread.join(); zap.start(.{ .threads = 1, diff --git a/examples/http_params/http_params.zig b/examples/http_params/http_params.zig index 512ec22..7f11325 100644 --- a/examples/http_params/http_params.zig +++ b/examples/http_params/http_params.zig @@ -16,8 +16,8 @@ pub const std_options: std.Options = .{ }; // We send ourselves a request -fn makeRequest(a: std.mem.Allocator, url: []const u8) !void { - var http_client: std.http.Client = .{ .allocator = a }; +fn makeRequest(a: std.mem.Allocator, io: std.Io, url: []const u8) !void { + var http_client: std.http.Client = .{ .allocator = a, .io = io }; defer http_client.deinit(); const response = try http_client.fetch(.{ @@ -31,8 +31,8 @@ fn makeRequest(a: std.mem.Allocator, url: []const u8) !void { } } -fn makeRequestThread(a: std.mem.Allocator, url: []const u8) !std.Thread { - return try std.Thread.spawn(.{}, makeRequest, .{ a, url }); +fn makeRequestThread(a: std.mem.Allocator, io: std.Io, url: []const u8) !std.Thread { + return try std.Thread.spawn(.{}, makeRequest, .{ a, io, url }); } // here we go @@ -138,7 +138,11 @@ pub fn main() !void { try listener.listen(); std.log.info("\n\nTerminate with CTRL+C or by sending query param terminate=true", .{}); - const thread = try makeRequestThread(allocator, "http://127.0.0.1:3000/?one=1&two=2&string=hello+world&float=6.28&bool=true"); + var threaded = std.Io.Threaded.init(allocator); + defer threaded.deinit(); + const io = threaded.io(); + + const thread = try makeRequestThread(allocator, io, "http://127.0.0.1:3000/?one=1&two=2&string=hello+world&float=6.28&bool=true"); defer thread.join(); zap.start(.{ .threads = 1, diff --git a/examples/https/https.zig b/examples/https/https.zig index 2379f3c..b9a3a32 100644 --- a/examples/https/https.zig +++ b/examples/https/https.zig @@ -39,14 +39,21 @@ fn help_and_exit(filename: []const u8, err: anyerror) void { std.process.exit(1); } pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + + var threaded = std.Io.Threaded.init(gpa.allocator()); + defer threaded.deinit(); + const io = threaded.io(); + const CERT_FILE = "mycert.pem"; const KEY_FILE = "mykey.pem"; - std.fs.cwd().access(CERT_FILE, .{}) catch |err| { + std.Io.Dir.cwd().access(io, CERT_FILE, .{}) catch |err| { help_and_exit(CERT_FILE, err); }; - std.fs.cwd().access(KEY_FILE, .{}) catch |err| { + std.Io.Dir.cwd().access(io, KEY_FILE, .{}) catch |err| { help_and_exit(KEY_FILE, err); }; diff --git a/src/http_auth.zig b/src/http_auth.zig index ee5a70b..8d1fe55 100644 --- a/src/http_auth.zig +++ b/src/http_auth.zig @@ -589,7 +589,8 @@ pub fn UserPassSession(comptime Lookup: type, comptime lockedPwLookups: bool) ty hasher.update(username); hasher.update(password); var buf: [16]u8 = undefined; - const time_nano = std.time.nanoTimestamp(); + const instant = std.time.Instant.now() catch unreachable; + const time_nano: i128 = @as(i128, instant.timestamp.sec) * std.time.ns_per_s + instant.timestamp.nsec; const timestampHex = try std.fmt.bufPrint(&buf, "{0x}", .{time_nano}); hasher.update(timestampHex); diff --git a/src/request.zig b/src/request.zig index 8ddb904..2961b6f 100644 --- a/src/request.zig +++ b/src/request.zig @@ -354,13 +354,12 @@ pub fn _internal_sendError(self: *const Request, err: anyerror, err_trace: ?std. // TODO: let's hope 20k is enough. Maybe just really allocate here self.h.*.status = errorcode_num; var buf: [20 * 1024]u8 = undefined; - var writer = std.io.Writer.fixed(&buf); + var writer = std.Io.Writer.fixed(&buf); try writer.print("ERROR: {any}\n\n", .{err}); - if (err_trace) |trace| { - const debugInfo = try std.debug.getSelfDebugInfo(); - const ttyConfig: std.io.tty.Config = .no_color; - try std.debug.writeStackTrace(trace, &writer, debugInfo, ttyConfig); + if (err_trace) |*trace| { + const ttyConfig: std.Io.tty.Config = .no_color; + try std.debug.writeStackTrace(trace, &writer, ttyConfig); } try self.sendBody(writer.buffered()); diff --git a/src/tests/test_auth.zig b/src/tests/test_auth.zig index ec87be2..836cc6c 100644 --- a/src/tests/test_auth.zig +++ b/src/tests/test_auth.zig @@ -110,8 +110,8 @@ const ClientAuthReqHeaderFields = struct { token: []const u8, }; -fn makeRequest(a: std.mem.Allocator, url: []const u8, auth: ?ClientAuthReqHeaderFields) !void { - var http_client: std.http.Client = .{ .allocator = a }; +fn makeRequest(a: std.mem.Allocator, io: std.Io, url: []const u8, auth: ?ClientAuthReqHeaderFields) !void { + var http_client: std.http.Client = .{ .allocator = a, .io = io }; defer http_client.deinit(); var auth_buf: [256]u8 = undefined; @@ -143,8 +143,8 @@ fn makeRequest(a: std.mem.Allocator, url: []const u8, auth: ?ClientAuthReqHeader zap.stop(); } -fn makeRequestThread(a: std.mem.Allocator, url: []const u8, auth: ?ClientAuthReqHeaderFields) !std.Thread { - return try std.Thread.spawn(.{}, makeRequest, .{ a, url, auth }); +fn makeRequestThread(a: std.mem.Allocator, io: std.Io, url: []const u8, auth: ?ClientAuthReqHeaderFields) !std.Thread { + return try std.Thread.spawn(.{}, makeRequest, .{ a, io, url, auth }); } pub const Endpoint = struct { @@ -154,7 +154,7 @@ pub const Endpoint = struct { pub fn get(_: *Endpoint, r: zap.Request) !void { r.sendBody(HTTP_RESPONSE) catch return; received_response = HTTP_RESPONSE; - std.Thread.sleep(1 * std.time.ns_per_s); + std.posix.nanosleep(1, 0); zap.stop(); } @@ -162,7 +162,7 @@ pub const Endpoint = struct { r.setStatus(.unauthorized); r.sendBody("UNAUTHORIZED ACCESS") catch return; received_response = "UNAUTHORIZED"; - std.Thread.sleep(1 * std.time.ns_per_s); + std.posix.nanosleep(1, 0); zap.stop(); } }; @@ -205,7 +205,11 @@ test "BearerAuthSingle authenticateRequest OK" { listener.listen() catch {}; - const thread = try makeRequestThread(a, "http://127.0.0.1:3001/test", .{ .auth = .Bearer, .token = token }); + var threaded = std.Io.Threaded.init(a); + defer threaded.deinit(); + const io = threaded.io(); + + const thread = try makeRequestThread(a, io, "http://127.0.0.1:3001/test", .{ .auth = .Bearer, .token = token }); defer thread.join(); // start worker threads @@ -258,7 +262,11 @@ test "BearerAuthSingle authenticateRequest test-unauthorized" { try listener.listen(); - const thread = try makeRequestThread(a, "http://127.0.0.1:3002/test", .{ .auth = .Bearer, .token = "invalid" }); + var threaded = std.Io.Threaded.init(a); + defer threaded.deinit(); + const io = threaded.io(); + + const thread = try makeRequestThread(a, io, "http://127.0.0.1:3002/test", .{ .auth = .Bearer, .token = "invalid" }); defer thread.join(); // start worker threads @@ -305,7 +313,11 @@ test "BearerAuthMulti authenticateRequest OK" { try listener.listen(); - const thread = try makeRequestThread(a, "http://127.0.0.1:3003/test", .{ .auth = .Bearer, .token = token }); + var threaded = std.Io.Threaded.init(a); + defer threaded.deinit(); + const io = threaded.io(); + + const thread = try makeRequestThread(a, io, "http://127.0.0.1:3003/test", .{ .auth = .Bearer, .token = token }); defer thread.join(); // start worker threads @@ -352,7 +364,11 @@ test "BearerAuthMulti authenticateRequest test-unauthorized" { listener.listen() catch {}; - const thread = try makeRequestThread(a, "http://127.0.0.1:3004/test", .{ .auth = .Bearer, .token = "invalid" }); + var threaded = std.Io.Threaded.init(a); + defer threaded.deinit(); + const io = threaded.io(); + + const thread = try makeRequestThread(a, io, "http://127.0.0.1:3004/test", .{ .auth = .Bearer, .token = "invalid" }); defer thread.join(); // start worker threads @@ -404,7 +420,11 @@ test "BasicAuth Token68 authenticateRequest" { listener.listen() catch {}; - const thread = try makeRequestThread(a, "http://127.0.0.1:3005/test", .{ .auth = .Basic, .token = token }); + var threaded = std.Io.Threaded.init(a); + defer threaded.deinit(); + const io = threaded.io(); + + const thread = try makeRequestThread(a, io, "http://127.0.0.1:3005/test", .{ .auth = .Basic, .token = token }); defer thread.join(); // start worker threads @@ -456,7 +476,11 @@ test "BasicAuth Token68 authenticateRequest test-unauthorized" { listener.listen() catch {}; - const thread = try makeRequestThread(a, "http://127.0.0.1:3006/test", .{ .auth = .Basic, .token = "invalid" }); + var threaded = std.Io.Threaded.init(a); + defer threaded.deinit(); + const io = threaded.io(); + + const thread = try makeRequestThread(a, io, "http://127.0.0.1:3006/test", .{ .auth = .Basic, .token = "invalid" }); defer thread.join(); // start worker threads @@ -518,7 +542,11 @@ test "BasicAuth UserPass authenticateRequest" { listener.listen() catch {}; - const thread = try makeRequestThread(a, "http://127.0.0.1:3007/test", .{ .auth = .Basic, .token = encoded }); + var threaded = std.Io.Threaded.init(a); + defer threaded.deinit(); + const io = threaded.io(); + + const thread = try makeRequestThread(a, io, "http://127.0.0.1:3007/test", .{ .auth = .Basic, .token = encoded }); defer thread.join(); // start worker threads @@ -583,7 +611,11 @@ test "BasicAuth UserPass authenticateRequest test-unauthorized" { listener.listen() catch {}; - const thread = try makeRequestThread(a, "http://127.0.0.1:3008/test", .{ .auth = .Basic, .token = "invalid" }); + var threaded = std.Io.Threaded.init(a); + defer threaded.deinit(); + const io = threaded.io(); + + const thread = try makeRequestThread(a, io, "http://127.0.0.1:3008/test", .{ .auth = .Basic, .token = "invalid" }); defer thread.join(); // start worker threads diff --git a/src/tests/test_http_params.zig b/src/tests/test_http_params.zig index eefb76e..5cb75e7 100644 --- a/src/tests/test_http_params.zig +++ b/src/tests/test_http_params.zig @@ -9,8 +9,8 @@ pub const std_options: std.Options = .{ }, }; -fn makeRequest(a: std.mem.Allocator, url: []const u8) !void { - var http_client: std.http.Client = .{ .allocator = a }; +fn makeRequest(a: std.mem.Allocator, io: std.Io, url: []const u8) !void { + var http_client: std.http.Client = .{ .allocator = a, .io = io }; defer http_client.deinit(); _ = try http_client.fetch(.{ @@ -20,8 +20,8 @@ fn makeRequest(a: std.mem.Allocator, url: []const u8) !void { zap.stop(); } -fn makeRequestThread(a: std.mem.Allocator, url: []const u8) !std.Thread { - return try std.Thread.spawn(.{}, makeRequest, .{ a, url }); +fn makeRequestThread(a: std.mem.Allocator, io: std.Io, url: []const u8) !std.Thread { + return try std.Thread.spawn(.{}, makeRequest, .{ a, io, url }); } test "http parameters" { @@ -74,7 +74,11 @@ test "http parameters" { ); try listener.listen(); - const thread = try makeRequestThread(allocator, "http://127.0.0.1:3010/?one=1&two=2&string=hello+world&float=6.28&bool=true"); + var threaded = std.Io.Threaded.init(allocator); + defer threaded.deinit(); + const io = threaded.io(); + + const thread = try makeRequestThread(allocator, io, "http://127.0.0.1:3010/?one=1&two=2&string=hello+world&float=6.28&bool=true"); defer thread.join(); zap.start(.{ .threads = 1, diff --git a/src/tests/test_recvfile.zig b/src/tests/test_recvfile.zig index e2da327..802020c 100644 --- a/src/tests/test_recvfile.zig +++ b/src/tests/test_recvfile.zig @@ -18,8 +18,8 @@ const EXPECTED_FILENAME = "myfile.txt"; var test_error: ?anyerror = null; -fn makeRequest(allocator: std.mem.Allocator, url: []const u8) !void { - var http_client: std.http.Client = .{ .allocator = allocator }; +fn makeRequest(allocator: std.mem.Allocator, io: std.Io, url: []const u8) !void { + var http_client: std.http.Client = .{ .allocator = allocator, .io = io }; defer http_client.deinit(); const payload_wrong_line_ending = try std.fmt.allocPrint(allocator, @@ -117,7 +117,11 @@ test "recv file" { ); try listener.listen(); - const t1 = try std.Thread.spawn(.{}, makeRequest, .{ allocator, "http://127.0.0.1:3020" }); + var threaded = std.Io.Threaded.init(allocator); + defer threaded.deinit(); + const io = threaded.io(); + + const t1 = try std.Thread.spawn(.{}, makeRequest, .{ allocator, io, "http://127.0.0.1:3020" }); defer t1.join(); zap.start(.{ diff --git a/src/tests/test_recvfile_notype.zig b/src/tests/test_recvfile_notype.zig index aa4162c..03eff1e 100644 --- a/src/tests/test_recvfile_notype.zig +++ b/src/tests/test_recvfile_notype.zig @@ -17,8 +17,8 @@ const EXPECTED_FILENAME = "myfile.txt"; var test_error: ?anyerror = null; -fn makeRequest(allocator: std.mem.Allocator, url: []const u8) !void { - var http_client: std.http.Client = .{ .allocator = allocator }; +fn makeRequest(allocator: std.mem.Allocator, io: std.Io, url: []const u8) !void { + var http_client: std.http.Client = .{ .allocator = allocator, .io = io }; defer http_client.deinit(); const payload_wrong_line_ending = try std.fmt.allocPrint(allocator, @@ -115,7 +115,11 @@ test "recv file" { ); try listener.listen(); - const t1 = try std.Thread.spawn(.{}, makeRequest, .{ allocator, "http://127.0.0.1:3030" }); + var threaded = std.Io.Threaded.init(allocator); + defer threaded.deinit(); + const io = threaded.io(); + + const t1 = try std.Thread.spawn(.{}, makeRequest, .{ allocator, io, "http://127.0.0.1:3030" }); defer t1.join(); zap.start(.{ diff --git a/src/tests/test_sendfile.zig b/src/tests/test_sendfile.zig index f13cbdd..288a8cd 100644 --- a/src/tests/test_sendfile.zig +++ b/src/tests/test_sendfile.zig @@ -14,11 +14,11 @@ var read_len: ?usize = null; const testfile = @embedFile("testfile.txt"); -fn makeRequest(a: std.mem.Allocator, url: []const u8) !void { - var http_client: std.http.Client = .{ .allocator = a }; +fn makeRequest(a: std.mem.Allocator, io: std.Io, url: []const u8) !void { + var http_client: std.http.Client = .{ .allocator = a, .io = io }; defer http_client.deinit(); - var response_writer = std.io.Writer.Allocating.init(a); + var response_writer = std.Io.Writer.Allocating.init(a); defer response_writer.deinit(); _ = try http_client.fetch(.{ @@ -33,8 +33,8 @@ fn makeRequest(a: std.mem.Allocator, url: []const u8) !void { zap.stop(); } -fn makeRequestThread(a: std.mem.Allocator, url: []const u8) !std.Thread { - return try std.Thread.spawn(.{}, makeRequest, .{ a, url }); +fn makeRequestThread(a: std.mem.Allocator, io: std.Io, url: []const u8) !std.Thread { + return try std.Thread.spawn(.{}, makeRequest, .{ a, io, url }); } pub fn on_request(r: zap.Request) !void { r.sendFile("src/tests/testfile.txt") catch unreachable; @@ -55,7 +55,11 @@ test "send file" { ); try listener.listen(); - const thread = try makeRequestThread(allocator, "http://127.0.0.1:3040/?file=src/tests/testfile.txt"); + var threaded = std.Io.Threaded.init(allocator); + defer threaded.deinit(); + const io = threaded.io(); + + const thread = try makeRequestThread(allocator, io, "http://127.0.0.1:3040/?file=src/tests/testfile.txt"); defer thread.join(); zap.start(.{ .threads = 1, diff --git a/src/util.zig b/src/util.zig index 27e86d8..b3e4e07 100644 --- a/src/util.zig +++ b/src/util.zig @@ -77,7 +77,7 @@ pub fn stringifyBuf( value: anytype, options: std.json.Stringify.Options, ) ![]const u8 { - var w: std.io.Writer = .fixed(buffer); + var w = std.Io.Writer.fixed(buffer); if (std.json.Stringify.value(value, options, &w)) { return w.buffered(); } else |err| { // error diff --git a/src/zap.zig b/src/zap.zig index 4e20ddd..0b3d5fb 100644 --- a/src/zap.zig +++ b/src/zap.zig @@ -288,7 +288,7 @@ pub const HttpListener = struct { // in debug2 and debug3 of hello example // std.debug.print("X\n", .{}); // TODO: still happening? - std.Thread.sleep(500 * std.time.ns_per_ms); + std.posix.nanosleep(0, 500 * std.time.ns_per_ms); var portbuf: [100]u8 = undefined; const printed_port = try std.fmt.bufPrintZ(&portbuf, "{d}", .{self.settings.port}); @@ -364,7 +364,7 @@ pub const LowLevel = struct { // in debug2 and debug3 of hello example // std.debug.print("X\n", .{}); // TODO: still happening? - std.Thread.sleep(500 * std.time.ns_per_ms); + std.posix.nanosleep(0, 500 * std.time.ns_per_ms); if (fio.http_listen(port, interface, x) == -1) { return error.ListenError; diff --git a/tools/announceybot.zig b/tools/announceybot.zig index 9fa8b96..f03f918 100644 --- a/tools/announceybot.zig +++ b/tools/announceybot.zig @@ -57,7 +57,10 @@ pub fn main() !void { } if (std.mem.eql(u8, command, "announce")) { - return command_announce(gpa, tagname); + var threaded = std.Io.Threaded.init(gpa); + defer threaded.deinit(); + const io = threaded.io(); + return command_announce(gpa, io, tagname); } if (std.mem.eql(u8, command, "release-notes")) { @@ -121,10 +124,9 @@ fn renderTemplate(allocator: std.mem.Allocator, template: []const u8, substitute return try std.mem.replaceOwned(u8, allocator, s1, "{annotation}", the_anno); } -fn sendToDiscordPart(allocator: std.mem.Allocator, url: []const u8, message_json: []const u8) !void { - +fn sendToDiscordPart(allocator: std.mem.Allocator, io: std.Io, url: []const u8, message_json: []const u8) !void { // client - var http_client: std.http.Client = .{ .allocator = allocator }; + var http_client: std.http.Client = .{ .allocator = allocator, .io = io }; const response = try http_client.fetch(.{ .location = .{ .url = url }, @@ -139,18 +141,18 @@ fn sendToDiscordPart(allocator: std.mem.Allocator, url: []const u8, message_json } } -fn sendToDiscord(allocator: std.mem.Allocator, url: []const u8, message: []const u8) !void { +fn sendToDiscord(allocator: std.mem.Allocator, io: std.Io, url: []const u8, message: []const u8) !void { // json payload // max size: 100kB const buf: []u8 = try allocator.alloc(u8, 100 * 1024); defer allocator.free(buf); - var w: std.io.Writer = .fixed(buf); + var w = std.Io.Writer.fixed(buf); try std.json.Stringify.value(.{ .content = message }, .{}, &w); const string = w.buffered(); // We need to split shit into max 2000 characters if (string.len < 1999) { - try sendToDiscordPart(allocator, url, string); + try sendToDiscordPart(allocator, io, url, string); return; } @@ -263,18 +265,18 @@ fn sendToDiscord(allocator: std.mem.Allocator, url: []const u8, message: []const const desc = chunks.items[it]; const part = message[desc.from..desc.to]; - var ww: std.io.Writer = .fixed(buf); + var ww = std.Io.Writer.fixed(buf); try std.json.Stringify.value(.{ .content = part }, .{}, &ww); const part_string = ww.buffered(); std.debug.print("SENDING PART {d} / {d}: ... ", .{ it, chunks.items.len }); - try sendToDiscordPart(allocator, url, part_string); + try sendToDiscordPart(allocator, io, url, part_string); std.debug.print("done!\n", .{}); it += 1; } } -fn command_announce(allocator: std.mem.Allocator, tag: []const u8) !void { +fn command_announce(allocator: std.mem.Allocator, io: std.Io, tag: []const u8) !void { const annotation = try get_tag_annotation(allocator, tag); defer allocator.free(annotation); @@ -287,7 +289,7 @@ fn command_announce(allocator: std.mem.Allocator, tag: []const u8) !void { defer allocator.free(announcement); const url = try std.process.getEnvVarOwned(allocator, "WEBHOOK_URL"); defer allocator.free(url); - sendToDiscord(allocator, url, announcement) catch |err| { + sendToDiscord(allocator, io, url, announcement) catch |err| { std.debug.print("HTTP ERROR: {any}\n", .{err}); std.process.exit(1); }; @@ -320,7 +322,7 @@ fn command_update_readme(allocator: std.mem.Allocator, tag: []const u8) !void { defer allocator.free(update_part); // read the readme - const readme = try std.fs.cwd().readFileAlloc(allocator, README_PATH, README_MAX_SIZE); + const readme = try std.fs.cwd().readFileAlloc(README_PATH, allocator, std.Io.Limit.limited(README_MAX_SIZE)); defer allocator.free(readme); var output_file = try std.fs.cwd().createFile(README_PATH, .{});