fediglam/src/http/server.zig

66 lines
2 KiB
Zig
Raw Normal View History

2022-06-23 07:25:50 +00:00
const std = @import("std");
const util = @import("util");
const http = @import("./lib.zig");
2022-07-09 21:18:43 +00:00
const Request = http.Request;
2022-06-26 07:00:14 +00:00
const Connection = http.Connection;
2022-06-23 07:25:50 +00:00
const request_buf_size = 1 << 16;
2022-07-09 21:18:43 +00:00
pub const Context = struct {
alloc: std.mem.Allocator,
request: Request,
connection: Connection,
2022-06-23 07:25:50 +00:00
2022-07-09 21:18:43 +00:00
const Writer = http.ResponseStream(Connection.Writer);
pub fn openResponse(self: *Context, headers: *const http.Headers, status: http.Status) !Writer {
return try http.response_stream.open(self.alloc, self.connection.stream.writer(), headers, status);
}
2022-07-09 22:14:49 +00:00
pub fn close(self: *Context) void {
2022-07-09 21:18:43 +00:00
// todo: deallocate request
2022-07-09 22:14:49 +00:00
self.connection.close();
2022-07-09 21:18:43 +00:00
}
};
const HttpServer = struct {
conn_server: http.ConnectionServer,
pub fn listen(addr: std.net.Address) !HttpServer {
2022-07-09 22:18:48 +00:00
return HttpServer{
2022-07-09 21:18:43 +00:00
.conn_server = try http.ConnectionServer.listen(addr),
};
}
pub fn accept(self: *HttpServer, alloc: std.mem.Allocator) !Context {
while (true) {
const conn = try self.conn_server.accept();
errdefer conn.close();
const req = http.Request.parse(alloc, conn.stream.reader()) catch |err| {
2022-07-09 22:17:44 +00:00
handleError(conn.stream.writer(), err) catch unreachable;
2022-07-09 21:18:43 +00:00
continue;
};
2022-07-09 22:18:48 +00:00
return Context{ .connection = conn, .request = req, .alloc = alloc };
2022-07-09 21:18:43 +00:00
}
}
pub fn shutdown(self: *HttpServer) void {
self.conn_server.shutdown();
}
};
2022-06-23 07:25:50 +00:00
2022-07-09 22:17:44 +00:00
// TODO: We should get more specific about what type of errors can happen
2022-06-26 06:35:31 +00:00
fn handleError(writer: anytype, err: anyerror) !void {
const status: http.Status = switch (err) {
error.BadRequest => .bad_request,
error.UnsupportedMediaType => .unsupported_media_type,
error.HttpVersionNotSupported => .http_version_not_supported,
2022-07-09 22:17:44 +00:00
else => return err,
2022-06-26 06:35:31 +00:00
};
2022-07-09 22:17:44 +00:00
try writer.print("HTTP/1.1 {} {s}\r\n\r\n", .{ @enumToInt(status), status.phrase() });
2022-06-26 06:35:31 +00:00
}