ref: fd3d8637eec28cba6a0fe52811e39b0de5ec977e
parent: a603374dcbe55fff12484acdc6ae3f2736280d1e
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Jun 29 06:38:14 EDT 2016
Rename verbs to clients.
--- a/lib/http/bld.sub
+++ b/lib/http/bld.sub
@@ -8,7 +8,9 @@
parse.myr
types.myr
url.myr
- verbs.myr
+ client.myr
+ server.myr
+ router.myr
session.myr
;;
--- /dev/null
+++ b/lib/http/client.myr
@@ -1,0 +1,281 @@
+use std
+use bio
+
+use "types"
+use "session"
+use "parse"
+
+pkg http =
+ /* simple versions */
+ const get : (s : session#, r : byte[:] -> std.result(resp#, err))
+ const head : (s : session#, r : byte[:] -> std.result(resp#, err))
+ const put : (s : session#, r : byte[:], data : byte[:] -> std.result(resp#, err))
+ const post : (s : session#, r : byte[:], data : byte[:] -> std.result(resp#, err))
+ const delete : (s : session#, r : byte[:] -> std.result(resp#, err))
+ const options : (s : session#, r : byte[:] -> std.result(resp#, err))
+ const trace : (s : session#, r : byte[:] -> std.result(resp#, err))
+
+ /* request based versions */
+ const getreq : (s : session#, r : req# -> std.result(resp#, err))
+ const headreq : (s : session#, r : req# -> std.result(resp#, err))
+ const putreq : (s : session#, r : req#, data : byte[:] -> std.result(resp#, err))
+ const postreq : (s : session#, r : req#, data : byte[:] -> std.result(resp#, err))
+ const deletereq : (s : session#, r : req# -> std.result(resp#, err))
+ const optionsreq : (s : session#, r : req# -> std.result(resp#, err))
+ const tracereq : (s : session#, r : req# -> std.result(resp#, err))
+
+ const freeresp : (r : resp# -> void)
+;;
+
+const get = {s, path; -> getreq(s, &[.url=&[.path=path]])}
+const head = {s, path; -> headreq(s, &[.url=&[.path=path]])}
+const put = {s, path, data; -> putreq(s, &[.url=&[.path=path]], data)}
+const post = {s, path, data; -> postreq(s, &[.url=&[.path=path]], data)}
+const delete = {s, path; -> deletereq(s, &[.url=&[.path=path]])}
+const options = {s, path; -> optionsreq(s, &[.url=&[.path=path]])}
+const trace = {s, path; -> tracereq(s, &[.url=&[.path=path]])}
+
+
+const getreq = {s, r
+ match request(s, `Get, r, `std.None)
+ | `std.Ok _: /* nothing */
+ | `std.Fail e: -> `std.Fail e
+ ;;
+
+ -> response(s, true)
+}
+
+const headreq = {s, r
+ match request(s, `Head, r, `std.None)
+ | `std.Ok _: /* nothing */
+ | `std.Fail e: -> `std.Fail e
+ ;;
+
+ -> response(s, false)
+}
+
+const putreq = {s, r, data
+ match request(s, `Put, r, `std.Some data)
+ | `std.Ok _: /* nothing */
+ | `std.Fail e: -> `std.Fail e
+ ;;
+
+ -> response(s, true)
+}
+
+const postreq = {s, r, data
+ match request(s, `Post, r, `std.Some data)
+ | `std.Ok _: /* nothing */
+ | `std.Fail e: -> `std.Fail e
+ ;;
+
+ -> response(s, true)
+}
+
+const deletereq = {s, r
+ match request(s, `Delete, r, `std.None)
+ | `std.Ok _: /* nothing */
+ | `std.Fail e: -> `std.Fail e
+ ;;
+
+ -> response(s, true)
+}
+
+const optionsreq = {s, r
+ match request(s, `Options, r, `std.None)
+ | `std.Ok _: /* nothing */
+ | `std.Fail e: -> `std.Fail e
+ ;;
+
+ -> response(s, true)
+}
+
+const tracereq = {s, r
+ match request(s, `Trace, r, `std.None)
+ | `std.Ok _: /* nothing */
+ | `std.Fail e: -> `std.Fail e
+ ;;
+
+ -> response(s, true)
+}
+
+const response = {s, body
+ var resp
+
+ resp = std.mk([
+ .hdrs = [][:],
+ .len = 0,
+ .err = `std.None,
+ .reason = "",
+ .status = 0,
+ .enc = `Length,
+ ])
+
+ if parseresp(s, resp)
+ if !body
+ -> `std.Ok resp
+ else
+ match readbody(s, resp)
+ | `std.Ok buf: resp.body = buf
+ | `std.Fail e: -> `std.Fail e
+ ;;
+ ;;
+ else
+ match resp.err
+ | `std.Some e: -> `std.Fail e
+ | `std.None: -> `std.Fail `Ewat
+ ;;
+ ;;
+ -> `std.Ok resp
+}
+
+const request = {s, method, r, data
+ /* status */
+ ioput(s, "{} {p} HTTP/1.1\r\n", method, r.url)
+
+ /* headers */
+ ioput(s, "Host: {}\r\n", s.host)
+ ioput(s, "User-Agent: {}\r\n", s.ua)
+ match data
+ | `std.Some d: ioput(s, "Content-Length: {}\r\n", d.len)
+ | `std.None: /* nothing to do */
+ ;;
+ for (k, v) in r.hdrs
+ ioput(s, "{}: {}\r\n", k, v)
+ ;;
+ ioput(s, "\r\n")
+
+ /* body */
+ match data
+ | `std.None: /* nothing to do */
+ | `std.Some d:
+ ioput(s, d)
+ ioput(s, "\r\n")
+ ;;
+ ioflush(s)
+
+ if s.err
+ -> `std.Fail `Econn
+ else
+ -> `std.Ok void
+ ;;
+
+}
+
+const readbody = {s, r -> std.result(byte[:], err)
+ match r.enc
+ | `Length: -> readlenbody(s, r)
+ | `Chunked: -> readchunkedbody(s, r)
+ | badenc: std.fatal("unsupported encoding {}\n", badenc)
+ ;;
+}
+
+const readlenbody = {s, r
+ var buf
+
+ buf = ""
+ if r.len == 0
+ -> `std.Ok buf
+ ;;
+
+ buf = std.slalloc(r.len)
+ match bio.read(s.f, buf)
+ | `bio.Err e: goto shortread
+ | `bio.Eof: goto shortread
+ | `bio.Ok rd:
+ if rd.len != r.len
+ goto shortread
+ ;;
+ ;;
+ -> `std.Ok buf
+:shortread
+ std.slfree(buf)
+ -> `std.Fail `Eshort
+}
+
+const __init__ = {
+ var m
+
+ m = `Get
+ std.fmtinstall(std.typeof(m), fmtmethod, [][:])
+}
+
+const readchunkedbody = {s, r
+ var buf, len
+
+ buf = ""
+ len = 0
+ while true
+ match parsechunksz(s)
+ | `std.Fail e:
+ std.slfree(buf)
+ -> `std.Fail e
+ | `std.Ok 0:
+ break
+ | `std.Ok sz:
+ std.slgrow(&buf, buf.len + sz)
+ match bio.read(s.f, buf[len:len + sz])
+ | `bio.Eof:
+ std.slfree(buf)
+ -> `std.Fail `Eshort
+ | `bio.Err e:
+ std.slfree(buf)
+ -> `std.Fail `Econn
+ | `bio.Ok str:
+ if str.len != sz
+ std.slfree(buf)
+ -> `std.Fail `Eshort
+ ;;
+ len += sz
+ match checkendln(s)
+ | `std.Ok _: /* nothing */
+ | `std.Fail e:
+ std.slfree(buf)
+ -> `std.Fail e
+ ;;
+ ;;
+ ;;
+ ;;
+ -> `std.Ok buf
+}
+
+const checkendln = {s
+ var r
+
+ match bio.readln(s.f)
+ | `bio.Err e: r = `std.Fail `Econn
+ | `bio.Eof: r = `std.Fail `Econn
+ | `bio.Ok crlf:
+ if std.strstrip(crlf).len == 0
+ r = `std.Ok void
+ else
+ r = `std.Fail `Eproto
+ ;;
+ std.slfree(crlf)
+ ;;
+ -> r
+}
+
+const fmtmethod = {sb, ap, opt
+ var r
+
+ r = std.vanext(ap)
+ match r
+ | `Get: std.sbputs(sb, "GET")
+ | `Head: std.sbputs(sb, "HEAD")
+ | `Put: std.sbputs(sb, "PUT")
+ | `Post: std.sbputs(sb, "POST")
+ | `Delete: std.sbputs(sb, "DELETE")
+ | `Trace: std.sbputs(sb, "TRACE")
+ | `Options: std.sbputs(sb, "OPTIONS")
+ ;;
+}
+
+const freeresp = {r
+ for (k, v) in r.hdrs
+ std.slfree(k)
+ std.slfree(v)
+ ;;
+ std.slfree(r.reason)
+ std.free(r)
+}
--- a/lib/http/verbs.myr
+++ /dev/null
@@ -1,281 +1,0 @@
-use std
-use bio
-
-use "types"
-use "session"
-use "parse"
-
-pkg http =
- /* simple versions */
- const get : (s : session#, r : byte[:] -> std.result(resp#, err))
- const head : (s : session#, r : byte[:] -> std.result(resp#, err))
- const put : (s : session#, r : byte[:], data : byte[:] -> std.result(resp#, err))
- const post : (s : session#, r : byte[:], data : byte[:] -> std.result(resp#, err))
- const delete : (s : session#, r : byte[:] -> std.result(resp#, err))
- const options : (s : session#, r : byte[:] -> std.result(resp#, err))
- const trace : (s : session#, r : byte[:] -> std.result(resp#, err))
-
- /* request versions */
- const getreq : (s : session#, r : req# -> std.result(resp#, err))
- const headreq : (s : session#, r : req# -> std.result(resp#, err))
- const putreq : (s : session#, r : req#, data : byte[:] -> std.result(resp#, err))
- const postreq : (s : session#, r : req#, data : byte[:] -> std.result(resp#, err))
- const deletereq : (s : session#, r : req# -> std.result(resp#, err))
- const optionsreq : (s : session#, r : req# -> std.result(resp#, err))
- const tracereq : (s : session#, r : req# -> std.result(resp#, err))
-
- const freeresp : (r : resp# -> void)
-;;
-
-const get = {s, path; -> getreq(s, &[.url=&[.path=path]])}
-const head = {s, path; -> headreq(s, &[.url=&[.path=path]])}
-const put = {s, path, data; -> putreq(s, &[.url=&[.path=path]], data)}
-const post = {s, path, data; -> postreq(s, &[.url=&[.path=path]], data)}
-const delete = {s, path; -> deletereq(s, &[.url=&[.path=path]])}
-const options = {s, path; -> optionsreq(s, &[.url=&[.path=path]])}
-const trace = {s, path; -> tracereq(s, &[.url=&[.path=path]])}
-
-
-const getreq = {s, r
- match request(s, `Get, r, `std.None)
- | `std.Ok _: /* nothing */
- | `std.Fail e: -> `std.Fail e
- ;;
-
- -> response(s, true)
-}
-
-const headreq = {s, r
- match request(s, `Head, r, `std.None)
- | `std.Ok _: /* nothing */
- | `std.Fail e: -> `std.Fail e
- ;;
-
- -> response(s, false)
-}
-
-const putreq = {s, r, data
- match request(s, `Put, r, `std.Some data)
- | `std.Ok _: /* nothing */
- | `std.Fail e: -> `std.Fail e
- ;;
-
- -> response(s, true)
-}
-
-const postreq = {s, r, data
- match request(s, `Post, r, `std.Some data)
- | `std.Ok _: /* nothing */
- | `std.Fail e: -> `std.Fail e
- ;;
-
- -> response(s, true)
-}
-
-const deletereq = {s, r
- match request(s, `Delete, r, `std.None)
- | `std.Ok _: /* nothing */
- | `std.Fail e: -> `std.Fail e
- ;;
-
- -> response(s, true)
-}
-
-const optionsreq = {s, r
- match request(s, `Options, r, `std.None)
- | `std.Ok _: /* nothing */
- | `std.Fail e: -> `std.Fail e
- ;;
-
- -> response(s, true)
-}
-
-const tracereq = {s, r
- match request(s, `Trace, r, `std.None)
- | `std.Ok _: /* nothing */
- | `std.Fail e: -> `std.Fail e
- ;;
-
- -> response(s, true)
-}
-
-const response = {s, body
- var resp
-
- resp = std.mk([
- .hdrs = [][:],
- .len = 0,
- .err = `std.None,
- .reason = "",
- .status = 0,
- .enc = `Length,
- ])
-
- if parseresp(s, resp)
- if !body
- -> `std.Ok resp
- else
- match readbody(s, resp)
- | `std.Ok buf: resp.body = buf
- | `std.Fail e: -> `std.Fail e
- ;;
- ;;
- else
- match resp.err
- | `std.Some e: -> `std.Fail e
- | `std.None: -> `std.Fail `Ewat
- ;;
- ;;
- -> `std.Ok resp
-}
-
-const request = {s, method, r, data
- /* status */
- ioput(s, "{} {p} HTTP/1.1\r\n", method, r.url)
-
- /* headers */
- ioput(s, "Host: {}\r\n", s.host)
- ioput(s, "User-Agent: {}\r\n", s.ua)
- match data
- | `std.Some d: ioput(s, "Content-Length: {}\r\n", d.len)
- | `std.None: /* nothing to do */
- ;;
- for (k, v) in r.hdrs
- ioput(s, "{}: {}\r\n", k, v)
- ;;
- ioput(s, "\r\n")
-
- /* body */
- match data
- | `std.None: /* nothing to do */
- | `std.Some d:
- ioput(s, d)
- ioput(s, "\r\n")
- ;;
- ioflush(s)
-
- if s.err
- -> `std.Fail `Econn
- else
- -> `std.Ok void
- ;;
-
-}
-
-const readbody = {s, r -> std.result(byte[:], err)
- match r.enc
- | `Length: -> readlenbody(s, r)
- | `Chunked: -> readchunkedbody(s, r)
- | badenc: std.fatal("unsupported encoding {}\n", badenc)
- ;;
-}
-
-const readlenbody = {s, r
- var buf
-
- buf = ""
- if r.len == 0
- -> `std.Ok buf
- ;;
-
- buf = std.slalloc(r.len)
- match bio.read(s.f, buf)
- | `bio.Err e: goto shortread
- | `bio.Eof: goto shortread
- | `bio.Ok rd:
- if rd.len != r.len
- goto shortread
- ;;
- ;;
- -> `std.Ok buf
-:shortread
- std.slfree(buf)
- -> `std.Fail `Eshort
-}
-
-const __init__ = {
- var m
-
- m = `Get
- std.fmtinstall(std.typeof(m), fmtmethod, [][:])
-}
-
-const readchunkedbody = {s, r
- var buf, len
-
- buf = ""
- len = 0
- while true
- match parsechunksz(s)
- | `std.Fail e:
- std.slfree(buf)
- -> `std.Fail e
- | `std.Ok 0:
- break
- | `std.Ok sz:
- std.slgrow(&buf, buf.len + sz)
- match bio.read(s.f, buf[len:len + sz])
- | `bio.Eof:
- std.slfree(buf)
- -> `std.Fail `Eshort
- | `bio.Err e:
- std.slfree(buf)
- -> `std.Fail `Econn
- | `bio.Ok str:
- if str.len != sz
- std.slfree(buf)
- -> `std.Fail `Eshort
- ;;
- len += sz
- match checkendln(s)
- | `std.Ok _: /* nothing */
- | `std.Fail e:
- std.slfree(buf)
- -> `std.Fail e
- ;;
- ;;
- ;;
- ;;
- -> `std.Ok buf
-}
-
-const checkendln = {s
- var r
-
- match bio.readln(s.f)
- | `bio.Err e: r = `std.Fail `Econn
- | `bio.Eof: r = `std.Fail `Econn
- | `bio.Ok crlf:
- if std.strstrip(crlf).len == 0
- r = `std.Ok void
- else
- r = `std.Fail `Eproto
- ;;
- std.slfree(crlf)
- ;;
- -> r
-}
-
-const fmtmethod = {sb, ap, opt
- var r
-
- r = std.vanext(ap)
- match r
- | `Get: std.sbputs(sb, "GET")
- | `Head: std.sbputs(sb, "HEAD")
- | `Put: std.sbputs(sb, "PUT")
- | `Post: std.sbputs(sb, "POST")
- | `Delete: std.sbputs(sb, "DELETE")
- | `Trace: std.sbputs(sb, "TRACE")
- | `Options: std.sbputs(sb, "OPTIONS")
- ;;
-}
-
-const freeresp = {r
- for (k, v) in r.hdrs
- std.slfree(k)
- std.slfree(v)
- ;;
- std.slfree(r.reason)
- std.free(r)
-}