moonbitstack/moonhttp/conditional does not have a README file

    Ask

    pub(all) struct Ask {
    matching : Tags?
    none_matching : Tags?
    modified_since :
    Moment
    ?
    unmodified_since :
    Moment
    ?
    ranging : Validator?
    } derive(Eq,
    Debug
    )

    The five precondition fields of one request (§13.1), already read.

    Ask::equal

    fn Ask::equal(Ask, Ask) -> Bool

    Ask::evaluate

    fn Ask::evaluate(self : Ask, verb~ : String, etag? : Tag, modified? :
    Moment
    , present? : Bool) -> Verdict

    Weigh the preconditions in the order §13.2.2 sets out.

    verb is the request method (method is reserved). It decides what a failed If-None-Match means: 304 for a GET or HEAD, 412 otherwise. No default — guessing GET would tell a PUT its copy is current.

    etag and modified are what the server holds; present is whether it holds anything at all, which is all * asks.

    Ask::new

    fn Ask::new(matching? : Tags, none_matching? : Tags, modified_since? :
    Moment
    , unmodified_since? :
    Moment
    , ranging? : Validator) -> Ask

    The preconditions a request carried, named one at a time.

    Ask::not_equal

    fn Ask::not_equal(x : Ask, y : Ask) -> Bool

    Ask::read

    fn Ask::read(headers : ArrayView[(String, String)]) -> Ask

    Pull the five fields out of a request's headers.

    Names match without regard to case (§5.1). Two lines of one list-valued field are one list (§5.3), so the tag fields are joined before reading; the date fields are not lists, so a repeat is ignored.

    A field present but unreadable comes back absent, per §13.1.3 and §13.1.4.

    Ask::to_repr

    Ask::unchanged

    fn Ask::unchanged(self : Ask, etag? : Tag, modified? :
    Moment
    ) -> Bool

    Whether If-Range still holds, and so whether a Range may be honoured (§13.1.5). Absent holds: no condition, nothing in the way.

    Both kinds compare strongly, and a weak tag is refused rather than compared — "may these octets be spliced onto yours" is what a weak tag may not answer.

    Tag

    pub(all) struct Tag {
    text : String
    weak : Bool
    } derive(Eq,
    Debug
    )

    An entity-tag (RFC 9110 §8.8.3).

    text is what is inside the quotes; keeping them would put the field's syntax inside the value.

    weak is the W/ in front. Two weak tags mark representations that are equivalent, not identical — enough for "has this changed", not enough for "may I splice these two ranges".

    Tag::alike

    fn Tag::alike(self : Tag, other : Tag) -> Bool

    Weak comparison (§8.8.3.2): the texts match, weakness ignored.

    If-None-Match uses this one — a weak tag can answer "has it changed".

    Tag::decode

    fn Tag::decode(text : StringView) -> Tag?

    Read one entity-tag. None when it is not one — usually an unquoted value, which §8.8.3 has no room for.

    Tag::encode

    fn Tag::encode(self : Tag) -> String

    Write the tag as a field value: "x", or W/"x" (§8.8.3).

    Tag::equal

    fn Tag::equal(Tag, Tag) -> Bool

    Tag::new

    fn Tag::new(text : String, weak? : Bool) -> Tag

    A tag with this text.

    Tag::not_equal

    fn Tag::not_equal(x : Tag, y : Tag) -> Bool

    Tag::same

    fn Tag::same(self : Tag, other : Tag) -> Bool

    Strong comparison (§8.8.3.2): neither is weak and the texts match.

    If-Match and If-Range use this one — both are about replacing or splicing octets, which a weak tag does not promise.

    Tag::to_repr

    Tags

    pub(all) enum Tags {
    Any
    These(Array[Tag])
    } derive(Eq,
    Debug
    )

    What a precondition field names (§13.1.1): every representation, or these tags.

    * is not a tag that matches everything. §13.1.1 and §13.1.2 both read it as "does a representation exist", and answer in opposite directions.

    Tags::decode

    fn Tags::decode(text : StringView) -> Tags?

    Read a whole field value.

    Commas are found outside the quotes: , is in the etagc set (§8.8.3), so a tag may contain one. None when any member is not an entity-tag — §13.1.1 has no reading for half a list.

    Tags::encode

    fn Tags::encode(self : Tags) -> String

    Write a whole field value: *, or the tags separated by commas.

    Tags::equal

    fn Tags::equal(Tags, Tags) -> Bool

    Tags::not_equal

    fn Tags::not_equal(x : Tags, y : Tags) -> Bool

    Tags::to_repr

    Validator

    pub(all) enum Validator {
    Marked(Tag)
    Dated(
    Moment
    )
    } derive(Eq,
    Debug
    )

    Either kind of validator (§8.8). If-Range takes one or the other (§13.1.5); the other four fields each take one kind.

    Validator::decode

    fn Validator::decode(text : StringView) -> Validator?

    Read an If-Range value (§13.1.5).

    The first two characters tell them apart, as §13.1.5 says: only an entity-tag starts with a quote, only a weak one with W/.

    Validator::encode

    fn Validator::encode(self : Validator) -> String raise
    Refused

    Write an If-Range value. Raises for a moment with no zone — an HTTP-date is GMT by definition (§5.6.7).

    Validator::equal

    fn Validator::equal(Validator, Validator) -> Bool

    Validator::not_equal

    fn Validator::not_equal(x : Validator, y : Validator) -> Bool

    Verdict

    pub(all) enum Verdict {
    Go
    Fresh
    Failed
    } derive(Eq,
    Debug
    )

    What §13.2.2 says to do with the request once the preconditions are weighed.

    Verdict::equal

    fn Verdict::equal(Verdict, Verdict) -> Bool

    Verdict::not_equal

    fn Verdict::not_equal(x : Verdict, y : Verdict) -> Bool

    Verdict::to_repr

    ask

    let ask : Ask

    A request that carried no preconditions at all.

    hash

    fn hash(raw : BytesView, digest~ : &
    Hash
    , weak? : Bool) -> Tag

    An entity-tag from the octets themselves: their count and their digest, both in hexadecimal. Strong, which is the point of hashing the content.

    digest is a parameter — which hash to spend on every response is the server's trade. The shape is the etag package Express serves static files with, "<length>-<digest>", in nginx and Apache's hexadecimal.

    stamp

    fn stamp(length~ : Int64, modified~ :
    Moment
    , weak? : Bool) -> Tag

    An entity-tag from what a file system knows without opening the file: when it last changed and how long it is. nginx's "<mtime>-<length>", one stat.

    Weak, as a one-second timestamp must be: two writes inside the same second leave both numbers unchanged.

    Source Files