Skip to main content

PageResponse

Struct PageResponse 

Source
pub struct PageResponse { /* private fields */ }
Expand description

A rendered page, ready to send.

As axum’s IntoResponse it always writes, together with the HTML:

  • Cache-Control: no-store, because the HTML embeds a nonce minted for this one response; a cached copy would hand that nonce to every later reader, and another user’s page with it;
  • Content-Security-Policy, the strict policy for that nonce (crate::csp::build_csp_header) with only the handler’s typed crate::PolicyExtensions added;
  • Trusted Types enforcement in the strict policy, in every build and without a reporting endpoint. The named route relaxation moves only those two directives to Content-Security-Policy-Report-Only;
  • Optional reporting through crate::PolicyExtensions::report_to or crate::PolicyExtensions::report_uri. Strict pages also carry a diagnostic Report-Only policy in debug builds; a relaxed route always carries it;
  • Cross-Origin-Opener-Policy: same-origin (or same-origin-allow-popups when the extensions ask for it), X-Content-Type-Options, Referrer-Policy and Permissions-Policy;
  • Content-Type: text/html; charset=utf-8.

A handler cannot take the HTML out and send it some other way except through PageResponse::into_parts_unchecked, the one named exit, which a consumer’s CI can search for:

ⓘ
let html = page().html; // private: the HTML leaves only with its headers
let parts = page().into_parts_unchecked(); // the named, searchable exit

Verified by: crates/forma-server/tests/internal_renderer/page_response.rs > “page_response_writes_no_store_the_policy_and_the_document_headers”

Implementations§

Source§

impl PageResponse

Source

pub fn frame(preview: &PreviewFrame) -> Result<PageResponse, FrameError>

The preview frame’s document, ready to send: an opaque origin, the runtime inline and allowed by its hash, and the requests the frame module docs list closed, with their residuals (the docs also set out the host’s side). The only response whose policy is rewritten, and only in its nine directives.

As every PageResponse, it writes Cache-Control: no-store, the document headers, and in a development build Trusted Types in Report-Only (no endpoint), with it; its HTML is reachable apart from them only through into_parts_unchecked().

§Errors

FRAME-201 when no nonce can be drawn for style-src: there is no frame without one; FRAME-202, ruled out by the checks at start.

Verified by: crates/forma-server/tests/internal_renderer/preview_frame.rs > “the_frame_document_inlines_the_runtime_by_its_hash_and_names_nothing_to_fetch”

Source§

impl PageResponse

Source

pub fn counts(&self) -> RenderCounts

What the render did: nodes, bytes and list rows walked, and time spent.

Source

pub fn into_parts_unchecked(self) -> PageParts

The HTML, its nonce and every header, apart.

The one way to reach the HTML without sending it as this response. It exists for the rare handler that must assemble its own response (a streaming body, a framework other than axum); each call site belongs on the application’s raw-entry allowlist (forma-raw-lint) with an owner.

Trait Implementations§

Source§

impl Debug for PageResponse

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl IntoResponse for PageResponse

Source§

fn into_response(self) -> Response

Create a response.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more