#[non_exhaustive]pub struct PageOutput {
pub html: String,
pub csp: String,
pub nonce: CspNonce,
/* private fields */
}Expand description
Output from render_page: HTML body + CSP header value + the nonce binding them together.
The HTML and the CSP header are a single unit — the HTML embeds a
per-request nonce that only this policy blesses. Serve them together with
Cache-Control: no-store and never cache the HTML across requests: a
cached body with a fresh policy kills every script, and caching both ships
one static, publicly-known nonce to every user, which defeats nonce-based
CSP entirely.
Superseded by PageResponse, which writes those
headers itself and cannot be sent without them. Turn a
PageOutput into one with PageOutput::into_page_response; the public
fields and PageOutput::headers are deprecated and go private in 3.0.0.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.html: Stringsend the page as a PageResponse (into_page_response), which carries no-store and the policy with it. Private in 3.0.0
The complete HTML document.
csp: Stringthe policy is typed now: extend it with PolicyExtensions and send a PageResponse rather than editing this text. Private in 3.0.0
The Content-Security-Policy header value that blesses it.
nonce: CspNoncerender with try_render (0.2.2), which draws the nonce and writes it into the page and its policy; a handler that must read it takes PageResponse::into_parts_unchecked().nonce. Private in 3.0.0, which gives no caller a nonce
The nonce embedded in html and blessed by csp.
Exposed so a caller can add its own nonced <script>/<style>, or
re-stamp a cached shell, without string-parsing the CSP.
Implementations§
Source§impl PageOutput
impl PageOutput
Sourcepub fn headers(&self) -> Vec<(HeaderName, HeaderValue)>
👎Deprecated since 0.2.2: use into_page_response: a PageResponse writes these headers itself and fails rather than dropping an invalid policy. Removed in 3.0.0
pub fn headers(&self) -> Vec<(HeaderName, HeaderValue)>
use into_page_response: a PageResponse writes these headers itself and fails rather than dropping an invalid policy. Removed in 3.0.0
Response headers for this page: content type, no-store, the CSP, and
(from 0.2.2, in development builds) Trusted Types in
Content-Security-Policy-Report-Only.
Reads the (public, mutable) csp field, so a caller that must rewrite
a directive can do so in place first and still use this helper. An
invalid csp is left out rather than reported; that silent drop is
one of the reasons this is deprecated.
Sourcepub fn into_page_response(
self,
extensions: &PolicyExtensions,
) -> Result<PageResponse, PolicyError>
pub fn into_page_response( self, extensions: &PolicyExtensions, ) -> Result<PageResponse, PolicyError>
This page as a PageResponse: no-store, the
strict policy for the page’s nonce with extensions added, and the
document headers, written whenever it is sent.
The policy is rebuilt from the nonce the HTML embeds, so a csp edited
as text would not carry over: it is refused instead, wherever the edit
went (a widening one would fail in the browser, a tightening one would
be lost). Express the edit as an extension:
// Was: page.csp.replace("img-src 'self' data:", "img-src 'self' data: https:")
let page = render_page(&config())
.into_page_response(&PolicyExtensions::new().img_src("https:"))?;The bridge trusts the deprecated public nonce and html as they
are: a nonce the caller chose (through render_page_with_nonce, or by
assigning the field) carries into the PageResponse. A fresh nonce
per response is guaranteed only when the render draws it, as
render_page and try_render do.
§Errors
A PolicyError naming the first extension that
is not a source a page may add, or, for directive
content-security-policy, a csp that is not the one forma-server
wrote for this page’s nonce. There is then no response to send:
answer with an error page rather than this one without its policy.
Verified by: crates/forma-server/tests/page_response.rs > “into_page_response_refuses_a_policy_edited_as_text”