add multipart parser beginnings

This commit is contained in:
Luna 2021-04-10 02:03:43 -03:00
parent fe07165792
commit 4ea0e086d9
2 changed files with 81 additions and 7 deletions

View file

@ -1,14 +1,16 @@
const std = @import("std");
const http = @import("apple_pie");
const hzzp = @import("hzzp");
const images_dir_path = "./images";
pub fn main() anyerror!void {
std.log.info("All your codebase are belong to us.", .{});
std.log.info("welcome to webscale", .{});
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
// TODO: configurable addr via env var
const bind_addr = try std.net.Address.parseIp("0.0.0.0", 8080);
std.log.info("serving on {}", .{bind_addr});
@ -46,10 +48,20 @@ fn generateImageId(buffer: []u8) []const u8 {
return buffer[0..i];
}
const Part = struct {};
const StreamT = std.io.FixedBufferStream([]const u8);
const ContentDisposition = struct {
name: []const u8,
filename: []const u8,
};
const Part = struct {
disposition: ContentDisposition,
content_type: []const u8,
};
const Multipart = struct {
body: []const u8,
stream: StreamT,
boundary: []const u8,
cursor: usize = 0,
@ -70,11 +82,68 @@ const Multipart = struct {
_ = boundary_it.next();
const boundary_value = boundary_it.next() orelse return error.InvalidBoundary;
return Self{ .body = body, .boundary = boundary_value };
return Self{
.stream = StreamT{ .buffer = body, .pos = 0 },
.boundary = boundary_value,
};
}
pub fn next(self: *Self) !?Part {
return null;
pub fn next(self: *Self, hzzp_buffer: []u8) !?Part {
var reader = self.stream.reader();
// first self.boundary.len+2 bytes MUST be boundary + \r + \n
var boundary_buffer: [512]u8 = undefined;
const maybe_boundary_raw = (try reader.readUntilDelimiterOrEof(&boundary_buffer, '\r')).?;
const maybe_boundary_strip1 = std.mem.trimRight(u8, maybe_boundary_raw, "\n");
const maybe_boundary_strip2 = std.mem.trimRight(u8, maybe_boundary_strip1, "\r");
if (!std.mem.eql(u8, maybe_boundary_strip2, self.boundary)) {
std.log.err("expected '{s}', got '{s}'", .{ self.boundary, maybe_boundary_strip2 });
return error.InvalidBoundaryBody;
}
// from there ownwards, its just http!
var parser = hzzp.parser.request.create(hzzp_buffer, reader);
// This is a hack so that it doesnt try to parse an http header.
parser.state = .header;
var content_disposition: ?ContentDisposition = null;
var content_type: ?[]const u8 = null;
while (try parser.next()) |event| {
switch (event) {
.status => unreachable,
.header => |header| {
// TODO lowercase header name
if (std.mem.eql(u8, header.name, "Content-Disposition")) {
// parse disposition
var disposition_it = std.mem.split(header.value, ";");
_ = disposition_it.next();
var dispo_name: []const u8 = undefined;
var dispo_filename: []const u8 = undefined;
while (disposition_it.next()) |disposition_part_raw| {
const disposition_part = std.mem.trim(u8, disposition_part_raw, " ");
}
content_disposition = ContentDisposition{
.name = dispo_name,
.filename = dispo_filename,
};
} else if (std.mem.eql(u8, header.name, "Content-Type")) {
content_type = header.value;
}
},
.end => break,
else => @panic("shit"),
}
}
return Part{
.disposition = content_disposition.?,
.content_type = content_type.?,
};
}
};
@ -94,8 +163,9 @@ fn uploadFile(response: *http.Response, request: http.Request) !void {
// parse multipart data
var multipart = try Multipart.init(request.body, content_type.?);
var hzzp_buffer: [1024]u8 = undefined;
while (try multipart.next()) |part| {
while (try multipart.next(&hzzp_buffer)) |part| {
std.log.info("part: {}", .{part});
}

View file

@ -6,3 +6,7 @@ dev_dependencies:
- src: git https://github.com/Luukdegram/apple_pie
name: apple_pie
main: src/apple_pie.zig
- src: git https://github.com/truemedian/hzzp
name: hzzp
main: src/main.zig