-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
wasi-http: Make child fields immutable #7524
wasi-http: Make child fields immutable #7524
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of checking the immutability flag in the callee, can we factor it into a get_fields
that returns a &FieldMap
and use that in all the cases that don't require mutability, and then turn get_fields_mut
which returns Result<&mut FieldMap, HeaderError>
that will only be used for set/append/delete and itself return Err(HeaderError::Immutable)
?
Clean up the interface to immutable fields by adding a different accessor.
Great call! I've reworked this to have two accessors now, and I like it much more. |
9d976dc
to
ede308f
Compare
@elliottt I didn't catch this earlier, but I think it's somewhat unfortunate to take such drastic measures here. Specifically, I would predict that fields entries sometimes being mutable, sometimes not, while in many languages it's not really possible to express that in the type system—and it's not expressed in whether we have a borrowed or mutable handle—will lead to lots of confusion. What if instead we made it so that headers are passed in as an owned handle when sending a request/response, ensuring that they can't be mutated at all anymore afterwards? For those use cases where the values still need to be accessible, the handle can be cloned. (I'd imagine that we could make that pretty cheap on the host side, by having |
I think your suggestion is what's implemented here: the |
More concretely: this doesn't treat individual headers in a special way, it makes it so that the |
I think ensuring that headers values can't be changed after they become relevant for error handling makes a lot of sense. What I had in mind was to move that point further back, to the moment where the request/response is actually sent. What I mean is not having headers be associated with requests/responses at all until the latter are sent. Concretely, that would entail four changes:
handle: func(
request: outgoing-request,
headers: headers,
options: option<request-options>
) -> result<future-incoming-response, error-code>;
set: static func(
param: response-outparam,
response: result<outgoing-response, headers, error-code>,
);
That should make it so that whenever one can get a handle to a All this said, I'm not 100% sure myself that this is the better approach, but it does seem to make things more self-explanatory at least. |
That makes sense to me, thank you for the detailed explanation! I'm open to making this change, would it make sense to also make the incoming handler take a |
ah, good point yeah: I think that symmetry would make a lot of sense |
* Make child fields immutable * Add `get_fields` and remove `FieldMapMutability` Clean up the interface to immutable fields by adding a different accessor. * Clean up the diff
Can't you achieve these with library code that just maintains the |
Yes, that's possible, but I think there are a couple of downsides. One is more of a conceptual one: The other is that that means not being able to use the stream at all until after creating the final Given that the key property we want to get at is to ensure that the headers don't change between setting them and sending off the parent resource, it seems to make sense to me to create that association just in time, by passing them in when sending. |
Thinking about this over the weekend, I think there's a problem with passing the headers to the handler: that means that the value of the
We should be able to report an error in step 6 for writing too much, but as the |
What I was envisioning was a modified sequence along these lines:
Now what I don't at all know is how hard it'd be to move setting the expected body length from step 3 into step 5. Certainly the request has a reference to it still, so ideally it shouldn't be too hard? |
* Remove timezone interface from wasi-clocks (#7515) * delete wasi-clocks timezone interface: import wit changes from WebAssembly/wasi-clocks#55 * remove other references to wasi:clocks/timezone in wits * remove todo! implementation of clocks/timezone and add_to_linker funcs * Move the `wasi:io/stream/error` resource into `wasi:io/error` (#7521) * Move the `error` resource into `wasi:io/error` * error.wit: update doc comments * downstream fixes to streams.wit doc comments * fix package name in error.wit --------- Co-authored-by: Trevor Elliott <[email protected]> * wasi-http: Make child fields immutable (#7524) * Make child fields immutable * Add `get_fields` and remove `FieldMapMutability` Clean up the interface to immutable fields by adding a different accessor. * Clean up the diff * wasi-http: Migrate to more descriptive error variant (#7434) * Migrate to a more specific error-code variant in wasi-http Co-authored-by: Pat Hickey <[email protected]> * Optional fields, and align with upstream pr * Update for upstream changes to the error-code variant * Sync with the upstream implementation * Missed updating an error for riscv64 and s390x * More debuggable error prtest:full * Try to stabilize the test on windows --------- Co-authored-by: Pat Hickey <[email protected]> * Remove a debugging eprintln (#7528) * Remove no-longer-necessary reactor world (#7516) The `wasi:cli` WIT package now has a `reactor` world so the adapter can use that instead of defining its own. --------- Co-authored-by: Pat Hickey <[email protected]> Co-authored-by: Trevor Elliott <[email protected]>
This PR adds a new case to the
header-error
variant,immutable
, which indicates that an operation that would modify thefields
value has failed because thatfields
is immutable. Allfields
returned by getter methods on any of the request/response types are considered immutable, whilefields
that have been created directly through the use of thefields
constructor are considered mutable until ownership is passed to an outgoing request or response.This change paves the way to runtime validation of the
Content-Length
header, ensuring that it's safe to check the value provided when an outgoing request or response is created.