Repository navigation
Let a middleware prepare with the request's services and refuse a request - #1364
Draft
jwrosewell wants to merge 13 commits into
Draft
jwrosewell wants to merge 13 commits into
jwrosewell wants to merge 13 commits into
Conversation
`Middleware::prepare` answers a future for a document whose decision needs the request's services or has to wait, on the key-value store or the network. The request's handler runs it before the document is processed, once per phase the document goes through, as the middleware's module and with the permissions it declares, and keeps what it answers under the middleware's name in the context's `Prepared`, where `create` takes it as the type it prepared. `create` and every streaming path stay synchronous, so the Fastly adapter is as it was. A middleware that prepares nothing is asked `create` as before. A preparation may answer a `Refusal` instead, with a status, an optional `Retry-After` and a message. The handler answers the request with that status and the message as plain text, marks the response private and unstorable, and processes no document, so a middleware responsible for a file fails closed when it cannot make it. The first refusal ends the preparations of a document. A copy read from the store prepares its serve chain the same way before it is assembled. The middleware fixture gains one that prepares and one that refuses, and the tests cover what is prepared reaching `create` in either phase, the refusal's status, headers and body, the chain keeping each answer under its name, and the first refusal ending the preparation.
The section says when a middleware prepares, what it is called with, where its answer goes, how a refusal is answered, and what each phase's preparation must not depend on. The changelog records the addition.
# Conflicts: # CHANGELOG.md # crates/trusted-server-core/src/middleware.rs # crates/trusted-server-core/src/middleware/tests.rs # crates/trusted-server-core/src/publisher.rs
…e reader A document that may be stored is prepared with the request's services alone, so no reader permission or Edge Cookie reaches the shared template. Retry-After rounds up to whole seconds. TextDocument is renamed ResponseDocument, the prepared field docs use one phrase, and the guide states which phases are prepared.
A document that is not stored is prepared in both phases before either is planned, and both kept what they prepared in one store under the middleware's name alone. A middleware running in both phases had its fetch preparation replaced by its serve one, so the fetch create took the serve value and the serve create took nothing. Prepared is now keyed by phase and name, and MiddlewareContext::take_prepared takes what was prepared in the context's own phase.
# Conflicts: # crates/trusted-server-core/src/html_processor.rs # crates/trusted-server-core/src/integrations/registry.rs # crates/trusted-server-core/src/middleware.rs # crates/trusted-server-core/src/publisher.rs
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Changes
crates/trusted-server-core/srcdocs/guideCHANGELOG.mdcrates/trusted-server-core/benchesCloses
Closes #1281
Test plan
CI: 19 of 19 checks green, the fork's CI on d9fb81a (jwrosewell#18).
cargo test-fastly && cargo test-axumcargo clippy-fastly && cargo clippy-axumcargo fmt --all -- --checkcd crates/trusted-server-js/lib && npx vitest runcd crates/trusted-server-js/lib && npm run formatcd docs && npm run formatcargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1fastly compute serveChecklist
unwrap()in production code (clippy deniesunwrap_usedin CI)logmacros as AGENTS.md asks (notprintln!)Stacks on making a file the origin does not have (#1309). The additions that follow the seven pull requests open here are listed in #777.
Compare
split/22-creatingwithsplit/23-prepareto see only this pull request's change.
What this pull request does
A middleware whose decision needs the request's services, or has to wait on the store or the network, answers
Middleware::preparewith a future. The request's handler runs it before the document is processed, as the middleware's module with the permissions it declares, and what it answers is kept under the middleware's name and phase forcreatein that phase to take.A preparation may answer a
Refusalinstead, with a status, an optionalRetry-Afterin whole seconds rounded up, and a message, and the request is answered with that status, no document is processed, and nothing is stored or served from the store.Why
createis synchronous, is given no services, and is asked inside the synchronous streaming paths that the Fastly adapter needs. A middleware that makes a well known file from what the store holds or a service answers, as robots.txt does, could not decide there, and could not fail closed when it had nothing to give, which for robots.txt matters because an empty file tells crawlers to crawl everything. The preparation runs where the handler is asynchronous on every adapter, and only its answer, aSendvalue, travels to the streaming paths, socreate, the plan and every streaming path are as they were.The rules
A middleware that prepares nothing is asked
createas before, and nothing of it changes.On a document fetched for the request that will not be stored, both phases are prepared, fetch then serve. On a document that may be stored, only the fetch phase is prepared, so the serve middleware of the reader it was fetched for find nothing prepared. On a copy read from the store, the serve phase alone. The preparations of a phase run in the order the entry names the middleware.
The first refusal ends the preparations of a document, and the response it makes is marked private and unstorable.
A fetch preparation of a document that may be stored is handed the request's services and nothing of the reader, neither its permissions, location nor Edge Cookie, because its answer is stored with the document.
What breaks
MiddlewareContext,HtmlProcessorConfigandReaderDocumenteach gain a required pub fieldprepared, so every struct literal of them outside this repository stops compiling.How it was verified
CI passed on
1c0c244f7on the fork. Not exercised: no preparation has run against a real store or network, because the fixtures answer from what they are called with. The preparation on a copy read from the store has no test, because the test services have no template cache.References #1281.