sourceextensions/web/lib/Web.xtl
1⍝# Web.xtl -- the facade of the web extension: HTTP serving, where the
2⍝# program is the request loop. axum serves on 127.0.0.1 in the
3⍝# background and queues each request; the program takes the next one,
4⍝# reads its parts, and replies.
5⍝# Import: "wb:" u_se< "Web"
6⍝# Run with xetal-x (xetal-x --ext DIR puts this directory on XETAL_PATH).
7⍝# Each signature line is written out by the binding macro (lib/Ffi.xtlm).
8
9ᶠᶠⁱ⁼u̲se< "Ffi"
10
11⍝# wb:s_erve! port: serve on 127.0.0.1 at the port (8470 is this
12⍝# repository's; 0 takes any free one); the port it serves on.
13"s_erve! : int -> int" ᶠᶠⁱb̲ind< "web/serve"
14⍝# wb:n_ext! seconds: wait up to that long for a request; "GET /path"
15⍝# (the method and path), or "none". A request taken before and not
16⍝# replied to is answered 500.
17"n_ext! : float -> text" ᶠᶠⁱb̲ind< "web/next"
18⍝## The request being answered
19
20⍝# wb:m_ethod @: its method (GET, POST, ...).
21"m_ethod : unit -> text" ᶠᶠⁱb̲ind< "web/method"
22⍝# wb:p_ath @: its path, without the query.
23"p_ath : unit -> text" ᶠᶠⁱb̲ind< "web/path"
24⍝# wb:q_uery @: its query, as sent (still encoded).
25"q_uery : unit -> text" ᶠᶠⁱb̲ind< "web/query"
26⍝# wb:b_ody @: its body, as text.
27"b_ody : unit -> text" ᶠᶠⁱb̲ind< "web/body"
28⍝# wb:p_aram "name": a query or form field, decoded ("" when absent).
29"p_aram : text -> text" ᶠᶠⁱb̲ind< "web/param"
30⍝# wb:c_ontent! "text/csv": the reply's content type (else it is guessed
31⍝# from the body: SVG, HTML, JSON or plain text).
32"c_ontent! : text -> int" ᶠᶠⁱb̲ind< "web/content"
33⍝# wb:h_eader! "Location: /": a header on the reply (a redirect's
34⍝# Location, Cache-Control, ...); how many the reply has.
35"h_eader! : text -> int" ᶠᶠⁱb̲ind< "web/header"
36⍝# status wb:r_eply! body: answer the request; the body's length in bytes.
37"r_eply! : int text -> int" ᶠᶠⁱb̲ind< "web/reply"
38⍝# wb:f_iles! "dir": serve the files under dir (relative, no ..) directly,
39⍝# without the program; "" stops. How many files it holds.
40"f_iles! : text -> int" ᶠᶠⁱb̲ind< "web/files"
41⍝# wb:s_top! @: stop serving; the port (0 if none was serving).
42"s_top! : unit -> int" ᶠᶠⁱb̲ind< "web/stop"
43
44⍝# The native package behind these functions.
45ˡpackage ← "web"
ᶠᶠⁱb̲ind< expands to
ˡs̲erve! ← { a → pa ← (f̲ormat r̲avel f̲loor a) ⎕N̲PUT "ext:web/serve?int=" c̲at f̲ormat s̲hape a f̲loor f̲irst n̲umbers ⎕N̲GET "ext:web/serve" }
ᶠᶠⁱb̲ind< expands to
ˡn̲ext! ← { a → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:web/next?float=" c̲at f̲ormat s̲hape a ⎕N̲GET "ext:web/next" }
ᶠᶠⁱb̲ind< expands to
ˡc̲ontent! ← { a → pa ← a ⎕N̲PUT "ext:web/content?text" f̲loor f̲irst n̲umbers ⎕N̲GET "ext:web/content" }
ᶠᶠⁱb̲ind< expands to
ˡh̲eader! ← { a → pa ← a ⎕N̲PUT "ext:web/header?text" f̲loor f̲irst n̲umbers ⎕N̲GET "ext:web/header" }
ᶠᶠⁱb̲ind< expands to
ˡr̲eply! ← { a b → pa ← (f̲ormat r̲avel f̲loor a) ⎕N̲PUT "ext:web/reply?int=" c̲at f̲ormat s̲hape a pb ← b ⎕N̲PUT "ext:web/reply?text" f̲loor f̲irst n̲umbers ⎕N̲GET "ext:web/reply" }
ᶠᶠⁱb̲ind< expands to
ˡf̲iles! ← { a → pa ← a ⎕N̲PUT "ext:web/files?text" f̲loor f̲irst n̲umbers ⎕N̲GET "ext:web/files" }