replacement in src/computer-networks/introduction-to-network-programming/http-header-server.zig at line 62
+ const SendHttpResponseError = os.SendError || HttpHeadersIterator.NextError || error{
+ Overflow,
+ NoStartLine,
+ BadStartLine,
+ };
+
+ fn sendHttpResponse(
+ comptime BUFFER_SIZE: usize,
+ sockfd: os.socket_t,
+ request: []const u8,
+ ) SendHttpResponseError!void {
+ const start_line = request[0 .. std.mem.indexOf(u8, request, "\r\n") orelse request.len];
+ if (request.len == 0) return SendHttpResponseError.NoStartLine;
+ // TODO don't assume start line is OK!
+
+ // Make the writer object.
+ var send_writer = OsSendWriter{ .sockfd = sockfd };
+ var buf_send_writer = std.io.BufferedWriter(
+ BUFFER_SIZE,
+ OsSendWriter.Writer,
+ ){ .unbuffered_writer = send_writer.writer() };
+ var writer = buf_send_writer.writer();
+ var json_writer = std.json.writeStream(writer, 3);
+
+ _ = try writer.write("HTTP/1.1 200 OK\r\n\r\n");
+
+ var headers_iter = HttpHeadersIterator.init(request[start_line.len + 2 ..]);
+
+ // Build the JSON blob.
+ try json_writer.beginObject();
+ while (try headers_iter.next()) |header| {
+ try json_writer.objectField(header[0]);
+ try json_writer.emitString(header[1]);
+ }
+ try json_writer.endObject();
+
+ // Flush the buffer.
+ try buf_send_writer.flush();
+ }
+
+ const OsSendWriter = struct {
+ sockfd: os.socket_t,
+
+ const Self = @This();
+
+ const WriteError = os.SendError;
+
+ pub fn write(self: *Self, str: []const u8) WriteError!usize {
+ return os.send(self.sockfd, str, 0);
+ }
+
+ pub const Writer = std.io.Writer(*Self, WriteError, write);
+
+ pub fn writer(self: *Self) Writer {
+ return .{ .context = self };
+ }
+ };
+
+ const HttpHeadersIterator = struct {
+ lines_iter: std.mem.SplitIterator(u8),
+
+ const Self = @This();
+
+ pub fn init(request: []const u8) Self {
+ return .{ .lines_iter = .{ .buffer = request, .delimiter = "\r\n", .index = 0 } };
+ }
+
+ const NextError = error{NoDivider};
+
+ pub fn next(self: *Self) !?struct { []const u8, []const u8 } {
+ const DIVIDER: []const u8 = ": ";
+
+ const line = self.lines_iter.next() orelse return null;
+ if (line.len == 0) return null;
+
+ const div_pos = std.mem.indexOf(u8, line, DIVIDER) orelse return NextError.NoDivider;
+ const result = .{
+ line[0..div_pos],
+ line[div_pos + DIVIDER.len ..],
+ };
+ return result;
+ }
+ };