aboutsummaryrefslogtreecommitdiff
path: root/comments
diff options
context:
space:
mode:
authorMartin Ashby <martin@ashbysoft.com>2024-02-18 20:28:55 +0000
committerMartin Ashby <martin@ashbysoft.com>2024-02-18 20:28:55 +0000
commit0284553f75fd927091dc35c502e37df856af05b6 (patch)
tree9a1e39957d7d07a0adc19fddfabbb983d4d00866 /comments
parent3395a562c419c60d046cdc295a88b759d4bc87fd (diff)
downloadmfashby.net-0284553f75fd927091dc35c502e37df856af05b6.tar.gz
mfashby.net-0284553f75fd927091dc35c502e37df856af05b6.tar.bz2
mfashby.net-0284553f75fd927091dc35c502e37df856af05b6.tar.xz
mfashby.net-0284553f75fd927091dc35c502e37df856af05b6.zip
Add CGI handling to my basic server
Fix some missing bits from the comments CGI program, specifically - respect content_length from the web server - write the http status response as a header in the result
Diffstat (limited to 'comments')
-rw-r--r--comments/src/main.zig31
1 files changed, 22 insertions, 9 deletions
diff --git a/comments/src/main.zig b/comments/src/main.zig
index ac8193e..4044ae7 100644
--- a/comments/src/main.zig
+++ b/comments/src/main.zig
@@ -35,6 +35,8 @@ const Err = error{
SystemResources,
Unexpected,
WouldBlock,
+ Overflow,
+ EndOfStream,
};
const Ctx = struct {
db: pq.Db,
@@ -80,13 +82,19 @@ const Response = struct {
return std.io.getStdIn().reader();
}
fn do(self: @This()) !void {
+ const wtr = std.io.getStdOut().writer();
+ if (self.status.phrase()) |phrase| {
+ try std.fmt.format(wtr, "status: {} {s}\r\n", .{@intFromEnum(self.status), phrase});
+ } else {
+ try std.fmt.format(wtr, "status: {}\r\n", .{@intFromEnum(self.status)});
+ }
for (self.headers._internal.items) |tup| {
- try std.io.getStdOut().writeAll(tup.key);
- try std.io.getStdOut().writeAll(": ");
- try std.io.getStdOut().writeAll(tup.val);
- try std.io.getStdOut().writeAll("\r\n");
+ try wtr.writeAll(tup.key);
+ try wtr.writeAll(": ");
+ try wtr.writeAll(tup.val);
+ try wtr.writeAll("\r\n");
}
- try std.io.getStdOut().writeAll("\r\n");
+ try wtr.writeAll("\r\n");
}
fn writer(_: @This()) std.fs.File.Writer {
return std.io.getStdOut().writer();
@@ -136,7 +144,7 @@ pub fn main() !void {
var res = Response{
.allocator = allocator,
.request = req,
- .status = .bad_request,
+ .status = .ok,
.transfer_encoding = .none,
.headers = Headers.init(allocator),
};
@@ -203,9 +211,12 @@ fn get_comment(res: *Response, ctx: Ctx, _: Params) Err!void {
}
fn post_comment(res: *Response, ctx: Ctx, _: Params) Err!void {
- var body_aa = std.ArrayList(u8).init(res.allocator);
- try res.reader().readAllArrayList(&body_aa, 1_000_000);
- const body = try body_aa.toOwnedSlice();
+ const cl = if (std.os.getenv("CONTENT_LENGTH")) |clh| try std.fmt.parseInt(usize, clh, 10) else {
+ return error.InvalidLength;
+ };
+ const body = try res.allocator.alloc(u8, cl);
+ defer res.allocator.free(body);
+ try res.reader().readNoEof(body);
var form = try zws.Form.parse(res.allocator, body);
const Form = struct {
url: []const u8,
@@ -215,6 +226,7 @@ fn post_comment(res: *Response, ctx: Ctx, _: Params) Err!void {
capcha_answer: []const u8,
};
const form_val = form.form_to_struct(Form) catch {
+ std.log.err("couldn't parse Form", .{});
try badrequest(res, ctx);
return;
};
@@ -231,6 +243,7 @@ fn post_comment(res: *Response, ctx: Ctx, _: Params) Err!void {
}
const ans = try stmt.read_column(0, []const u8);
if (!std.mem.eql(u8, ans, form_val.capcha_answer)) {
+ std.log.err("bad capcha answer {s} expected {s}", .{form_val.capcha_answer, ans});
try constresponse(res, @embedFile("templates/capchainvalid.html"), std.http.Status.unauthorized);
return;
}