mirror of
https://github.com/zigzap/zap.git
synced 2025-10-21 15:44:10 +00:00
Merge e8d789329a
into 76679f308c
This commit is contained in:
commit
7d168de031
4 changed files with 74 additions and 79 deletions
|
@ -354,12 +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
|
// TODO: let's hope 20k is enough. Maybe just really allocate here
|
||||||
self.h.*.status = errorcode_num;
|
self.h.*.status = errorcode_num;
|
||||||
var buf: [20 * 1024]u8 = undefined;
|
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});
|
try writer.print("ERROR: {any}\n\n", .{err});
|
||||||
|
|
||||||
if (err_trace) |trace| {
|
if (err_trace) |trace| {
|
||||||
const debugInfo = try std.debug.getSelfDebugInfo();
|
const debugInfo = try std.debug.getSelfDebugInfo();
|
||||||
const ttyConfig: std.io.tty.Config = .no_color;
|
const ttyConfig: std.Io.tty.Config = .no_color;
|
||||||
try std.debug.writeStackTrace(trace, &writer, debugInfo, ttyConfig);
|
try std.debug.writeStackTrace(trace, &writer, debugInfo, ttyConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ fn makeRequest(a: std.mem.Allocator, url: []const u8) !void {
|
||||||
var http_client: std.http.Client = .{ .allocator = a };
|
var http_client: std.http.Client = .{ .allocator = a };
|
||||||
defer http_client.deinit();
|
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();
|
defer response_writer.deinit();
|
||||||
|
|
||||||
_ = try http_client.fetch(.{
|
_ = try http_client.fetch(.{
|
||||||
|
|
|
@ -77,7 +77,7 @@ pub fn stringifyBuf(
|
||||||
value: anytype,
|
value: anytype,
|
||||||
options: std.json.Stringify.Options,
|
options: std.json.Stringify.Options,
|
||||||
) ![]const u8 {
|
) ![]const u8 {
|
||||||
var w: std.io.Writer = .fixed(buffer);
|
var w: std.Io.Writer = .fixed(buffer);
|
||||||
if (std.json.Stringify.value(value, options, &w)) {
|
if (std.json.Stringify.value(value, options, &w)) {
|
||||||
return w.buffered();
|
return w.buffered();
|
||||||
} else |err| { // error
|
} else |err| { // error
|
||||||
|
|
55
src/zap.zig
55
src/zap.zig
|
@ -140,8 +140,8 @@ pub const HttpListenerSettings = struct {
|
||||||
on_response: ?HttpRequestFn = null,
|
on_response: ?HttpRequestFn = null,
|
||||||
on_upgrade: ?HttpUpgradeFn = null,
|
on_upgrade: ?HttpUpgradeFn = null,
|
||||||
on_finish: ?HttpFinishFn = null,
|
on_finish: ?HttpFinishFn = null,
|
||||||
// provide any pointer in there for "user data". it will be passed pack in
|
/// User defined data can be extracted in a request handler using `Request.getUserContext(T)`
|
||||||
// on_finish()'s copy of the struct_http_settings_s
|
/// In `on_finish()` it can be extracted using `HttpListener.getUserContext(T, fio.struct_http_settings_s.udata.?)`
|
||||||
udata: ?*anyopaque = null,
|
udata: ?*anyopaque = null,
|
||||||
public_folder: ?[]const u8 = null,
|
public_folder: ?[]const u8 = null,
|
||||||
max_clients: ?isize = null,
|
max_clients: ?isize = null,
|
||||||
|
@ -156,21 +156,27 @@ pub const HttpListenerSettings = struct {
|
||||||
/// Http listener
|
/// Http listener
|
||||||
pub const HttpListener = struct {
|
pub const HttpListener = struct {
|
||||||
settings: HttpListenerSettings,
|
settings: HttpListenerSettings,
|
||||||
|
userData: ?*anyopaque,
|
||||||
|
|
||||||
var the_one_and_only_listener: ?*HttpListener = null;
|
const Self = @This();
|
||||||
|
|
||||||
/// Create a listener
|
/// Create a listener
|
||||||
pub fn init(settings: HttpListenerSettings) HttpListener {
|
pub fn init(settings: HttpListenerSettings) HttpListener {
|
||||||
std.debug.assert(settings.on_request != null);
|
std.debug.assert(settings.on_request != null);
|
||||||
return .{
|
return .{
|
||||||
.settings = settings,
|
.settings = settings,
|
||||||
|
.userData = settings.udata,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// we could make it dynamic by passing a HttpListener via udata
|
pub fn getUserContext(comptime T: type, udata: *anyopaque) ?*T {
|
||||||
|
const self: *Self = @ptrCast(@alignCast(udata));
|
||||||
|
return @ptrCast(@alignCast(self.userData));
|
||||||
|
}
|
||||||
|
|
||||||
/// Used internally: the listener's facilio request callback
|
/// Used internally: the listener's facilio request callback
|
||||||
pub fn theOneAndOnlyRequestCallBack(r: [*c]fio.http_s) callconv(.c) void {
|
pub fn theOneAndOnlyRequestCallBack(r: [*c]fio.http_s) callconv(.c) void {
|
||||||
if (the_one_and_only_listener) |l| {
|
const self: *Self = @ptrCast(@alignCast(r.*.udata.?));
|
||||||
var req: Request = .{
|
var req: Request = .{
|
||||||
.path = util.fio2str(r.*.path),
|
.path = util.fio2str(r.*.path),
|
||||||
.query = util.fio2str(r.*.query),
|
.query = util.fio2str(r.*.query),
|
||||||
|
@ -182,22 +188,21 @@ pub const HttpListener = struct {
|
||||||
};
|
};
|
||||||
req._is_finished = &req._is_finished_request_global;
|
req._is_finished = &req._is_finished_request_global;
|
||||||
|
|
||||||
var user_context: Request.UserContext = .{};
|
var user_context: Request.UserContext = .{ .user_context = self.userData };
|
||||||
req._user_context = &user_context;
|
req._user_context = &user_context;
|
||||||
|
|
||||||
req.markAsFinished(false);
|
req.markAsFinished(false);
|
||||||
std.debug.assert(l.settings.on_request != null);
|
std.debug.assert(self.settings.on_request != null);
|
||||||
if (l.settings.on_request) |on_request| {
|
if (self.settings.on_request) |on_request| {
|
||||||
on_request(req) catch |err| {
|
on_request(req) catch |err| {
|
||||||
Logging.on_uncaught_error("HttpListener on_request", err);
|
Logging.on_uncaught_error("HttpListener on_request", err);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Used internally: the listener's facilio response callback
|
/// Used internally: the listener's facilio response callback
|
||||||
pub fn theOneAndOnlyResponseCallBack(r: [*c]fio.http_s) callconv(.c) void {
|
pub fn theOneAndOnlyResponseCallBack(r: [*c]fio.http_s) callconv(.c) void {
|
||||||
if (the_one_and_only_listener) |l| {
|
const self: *Self = @ptrCast(@alignCast(r.*.udata.?));
|
||||||
var req: Request = .{
|
var req: Request = .{
|
||||||
.path = util.fio2str(r.*.path),
|
.path = util.fio2str(r.*.path),
|
||||||
.query = util.fio2str(r.*.query),
|
.query = util.fio2str(r.*.query),
|
||||||
|
@ -209,18 +214,17 @@ pub const HttpListener = struct {
|
||||||
};
|
};
|
||||||
req._is_finished = &req._is_finished_request_global;
|
req._is_finished = &req._is_finished_request_global;
|
||||||
|
|
||||||
var user_context: Request.UserContext = .{};
|
var user_context: Request.UserContext = .{ .user_context = self.userData };
|
||||||
req._user_context = &user_context;
|
req._user_context = &user_context;
|
||||||
|
|
||||||
l.settings.on_response.?(req) catch |err| {
|
self.settings.on_response.?(req) catch |err| {
|
||||||
Logging.on_uncaught_error("HttpListener on_response", err);
|
Logging.on_uncaught_error("HttpListener on_response", err);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Used internally: the listener's facilio upgrade callback
|
/// Used internally: the listener's facilio upgrade callback
|
||||||
pub fn theOneAndOnlyUpgradeCallBack(r: [*c]fio.http_s, target: [*c]u8, target_len: usize) callconv(.c) void {
|
pub fn theOneAndOnlyUpgradeCallBack(r: [*c]fio.http_s, target: [*c]u8, target_len: usize) callconv(.c) void {
|
||||||
if (the_one_and_only_listener) |l| {
|
const self: *Self = @ptrCast(@alignCast(r.*.udata.?));
|
||||||
var req: Request = .{
|
var req: Request = .{
|
||||||
.path = util.fio2str(r.*.path),
|
.path = util.fio2str(r.*.path),
|
||||||
.query = util.fio2str(r.*.query),
|
.query = util.fio2str(r.*.query),
|
||||||
|
@ -233,23 +237,21 @@ pub const HttpListener = struct {
|
||||||
const zigtarget: []u8 = target[0..target_len];
|
const zigtarget: []u8 = target[0..target_len];
|
||||||
req._is_finished = &req._is_finished_request_global;
|
req._is_finished = &req._is_finished_request_global;
|
||||||
|
|
||||||
var user_context: Request.UserContext = .{};
|
var user_context: Request.UserContext = .{ .user_context = self.userData };
|
||||||
req._user_context = &user_context;
|
req._user_context = &user_context;
|
||||||
|
|
||||||
l.settings.on_upgrade.?(req, zigtarget) catch |err| {
|
self.settings.on_upgrade.?(req, zigtarget) catch |err| {
|
||||||
Logging.on_uncaught_error("HttpListener on_upgrade", err);
|
Logging.on_uncaught_error("HttpListener on_upgrade", err);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Used internally: the listener's facilio finish callback
|
/// Used internally: the listener's facilio finish callback
|
||||||
pub fn theOneAndOnlyFinishCallBack(s: [*c]fio.struct_http_settings_s) callconv(.c) void {
|
pub fn theOneAndOnlyFinishCallBack(s: [*c]fio.struct_http_settings_s) callconv(.c) void {
|
||||||
if (the_one_and_only_listener) |l| {
|
const self: *Self = @ptrCast(@alignCast(s.*.udata.?));
|
||||||
l.settings.on_finish.?(s) catch |err| {
|
self.settings.on_finish.?(s) catch |err| {
|
||||||
Logging.on_uncaught_error("HttpListener on_finish", err);
|
Logging.on_uncaught_error("HttpListener on_finish", err);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Start listening
|
/// Start listening
|
||||||
pub fn listen(self: *HttpListener) !void {
|
pub fn listen(self: *HttpListener) !void {
|
||||||
|
@ -267,7 +269,7 @@ pub const HttpListener = struct {
|
||||||
.on_upgrade = if (self.settings.on_upgrade) |_| HttpListener.theOneAndOnlyUpgradeCallBack else null,
|
.on_upgrade = if (self.settings.on_upgrade) |_| HttpListener.theOneAndOnlyUpgradeCallBack else null,
|
||||||
.on_response = if (self.settings.on_response) |_| HttpListener.theOneAndOnlyResponseCallBack else null,
|
.on_response = if (self.settings.on_response) |_| HttpListener.theOneAndOnlyResponseCallBack else null,
|
||||||
.on_finish = if (self.settings.on_finish) |_| HttpListener.theOneAndOnlyFinishCallBack else null,
|
.on_finish = if (self.settings.on_finish) |_| HttpListener.theOneAndOnlyFinishCallBack else null,
|
||||||
.udata = null,
|
.udata = self,
|
||||||
.public_folder = pfolder,
|
.public_folder = pfolder,
|
||||||
.public_folder_length = pfolder_len,
|
.public_folder_length = pfolder_len,
|
||||||
.max_header_size = 32 * 1024,
|
.max_header_size = 32 * 1024,
|
||||||
|
@ -297,14 +299,6 @@ pub const HttpListener = struct {
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
return error.ListenError;
|
return error.ListenError;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set ourselves up to handle requests:
|
|
||||||
// TODO: do we mind the race condition?
|
|
||||||
// the HttpRequestFn will check if this is null and not process
|
|
||||||
// the request if it isn't set. hence, if started under full load, the
|
|
||||||
// first request(s) might not be serviced, as long as it takes from
|
|
||||||
// fio.http_listen() to here
|
|
||||||
HttpListener.the_one_and_only_listener = self;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -323,6 +317,7 @@ pub const LowLevel = struct {
|
||||||
max_clients: isize = 100,
|
max_clients: isize = 100,
|
||||||
keepalive_timeout_s: u8 = 5,
|
keepalive_timeout_s: u8 = 5,
|
||||||
log: bool = false,
|
log: bool = false,
|
||||||
|
udata: ?*anyopaque = null,
|
||||||
|
|
||||||
/// Create settings with defaults
|
/// Create settings with defaults
|
||||||
pub fn init() ListenSettings {
|
pub fn init() ListenSettings {
|
||||||
|
@ -344,7 +339,7 @@ pub const LowLevel = struct {
|
||||||
.on_upgrade = settings.on_upgrade,
|
.on_upgrade = settings.on_upgrade,
|
||||||
.on_response = settings.on_response,
|
.on_response = settings.on_response,
|
||||||
.on_finish = settings.on_finish,
|
.on_finish = settings.on_finish,
|
||||||
.udata = null,
|
.udata = settings.udata,
|
||||||
.public_folder = pfolder,
|
.public_folder = pfolder,
|
||||||
.public_folder_length = pfolder_len,
|
.public_folder_length = pfolder_len,
|
||||||
.max_header_size = settings.max_header_size,
|
.max_header_size = settings.max_header_size,
|
||||||
|
|
Loading…
Add table
Reference in a new issue