Skip to content

Rework Headers in general #25

@Vlix

Description

@Vlix

Rework HeaderNames (old title of issue)

Probably something for a new major version.

Having regular pinned ByteStrings makes it really easy to hold on to the entire request during processing, which might be unnecessary. And it being a case insensitive CI also creates a pinned copy.
So for a few reasons, it might be smart to replace the current type synonym with a custom type:

  • Base the new type on CI, but don't make it strict
    (at least not in the foldedCase field, if it never gets compared, there's no reason to make another copy)
  • Use ShortByteString, at least for the HeaderName, since they are guaranteed to be short.
  • (Would ShortByteString be a good option for the header value as well? 🤔)

Side note: using ShortByteStrings would also add copying of headers, so maybe not the best solution.


I've been thinking of HTTP headers for some time now, and using a list is pretty inefficient and makes it difficult to keep to the HTTP standard of rules surrounding headers.

A few things that Headers should make easy and rules it should abide by:

  • order is preserved
    no loss of information
  • original values are preserved
    no loss of information
  • comparison of header names is case-insensitive
    HTTP rule
  • duplicates are allowed
    HTTP rule, at least for 'Set-Cookie', and other cases
  • lookup is quick (and might produce duplicates, also ordered)
    quick decision making
  • deletion doesn't have to be optimal
    happens rarely
  • insertion is quick and can be at the front or the back
    constructing should be quick to keep response times low
  • replacement doesn't have to be optimal
    not golden path, won't happen often. deletion + insertion is also fine
  • use/accept ByteStrings as values
    server requirement: don't use more memory/compute than necessary, since we're getting the headers in 'ByteString' format
  • avoid copying header names and/or values (in the ByteString case)
    keep memory usage to a minimum; the 'CI ByteString' instance strictly copies every 'HeaderName', for example. Unnecessary: lazy would suffice

The main reason for these requirements are because of the fact the collection of headers should be quickly constructed when a Request comes in on the server side, and should use minimal space, if possible. The lookup has to be quick, because the server (and user) checks headers a lot. And since we get ByteStrings over the socket, that's the type we'll stick with until we need further parsing.
Clients will also eventually send the headers over a socket, probably using ByteStrings, so keeping that as the

When constructing the collection of headers for the Response, it doesn't have to be quick, but lookups and replacements are more important, since the server and user shouldn't introduce duplicates if they don't have to/want to.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions