mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-19 12:51:51 +03:00
Merge pull request #6472 from urbit/x/json-bgon
eyre: add support for noun-based channels
This commit is contained in:
commit
03e85551f6
@ -7,7 +7,7 @@
|
|||||||
|_ mud=@
|
|_ mud=@
|
||||||
++ grow
|
++ grow
|
||||||
|%
|
|%
|
||||||
++ mime [/application/octet-stream (as-octs mud)]
|
++ mime [/application/x-urb-jam (as-octs mud)]
|
||||||
--
|
--
|
||||||
++ grab
|
++ grab
|
||||||
|% :: convert from
|
|% :: convert from
|
||||||
|
@ -1536,7 +1536,8 @@
|
|||||||
:: events since then.
|
:: events since then.
|
||||||
::
|
::
|
||||||
+$ channel
|
+$ channel
|
||||||
$: :: channel-state: expiration time or the duct currently listening
|
$: mode=?(%json %jam)
|
||||||
|
:: channel-state: expiration time or the duct currently listening
|
||||||
::
|
::
|
||||||
:: For each channel, there is at most one open EventSource
|
:: For each channel, there is at most one open EventSource
|
||||||
:: connection. A 400 is issues on duplicate attempts to connect to the
|
:: connection. A 400 is issues on duplicate attempts to connect to the
|
||||||
|
@ -67,8 +67,12 @@
|
|||||||
:: more structures
|
:: more structures
|
||||||
::
|
::
|
||||||
|%
|
|%
|
||||||
+$ axle
|
++ axle
|
||||||
$: %~2023.3.16
|
$: :: date: date at which http-server's state was updated to this data structure
|
||||||
|
::
|
||||||
|
date=%~2023.4.11
|
||||||
|
:: server-state: state of inbound requests
|
||||||
|
::
|
||||||
=server-state
|
=server-state
|
||||||
==
|
==
|
||||||
:: +server-state: state relating to open inbound HTTP connections
|
:: +server-state: state relating to open inbound HTTP connections
|
||||||
@ -121,9 +125,12 @@
|
|||||||
$% :: %ack: acknowledges that the client has received events up to :id
|
$% :: %ack: acknowledges that the client has received events up to :id
|
||||||
::
|
::
|
||||||
[%ack event-id=@ud]
|
[%ack event-id=@ud]
|
||||||
:: %poke: pokes an application, translating :json to :mark.
|
:: %poke: pokes an application, validating :noun against :mark
|
||||||
::
|
::
|
||||||
[%poke request-id=@ud ship=@p app=term mark=@tas =json]
|
[%poke request-id=@ud ship=@p app=term mark=@tas =noun]
|
||||||
|
:: %poke-json: pokes an application, translating :json to :mark
|
||||||
|
::
|
||||||
|
[%poke-json request-id=@ud ship=@p app=term mark=@tas =json]
|
||||||
:: %watch: subscribes to an application path
|
:: %watch: subscribes to an application path
|
||||||
::
|
::
|
||||||
[%subscribe request-id=@ud ship=@p app=term =path]
|
[%subscribe request-id=@ud ship=@p app=term =path]
|
||||||
@ -200,13 +207,44 @@
|
|||||||
%+ ~(put by unacked) rid
|
%+ ~(put by unacked) rid
|
||||||
?: (lte u.sus ack) 0
|
?: (lte u.sus ack) 0
|
||||||
(sub u.sus ack)
|
(sub u.sus ack)
|
||||||
|
:: +find-channel-mode: deduce requested mode from headers
|
||||||
|
::
|
||||||
|
++ find-channel-mode
|
||||||
|
|= [met=method:http hes=header-list:http]
|
||||||
|
^- ?(%json %jam)
|
||||||
|
=+ ^- [hed=@t jam=@t]
|
||||||
|
?: ?=(%'GET' met) ['x-channel-format' 'application/x-urb-jam']
|
||||||
|
['content-type' 'application/x-urb-jam']
|
||||||
|
=+ typ=(bind (get-header:http hed hes) :(cork trip cass crip))
|
||||||
|
?:(=(`jam typ) %jam %json)
|
||||||
:: +parse-channel-request: parses a list of channel-requests
|
:: +parse-channel-request: parses a list of channel-requests
|
||||||
::
|
::
|
||||||
|
++ parse-channel-request
|
||||||
|
|= [mode=?(%json %jam) body=octs]
|
||||||
|
^- (each (list channel-request) @t)
|
||||||
|
?- mode
|
||||||
|
%json
|
||||||
|
?~ maybe-json=(de-json:html q.body)
|
||||||
|
|+'put body not json'
|
||||||
|
?~ maybe-requests=(parse-channel-request-json u.maybe-json)
|
||||||
|
|+'invalid channel json'
|
||||||
|
&+u.maybe-requests
|
||||||
|
::
|
||||||
|
%jam
|
||||||
|
?~ maybe-noun=(bind (slaw %uw q.body) cue)
|
||||||
|
|+'invalid request format'
|
||||||
|
?~ maybe-reqs=((soft (list channel-request)) u.maybe-noun)
|
||||||
|
~& [%miss u.maybe-noun]
|
||||||
|
|+'invalid request data'
|
||||||
|
&+u.maybe-reqs
|
||||||
|
==
|
||||||
|
:: +parse-channel-request-json: parses a json list of channel-requests
|
||||||
|
::
|
||||||
:: Parses a json array into a list of +channel-request. If any of the items
|
:: Parses a json array into a list of +channel-request. If any of the items
|
||||||
:: in the list fail to parse, the entire thing fails so we can 400 properly
|
:: in the list fail to parse, the entire thing fails so we can 400 properly
|
||||||
:: to the client.
|
:: to the client.
|
||||||
::
|
::
|
||||||
++ parse-channel-request
|
++ parse-channel-request-json
|
||||||
|= request-list=json
|
|= request-list=json
|
||||||
^- (unit (list channel-request))
|
^- (unit (list channel-request))
|
||||||
:: parse top
|
:: parse top
|
||||||
@ -222,7 +260,9 @@
|
|||||||
?: =('ack' u.maybe-key)
|
?: =('ack' u.maybe-key)
|
||||||
((pe %ack (ot event-id+ni ~)) item)
|
((pe %ack (ot event-id+ni ~)) item)
|
||||||
?: =('poke' u.maybe-key)
|
?: =('poke' u.maybe-key)
|
||||||
((pe %poke (ot id+ni ship+(su fed:ag) app+so mark+(su sym) json+some ~)) item)
|
%. item
|
||||||
|
%+ pe %poke-json
|
||||||
|
(ot id+ni ship+(su fed:ag) app+so mark+(su sym) json+some ~)
|
||||||
?: =('subscribe' u.maybe-key)
|
?: =('subscribe' u.maybe-key)
|
||||||
%. item
|
%. item
|
||||||
%+ pe %subscribe
|
%+ pe %subscribe
|
||||||
@ -1234,7 +1274,7 @@
|
|||||||
:: state.
|
:: state.
|
||||||
::
|
::
|
||||||
++ update-timeout-timer-for
|
++ update-timeout-timer-for
|
||||||
|= channel-id=@t
|
|= [mode=?(%json %jam) channel-id=@t]
|
||||||
^+ ..update-timeout-timer-for
|
^+ ..update-timeout-timer-for
|
||||||
:: when our callback should fire
|
:: when our callback should fire
|
||||||
::
|
::
|
||||||
@ -1246,7 +1286,7 @@
|
|||||||
%_ ..update-timeout-timer-for
|
%_ ..update-timeout-timer-for
|
||||||
session.channel-state.state
|
session.channel-state.state
|
||||||
%+ ~(put by session.channel-state.state) channel-id
|
%+ ~(put by session.channel-state.state) channel-id
|
||||||
[[%& expiration-time duct] 0 now ~ ~ ~ ~]
|
[mode [%& expiration-time duct] 0 now ~ ~ ~ ~]
|
||||||
::
|
::
|
||||||
moves
|
moves
|
||||||
[(set-timeout-move channel-id expiration-time) moves]
|
[(set-timeout-move channel-id expiration-time) moves]
|
||||||
@ -1301,10 +1341,19 @@
|
|||||||
|= [channel-id=@t =request:http]
|
|= [channel-id=@t =request:http]
|
||||||
^- [(list move) server-state]
|
^- [(list move) server-state]
|
||||||
:: if there's no channel-id, we must 404
|
:: if there's no channel-id, we must 404
|
||||||
|
::TODO but arm description says otherwise?
|
||||||
::
|
::
|
||||||
?~ maybe-channel=(~(get by session.channel-state.state) channel-id)
|
?~ maybe-channel=(~(get by session.channel-state.state) channel-id)
|
||||||
%^ return-static-data-on-duct 404 'text/html'
|
%^ return-static-data-on-duct 404 'text/html'
|
||||||
(error-page 404 %.y url.request ~)
|
(error-page 404 %.y url.request ~)
|
||||||
|
:: find the requested "mode" and make sure it doesn't conflict
|
||||||
|
::
|
||||||
|
=/ mode=?(%json %jam)
|
||||||
|
(find-channel-mode %'GET' header-list.request)
|
||||||
|
?. =(mode mode.u.maybe-channel)
|
||||||
|
%^ return-static-data-on-duct 406 'text/html'
|
||||||
|
=; msg=tape (error-page 406 %.y url.request msg)
|
||||||
|
"channel already established in {(trip mode.u.maybe-channel)} mode"
|
||||||
:: when opening an event-stream, we must cancel our timeout timer
|
:: when opening an event-stream, we must cancel our timeout timer
|
||||||
:: if there's no duct already bound. Else, kill the old request
|
:: if there's no duct already bound. Else, kill the old request
|
||||||
:: and replace it
|
:: and replace it
|
||||||
@ -1349,8 +1398,10 @@
|
|||||||
=/ sign
|
=/ sign
|
||||||
(channel-event-to-sign u.maybe-channel request-id channel-event)
|
(channel-event-to-sign u.maybe-channel request-id channel-event)
|
||||||
?~ sign $
|
?~ sign $
|
||||||
?~ jive=(sign-to-json u.maybe-channel request-id u.sign) $
|
=/ said
|
||||||
$(events [(event-json-to-wall id +.u.jive) events])
|
(sign-to-tape u.maybe-channel request-id u.sign)
|
||||||
|
?~ said $
|
||||||
|
$(events [(event-tape-to-wall id +.u.said) events])
|
||||||
:: send the start event to the client
|
:: send the start event to the client
|
||||||
::
|
::
|
||||||
=^ http-moves state
|
=^ http-moves state
|
||||||
@ -1382,13 +1433,18 @@
|
|||||||
::
|
::
|
||||||
=/ heartbeat-time=@da (add now ~s20)
|
=/ heartbeat-time=@da (add now ~s20)
|
||||||
=/ heartbeat (set-heartbeat-move channel-id heartbeat-time)
|
=/ heartbeat (set-heartbeat-move channel-id heartbeat-time)
|
||||||
:: clear the event queue, record the duct for future output and
|
:: clear the event queue, record the mode & duct for future output,
|
||||||
:: record heartbeat-time for possible future cancel
|
:: and record heartbeat-time for possible future cancel
|
||||||
::
|
::
|
||||||
=. session.channel-state.state
|
=. session.channel-state.state
|
||||||
%+ ~(jab by session.channel-state.state) channel-id
|
%+ ~(jab by session.channel-state.state) channel-id
|
||||||
|= =channel
|
|= =channel
|
||||||
channel(events ~, state [%| duct], heartbeat (some [heartbeat-time duct]))
|
%_ channel
|
||||||
|
mode mode
|
||||||
|
events ~
|
||||||
|
state [%| duct]
|
||||||
|
heartbeat (some [heartbeat-time duct])
|
||||||
|
==
|
||||||
::
|
::
|
||||||
[[heartbeat :(weld http-moves cancel-moves moves)] state]
|
[[heartbeat :(weld http-moves cancel-moves moves)] state]
|
||||||
:: +acknowledge-events: removes events before :last-event-id on :channel-id
|
:: +acknowledge-events: removes events before :last-event-id on :channel-id
|
||||||
@ -1420,19 +1476,19 @@
|
|||||||
?~ body.request
|
?~ body.request
|
||||||
%^ return-static-data-on-duct 400 'text/html'
|
%^ return-static-data-on-duct 400 'text/html'
|
||||||
(error-page 400 %.y url.request "no put body")
|
(error-page 400 %.y url.request "no put body")
|
||||||
:: if the incoming body isn't json, this is a bad request, 400.
|
|
||||||
::
|
::
|
||||||
?~ maybe-json=(de-json:html q.u.body.request)
|
=/ mode=?(%json %jam)
|
||||||
%^ return-static-data-on-duct 400 'text/html'
|
(find-channel-mode %'PUT' header-list.request)
|
||||||
(error-page 400 %.y url.request "put body not json")
|
:: if we cannot parse requests from the body, give an error
|
||||||
:: parse the json into an array of +channel-request items
|
|
||||||
::
|
::
|
||||||
?~ maybe-requests=(parse-channel-request u.maybe-json)
|
=/ maybe-requests=(each (list channel-request) @t)
|
||||||
|
(parse-channel-request mode u.body.request)
|
||||||
|
?: ?=(%| -.maybe-requests)
|
||||||
%^ return-static-data-on-duct 400 'text/html'
|
%^ return-static-data-on-duct 400 'text/html'
|
||||||
(error-page 400 %.y url.request "invalid channel json")
|
(error-page 400 & url.request (trip p.maybe-requests))
|
||||||
:: while weird, the request list could be empty
|
:: while weird, the request list could be empty
|
||||||
::
|
::
|
||||||
?: =(~ u.maybe-requests)
|
?: =(~ p.maybe-requests)
|
||||||
%^ return-static-data-on-duct 400 'text/html'
|
%^ return-static-data-on-duct 400 'text/html'
|
||||||
(error-page 400 %.y url.request "empty list of actions")
|
(error-page 400 %.y url.request "empty list of actions")
|
||||||
:: check for the existence of the channel-id
|
:: check for the existence of the channel-id
|
||||||
@ -1441,10 +1497,10 @@
|
|||||||
:: :channel-timeout from now. if we have one which has a timer, update
|
:: :channel-timeout from now. if we have one which has a timer, update
|
||||||
:: that timer.
|
:: that timer.
|
||||||
::
|
::
|
||||||
=. ..on-put-request (update-timeout-timer-for channel-id)
|
=. ..on-put-request (update-timeout-timer-for mode channel-id)
|
||||||
:: for each request, execute the action passed in
|
:: for each request, execute the action passed in
|
||||||
::
|
::
|
||||||
=+ requests=u.maybe-requests
|
=+ requests=p.maybe-requests
|
||||||
:: gall-moves: put moves here first so we can flop for ordering
|
:: gall-moves: put moves here first so we can flop for ordering
|
||||||
::
|
::
|
||||||
:: TODO: Have an error state where any invalid duplicate subscriptions
|
:: TODO: Have an error state where any invalid duplicate subscriptions
|
||||||
@ -1475,7 +1531,7 @@
|
|||||||
requests t.requests
|
requests t.requests
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
%poke
|
?(%poke %poke-json)
|
||||||
::
|
::
|
||||||
=. gall-moves
|
=. gall-moves
|
||||||
:_ gall-moves
|
:_ gall-moves
|
||||||
@ -1483,7 +1539,12 @@
|
|||||||
:^ duct %pass /channel/poke/[channel-id]/(scot %ud request-id.i.requests)
|
:^ duct %pass /channel/poke/[channel-id]/(scot %ud request-id.i.requests)
|
||||||
=, i.requests
|
=, i.requests
|
||||||
:* %g %deal `sock`[our ship] app
|
:* %g %deal `sock`[our ship] app
|
||||||
`task:agent:gall`[%poke-as mark %json !>(json)]
|
^- task:agent:gall
|
||||||
|
:+ %poke-as mark
|
||||||
|
?- -.i.requests
|
||||||
|
%poke [%noun !>(noun)]
|
||||||
|
%poke-json [%json !>(json)]
|
||||||
|
==
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
$(requests t.requests)
|
$(requests t.requests)
|
||||||
@ -1618,18 +1679,16 @@
|
|||||||
:: if conversion succeeds, we *can* send it. if the client is actually
|
:: if conversion succeeds, we *can* send it. if the client is actually
|
||||||
:: connected, we *will* send it immediately.
|
:: connected, we *will* send it immediately.
|
||||||
::
|
::
|
||||||
=/ jive=(unit (quip move json))
|
=/ said=(unit (quip move tape))
|
||||||
(sign-to-json u.channel request-id sign)
|
(sign-to-tape u.channel request-id sign)
|
||||||
=/ json=(unit json)
|
=? moves ?=(^ said)
|
||||||
?~(jive ~ `+.u.jive)
|
(weld moves -.u.said)
|
||||||
=? moves ?=(^ jive)
|
=* sending &(?=([%| *] state.u.channel) ?=(^ said))
|
||||||
(weld moves -.u.jive)
|
|
||||||
=* sending &(?=([%| *] state.u.channel) ?=(^ json))
|
|
||||||
::
|
::
|
||||||
=/ next-id next-id.u.channel
|
=/ next-id next-id.u.channel
|
||||||
:: if we can send it, store the event as unacked
|
:: if we can send it, store the event as unacked
|
||||||
::
|
::
|
||||||
=? events.u.channel ?=(^ json)
|
=? events.u.channel ?=(^ said)
|
||||||
%- ~(put to events.u.channel)
|
%- ~(put to events.u.channel)
|
||||||
[next-id request-id (sign-to-channel-event sign)]
|
[next-id request-id (sign-to-channel-event sign)]
|
||||||
:: if it makes sense to do so, send the event to the client
|
:: if it makes sense to do so, send the event to the client
|
||||||
@ -1645,11 +1704,11 @@
|
|||||||
::
|
::
|
||||||
^= data
|
^= data
|
||||||
%- wall-to-octs
|
%- wall-to-octs
|
||||||
(event-json-to-wall next-id (need json))
|
(event-tape-to-wall next-id +:(need said))
|
||||||
::
|
::
|
||||||
complete=%.n
|
complete=%.n
|
||||||
==
|
==
|
||||||
=? next-id ?=(^ json) +(next-id)
|
=? next-id ?=(^ said) +(next-id)
|
||||||
:: update channel's unacked counts, find out if clogged
|
:: update channel's unacked counts, find out if clogged
|
||||||
::
|
::
|
||||||
=^ clogged unacked.u.channel
|
=^ clogged unacked.u.channel
|
||||||
@ -1657,7 +1716,7 @@
|
|||||||
:: and of course don't count events we can't send as unacked.
|
:: and of course don't count events we can't send as unacked.
|
||||||
::
|
::
|
||||||
?: ?| !?=(%fact -.sign)
|
?: ?| !?=(%fact -.sign)
|
||||||
?=(~ json)
|
?=(~ said)
|
||||||
==
|
==
|
||||||
[| unacked.u.channel]
|
[| unacked.u.channel]
|
||||||
=/ num=@ud
|
=/ num=@ud
|
||||||
@ -1673,7 +1732,7 @@
|
|||||||
=/ kicking=?
|
=/ kicking=?
|
||||||
?: clogged
|
?: clogged
|
||||||
((trace 0 |.("clogged {msg}")) &)
|
((trace 0 |.("clogged {msg}")) &)
|
||||||
?. ?=(~ json) |
|
?. ?=(~ said) |
|
||||||
((trace 0 |.("can't serialize event, kicking {msg}")) &)
|
((trace 0 |.("can't serialize event, kicking {msg}")) &)
|
||||||
=? moves kicking
|
=? moves kicking
|
||||||
:_ moves
|
:_ moves
|
||||||
@ -1705,8 +1764,8 @@
|
|||||||
::
|
::
|
||||||
^= data
|
^= data
|
||||||
%- wall-to-octs
|
%- wall-to-octs
|
||||||
%+ event-json-to-wall next-id
|
%+ event-tape-to-wall next-id
|
||||||
+:(need (sign-to-json u.channel request-id %kick ~))
|
+:(need (sign-to-tape u.channel request-id %kick ~))
|
||||||
::
|
::
|
||||||
complete=%.n
|
complete=%.n
|
||||||
==
|
==
|
||||||
@ -1759,6 +1818,17 @@
|
|||||||
?: ?=(%| -.res)
|
?: ?=(%| -.res)
|
||||||
((trace 0 |.("stale fact of mark {(trip have)}")) ~)
|
((trace 0 |.("stale fact of mark {(trip have)}")) ~)
|
||||||
`[%fact have p.res]
|
`[%fact have p.res]
|
||||||
|
:: +sign-to-tape: render sign from request-id in specified mode
|
||||||
|
::
|
||||||
|
++ sign-to-tape
|
||||||
|
|= [=channel request-id=@ud =sign:agent:gall]
|
||||||
|
^- (unit (quip move tape))
|
||||||
|
?- mode.channel
|
||||||
|
%json %+ bind (sign-to-json channel request-id sign)
|
||||||
|
|=((quip move json) [+<- (en-json:html +<+)])
|
||||||
|
%jam =- `[~ (scow %uw (jam -))]
|
||||||
|
[request-id (sign-to-channel-event sign)]
|
||||||
|
==
|
||||||
:: +sign-to-json: render sign from request-id as json channel event
|
:: +sign-to-json: render sign from request-id as json channel event
|
||||||
::
|
::
|
||||||
++ sign-to-json
|
++ sign-to-json
|
||||||
@ -1827,12 +1897,12 @@
|
|||||||
==
|
==
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
++ event-json-to-wall
|
++ event-tape-to-wall
|
||||||
~% %eyre-json-to-wall ..part ~
|
~% %eyre-tape-to-wall ..part ~
|
||||||
|= [event-id=@ud =json]
|
|= [event-id=@ud =tape]
|
||||||
^- wall
|
^- wall
|
||||||
:~ (weld "id: " (format-ud-as-integer event-id))
|
:~ (weld "id: " (format-ud-as-integer event-id))
|
||||||
(weld "data: " (en-json:html json))
|
(weld "data: " tape)
|
||||||
""
|
""
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
@ -2152,6 +2222,8 @@
|
|||||||
::
|
::
|
||||||
=/ request-line (parse-request-line url)
|
=/ request-line (parse-request-line url)
|
||||||
=/ parsed-url=(list @t) site.request-line
|
=/ parsed-url=(list @t) site.request-line
|
||||||
|
=? parsed-url ?=([%'~' %channel-jam *] parsed-url)
|
||||||
|
parsed-url(i.t %channel)
|
||||||
::
|
::
|
||||||
=/ bindings bindings.state
|
=/ bindings bindings.state
|
||||||
|-
|
|-
|
||||||
@ -2648,6 +2720,9 @@
|
|||||||
::
|
::
|
||||||
?^ error.sign
|
?^ error.sign
|
||||||
[[duct %slip %d %flog %crud %wake u.error.sign]~ http-server-gate]
|
[[duct %slip %d %flog %crud %wake u.error.sign]~ http-server-gate]
|
||||||
|
::NOTE we are not concerned with expiring channels that are still in
|
||||||
|
:: use. we require acks for messages, which bump their session's
|
||||||
|
:: timer. channels have their own expiry timer, too.
|
||||||
:: remove cookies that have expired
|
:: remove cookies that have expired
|
||||||
::
|
::
|
||||||
=* sessions sessions.authentication-state.server-state.ax
|
=* sessions sessions.authentication-state.server-state.ax
|
||||||
@ -2689,100 +2764,111 @@
|
|||||||
++ load
|
++ load
|
||||||
=> |%
|
=> |%
|
||||||
+$ axle-any
|
+$ axle-any
|
||||||
$% [%~2020.10.18 =server-state-0]
|
$% [date=%~2020.10.18 server-state=server-state-0]
|
||||||
[%~2022.7.26 =server-state-0]
|
[date=%~2022.7.26 server-state=server-state-0]
|
||||||
[%~2023.2.17 =server-state-1]
|
[date=%~2023.2.17 server-state=server-state-1]
|
||||||
[%~2023.3.16 =server-state]
|
[date=%~2023.3.16 server-state=server-state-2]
|
||||||
|
[date=%~2023.4.11 =server-state]
|
||||||
==
|
==
|
||||||
|
::
|
||||||
+$ server-state-0
|
+$ server-state-0
|
||||||
$: bindings=(list [=binding =duct =action])
|
$: bindings=(list [=binding =duct =action])
|
||||||
=cors-registry
|
=cors-registry
|
||||||
connections=(map duct outstanding-connection)
|
connections=(map duct outstanding-connection)
|
||||||
=authentication-state
|
=authentication-state
|
||||||
=channel-state
|
channel-state=channel-state-2
|
||||||
domains=(set turf)
|
domains=(set turf)
|
||||||
=http-config
|
=http-config
|
||||||
ports=[insecure=@ud secure=(unit @ud)]
|
ports=[insecure=@ud secure=(unit @ud)]
|
||||||
outgoing-duct=duct
|
outgoing-duct=duct
|
||||||
==
|
==
|
||||||
|
::
|
||||||
+$ server-state-1
|
+$ server-state-1
|
||||||
$: bindings=(list [=binding =duct =action])
|
$: bindings=(list [=binding =duct =action])
|
||||||
=cors-registry
|
=cors-registry
|
||||||
connections=(map duct outstanding-connection)
|
connections=(map duct outstanding-connection)
|
||||||
=authentication-state
|
=authentication-state
|
||||||
=channel-state
|
channel-state=channel-state-2
|
||||||
|
domains=(set turf)
|
||||||
|
=http-config
|
||||||
|
ports=[insecure=@ud secure=(unit @ud)]
|
||||||
|
outgoing-duct=duct
|
||||||
|
verb=@ :: <- new
|
||||||
|
==
|
||||||
|
::
|
||||||
|
+$ server-state-2
|
||||||
|
$: bindings=(list [=binding =duct =action])
|
||||||
|
cache=(map url=@t [aeon=@ud val=(unit cache-entry)]) :: <- new
|
||||||
|
=cors-registry
|
||||||
|
connections=(map duct outstanding-connection)
|
||||||
|
=authentication-state
|
||||||
|
channel-state=channel-state-2
|
||||||
domains=(set turf)
|
domains=(set turf)
|
||||||
=http-config
|
=http-config
|
||||||
ports=[insecure=@ud secure=(unit @ud)]
|
ports=[insecure=@ud secure=(unit @ud)]
|
||||||
outgoing-duct=duct
|
outgoing-duct=duct
|
||||||
verb=@
|
verb=@
|
||||||
==
|
==
|
||||||
|
+$ channel-state-2
|
||||||
|
$: session=(map @t channel-2)
|
||||||
|
duct-to-key=(map duct @t)
|
||||||
|
==
|
||||||
|
+$ channel-2
|
||||||
|
$: state=(each timer duct)
|
||||||
|
next-id=@ud
|
||||||
|
last-ack=@da
|
||||||
|
events=(qeu [id=@ud request-id=@ud =channel-event])
|
||||||
|
unacked=(map @ud @ud)
|
||||||
|
subscriptions=(map @ud [ship=@p app=term =path duc=duct])
|
||||||
|
heartbeat=(unit timer)
|
||||||
|
==
|
||||||
--
|
--
|
||||||
|= old=axle-any
|
|= old=axle-any
|
||||||
^+ ..^$
|
^+ http-server-gate
|
||||||
?- -.old
|
?- -.old
|
||||||
|
::
|
||||||
|
:: adds /~/name
|
||||||
|
::
|
||||||
%~2020.10.18
|
%~2020.10.18
|
||||||
=, server-state-0.old
|
%= $
|
||||||
%= ..^$
|
date.old %~2022.7.26
|
||||||
ax ^- axle
|
::
|
||||||
:* %~2023.3.16
|
bindings.server-state.old
|
||||||
(insert-binding [[~ /~/name] outgoing-duct [%name ~]] bindings)
|
%+ insert-binding
|
||||||
*(map url=@t [aeon=@ud val=(unit cache-entry)])
|
[[~ /~/name] outgoing-duct.server-state.old [%name ~]]
|
||||||
cors-registry
|
bindings.server-state.old
|
||||||
connections
|
==
|
||||||
authentication-state
|
::
|
||||||
channel-state
|
:: enables https redirects if certificate configured
|
||||||
domains
|
:: inits .verb
|
||||||
http-config
|
|
||||||
ports
|
|
||||||
outgoing-duct
|
|
||||||
0
|
|
||||||
== ==
|
|
||||||
::
|
::
|
||||||
%~2022.7.26
|
%~2022.7.26
|
||||||
=, server-state-0.old
|
|
||||||
%= ..^$
|
|
||||||
ax ^- axle
|
|
||||||
:* %~2023.3.16
|
|
||||||
bindings
|
|
||||||
*(map url=@t [aeon=@ud val=(unit cache-entry)])
|
|
||||||
cors-registry
|
|
||||||
connections
|
|
||||||
authentication-state
|
|
||||||
channel-state
|
|
||||||
domains
|
|
||||||
http-config
|
|
||||||
ports
|
|
||||||
outgoing-duct
|
|
||||||
0
|
|
||||||
== ==
|
|
||||||
::
|
|
||||||
%~2023.2.17
|
|
||||||
=, server-state-1.old
|
|
||||||
%= ..^$
|
|
||||||
ax ^- axle
|
|
||||||
:* %~2023.3.16
|
|
||||||
bindings
|
|
||||||
*(map url=@t [aeon=@ud val=(unit cache-entry)])
|
|
||||||
cors-registry
|
|
||||||
connections
|
|
||||||
authentication-state
|
|
||||||
channel-state
|
|
||||||
domains
|
|
||||||
http-config
|
|
||||||
ports
|
|
||||||
outgoing-duct
|
|
||||||
verb
|
|
||||||
== ==
|
|
||||||
::
|
|
||||||
%~2023.3.16
|
|
||||||
:: enable https redirects if certificate configured
|
|
||||||
::
|
|
||||||
=. redirect.http-config.server-state.old
|
=. redirect.http-config.server-state.old
|
||||||
?& ?=(^ secure.ports.server-state.old)
|
?& ?=(^ secure.ports.server-state.old)
|
||||||
?=(^ secure.http-config.server-state.old)
|
?=(^ secure.http-config.server-state.old)
|
||||||
==
|
==
|
||||||
..^$(ax old)
|
$(old [%~2023.2.17 server-state.old(|8 [|8 verb=0]:server-state.old)])
|
||||||
|
::
|
||||||
|
:: inits .cache
|
||||||
|
::
|
||||||
|
%~2023.2.17
|
||||||
|
$(old [%~2023.3.16 [bindings ~ +]:server-state.old])
|
||||||
|
::
|
||||||
|
:: inits channel mode
|
||||||
|
::
|
||||||
|
%~2023.3.16
|
||||||
|
%= $
|
||||||
|
date.old %~2023.4.11
|
||||||
|
::
|
||||||
|
server-state.old
|
||||||
|
%= server-state.old
|
||||||
|
session.channel-state
|
||||||
|
(~(run by session.channel-state.server-state.old) (lead %json))
|
||||||
|
==
|
||||||
|
==
|
||||||
|
::
|
||||||
|
%~2023.4.11
|
||||||
|
http-server-gate(ax old)
|
||||||
==
|
==
|
||||||
:: +stay: produce current state
|
:: +stay: produce current state
|
||||||
::
|
::
|
||||||
|
@ -643,17 +643,30 @@
|
|||||||
!> (rush '192.168.1.1' simplified-url-parser:eyre-gate)
|
!> (rush '192.168.1.1' simplified-url-parser:eyre-gate)
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
++ test-parse-channel-request
|
++ test-parse-channel-request-jam
|
||||||
;: weld
|
;: weld
|
||||||
%+ expect-eq
|
%+ expect-eq
|
||||||
!> `[%ack 5]~
|
!> &+[%ack 5]~
|
||||||
!> %- parse-channel-request:eyre-gate
|
!> %+ parse-channel-request:eyre-gate %jam
|
||||||
(need (de-json:html '[{"action": "ack", "event-id": 5}]'))
|
(as-octs:mimes:html (scot %uw (jam [%ack 5]~)))
|
||||||
::
|
::
|
||||||
%+ expect-eq
|
%+ expect-eq
|
||||||
!> `[%poke 0 ~nec %app1 %app-type [%n '5']]~
|
!> |+'invalid request data'
|
||||||
!> %- parse-channel-request:eyre-gate
|
!> %+ parse-channel-request:eyre-gate %jam
|
||||||
%- need %- de-json:html
|
(as-octs:mimes:html (scot %uw (jam [%not %a %chanreq %list])))
|
||||||
|
==
|
||||||
|
::
|
||||||
|
++ test-parse-channel-request-json
|
||||||
|
;: weld
|
||||||
|
%+ expect-eq
|
||||||
|
!> &+[%ack 5]~
|
||||||
|
!> %+ parse-channel-request:eyre-gate %json
|
||||||
|
(as-octs:mimes:html '[{"action": "ack", "event-id": 5}]')
|
||||||
|
::
|
||||||
|
%+ expect-eq
|
||||||
|
!> &+[%poke-json 0 ~nec %app1 %app-type [%n '5']]~
|
||||||
|
!> %+ parse-channel-request:eyre-gate %json
|
||||||
|
%- as-octs:mimes:html
|
||||||
'''
|
'''
|
||||||
[{"action": "poke",
|
[{"action": "poke",
|
||||||
"id": 0,
|
"id": 0,
|
||||||
@ -664,9 +677,9 @@
|
|||||||
'''
|
'''
|
||||||
::
|
::
|
||||||
%+ expect-eq
|
%+ expect-eq
|
||||||
!> `[%subscribe 1 ~sampyl-sipnym %hall /this/path]~
|
!> &+[%subscribe 1 ~sampyl-sipnym %hall /this/path]~
|
||||||
!> %- parse-channel-request:eyre-gate
|
!> %+ parse-channel-request:eyre-gate %json
|
||||||
%- need %- de-json:html
|
%- as-octs:mimes:html
|
||||||
'''
|
'''
|
||||||
[{"action": "subscribe",
|
[{"action": "subscribe",
|
||||||
"id": 1,
|
"id": 1,
|
||||||
@ -676,9 +689,9 @@
|
|||||||
'''
|
'''
|
||||||
::
|
::
|
||||||
%+ expect-eq
|
%+ expect-eq
|
||||||
!> `[%unsubscribe 2 1]~
|
!> &+[%unsubscribe 2 1]~
|
||||||
!> %- parse-channel-request:eyre-gate
|
!> %+ parse-channel-request:eyre-gate %json
|
||||||
%- need %- de-json:html
|
%- as-octs:mimes:html
|
||||||
'''
|
'''
|
||||||
[{"action": "unsubscribe",
|
[{"action": "unsubscribe",
|
||||||
"id": 2,
|
"id": 2,
|
||||||
@ -686,30 +699,30 @@
|
|||||||
'''
|
'''
|
||||||
::
|
::
|
||||||
%+ expect-eq
|
%+ expect-eq
|
||||||
!> ~
|
!> |+'invalid channel json'
|
||||||
!> %- parse-channel-request:eyre-gate
|
!> %+ parse-channel-request:eyre-gate %json
|
||||||
%- need %- de-json:html
|
%- as-octs:mimes:html
|
||||||
'[{"noaction": "noaction"}]'
|
'[{"noaction": "noaction"}]'
|
||||||
::
|
::
|
||||||
%+ expect-eq
|
%+ expect-eq
|
||||||
!> ~
|
!> |+'invalid channel json'
|
||||||
!> %- parse-channel-request:eyre-gate
|
!> %+ parse-channel-request:eyre-gate %json
|
||||||
%- need %- de-json:html
|
%- as-octs:mimes:html
|
||||||
'[{"action": "bad-action"}]'
|
'[{"action": "bad-action"}]'
|
||||||
::
|
::
|
||||||
%+ expect-eq
|
%+ expect-eq
|
||||||
!> ~
|
!> |+'invalid channel json'
|
||||||
!> %- parse-channel-request:eyre-gate
|
!> %+ parse-channel-request:eyre-gate %json
|
||||||
%- need %- de-json:html
|
%- as-octs:mimes:html
|
||||||
'[{"action": "ack", "event-id": 5}, {"action": "bad-action"}]'
|
'[{"action": "ack", "event-id": 5}, {"action": "bad-action"}]'
|
||||||
::
|
::
|
||||||
%+ expect-eq
|
%+ expect-eq
|
||||||
!> :- ~
|
!> :- %&
|
||||||
:~ [%ack 9]
|
:~ [%ack 9]
|
||||||
[%poke 3 ~bud %wut %wut-type [%a [%n '2'] [%n '1'] ~]]
|
[%poke-json 3 ~bud %wut %wut-type [%a [%n '2'] [%n '1'] ~]]
|
||||||
==
|
==
|
||||||
!> %- parse-channel-request:eyre-gate
|
!> %+ parse-channel-request:eyre-gate %json
|
||||||
%- need %- de-json:html
|
%- as-octs:mimes:html
|
||||||
'''
|
'''
|
||||||
[{"action": "ack", "event-id": 9},
|
[{"action": "ack", "event-id": 9},
|
||||||
{"action": "poke",
|
{"action": "poke",
|
||||||
|
Loading…
Reference in New Issue
Block a user