vrischmann/zig-picohttpparser
Small Zig wrapper for picohttpparser
This is a small Zig wrapper to use picohttpparser.
picohttpparser
could be used directly but this wrapper makes it feel more idiomatic Zig.
This package leverages the Zig build system and is based on zig-picohttpparser-sys.
Only Zig master is currently supported. Once 0.14.0 is released we should be able to support it.
Use zig fetch
:
zig fetch --save git+https://github.com/vrischmann/zig-picohttpparser#master
You can then import picohttpparser
in your build.zig
:
const picohttpparser = b.dependency("picohttpparser", .{
.target = target,
.optimize = optimize,
});
your_exe.addImport("picohttpparser", picohttpparser.module("picohttpparser"));
picohttpparser doesn't have many features. The following is a list of what is implemented in this wrapper.
There is only one function exposed, parseRequest
:
pub fn parseRequest(buffer: []const u8, previous_buffer_len: usize) ParseRequestError!?ParseRequestResult {
This function takes in a buffer and a previous buffer length and returns either a parsing error or a result.
The buffer is easy to understand, it's the string you want to parse as an HTTP request. The previous buffer length is the length in the current buffer that you already tried to parse. This is needed to resume parsing incomplete buffers.
The returned result contains the raw request (of type RawRequest
) and the number of bytes consumed from the buffer.
Here is an example usage:
const std = @import("std");
const picohttpparser = @import("picohttpparser");
pub fn main() !void {
const data = "GET /lol/foo HTTP/1.0\r\nfoo: ab\r\nContent-Length: 200\r\n\r\n";
if (try picohttpparser.parseRequest(data, 0)) |result| {
std.log.info("request: {s}, consumed: {d}", .{ result.raw_request.getPath(), result.consumed });
}
}
This assumes the data is complete, in the real world you probably can't assume this. You probably want to do something like this:
var buf = std.ArrayList(u8).init(allocator);
const result = while (true) {
// Feed more data to buf somehow: read from a socket, copy from another buffer, etc
if (try picohttpparser.parseRequest(buf.items, 0)) |result| {
break result;
}
};
// Use the result
Look into example/main.zig for a more complete example.
You can also take a look at my project zig-io_uring-http-server where I use picohttpparser
.