gquintard / varnish-rs

Rust bindings for the Varnish Cache project
BSD 3-Clause "New" or "Revised" License
23 stars 4 forks source link

Exposing specific HTTP headers per user function API design #140

Open nyurik opened 1 week ago

nyurik commented 1 week ago

Context Ctx object contains a bunch of VCL_HTTP values - most of which users do not need most of the time. Instead, we should create an individual VCL_HTTP on demand:

pub fn user_func(req: &mut RequestHeaders) {...}

This means the user needs just the request headers, and will be able to modify it as needed. We can also support readonly headers with a non-mutable reference &RequestHeaders.

Implementation

Since our macro generator does not actually have type information (it gets resolved by the compiler after macro expansion), we can only rely on name matching. I propose we add these type aliases:

pub type RequestHeaders<'a> = HttpHeaders<'a>;
pub type RequestTopHeaders<'a> = HttpHeaders<'a>;
pub type ResponseHeaders<'a> = HttpHeaders<'a>;
pub type BackendRequestHeaders<'a> = HttpHeaders<'a>;
pub type BackendResponseHeaders<'a> = HttpHeaders<'a>;

This way macro generator will know which instance to create from the raw context, doing it just in time.

Safety

gquintard commented 1 week ago

most of which users do not need most of the time.

that's quite the assessment, I feel like it's not as informed as it could be. We have plenty of vmods that will need/benefit from header access, such as cookie, headers, jwt, uri, urlplus, etc.

the main problem to solve here is that it you give access to a header struct, you can't have access to the workspace, as it's the backing store for it

nyurik commented 1 week ago

I meant you don't need many of these things at the same time, i.e. most of the time you don't need all 5.

Workspace is a fair concern, thx. Do multiple header section get backed by the same workspace, or is there a separate workspace per header?

gquintard commented 1 week ago

fair angle, usually you need at most two, and half of the time, you only have access to one.

Client side share the same workspace, backend side shares another one, and the req_top part can be either the same workspace as the current request, or a completely different one