~/bend-docscommunity

http/headers.bend source

http/headers.bend on the hub · documented module

import Baseimport ./text.bend as T# header fields in the order they came (RFC 9110 §5); a name may repeat,# and names compare ignoring casetype Header is Data:  Header{name: String, value: String}def Headers() -> Type:  List<&2, Header># headers' own compare: http1 calls T.same_ci with literals, which makes# it the owner of what it reads; a name used for every header would then# be shareddef name_eq(a: String, b: String, ok: Bool) -> Bool:  match a b:    case SNil{} SNil{}:      ok    case SCon{Chr{+x}, at} SCon{Chr{+y}, bt}:      name_eq(at, bt, Bool.and(ok, T.fold.eq(x, y)))    case _ _:      False{}def keep(hit: Bool, v: String, found: Maybe<&2, String>) -> Maybe<&2, String>:  match hit found:    case True{} None{}:      Some{v}    case _ other:      otherdef get.go(hs: List<&2, Header>, +name: String, found: Maybe<&2, String>) -> Maybe<&2, String>:  match hs:    case Nil{}:      found    case Con{Header{n, v}, t}:      get.go(t, name, keep(name_eq(n, name, True{}), v, found))# the first value of a headerdef get(hs: List<&2, Header>, +name: String) -> Maybe<&2, String>:  get.go(hs, name, None{})def all.add(hit: Bool, v: String, acc: List<&2, String>) -> List<&2, String>:  match hit:    case True{}:      Con{v, acc}    case False{}:      accdef all.go(hs: List<&2, Header>, +name: String, acc: List<&2, String>) -> List<&2, String>:  match hs:    case Nil{}:      List.reverse(&2, String, acc)    case Con{Header{n, v}, t}:      all.go(t, name, all.add(name_eq(n, name, True{}), v, acc))# every value of a header, in orderdef all(hs: List<&2, Header>, +name: String) -> List<&2, String>:  all.go(hs, name, [])def drop.keep(hit: Bool, h: Header, acc: List<&2, Header>) -> List<&2, Header>:  match hit:    case True{}:      acc    case False{}:      Con{h, acc}def drop.go(hs: List<&2, Header>, +name: String, acc: List<&2, Header>) -> List<&2, Header>:  match hs:    case Nil{}:      List.reverse(&2, Header, acc)    case Con{Header{+n, v}, t}:      drop.go(t, name, drop.keep(name_eq(n, name, True{}), Header{n, v}, acc))# every header but those named namedef remove(hs: List<&2, Header>, +name: String) -> List<&2, Header>:  drop.go(hs, name, [])# one more header, after the othersdef add(hs: List<&2, Header>, name: String, value: String) -> List<&2, Header>:  List.append(&2, Header, hs, [Header{name, value}])# the header set to one value, replacing any othersdef set(hs: List<&2, Header>, +name: String, value: String) -> List<&2, Header>:  add(remove(hs, name), name, value)