| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Ecluse.Core.Server.Response
Description
Map policy and upstream outcomes to HTTP statuses. Artifact requests use one outcome, while packuments choose a status from the surviving versions. Ecosystem contracts own response bodies.
Synopsis
- data ServeDecision
- data Rejection = Rejection {}
- data RejectReason
- data Transience
- newtype RetryAfter = RetryAfter Int
- newtype RuleName = RuleName Text
- rejectUnavailable :: Transience -> Text -> ServeDecision
- serveDecisionOf :: PackageDetails -> Decision -> ServeDecision
- data ArtifactStatus
- artifactStatus :: ServeDecision -> ArtifactStatus
- artifactHttpStatus :: ArtifactStatus -> Status
- data PackumentStatus
- packumentStatus :: [ServeDecision] -> PackumentStatus
- longestRetry :: [Maybe RetryAfter] -> Maybe RetryAfter
- data HelpMessage
- mkHelpMessage :: Text -> HelpMessage
- appendHelp :: Maybe HelpMessage -> Text -> Text
- data Refusal = Refusal {}
- mkRefusal :: Maybe HelpMessage -> Text -> Refusal
- renderRefusal :: Refusal -> Text
Serve outcomes
data ServeDecision Source #
The outcome of deciding a request: serve it, or refuse it with a reason. Every client-facing reply renders one of these.
Constructors
| Admit | Serve the request (the |
| Reject Rejection | Refuse the request, with the reason and a client-facing message. |
Instances
| Show ServeDecision Source # | |
Defined in Ecluse.Core.Server.Response Methods showsPrec :: Int -> ServeDecision -> ShowS # show :: ServeDecision -> String # showList :: [ServeDecision] -> ShowS # | |
| Eq ServeDecision Source # | |
Defined in Ecluse.Core.Server.Response Methods (==) :: ServeDecision -> ServeDecision -> Bool # (/=) :: ServeDecision -> ServeDecision -> Bool # | |
A refusal: why the request was refused, and an intuitive message for the client.
Constructors
| Rejection | |
Fields
| |
data RejectReason Source #
Why a request was refused. A policy refusal is final for this request. An unavailability is
an inability to decide, whose Transience separates a retryable 503 from a terminal 500.
Constructors
| ByPolicy RuleName | A rule denied the version (deny-by-default included). The |
| Unavailable Transience | The version could not be vetted. Refuse it, with transience indicating whether a retry can help. |
| MissingIntegrity | A public artifact lacks a digest, so admission cannot verify its bytes and refuses with |
| BelowIntegrityFloor | A public artifact's strongest digest falls below the configured floor, so admission refuses with |
| UpstreamInvalid | An upstream packument names a different package and cannot enter the merge.
When no valid origin remains, the packument request returns |
Instances
| Show RejectReason Source # | |
Defined in Ecluse.Core.Server.Response Methods showsPrec :: Int -> RejectReason -> ShowS # show :: RejectReason -> String # showList :: [RejectReason] -> ShowS # | |
| Eq RejectReason Source # | |
Defined in Ecluse.Core.Server.Response | |
data Transience Source #
Serve transient outages, rate limits, timeouts, and open breakers as 503.
Serve internal or parse faults as 500. WillResolve and WontResolve encode that distinction.
Constructors
| WillResolve (Maybe RetryAfter) | A retry may succeed after an outage, timeout, or open breaker.
The optional |
| WontResolve | Not expected to self-heal (an internal or parse error). Retrying cannot
help, so the request is a |
Instances
| Show Transience Source # | |
Defined in Ecluse.Core.Rules.Types Methods showsPrec :: Int -> Transience -> ShowS # show :: Transience -> String # showList :: [Transience] -> ShowS # | |
| Eq Transience Source # | |
Defined in Ecluse.Core.Rules.Types | |
newtype RetryAfter Source #
A Retry-After delay, in whole seconds. A 'newtype' so a raw count of seconds is
never confused with some other integer when it reaches a response header or a sweep's wait.
Constructors
| RetryAfter Int |
Instances
| Show RetryAfter Source # | |
Defined in Ecluse.Core.Fault Methods showsPrec :: Int -> RetryAfter -> ShowS # show :: RetryAfter -> String # showList :: [RetryAfter] -> ShowS # | |
| Eq RetryAfter Source # | |
Defined in Ecluse.Core.Fault | |
| Ord RetryAfter Source # | |
Defined in Ecluse.Core.Fault Methods compare :: RetryAfter -> RetryAfter -> Ordering # (<) :: RetryAfter -> RetryAfter -> Bool # (<=) :: RetryAfter -> RetryAfter -> Bool # (>) :: RetryAfter -> RetryAfter -> Bool # (>=) :: RetryAfter -> RetryAfter -> Bool # max :: RetryAfter -> RetryAfter -> RetryAfter # min :: RetryAfter -> RetryAfter -> RetryAfter # | |
The name of the rule that decided a refusal, for the audit trail and the denial body.
rejectUnavailable :: Transience -> Text -> ServeDecision Source #
Refuse a request that could not be decided. The Transience it carries is what
artifactStatus renders as a 503 or a 500, so a caller states that rather than a status.
serveDecisionOf :: PackageDetails -> Decision -> ServeDecision Source #
Project a rules Decision into a serve outcome. An Undecidable decision rejects as
Unavailable, which is fail-closed: a version no rule could vet is never admitted.
Concrete-artifact status
data ArtifactStatus Source #
The HTTP status a concrete-artifact request renders to. A packument request has no single
status, because the pipeline chooses one over the survivors: PackumentStatus models that.
Constructors
| Ok |
|
| Forbidden |
|
| Unavailable' (Maybe RetryAfter) |
|
| ServerError |
|
| NotFound |
|
Instances
| Show ArtifactStatus Source # | |
Defined in Ecluse.Core.Server.Response Methods showsPrec :: Int -> ArtifactStatus -> ShowS # show :: ArtifactStatus -> String # showList :: [ArtifactStatus] -> ShowS # | |
| Eq ArtifactStatus Source # | |
Defined in Ecluse.Core.Server.Response Methods (==) :: ArtifactStatus -> ArtifactStatus -> Bool # (/=) :: ArtifactStatus -> ArtifactStatus -> Bool # | |
artifactStatus :: ServeDecision -> ArtifactStatus Source #
Map a serve outcome to its concrete-artifact status: 503 only where it will resolve, so a
WontResolve unavailability is a 500. An upstream 404 is no serve decision and never appears.
artifactHttpStatus :: ArtifactStatus -> Status Source #
The HTTP status an ArtifactStatus renders as.
Packument status (over the merged survivor set)
data PackumentStatus Source #
The HTTP status a packument request renders to, chosen over the merged survivor set. There
is no 404: the package exists, and a genuine absence is decided before the merge.
Constructors
| PackumentOk |
|
| PackumentForbidden |
|
| PackumentUnavailable (Maybe RetryAfter) |
|
| PackumentBadGateway |
|
| PackumentServerError |
|
Instances
| Show PackumentStatus Source # | |
Defined in Ecluse.Core.Server.Response Methods showsPrec :: Int -> PackumentStatus -> ShowS # show :: PackumentStatus -> String # showList :: [PackumentStatus] -> ShowS # | |
| Eq PackumentStatus Source # | |
Defined in Ecluse.Core.Server.Response Methods (==) :: PackumentStatus -> PackumentStatus -> Bool # (/=) :: PackumentStatus -> PackumentStatus -> Bool # | |
packumentStatus :: [ServeDecision] -> PackumentStatus Source #
A packument's status from the per-version outcomes: with no survivor the most recoverable cause
wins, 502 under 503 as a transient origin may yet answer, and an empty input is a 403.
longestRetry :: [Maybe RetryAfter] -> Maybe RetryAfter Source #
The longest suggested RetryAfter among transient causes, or Nothing when
none of them suggested a delay.
Denial help text
data HelpMessage Source #
An operator-configured message appended to every denial, typically where to ask for help. Stored trimmed, so an all-blank value contributes nothing.
Instances
| Show HelpMessage Source # | |
Defined in Ecluse.Core.Server.Response Methods showsPrec :: Int -> HelpMessage -> ShowS # show :: HelpMessage -> String # showList :: [HelpMessage] -> ShowS # | |
| Eq HelpMessage Source # | |
Defined in Ecluse.Core.Server.Response | |
mkHelpMessage :: Text -> HelpMessage Source #
Build a HelpMessage, trimming surrounding whitespace.
appendHelp :: Maybe HelpMessage -> Text -> Text Source #
Append a non-blank operator HelpMessage to a denial message, separated by a single space.
A blank or absent help message contributes nothing.
A refusal's two parts
A refusal's text in its two parts, so an ecosystem renders whichever its own denial surface carries and the help message is not dropped for one with no envelope to hold both.
Constructors
| Refusal | |
Fields
| |
mkRefusal :: Maybe HelpMessage -> Text -> Refusal Source #
Pair a decided reason with the mount's configured help message, if it has a non-blank one.
renderRefusal :: Refusal -> Text Source #
The refusal as one line: the reason, with the help message appended after a single space.