http_router/router.bend checks
raw source on the hub · import 0x64e1b9e0466cf913fa57e70aeb11c176/http_router/router.bend as Router
3 imports
import Base import ../http/method.bend as M import ../http/request.bend as Req
Types
type Seg source · line 14 · raw
Data
a pattern's segment: a literal, or a :name capture
Lit@text:String -> Seg
Cap@name:String -> Seg
type Route source · line 18 · raw
@-R:Data -> Data
Route@-R:Data -> @method:0x64e1b9e0466cf913fa57e70aeb11c176/http/method.Method -> @path:List<&2, Seg> -> @route:R -> Route<R>
type Param source · line 22 · raw
Data
a captured segment
Param@name:String -> @value:String -> Param
type Match source · line 25 · raw
@-R:Data -> Data
Found@-R:Data -> @route:R -> @params:List<&2, Param> -> Match<R>
NotFound@-R:Data -> Match<R>
MethodNotAllowed@-R:Data -> @allowed:List<&2, 0x64e1b9e0466cf913fa57e70aeb11c176/http/method.Method> -> Match<R>
type Parts source · line 33 · raw
Data
A request's path, cut at /. A type of its own, not a List<String>: every route reads it, and a generic List read and then used again makes Lists reference counted in the whole program
PNilParts
PCon@head:String -> @tail:Parts -> Parts
type Acc source · line 167 · raw
@-R:Data -> Data
the scan so far: a route found, or the methods of routes whose path matched (for 405 and its Allow header)
AFound@-R:Data -> @route:R -> @params:List<&2, Param> -> Acc<R>
ANone@-R:Data -> @allowed:List<&2, 0x64e1b9e0466cf913fa57e70aeb11c176/http/method.Method> -> Acc<R>
type Routed source · line 214 · raw
@-R:Data -> Data
a match, and the request it came from, untouched
Routed@-R:Data -> @found:Match<R> -> @req:0x64e1b9e0466cf913fa57e70aeb11c176/http/request.Request -> Routed<R>
Definitions
def same source · line 39 · raw
@a:String -> @b:String -> @ok:Bool -> Bool
the router's own compare: sharing http's with the server makes one def both a reader here and an owner there
def parts.rev source · line 48 · raw
@p:Parts -> @acc:Parts -> Parts
def parts.go source · line 55 · raw
@s:String -> @cur:String -> @acc:Parts -> Parts
def parts source · line 65 · raw
@path:String -> Parts
"/todos/7" is todos, 7; "/" is one empty part; a trailing / adds one
def segs.go source · line 72 · raw
@p:Parts -> @acc:List<&2, Seg> -> List<&2, Seg>
def pattern source · line 82 · raw
@s:String -> List<&2, Seg>
a pattern like "/todos/:id"
def get source · line 85 · raw
@-R:Data -> @p:String -> @r:R -> Route<R>
def post source · line 88 · raw
@-R:Data -> @p:String -> @r:R -> Route<R>
def put source · line 91 · raw
@-R:Data -> @p:String -> @r:R -> Route<R>
def patch source · line 94 · raw
@-R:Data -> @p:String -> @r:R -> Route<R>
def delete source · line 97 · raw
@-R:Data -> @p:String -> @r:R -> Route<R>
def route source · line 100 · raw
@-R:Data -> @m:0x64e1b9e0466cf913fa57e70aeb11c176/http/method.Method -> @p:String -> @r:R -> Route<R>
def copy source · line 104 · raw
@s:String -> @acc:String -> String
a copy, built by reading only: the request's parts are read by every route
def filled source · line 112 · raw
@s:String -> Bool
a capture takes a segment with something in it: /todos/ is not /todos/:id
def bind.end source · line 119 · raw
@ok:Bool -> @acc:List<&2, Param> -> Maybe<&2, List<&2, Param>>
def bind source · line 129 · raw
@pat:List<&2, Seg> -> @ps:Parts -> @acc:List<&2, Param> -> @ok:Bool -> Maybe<&2, List<&2, Param>>
the captures, if the pattern matches the parts; None if it does not. ok says the literals so far matched: the walk goes on either way, so there is one loop
def method_eq source · line 140 · raw
@a:0x64e1b9e0466cf913fa57e70aeb11c176/http/method.Method -> @b:0x64e1b9e0466cf913fa57e70aeb11c176/http/method.Method -> Bool
def acc.step source · line 171 · raw
@-R:Data -> @st:Acc<R> -> @bound:Maybe<&2, List<&2, Param>> -> @same:Bool -> @m:0x64e1b9e0466cf913fa57e70aeb11c176/http/method.Method -> @r:R -> Acc<R>
def acc.end source · line 182 · raw
@-R:Data -> @st:Acc<R> -> Match<R>
def find.go source · line 192 · raw
@-R:Data -> @rs:List<&2, Route<R>> -> @+method:0x64e1b9e0466cf913fa57e70aeb11c176/http/method.Method -> @+ps:Parts -> @st:Acc<R> -> Match<R>
every route is tried, in order; the first whose method and path match wins
def path.of source · line 200 · raw
@s:String -> @acc:String -> String
a copy of the target's path, up to any ?, built by reading it only
def find source · line 210 · raw
@-R:Data -> @rs:List<&2, Route<R>> -> @method:0x64e1b9e0466cf913fa57e70aeb11c176/http/method.Method -> @target:String -> Match<R>
the match for a method and a target (its path before any ?)
def route_req source · line 220 · raw
@-R:Data -> @rs:List<&2, Route<R>> -> @r:0x64e1b9e0466cf913fa57e70aeb11c176/http/request.Request -> Routed<R>
match a request, handing it back for the handler. It reads the target here rather than through find: a def whose last use of a String is a read takes it, so the read must be in the def that uses the String after
def param.keep source · line 225 · raw
@hit:Bool -> @v:String -> @acc:Maybe<&2, String> -> Maybe<&2, String>
def get.go source · line 232 · raw
@ps:List<&2, Param> -> @+name:String -> @acc:Maybe<&2, String> -> Maybe<&2, String>
def param source · line 240 · raw
@ps:List<&2, Param> -> @+name:String -> Maybe<&2, String>
a capture's value
def allow.go source · line 243 · raw
@ms:List<&2, 0x64e1b9e0466cf913fa57e70aeb11c176/http/method.Method> -> @out:String -> String
def allow source · line 253 · raw
@ms:List<&2, 0x64e1b9e0466cf913fa57e70aeb11c176/http/method.Method> -> String
the Allow header's value for a 405 (RFC 9110 §10.2.1): "GET, POST"