apple_pie icon indicating copy to clipboard operation
apple_pie copied to clipboard

Proposal: Better response header handling to reduce allocations

Open Luukdegram opened this issue 2 years ago • 0 comments

This proposal includes multiple changes to the way responses handle headers.

The first idea is to make the key of a header an union(enum). This allows us to provide pre-defined keys, and also allow the user to provide a custom key. Meaning we reduce the amount of allocations required as the keys are a simple enum in most cases. The header key would look like:

const HeaderKey = union(enum) {
    content_type,
    content_length,
    custom: []const u8,
    
    fn toString(self: HeaderKey) {
        switch(self) {
            .content_type => return "Content-Type",
            .custom => |custom| return custom,
            ...
        }
    }
};

All keys apart from custom are of type void and do not require any allocations therefore while also preventing typos.

The second change is to provide a method to write a header directly, rather than appending it to some set/map. This means it requires no allocation, but also means the user does not have to clean up any memory afterward. However, this does come with some consideration. As headers come after the status line, we must either ensure the status code is written before writing any headers to the client. How to solve this must still be considered. The method could look like:

fn writeHeader(self: *Response, key: HeaderKey, value: []const u8)!void

A worthwhile benefit to this approach is that we do not have to iterate over the map to detect if certain headers are set. As we can simply check this during the writeHeader method.

Luukdegram avatar Jun 29 '21 09:06 Luukdegram