Expand description
The pre_request and post_request hooks: compiling them, running them,
and the closed surface a script can see.
§What a script is
A script is Rhai source, written inline in the request file as a YAML block scalar:
method: POST
url: https://api.example.com/orders
pre_request: |
request.headers["X-Request-Id"] = "abc-123";
post_request: |
if response.status != 201 {
throw "expected 201, got " + response.status;
}Rhai rather than an embedded JavaScript engine because the whole point of
the feature is that a script needs nothing installed next to sendra: the
interpreter is linked into the binary, there is no FFI boundary, and the
sandbox is a property of what the Engine was built with
rather than of a separate runtime’s flags.
§Script source is never substituted
A {{variable}} or ${OS_VAR} inside a script is not expanded. It is
whatever those characters mean to Rhai — in practice, part of a string
literal. Environment::apply copies both script fields through verbatim,
and there is a test on exactly that.
This is a decision, not an oversight. Substitution is textual, and the whole
reason it is confined to values is that a value must not be able to change
the structure of the document it sits in. A script is structure: it is
executable code, so the failure mode is not a malformed URL but a variable
whose contents get parsed as program text. A script that needs an
environment value reads it off the request it is handed — request.url and
request.headers arrive fully substituted — which is both safe and the
honest place for it to come from.
§Ordering
Fixed, and stated here because it decides what an existing file means:
- Environment substitution.
- Config apply.
pre_request, against the fully-substituted, config-applied request. It is the last thing to touch the request before it goes over the wire, so a header it removes stays removed — which is why the CLI applies the config itself and then callssend_preparedrather thansend, whose whole job is to apply it.- Send.
post_request, against the response.- Assertions, against the same response, unaffected by whether a
post_requestscript ran or what it decided.
Scripts and assertions are two independent mechanisms that happen to look at the same response. Neither can see the other.
§Both scripts are compiled before the request is sent
Scripts::compile compiles pre_request and post_request up front,
so a syntax error in a post_request script is found before the POST that
would have created an order — not after. A file whose script does not parse
is a broken file in the same way a collection with two identically-named
requests is a broken file, and Collection already
makes the argument: finding that out before the first request goes over the
wire beats finding it out halfway through a run.
It is compiled per request rather than for the whole file, in the same place and for the same reason substitution is per request: a script that will not compile is that request’s problem, not its siblings’.
Structs§
- Script
- A script that has been parsed and is ready to run.
- Script
Output - Anything a script printed while it ran, in the order it printed it.
- Scripts
- A request’s two scripts, both compiled.
Enums§
- Hook
- Which of the two hooks a script is.
- Script
Outcome - What a
post_requestscript decided about a response.
Functions§
- run_
post_ request - Run a
post_requestscript against a response, returning its verdict and anything it printed. - run_
pre_ request - Run a
pre_requestscript and return the request it left behind, along with anything it printed.