Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typed HTTP Header API #966

Closed
wants to merge 10 commits into from
Closed

Typed HTTP Header API #966

wants to merge 10 commits into from

Conversation

bikallem
Copy link
Contributor

@bikallem bikallem commented Jan 30, 2023

This PR adds typed Header API to cohttp-eio.

This is the first PR in this series. I will open additional PRs that will build on this PR and which will use the header api defined here. Future PRs will address changes required in Request, Response, (Server?) and Client modules. This is mostly to ease review and merge.

Usages of the new API can be seen in the header.md tests.

A Brief Overview

The header functionality implemented in the module Header aims to address the following core requirements,

  1. Type-safe API to manipulate (add,update,find, remove, etc ) HTTP headers.
  2. Extendable by end-users so that custom headers can be used while still following (1) above.

For (1) and (2) we define an extensible GADT -

type 'a header = ..

where 'a defines the header type. For example to define Content-Type header we define it as

type 'a header += Content_length : int header

This ensures that valid Content-Type header is an int.

The current PR provides implementation for three common HTTP headers, Content-Type and Transfer-Encoding and a type-unsafe, generic/catch all header aptly named H name. The plan is to increase this number in future PRs after this PR is merged.

Some headers are only applicable to either requests only or response only, as such they will be defined in Request and Response module respectively. Common headers to both Request and Response will be defined in the Header module itself.

Type 'a header = .. is also an extensible type so that end-users can define custom headers should they so desire, for example we can define Header1 and Header2 as such:

type 'a Header.header += 
  | Header1 : string Header.header
  | Header2 : float Header.header 

Tests in header.md contains a test for custom headers and its usage.

Lastly, the header values are not decoded during insertion time, they are encoded as a 'a Lazy.t values and are only decoded on demand. This ensures that we don't incur performance penalty for those headers which we may never use. The backing store of headers is a list so insertion is 0(1).

/cc @avsm @mseri

@bikallem bikallem force-pushed the typed-header branch 4 times, most recently from 139f0e0 to c0e8f44 Compare February 6, 2023 09:35
@bikallem bikallem force-pushed the typed-header branch 3 times, most recently from cf9f79b to 743b33b Compare February 6, 2023 14:54
Renames Header.undecoded to Header.value.

Add notes about concurrency usage of Header.decode.
@bikallem
Copy link
Contributor Author

Closing this in support of discussion happening at #969

@bikallem bikallem closed this Feb 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant