Messages from %l to %g

This commit is contained in:
Elliot Glaysher 2018-09-20 16:36:04 -07:00
parent 36841a5280
commit e172e601f2
2 changed files with 203 additions and 36 deletions

View File

@ -118,14 +118,14 @@
:: +http-method: exhaustive list of http verbs :: +http-method: exhaustive list of http verbs
:: ::
+$ http-method +$ http-method
$? %'CONNECT' $? _'CONNECT'
%'DELETE' _'DELETE'
%'GET' _'GET'
%'HEAD' _'HEAD'
%'OPTIONS' _'OPTIONS'
%'POST' _'POST'
%'PUT' _'PUT'
%'TRACE' _'TRACE'
== ==
:: +http-request: a single http-request :: +http-request: a single http-request
:: ::
@ -174,6 +174,13 @@
:: ::
:: ::
$% [%build our=@p live=? schematic=schematic:ford] $% [%build our=@p live=? schematic=schematic:ford]
== ==
:: %g: to gall
::
$: %g
::
::
$% [%deal id=sock data=cush:gall]
== == == == == ==
-- --
:: more structures :: more structures
@ -208,6 +215,13 @@
:: the :binding into a (map (unit @t) (trie knot =action)). :: the :binding into a (map (unit @t) (trie knot =action)).
:: ::
bindings=(list [=binding =duct =action]) bindings=(list [=binding =duct =action])
:: outstanding: open http connections not fully complete
::
:: This refers to outstanding connections where the connection to
:: outside is opened and we are currently waiting on ford or an app to
:: produce the results.
::
outstanding=(map duct action)
== ==
:: +action: the action to take when a binding matches an incoming request :: +action: the action to take when a binding matches an incoming request
:: ::
@ -229,6 +243,23 @@
:: utilities :: utilities
:: ::
|% |%
:: +file-not-found-page: 404 page for when all other options failed
::
++ file-not-found-page
|= url=@t
^- octs
%- as-octs:mimes:html
%- crip
%- en-xml:html
;html
;head
;title:"404 Not Found"
==
;body
;h1:"Not Found"
;p:"The requested URL {<(trip url)>} was not found on this server."
==
==
:: +get-header: returns the value for :header, if it exists in :header-list :: +get-header: returns the value for :header, if it exists in :header-list
:: ::
++ get-header ++ get-header
@ -247,28 +278,52 @@
++ per-server-event ++ per-server-event
|= [[our=@p =duct now=@da scry=sley] state=server-state] |= [[our=@p =duct now=@da scry=sley] state=server-state]
|% |%
:: +request: starts handling an inbound http request
::
++ request ++ request
|= [secure=? =address =http-request] |= [secure=? =address =http-request]
^- [(list move) server-state] ^- [(list move) server-state]
:: ::
=+ host=(get-header 'Host' header-list.http-request) =+ host=(get-header 'Host' header-list.http-request)
=+ action=(get-action-for-binding host url.http-request) =+ action=(get-action-for-binding host url.http-request)
:: if no action matches, send the built in 404 page.
:: ::
?~ action ?~ action
~& %no-match-for-request :_ state
:: todo: return a reconstruction of the apache 404 page here :_ ~
:: :+ duct %give
[~ state] :* %http-response %start
status-code=404
:: TODO: Content-Length?
headers=['Content-Type' 'text/html']~
data=[~ (file-not-found-page url.http-request)]
complete=%.y
==
:: record that we started an asynchronous response
::
=. outstanding.state (~(put by outstanding.state) duct u.action)
:: ::
?- -.u.action ?- -.u.action
:: ::
%gen %gen
:: TODO: when we get here, we need to make sure that the generator has
:: been compiled.
::
~& [%i-should-run-a-generator generator.u.action] ~& [%i-should-run-a-generator generator.u.action]
[~ state] [~ state]
:: ::
%app %app
~& [%i-should-run-an-app app.u.action] :_ state
[~ state] :_ ~
:^ duct %pass /run-app/[app.u.action]
^- note
:^ %g %deal [our our]
:: todo: i don't entirely understand gall; there's a way to make a gall
:: use a %handle arm instead of a sub-%poke with the
:: %handle-http-request type.
::
^- cush:gall
[app.u.action %poke %handle-http-request !>([secure address http-request])]
== ==
:: +add-binding: conditionally add a pairing between binding and action :: +add-binding: conditionally add a pairing between binding and action
:: ::
@ -311,16 +366,6 @@
^- ? ^- ?
&(=(item-binding binding) =(item-duct duct)) &(=(item-binding binding) =(item-duct duct))
== ==
::
:: Split string by parsing rule delimiter.
++ split
|* {str/tape delim/cord}
^- (list tape)
%+ fall
(rust str (more (jest delim) (star ;~(less (jest delim) next))))
[str ~]
:: +get-action-for-binding: finds an action for an incoming web request :: +get-action-for-binding: finds an action for an incoming web request
:: ::
++ get-action-for-binding ++ get-action-for-binding
@ -352,12 +397,8 @@
raw-host raw-host
:: url is the raw thing passed over the 'Request-Line'. :: url is the raw thing passed over the 'Request-Line'.
:: ::
:: We need to handle both the form 'http://one.com/two/three' and
:: '/two/three', but we're punting for now and just doing a split on
:: '/'.
::
=/ parsed-url=(list @t) =/ parsed-url=(list @t)
(turn (split (trip url) '/') crip) q:(need (rush url apat:de-purl:html))
:: ::
=/ bindings bindings.state =/ bindings bindings.state
|- |-
@ -366,8 +407,13 @@
~ ~
:: ::
?: ?& =(site.binding.i.bindings host) ?: ?& =(site.binding.i.bindings host)
=(`0 (find path.binding.i.bindings parsed-url)) ?| :: root directory
== ::
&(=(~ parsed-url) =(~ path.binding.i.bindings))
:: everything else
::
=(`0 (find path.binding.i.bindings parsed-url))
== ==
`action.i.bindings `action.i.bindings
:: ::
$(bindings t.bindings) $(bindings t.bindings)

View File

@ -152,8 +152,51 @@
results3 results3
results4 results4
== ==
:: tests that when we have no match, that we fall back to the built-in 404
:: ::
++ test-basic-request ++ test-builtin-four-oh-four
::
=^ results1 light-gate
%- light-call :*
light-gate
now=~1111.1.1
scry=*sley
call-args=[duct=~[/init] ~ [%init ~nul]]
expected-moves=~
==
:: when there's no configuration and nothing matches, expect 404
::
=^ results2 light-gate
%- light-call :*
light-gate
now=~1111.1.1
scry=*sley
^= call-args
:* duct=~[/http-blah] ~
%inbound-request
%.n
[%ipv4 .192.168.1.1]
['GET' '/' ~ ~]
==
^= expectec-moves
^- (list move:light-gate)
:~ :* duct=~[/http-blah]
%give
%http-response
%start
404
['Content-Type' 'text/html']~
[~ (file-not-found-page:light-gate '/')]
complete=%.y
== ==
==
::
;: weld
results1
results2
==
::
++ test-basic-app-request
:: ::
=^ results1 light-gate =^ results1 light-gate
%- light-call :* %- light-call :*
@ -173,15 +216,42 @@
call-args=[duct=~[/app1] ~ [%connect [~ /] %app1]] call-args=[duct=~[/app1] ~ [%connect [~ /] %app1]]
expected-moves=[duct=~[/app1] %give %bound %.y [~ /]]~ expected-moves=[duct=~[/app1] %give %bound %.y [~ /]]~
== ==
:: :: outside requests a path that app1 has bound to
:: ::
=^ results3 light-gate =^ results3 light-gate
%- light-call :* %- light-call-with-comparator :*
light-gate light-gate
now=~1111.1.3 now=~1111.1.3
scry=*sley scry=*sley
call-args=[duct=~[/http-blah] ~ [%inbound-request %.n [%ipv4 .192.168.1.1]]] ^= call-args
expectec-moves=~ :* duct=~[/http-blah] ~
%inbound-request
%.n
[%ipv4 .192.168.1.1]
['GET' '/' ~ ~]
==
^= comparator
|= moves=(list move:light-gate)
^- tang
::
?. ?=([* ~] moves)
[%leaf "wrong number of moves: {<(lent moves)>}"]~
::
::
=/ move=move:light-gate i.moves
=/ =duct duct.move
=/ card=(wind note:light-gate gift:able:light-gate) card.move
::
%+ weld
(expect-eq !>(~[/http-blah]) !>(duct))
::
%+ expect-gall-deal
:+ /run-app/app1 [~nul ~nul]
^- cush:gall
:* %app1 %poke %handle-http-request
!>([%.n [%ipv4 .192.168.1.1] ['GET' '/' ~ ~]])
==
card
== ==
;: weld ;: weld
results1 results1
@ -208,4 +278,55 @@
!> moves !> moves
:: ::
[output light-gate] [output light-gate]
::
++ light-call-with-comparator
|= $: light-gate=_light-gate
now=@da
scry=sley
call-args=[=duct type=* wrapped-task=(hobo task:able:light-gate)]
move-comparator=$-((list move:light-gate) tang)
==
^- [tang _light-gate]
::
=/ light-core (light-gate now=now eny=0xdead.beef scry=scry)
::
=^ moves light-gate (call:light-core call-args)
::
=/ output=tang (move-comparator moves)
::
[output light-gate]
::
++ expect-gall-deal
|= $: expected=[wire=path id=sock data=cush:gall]
actual=(wind note:light-gate gift:able:light-gate)
==
^- tang
::
?. ?=(%pass -.actual)
[%leaf "bad move, not a %pass: {<actual>}"]~
::
%+ weld
(expect-eq !>(wire.expected) !>(p.actual))
::
=/ note=note:light-gate q.actual
?. ?=([%g %deal *] note)
[%leaf "bad move, not a %deal: {<actual>}"]~
::
%+ weld
(expect-eq !>(id.expected) !>(id.note))
::
%+ weld
(expect-eq !>(p.data.expected) !>(p.data.note))
:: todo: handle other deals
::
?. ?=([%poke *] q.data.note)
[%leaf "todo: can only handle %poke right now"]~
?. ?=([%poke *] q.data.expected)
[%leaf "todo: can only handle %poke right now"]~
::
%+ weld
(expect-eq !>(p.p.q.data.expected) !>(p.p.q.data.note))
:: compare the payload vases
::
(expect-eq q.p.q.data.expected q.p.q.data.note)
-- --