Skip to content

martensite

Zig · learning project

An HTTP/1.1 library in Zig. It parses and writes HTTP messages and nothing in it allocates. I wrote it to learn what a web framework does for you.

Why I built it

I had been building backends on top of frameworks for a while, and I wanted to know what they were doing for me. So I wrote the HTTP part myself. It is a learning project.

I picked Zig because it has no garbage collector and no hidden allocation. I had to decide where every buffer lives and how long it stays valid, which a framework normally decides for me.

What it does

martensite parses requests and responses, works out where a body ends, handles chunked encoding and writes responses. It has no router and no middleware.

Nothing in it allocates. Every slice it gives you points into a buffer you own, and it stays valid until the next read on that buffer. If you use one after that, debug builds stop with an error instead of reading old data.

Ambiguous requests

When a proxy and a server disagree about where a body ends, someone can hide a second request inside the first. This is called request smuggling. martensite rejects any request that could be read two ways, for example one with both Content-Length and Transfer-Encoding. It also refuses to write a message its own parser would reject.

Every server test also runs a second time with the bytes arriving one at a time. That catches code that assumes more data has arrived than actually has.