mirror of
https://github.com/jetzig-framework/jetzig.git
synced 2025-05-14 14:06:08 +00:00
WIP
This commit is contained in:
parent
86d82026ab
commit
2072b59937
85
demo/src/app/views/websockets.zig
Normal file
85
demo/src/app/views/websockets.zig
Normal file
@ -0,0 +1,85 @@
|
||||
const std = @import("std");
|
||||
const jetzig = @import("jetzig");
|
||||
|
||||
pub fn index(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View {
|
||||
_ = data;
|
||||
return request.render(.ok);
|
||||
}
|
||||
|
||||
pub fn get(id: []const u8, request: *jetzig.Request, data: *jetzig.Data) !jetzig.View {
|
||||
_ = data;
|
||||
_ = id;
|
||||
return request.render(.ok);
|
||||
}
|
||||
|
||||
pub fn post(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View {
|
||||
_ = data;
|
||||
return request.render(.created);
|
||||
}
|
||||
|
||||
pub fn put(id: []const u8, request: *jetzig.Request, data: *jetzig.Data) !jetzig.View {
|
||||
_ = data;
|
||||
_ = id;
|
||||
return request.render(.ok);
|
||||
}
|
||||
|
||||
pub fn patch(id: []const u8, request: *jetzig.Request, data: *jetzig.Data) !jetzig.View {
|
||||
_ = data;
|
||||
_ = id;
|
||||
return request.render(.ok);
|
||||
}
|
||||
|
||||
pub fn delete(id: []const u8, request: *jetzig.Request, data: *jetzig.Data) !jetzig.View {
|
||||
_ = data;
|
||||
_ = id;
|
||||
return request.render(.ok);
|
||||
}
|
||||
|
||||
|
||||
test "index" {
|
||||
var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
|
||||
defer app.deinit();
|
||||
|
||||
const response = try app.request(.GET, "/websockets", .{});
|
||||
try response.expectStatus(.ok);
|
||||
}
|
||||
|
||||
test "get" {
|
||||
var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
|
||||
defer app.deinit();
|
||||
|
||||
const response = try app.request(.GET, "/websockets/example-id", .{});
|
||||
try response.expectStatus(.ok);
|
||||
}
|
||||
|
||||
test "post" {
|
||||
var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
|
||||
defer app.deinit();
|
||||
|
||||
const response = try app.request(.POST, "/websockets", .{});
|
||||
try response.expectStatus(.created);
|
||||
}
|
||||
|
||||
test "put" {
|
||||
var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
|
||||
defer app.deinit();
|
||||
|
||||
const response = try app.request(.PUT, "/websockets/example-id", .{});
|
||||
try response.expectStatus(.ok);
|
||||
}
|
||||
|
||||
test "patch" {
|
||||
var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
|
||||
defer app.deinit();
|
||||
|
||||
const response = try app.request(.PATCH, "/websockets/example-id", .{});
|
||||
try response.expectStatus(.ok);
|
||||
}
|
||||
|
||||
test "delete" {
|
||||
var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
|
||||
defer app.deinit();
|
||||
|
||||
const response = try app.request(.DELETE, "/websockets/example-id", .{});
|
||||
try response.expectStatus(.ok);
|
||||
}
|
17
demo/src/app/views/websockets/index.zmpl
Normal file
17
demo/src/app/views/websockets/index.zmpl
Normal file
@ -0,0 +1,17 @@
|
||||
@if (context.request) |request|
|
||||
@if (request.headers.get("host")) |host|
|
||||
<script>
|
||||
const websocket = new WebSocket('ws://{{host}}');
|
||||
|
||||
console.log(websocket);
|
||||
|
||||
websocket.addEventListener("message", (event) => {
|
||||
console.log(event.data);
|
||||
});
|
||||
|
||||
websocket.addEventListener("open", (event) => {
|
||||
websocket.send("hello jetzig websocket");
|
||||
});
|
||||
</script>
|
||||
@end
|
||||
@end
|
@ -13,6 +13,7 @@ pub const Response = @import("http/Response.zig");
|
||||
pub const Session = @import("http/Session.zig");
|
||||
pub const Cookies = @import("http/Cookies.zig");
|
||||
pub const Headers = @import("http/Headers.zig");
|
||||
pub const Websocket = @import("http/Websocket.zig");
|
||||
pub const Query = @import("http/Query.zig");
|
||||
pub const MultipartQuery = @import("http/MultipartQuery.zig");
|
||||
pub const File = @import("http/File.zig");
|
||||
|
@ -41,6 +41,12 @@ pub fn get(self: Headers, name: []const u8) ?[]const u8 {
|
||||
return self.httpz_headers.get(lower);
|
||||
}
|
||||
|
||||
/// Get the first value for a given header identified by `name`, which is assumed to be lower case.
|
||||
pub fn getLower(self: Headers, name: []const u8) ?[]const u8 {
|
||||
std.debug.assert(name.len <= max_bytes_header_name);
|
||||
return self.httpz_headers.get(name);
|
||||
}
|
||||
|
||||
/// Get all values for a given header identified by `name`. Names are case insensitive.
|
||||
pub fn getAll(self: Headers, name: []const u8) []const []const u8 {
|
||||
var headers = std.ArrayList([]const u8).init(self.allocator);
|
||||
|
@ -26,6 +26,7 @@ allocator: std.mem.Allocator,
|
||||
path: jetzig.http.Path,
|
||||
method: Method,
|
||||
headers: jetzig.http.Headers,
|
||||
host: []const u8,
|
||||
server: *jetzig.http.Server,
|
||||
httpz_request: *httpz.Request,
|
||||
httpz_response: *httpz.Response,
|
||||
@ -146,12 +147,15 @@ pub fn init(
|
||||
|
||||
const response_data = try allocator.create(jetzig.data.Data);
|
||||
response_data.* = jetzig.data.Data.init(allocator);
|
||||
const headers = jetzig.http.Headers.init(allocator, httpz_request.headers);
|
||||
const host = headers.getLower("host") orelse "";
|
||||
|
||||
return .{
|
||||
.allocator = allocator,
|
||||
.path = path,
|
||||
.method = method,
|
||||
.headers = jetzig.http.Headers.init(allocator, httpz_request.headers),
|
||||
.headers = headers,
|
||||
.host = host,
|
||||
.server = server,
|
||||
.response = response,
|
||||
.response_data = response_data,
|
||||
|
@ -61,10 +61,12 @@ pub fn deinit(self: *Server) void {
|
||||
self.allocator.free(self.env.bind);
|
||||
}
|
||||
|
||||
const Dispatcher = struct {
|
||||
const HttpzHandler = struct {
|
||||
server: *Server,
|
||||
|
||||
pub fn handle(self: Dispatcher, request: *httpz.Request, response: *httpz.Response) void {
|
||||
pub const WebsocketHandler = jetzig.http.Websocket;
|
||||
|
||||
pub fn handle(self: HttpzHandler, request: *httpz.Request, response: *httpz.Response) void {
|
||||
self.server.processNextRequest(request, response) catch |err| {
|
||||
self.server.errorHandlerFn(request, response, err) catch {};
|
||||
};
|
||||
@ -77,7 +79,7 @@ pub fn listen(self: *Server) !void {
|
||||
const worker_count = jetzig.config.get(u16, "worker_count");
|
||||
const thread_count: u16 = jetzig.config.get(?u16, "thread_count") orelse @intCast(try std.Thread.getCpuCount());
|
||||
|
||||
var httpz_server = try httpz.Server(Dispatcher).init(
|
||||
var httpz_server = try httpz.Server(HttpzHandler).init(
|
||||
self.allocator,
|
||||
.{
|
||||
.port = self.env.port,
|
||||
@ -96,7 +98,7 @@ pub fn listen(self: *Server) !void {
|
||||
.max_body_size = jetzig.config.get(usize, "max_bytes_request_body"),
|
||||
},
|
||||
},
|
||||
Dispatcher{ .server = self },
|
||||
HttpzHandler{ .server = self },
|
||||
);
|
||||
defer httpz_server.deinit();
|
||||
|
||||
@ -139,6 +141,11 @@ pub fn processNextRequest(
|
||||
var repo = try self.repo.bindConnect(.{ .allocator = httpz_response.arena });
|
||||
defer repo.release();
|
||||
|
||||
if (try self.upgradeWebsocket(httpz_request, httpz_response)) {
|
||||
try self.logger.DEBUG("Websocket upgrade request successful.", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
var response = try jetzig.http.Response.init(httpz_response.arena, httpz_response);
|
||||
var request = try jetzig.http.Request.init(
|
||||
httpz_response.arena,
|
||||
@ -169,6 +176,14 @@ pub fn processNextRequest(
|
||||
try self.logger.logRequest(&request);
|
||||
}
|
||||
|
||||
fn upgradeWebsocket(self: *const Server, httpz_request: *httpz.Request, httpz_response: *httpz.Response) !bool {
|
||||
return try httpz.upgradeWebsocket(
|
||||
jetzig.http.Websocket,
|
||||
httpz_request,
|
||||
httpz_response,
|
||||
jetzig.http.Websocket.Context{ .allocator = self.allocator },
|
||||
);
|
||||
}
|
||||
fn maybeMiddlewareRender(request: *jetzig.http.Request, response: *const jetzig.http.Response) !bool {
|
||||
if (request.middleware_rendered) |_| {
|
||||
// Request processing ends when a middleware renders or redirects.
|
||||
|
24
src/jetzig/http/Websocket.zig
Normal file
24
src/jetzig/http/Websocket.zig
Normal file
@ -0,0 +1,24 @@
|
||||
const std = @import("std");
|
||||
|
||||
const httpz = @import("httpz");
|
||||
|
||||
pub const Context = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
};
|
||||
|
||||
const Websocket = @This();
|
||||
|
||||
connection: *httpz.websocket.Conn,
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
pub fn init(connection: *httpz.websocket.Conn, context: Context) !Websocket {
|
||||
return .{
|
||||
.connection = connection,
|
||||
.allocator = context.allocator,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn clientMessage(self: *Websocket, data: []const u8) !void {
|
||||
const message = try std.mem.concat(self.allocator, u8, &.{ "Hello from Jetzig websocket. Your message was: ", data });
|
||||
try self.connection.write(message);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user