ecluse:ecluse-core
Safe HaskellNone
LanguageGHC2021

Ecluse.Core.Server.Conditional

Description

Conditional-GET and ETag handling, split by how the served body relates to upstream's.

A pass-through body (an artifact, unfiltered private metadata) is byte-identical to upstream's, so the client's validators are relayed upstream (forwardValidators) and an upstream 304 is passed back (isNotModified). A transformed body (every packument is merged and filtered) takes our own strong ETag instead, derived from the serve's inputs rather than hashed over its output. It can therefore be stale only in the safe direction, a spurious 200 and never a wrong 304, and a 304 costs no assembly at all.

Synopsis

Our own ETag (transformed bodies)

data ETag Source #

A strong entity tag in the quoted wire form ("…") the ETag header carries. The 'newtype' keeps that quoted form from being confused with the bare digest.

Instances

Instances details
Show ETag Source # 
Instance details

Defined in Ecluse.Core.Server.Conditional

Methods

showsPrec :: Int -> ETag -> ShowS #

show :: ETag -> String #

showList :: [ETag] -> ShowS #

Eq ETag Source # 
Instance details

Defined in Ecluse.Core.Server.Conditional

Methods

(==) :: ETag -> ETag -> Bool #

(/=) :: ETag -> ETag -> Bool #

Ord ETag Source # 
Instance details

Defined in Ecluse.Core.Server.Conditional

Methods

compare :: ETag -> ETag -> Ordering #

(<) :: ETag -> ETag -> Bool #

(<=) :: ETag -> ETag -> Bool #

(>) :: ETag -> ETag -> Bool #

(>=) :: ETag -> ETag -> Bool #

max :: ETag -> ETag -> ETag #

min :: ETag -> ETag -> ETag #

mkStrongETag :: Digest SHA256 -> ETag Source #

Quote a SHA-256 digest as a strong ETag, hex-encoded. The digest is whatever fingerprint the serving layer stands behind.

renderETag :: ETag -> Text Source #

The ETags wire form, the quoted opaque tag as it goes into the header.

etagHeader :: ETag -> Header Source #

The ETag response header carrying this validator.

data Conditional Source #

The conditional outcome for a transformed body: whether the client's validator already matches what we would serve.

Constructors

NotModified ETag

The served body is unchanged from the client's validator. Answer 304 with this ETag and no body.

Modified ETag

The served body differs, or no validator was sent. Serve 200 with this ETag header.

Instances

Instances details
Show Conditional Source # 
Instance details

Defined in Ecluse.Core.Server.Conditional

Eq Conditional Source # 
Instance details

Defined in Ecluse.Core.Server.Conditional

evaluateETag :: RequestHeaders -> ETag -> Conditional Source #

Evaluate a conditional request against our own ETag. The comparison is weak (RFC 7232), and If-Modified-Since is not consulted: a merge has no single upstream timestamp.

Relaying validators (pass-through bodies)

forwardValidators :: RequestHeaders -> RequestHeaders Source #

The client's conditional validators to relay upstream for a pass-through body. Only these two are forwarded, so upstream answers 304 without receiving any other client header.

isNotModified :: Status -> Bool Source #

Whether an upstream response is a 304 Not Modified to pass straight back to the client. Used on the pass-through path, where upstream's own validator decided.