mirror of
https://github.com/jetzig-framework/jetzig.git
synced 2025-05-15 06:26:07 +00:00
Refactor response interface
Create `jetzig.http.Response` when `std.http.Server.Response` is created and delegate all management of `std.http.Server.Response` to `jetzig.http.Response`. Using this internally means we use the same internal interface for the `Response` as the user, which gives us things like response headers management in views for free (user simply calls `request.response.headers.append()` etc.).
This commit is contained in:
parent
2ebb644421
commit
a07c71e725
@ -16,9 +16,9 @@ pub fn beforeRequest(self: *Self, request: *jetzig.http.Request) !void {
|
|||||||
self.my_data = 43;
|
self.my_data = 43;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn afterRequest(self: *Self, request: *jetzig.http.Request, result: *jetzig.caches.Result) !void {
|
pub fn afterRequest(self: *Self, request: *jetzig.http.Request, response: *jetzig.http.Response) !void {
|
||||||
request.server.logger.debug("[middleware] After request, custom data: {d}", .{self.my_data});
|
request.server.logger.debug("[middleware] After request, custom data: {d}", .{self.my_data});
|
||||||
request.server.logger.debug("[middleware] content-type: {s}", .{result.value.content_type});
|
request.server.logger.debug("[middleware] content-type: {s}", .{response.content_type});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Self, request: *jetzig.http.Request) void {
|
pub fn deinit(self: *Self, request: *jetzig.http.Request) void {
|
||||||
|
@ -1,20 +1,24 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
headers: std.http.Headers,
|
std_headers: std.http.Headers,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, headers: std.http.Headers) Self {
|
pub fn init(allocator: std.mem.Allocator, headers: std.http.Headers) Self {
|
||||||
return .{ .allocator = allocator, .headers = headers };
|
return .{ .allocator = allocator, .std_headers = headers };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *Self) void {
|
||||||
|
self.std_headers.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getFirstValue(self: *Self, key: []const u8) ?[]const u8 {
|
pub fn getFirstValue(self: *Self, key: []const u8) ?[]const u8 {
|
||||||
return self.headers.getFirstValue(key);
|
return self.std_headers.getFirstValue(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append(self: *Self, key: []const u8, value: []const u8) !void {
|
pub fn append(self: *Self, key: []const u8, value: []const u8) !void {
|
||||||
try self.headers.append(key, value);
|
try self.std_headers.append(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
@ -16,6 +16,7 @@ headers: jetzig.http.Headers,
|
|||||||
segments: std.ArrayList([]const u8),
|
segments: std.ArrayList([]const u8),
|
||||||
server: *jetzig.http.Server,
|
server: *jetzig.http.Server,
|
||||||
session: *jetzig.http.Session,
|
session: *jetzig.http.Session,
|
||||||
|
response: *jetzig.http.Response,
|
||||||
status_code: jetzig.http.status_codes.StatusCode = undefined,
|
status_code: jetzig.http.status_codes.StatusCode = undefined,
|
||||||
response_data: *jetzig.data.Data,
|
response_data: *jetzig.data.Data,
|
||||||
query_data: *jetzig.data.Data,
|
query_data: *jetzig.data.Data,
|
||||||
@ -26,10 +27,10 @@ body: []const u8,
|
|||||||
pub fn init(
|
pub fn init(
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
server: *jetzig.http.Server,
|
server: *jetzig.http.Server,
|
||||||
response: *std.http.Server.Response,
|
response: *jetzig.http.Response,
|
||||||
body: []const u8,
|
body: []const u8,
|
||||||
) !Self {
|
) !Self {
|
||||||
const method = switch (response.request.method) {
|
const method = switch (response.std_response.request.method) {
|
||||||
.DELETE => Method.DELETE,
|
.DELETE => Method.DELETE,
|
||||||
.GET => Method.GET,
|
.GET => Method.GET,
|
||||||
.PATCH => Method.PATCH,
|
.PATCH => Method.PATCH,
|
||||||
@ -42,14 +43,14 @@ pub fn init(
|
|||||||
_ => return error.JetzigUnsupportedHttpMethod,
|
_ => return error.JetzigUnsupportedHttpMethod,
|
||||||
};
|
};
|
||||||
|
|
||||||
var it = std.mem.splitScalar(u8, response.request.target, '/');
|
var it = std.mem.splitScalar(u8, response.std_response.request.target, '/');
|
||||||
var segments = std.ArrayList([]const u8).init(allocator);
|
var segments = std.ArrayList([]const u8).init(allocator);
|
||||||
while (it.next()) |segment| try segments.append(segment);
|
while (it.next()) |segment| try segments.append(segment);
|
||||||
|
|
||||||
var cookies = try allocator.create(jetzig.http.Cookies);
|
var cookies = try allocator.create(jetzig.http.Cookies);
|
||||||
cookies.* = jetzig.http.Cookies.init(
|
cookies.* = jetzig.http.Cookies.init(
|
||||||
allocator,
|
allocator,
|
||||||
response.request.headers.getFirstValue("Cookie") orelse "",
|
response.std_response.request.headers.getFirstValue("Cookie") orelse "",
|
||||||
);
|
);
|
||||||
try cookies.parse();
|
try cookies.parse();
|
||||||
|
|
||||||
@ -75,9 +76,9 @@ pub fn init(
|
|||||||
|
|
||||||
return .{
|
return .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.path = response.request.target,
|
.path = response.std_response.request.target,
|
||||||
.method = method,
|
.method = method,
|
||||||
.headers = jetzig.http.Headers.init(allocator, response.request.headers),
|
.headers = jetzig.http.Headers.init(allocator, response.std_response.request.headers),
|
||||||
.server = server,
|
.server = server,
|
||||||
.segments = segments,
|
.segments = segments,
|
||||||
.cookies = cookies,
|
.cookies = cookies,
|
||||||
@ -86,6 +87,7 @@ pub fn init(
|
|||||||
.query_data = query_data,
|
.query_data = query_data,
|
||||||
.query = query,
|
.query = query,
|
||||||
.body = body,
|
.body = body,
|
||||||
|
.response = response,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,34 +1,82 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const jetzig = @import("../../jetzig.zig");
|
||||||
const http = @import("../http.zig");
|
const http = @import("../http.zig");
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
std_response: *std.http.Server.Response,
|
||||||
|
headers: *jetzig.http.Headers,
|
||||||
content: []const u8,
|
content: []const u8,
|
||||||
status_code: http.status_codes.StatusCode,
|
status_code: http.status_codes.StatusCode,
|
||||||
content_type: []const u8,
|
content_type: []const u8,
|
||||||
|
|
||||||
pub fn init(
|
pub fn init(
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
content: []const u8,
|
std_response: *std.http.Server.Response,
|
||||||
status_code: http.status_codes.StatusCode,
|
) !Self {
|
||||||
content_type: []const u8,
|
const headers = try allocator.create(jetzig.http.Headers);
|
||||||
) Self {
|
headers.* = jetzig.http.Headers.init(allocator, std_response.headers);
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.status_code = status_code,
|
|
||||||
.content = content,
|
|
||||||
.content_type = content_type,
|
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
|
.std_response = std_response,
|
||||||
|
.status_code = .no_content,
|
||||||
|
.content_type = "application/octet-stream",
|
||||||
|
.content = "",
|
||||||
|
.headers = headers,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *const Self) void {
|
pub fn deinit(self: *const Self) void {
|
||||||
_ = self;
|
self.headers.deinit();
|
||||||
// self.allocator.free(self.content);
|
// self.allocator.free(self.content);
|
||||||
// self.allocator.free(self.content_type);
|
// self.allocator.free(self.content_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ResetState = enum { reset, closing };
|
||||||
|
|
||||||
|
/// Resets the current connection.
|
||||||
|
pub fn reset(self: *const Self) ResetState {
|
||||||
|
return switch (self.std_response.reset()) {
|
||||||
|
.reset => .reset,
|
||||||
|
.closing => .closing,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Waits for the current request to finish sending.
|
||||||
|
pub fn wait(self: *const Self) !void {
|
||||||
|
try self.std_response.wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn finish(self: *const Self) !void {
|
||||||
|
self.std_response.status = switch (self.status_code) {
|
||||||
|
inline else => |status_code| @field(std.http.Status, @tagName(status_code)),
|
||||||
|
};
|
||||||
|
|
||||||
|
try self.std_response.send();
|
||||||
|
try self.std_response.writeAll(self.content);
|
||||||
|
try self.std_response.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads the current request body. Caller owns memory.
|
||||||
|
pub fn read(self: *const Self) ![]const u8 {
|
||||||
|
return try self.std_response.reader().readAllAlloc(self.allocator, jetzig.config.max_bytes_request_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
const TransferEncodingOptions = struct {
|
||||||
|
content_length: usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Sets the transfer encoding for the current response (content length/chunked encoding).
|
||||||
|
/// ```
|
||||||
|
/// setTransferEncoding(.{ .content_length = 1000 });
|
||||||
|
/// ```
|
||||||
|
pub fn setTransferEncoding(self: *const Self, transfer_encoding: TransferEncodingOptions) void {
|
||||||
|
// TODO: Chunked encoding
|
||||||
|
self.std_response.transfer_encoding = .{ .content_length = transfer_encoding.content_length };
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dupe(self: *const Self) !Self {
|
pub fn dupe(self: *const Self) !Self {
|
||||||
return .{
|
return .{
|
||||||
.allocator = self.allocator,
|
.allocator = self.allocator,
|
||||||
|
@ -67,7 +67,12 @@ pub fn listen(self: *Self) !void {
|
|||||||
|
|
||||||
fn processRequests(self: *Self) !void {
|
fn processRequests(self: *Self) !void {
|
||||||
while (true) {
|
while (true) {
|
||||||
var response = try self.server.accept(.{ .allocator = self.allocator });
|
var std_response = try self.server.accept(.{ .allocator = self.allocator });
|
||||||
|
|
||||||
|
var response = try jetzig.http.Response.init(
|
||||||
|
self.allocator,
|
||||||
|
&std_response,
|
||||||
|
);
|
||||||
errdefer response.deinit();
|
errdefer response.deinit();
|
||||||
|
|
||||||
try response.headers.append("Connection", "close");
|
try response.headers.append("Connection", "close");
|
||||||
@ -86,12 +91,12 @@ fn processRequests(self: *Self) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn processNextRequest(self: *Self, response: *std.http.Server.Response) !void {
|
fn processNextRequest(self: *Self, response: *jetzig.http.Response) !void {
|
||||||
try response.wait();
|
try response.wait();
|
||||||
|
|
||||||
self.start_time = std.time.nanoTimestamp();
|
self.start_time = std.time.nanoTimestamp();
|
||||||
|
|
||||||
const body = try response.reader().readAllAlloc(self.allocator, jetzig.config.max_bytes_request_body);
|
const body = try response.read();
|
||||||
defer self.allocator.free(body);
|
defer self.allocator.free(body);
|
||||||
|
|
||||||
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
||||||
@ -102,119 +107,97 @@ fn processNextRequest(self: *Self, response: *std.http.Server.Response) !void {
|
|||||||
|
|
||||||
var middleware_data = try jetzig.http.middleware.beforeMiddleware(&request);
|
var middleware_data = try jetzig.http.middleware.beforeMiddleware(&request);
|
||||||
|
|
||||||
var result = try self.pageContent(&request);
|
try self.renderResponse(&request, response);
|
||||||
defer result.deinit();
|
|
||||||
|
|
||||||
try jetzig.http.middleware.afterMiddleware(&middleware_data, &request, &result);
|
try jetzig.http.middleware.afterMiddleware(&middleware_data, &request, response);
|
||||||
|
|
||||||
|
response.setTransferEncoding(.{ .content_length = response.content.len });
|
||||||
|
|
||||||
response.transfer_encoding = .{ .content_length = result.value.content.len };
|
|
||||||
var cookie_it = request.cookies.headerIterator();
|
var cookie_it = request.cookies.headerIterator();
|
||||||
while (try cookie_it.next()) |header| {
|
while (try cookie_it.next()) |header| {
|
||||||
// FIXME: Skip setting cookies that are already present ?
|
// FIXME: Skip setting cookies that are already present ?
|
||||||
try response.headers.append("Set-Cookie", header);
|
try response.headers.append("Set-Cookie", header);
|
||||||
}
|
}
|
||||||
|
|
||||||
try response.headers.append("Content-Type", result.value.content_type);
|
try response.headers.append("Content-Type", response.content_type);
|
||||||
|
|
||||||
response.status = switch (result.value.status_code) {
|
|
||||||
inline else => |status_code| @field(std.http.Status, @tagName(status_code)),
|
|
||||||
};
|
|
||||||
|
|
||||||
try response.send();
|
|
||||||
try response.writeAll(result.value.content);
|
|
||||||
try response.finish();
|
try response.finish();
|
||||||
|
|
||||||
const log_message = try self.requestLogMessage(&request, result);
|
const log_message = try self.requestLogMessage(&request, response);
|
||||||
defer self.allocator.free(log_message);
|
defer self.allocator.free(log_message);
|
||||||
self.logger.debug("{s}", .{log_message});
|
self.logger.debug("{s}", .{log_message});
|
||||||
|
|
||||||
jetzig.http.middleware.deinit(&middleware_data, &request);
|
jetzig.http.middleware.deinit(&middleware_data, &request);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pageContent(self: *Self, request: *jetzig.http.Request) !jetzig.caches.Result {
|
fn renderResponse(self: *Self, request: *jetzig.http.Request, response: *jetzig.http.Response) !void {
|
||||||
const cache_key = try request.hash();
|
|
||||||
|
|
||||||
if (self.cache.get(cache_key)) |item| {
|
|
||||||
return item;
|
|
||||||
} else {
|
|
||||||
const response = try self.renderResponse(request);
|
|
||||||
return try self.cache.put(cache_key, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn renderResponse(self: *Self, request: *jetzig.http.Request) !jetzig.http.Response {
|
|
||||||
const static = self.matchStaticResource(request) catch |err| {
|
const static = self.matchStaticResource(request) catch |err| {
|
||||||
if (isUnhandledError(err)) return err;
|
if (isUnhandledError(err)) return err;
|
||||||
|
|
||||||
const rendered = try self.renderInternalServerError(request, err);
|
const rendered = try self.renderInternalServerError(request, err);
|
||||||
return .{
|
|
||||||
.allocator = self.allocator,
|
response.content = rendered.content;
|
||||||
.status_code = .internal_server_error,
|
response.status_code = .internal_server_error;
|
||||||
.content = rendered.content,
|
response.content_type = "text/html";
|
||||||
.content_type = "text/html",
|
|
||||||
};
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (static) |resource| return try self.renderStatic(request, resource);
|
if (static) |resource| {
|
||||||
|
try renderStatic(resource, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const route = try self.matchRoute(request, false);
|
const route = try self.matchRoute(request, false);
|
||||||
|
|
||||||
switch (request.requestFormat()) {
|
switch (request.requestFormat()) {
|
||||||
.HTML => return self.renderHTML(request, route),
|
.HTML => try self.renderHTML(request, response, route),
|
||||||
.JSON => return self.renderJSON(request, route),
|
.JSON => try self.renderJSON(request, response, route),
|
||||||
.UNKNOWN => return self.renderHTML(request, route),
|
.UNKNOWN => try self.renderHTML(request, response, route),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderStatic(self: *Self, request: *jetzig.http.Request, resource: StaticResource) !jetzig.http.Response {
|
fn renderStatic(resource: StaticResource, response: *jetzig.http.Response) !void {
|
||||||
_ = request;
|
response.status_code = .ok;
|
||||||
return .{
|
response.content = resource.content;
|
||||||
.allocator = self.allocator,
|
response.content_type = resource.mime_type;
|
||||||
.status_code = .ok,
|
|
||||||
.content = resource.content,
|
|
||||||
.content_type = resource.mime_type,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderHTML(
|
fn renderHTML(
|
||||||
self: *Self,
|
self: *Self,
|
||||||
request: *jetzig.http.Request,
|
request: *jetzig.http.Request,
|
||||||
|
response: *jetzig.http.Response,
|
||||||
route: ?jetzig.views.Route,
|
route: ?jetzig.views.Route,
|
||||||
) !jetzig.http.Response {
|
) !void {
|
||||||
if (route) |matched_route| {
|
if (route) |matched_route| {
|
||||||
for (self.templates) |template| {
|
for (self.templates) |template| {
|
||||||
// TODO: Use a hashmap to avoid O(n)
|
// TODO: Use a hashmap to avoid O(n)
|
||||||
if (std.mem.eql(u8, matched_route.template, template.name)) {
|
if (std.mem.eql(u8, matched_route.template, template.name)) {
|
||||||
const rendered = try self.renderView(matched_route, request, template);
|
const rendered = try self.renderView(matched_route, request, template);
|
||||||
return .{
|
response.content = rendered.content;
|
||||||
.allocator = self.allocator,
|
response.status_code = rendered.view.status_code;
|
||||||
.content = rendered.content,
|
response.content_type = "text/html";
|
||||||
.status_code = rendered.view.status_code,
|
return;
|
||||||
.content_type = "text/html",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return .{
|
response.content = "";
|
||||||
.allocator = self.allocator,
|
response.status_code = .not_found;
|
||||||
.content = "",
|
response.content_type = "text/html";
|
||||||
.status_code = .not_found,
|
return;
|
||||||
.content_type = "text/html",
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
return .{
|
response.content = "";
|
||||||
.allocator = self.allocator,
|
response.status_code = .not_found;
|
||||||
.content = "",
|
response.content_type = "text/html";
|
||||||
.status_code = .not_found,
|
|
||||||
.content_type = "text/html",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderJSON(
|
fn renderJSON(
|
||||||
self: *Self,
|
self: *Self,
|
||||||
request: *jetzig.http.Request,
|
request: *jetzig.http.Request,
|
||||||
|
response: *jetzig.http.Response,
|
||||||
route: ?jetzig.views.Route,
|
route: ?jetzig.views.Route,
|
||||||
) !jetzig.http.Response {
|
) !void {
|
||||||
if (route) |matched_route| {
|
if (route) |matched_route| {
|
||||||
const rendered = try self.renderView(matched_route, request, null);
|
const rendered = try self.renderView(matched_route, request, null);
|
||||||
var data = rendered.view.data;
|
var data = rendered.view.data;
|
||||||
@ -222,18 +205,14 @@ fn renderJSON(
|
|||||||
if (data.value) |_| {} else _ = try data.object();
|
if (data.value) |_| {} else _ = try data.object();
|
||||||
try request.headers.append("Content-Type", "application/json");
|
try request.headers.append("Content-Type", "application/json");
|
||||||
|
|
||||||
return .{
|
response.content = try data.toJson();
|
||||||
.allocator = self.allocator,
|
response.status_code = rendered.view.status_code;
|
||||||
.content = try data.toJson(),
|
response.content_type = "application/json";
|
||||||
.status_code = rendered.view.status_code,
|
} else {
|
||||||
.content_type = "application/json",
|
response.content = "";
|
||||||
};
|
response.status_code = .not_found;
|
||||||
} else return .{
|
response.content_type = "application/json";
|
||||||
.allocator = self.allocator,
|
}
|
||||||
.content = "",
|
|
||||||
.status_code = .not_found,
|
|
||||||
.content_type = "application/json",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const RenderedView = struct { view: jetzig.views.View, content: []const u8 };
|
const RenderedView = struct { view: jetzig.views.View, content: []const u8 };
|
||||||
@ -313,8 +292,8 @@ fn logStackTrace(
|
|||||||
try object.put("backtrace", request.response_data.string(array.items));
|
try object.put("backtrace", request.response_data.string(array.items));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn requestLogMessage(self: *Self, request: *jetzig.http.Request, result: jetzig.caches.Result) ![]const u8 {
|
fn requestLogMessage(self: *Self, request: *jetzig.http.Request, response: *jetzig.http.Response) ![]const u8 {
|
||||||
const status: jetzig.http.status_codes.TaggedStatusCode = switch (result.value.status_code) {
|
const status: jetzig.http.status_codes.TaggedStatusCode = switch (response.status_code) {
|
||||||
inline else => |status_code| @unionInit(
|
inline else => |status_code| @unionInit(
|
||||||
jetzig.http.status_codes.TaggedStatusCode,
|
jetzig.http.status_codes.TaggedStatusCode,
|
||||||
@tagName(status_code),
|
@tagName(status_code),
|
||||||
|
@ -40,7 +40,7 @@ pub fn beforeMiddleware(request: *jetzig.http.Request) !MiddlewareData {
|
|||||||
pub fn afterMiddleware(
|
pub fn afterMiddleware(
|
||||||
middleware_data: *MiddlewareData,
|
middleware_data: *MiddlewareData,
|
||||||
request: *jetzig.http.Request,
|
request: *jetzig.http.Request,
|
||||||
result: *jetzig.caches.Result,
|
response: *jetzig.http.Response,
|
||||||
) !void {
|
) !void {
|
||||||
inline for (middlewares, 0..) |middleware, index| {
|
inline for (middlewares, 0..) |middleware, index| {
|
||||||
if (comptime !@hasDecl(middleware, "afterRequest")) continue;
|
if (comptime !@hasDecl(middleware, "afterRequest")) continue;
|
||||||
@ -49,10 +49,10 @@ pub fn afterMiddleware(
|
|||||||
try @call(
|
try @call(
|
||||||
.always_inline,
|
.always_inline,
|
||||||
middleware.afterRequest,
|
middleware.afterRequest,
|
||||||
.{ @as(*middleware, @ptrCast(@alignCast(data))), request, result },
|
.{ @as(*middleware, @ptrCast(@alignCast(data))), request, response },
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
try @call(.always_inline, middleware.afterRequest, .{ request, result });
|
try @call(.always_inline, middleware.afterRequest, .{ request, response });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user