https://github.com/vrischmann/zig-picohttpparser
Small Zig wrapper for picohttpparser
https://github.com/vrischmann/zig-picohttpparser
http picohttpparser zig
Last synced: about 1 month ago
JSON representation
Small Zig wrapper for picohttpparser
- Host: GitHub
- URL: https://github.com/vrischmann/zig-picohttpparser
- Owner: vrischmann
- License: mit
- Created: 2024-12-22T00:50:58.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2025-04-29T16:42:11.000Z (11 months ago)
- Last Synced: 2025-06-25T01:04:29.348Z (9 months ago)
- Topics: http, picohttpparser, zig
- Language: Zig
- Homepage:
- Size: 18.6 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# zig-picohttpparser
This is a small Zig wrapper to use [picohttpparser](https://github.com/h2o/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](https://github.com/vrischmann/zig-picohttpparser-sys).
# Supported Zig version
Only Zig master is currently supported. Once 0.14.0 is released we should be able to support it.
# Installation
Use `zig fetch`:
```
zig fetch --save git+https://github.com/vrischmann/zig-picohttpparser#master
```
You can then import `picohttpparser` in your `build.zig`:
```zig
const picohttpparser = b.dependency("picohttpparser", .{
.target = target,
.optimize = optimize,
});
your_exe.addImport("picohttpparser", picohttpparser.module("picohttpparser"));
```
# Features implemented
picohttpparser doesn't have many features. The following is a list of what is implemented in this wrapper.
* [x] Parsing a request
* [ ] Parsing a response
* [ ] Parsing chunk-encoded data
* [ ] Parsing headers only
# Usage
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:
```zig
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:
```zig
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](/example/main.zig) for a more complete example.
You can also take a look at my project [zig-io_uring-http-server](https://github.com/vrischmann/zig-io_uring-http-server) where I [use `picohttpparser`](https://github.com/vrischmann/zig-io_uring-http-server/blob/master/src/lib.zig#L841-L855).