add multipart parser beginnings
This commit is contained in:
parent
fe07165792
commit
4ea0e086d9
2 changed files with 81 additions and 7 deletions
84
src/main.zig
84
src/main.zig
|
@ -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});
|
||||
}
|
||||
|
||||
|
|
4
zig.mod
4
zig.mod
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue