Remove http_translator
There is better HTTP schema defined elsewhere. See syndicate-protocols/schemas/http.prs.
This commit is contained in:
parent
fe76b714a5
commit
fc9b54f339
|
@ -1,5 +1,4 @@
|
||||||
/.direnv
|
/.direnv
|
||||||
http_translator
|
|
||||||
json_translator
|
json_translator
|
||||||
msg
|
msg
|
||||||
json_socket_translator
|
json_socket_translator
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
# Syndicate utils
|
# Syndicate utils
|
||||||
|
|
||||||
## http_translator
|
|
||||||
|
|
||||||
Dispatches HTTP requests to registered handlers.
|
|
||||||
|
|
||||||
See [http_translator.config-example.pr](./http_translator.config-example.pr) for an example configuration.
|
|
||||||
|
|
||||||
## json_translator
|
## json_translator
|
||||||
|
|
||||||
Wrapper that executes a command, parses its JSON output, and asserts a Preserves conversion in an `<output …>` record.
|
Wrapper that executes a command, parses its JSON output, and asserts a Preserves conversion in an `<output …>` record.
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
version 1 .
|
|
||||||
|
|
||||||
Method = =GET / =HEAD / =POST / =PUT / =DELETE / =CONNECT / =OPTIONS / =TRACE / =PATCH .
|
|
||||||
Methods = #{Method} .
|
|
||||||
|
|
||||||
; A URL path split into elements
|
|
||||||
Path = [string ...] .
|
|
||||||
|
|
||||||
Listener = <listen @port int> .
|
|
||||||
|
|
||||||
; Register an entity that will handle requests at path prefix.
|
|
||||||
; TODO: assert the public base URL of the handler to the entity.
|
|
||||||
Handler = <handler @methods Methods @path Path @entity #!any> .
|
|
||||||
|
|
||||||
Headers = {string: [string ...] ...:...} .
|
|
||||||
|
|
||||||
; A request awaiting a response at handle.
|
|
||||||
; TODO: query parameters
|
|
||||||
Request = <http @handle int @method Method @headers Headers @path Path @body string> .
|
|
||||||
|
|
||||||
; A response to handle.
|
|
||||||
Response = <http @handle int @code int @headers Headers @body string> .
|
|
|
@ -1,20 +0,0 @@
|
||||||
<require-service <daemon http_translator>>
|
|
||||||
|
|
||||||
<daemon http_translator {
|
|
||||||
argv: "/home/repo/syndicate/syndicate_utils/src/http_translator"
|
|
||||||
protocol: text/syndicate
|
|
||||||
}>
|
|
||||||
|
|
||||||
let ?other = dataspace
|
|
||||||
|
|
||||||
$other [
|
|
||||||
? <http ?handle GET ?headers ?path ?body> [
|
|
||||||
<http $handle 200 {} "get handler invoked">
|
|
||||||
]
|
|
||||||
]
|
|
||||||
|
|
||||||
? <service-object <daemon http_translator> ?cap> $cap [
|
|
||||||
<listen 8888>
|
|
||||||
; publish GET requests with prefix "/foo/bar" to other dataspace
|
|
||||||
handler #{GET} ["foo" "bar" ] $other>
|
|
||||||
]
|
|
|
@ -1,90 +0,0 @@
|
||||||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
|
||||||
# SPDX-License-Identifier: Unlicense
|
|
||||||
|
|
||||||
import std/[asyncdispatch, asynchttpserver, strutils, tables, uri]
|
|
||||||
import preserves
|
|
||||||
import syndicate, syndicate/actors
|
|
||||||
|
|
||||||
import ./schema/http_protocol
|
|
||||||
|
|
||||||
func toHttpCore(methods: Methods): set[HttpMethod] =
|
|
||||||
# Convert the schema type to the type in the httpcore module.
|
|
||||||
for m in methods:
|
|
||||||
result.incl(
|
|
||||||
case m
|
|
||||||
of Method.GET: HttpGET
|
|
||||||
of Method.HEAD: HttpHEAD
|
|
||||||
of Method.POST: HttpPOST
|
|
||||||
of Method.PUT: HttpPUT
|
|
||||||
of Method.DELETE: HttpDELETE
|
|
||||||
of Method.CONNECT: HttpCONNECT
|
|
||||||
of Method.OPTIONS: HttpOPTIONS
|
|
||||||
of Method.TRACE: HttpTRACE
|
|
||||||
of Method.PATCH: HttpPATCH)
|
|
||||||
|
|
||||||
proc splitPath(u: Uri): Path =
|
|
||||||
u.path.strip(chars = {'/'}).split("/")
|
|
||||||
|
|
||||||
proc hitch(a, b: Future[void]) =
|
|
||||||
a.addCallback do (f: Future[void]):
|
|
||||||
if f.failed: fail(b, f.error)
|
|
||||||
else: complete(b)
|
|
||||||
|
|
||||||
runActor("main") do (ds: Ref; turn: var Turn):
|
|
||||||
connectStdio(ds, turn)
|
|
||||||
var
|
|
||||||
handlers: Table[seq[string], (Ref, set[HttpMethod])]
|
|
||||||
pathPrefixMaxLen = 0
|
|
||||||
requestIdSource = 0
|
|
||||||
|
|
||||||
during(turn, ds, ?Handler) do (methods: Methods; path: seq[string]; entity: Ref):
|
|
||||||
handlers[path] = (entity, methods.toHttpCore)
|
|
||||||
pathPrefixMaxLen = max(pathPrefixMaxLen, path.len)
|
|
||||||
do:
|
|
||||||
handlers.del(path)
|
|
||||||
pathPrefixMaxLen = 0
|
|
||||||
for path in handlers.keys:
|
|
||||||
pathPrefixMaxLen = max(pathPrefixMaxLen, path.len)
|
|
||||||
|
|
||||||
var parentFacet = turn.facet
|
|
||||||
proc handleRequest(req: asynchttpserver.Request): Future[void] =
|
|
||||||
# TODO: use pattern matching
|
|
||||||
var
|
|
||||||
entity: Ref
|
|
||||||
methods: set[HttpMethod]
|
|
||||||
path = req.url.splitPath()
|
|
||||||
block:
|
|
||||||
var prefix = path[0..min(pathPrefixMaxLen.succ, path.high)]
|
|
||||||
while entity.isNil:
|
|
||||||
(entity, methods) = handlers.getOrDefault(prefix)
|
|
||||||
if prefix.len == 0: break
|
|
||||||
else: discard prefix.pop()
|
|
||||||
if entity.isNil:
|
|
||||||
result = req.respond(Http503, "no handler registered for this path")
|
|
||||||
else:
|
|
||||||
var parentFut = newFuture[void]("handleRequest")
|
|
||||||
result = parentFut
|
|
||||||
if req.reqMethod notin methods:
|
|
||||||
result = req.respond(Http405, "method not valid for this handler")
|
|
||||||
else:
|
|
||||||
run(parentFacet) do (turn: var Turn):
|
|
||||||
inc requestIdSource
|
|
||||||
let
|
|
||||||
rId = requestIdSource
|
|
||||||
let rHandle = publish(turn, entity, http_protocol.Request(
|
|
||||||
handle: rId,
|
|
||||||
`method`: Method.GET,
|
|
||||||
headers: req.headers.table[],
|
|
||||||
path: path,
|
|
||||||
body: req.body))
|
|
||||||
|
|
||||||
onPublish(turn, entity, Response ? { 0: ?rId, 1: ?int, 3: ?string }) do (code: HttpCode, body: string):
|
|
||||||
req.respond(code, body).addCallback do (fut: Future[void]):
|
|
||||||
run(parentFacet) do (turn: var Turn): retract(turn, rHandle)
|
|
||||||
hitch(fut, parentFut)
|
|
||||||
|
|
||||||
during(turn, ds, ?Listener) do (port: Port):
|
|
||||||
var http = newAsyncHttpServer()
|
|
||||||
asyncCheck serve(http, port, handleRequest)
|
|
||||||
do:
|
|
||||||
close(http)
|
|
|
@ -1,38 +0,0 @@
|
||||||
|
|
||||||
import
|
|
||||||
std/typetraits, preserves, std/tables
|
|
||||||
|
|
||||||
type
|
|
||||||
Path* = seq[string]
|
|
||||||
Headers* = Table[string, seq[string]]
|
|
||||||
Response* {.preservesRecord: "http".} = object
|
|
||||||
`handle`*: BiggestInt
|
|
||||||
`code`*: BiggestInt
|
|
||||||
`headers`*: Headers
|
|
||||||
`body`*: string
|
|
||||||
|
|
||||||
Listener* {.preservesRecord: "listen".} = object
|
|
||||||
`port`*: BiggestInt
|
|
||||||
|
|
||||||
Handler* {.preservesRecord: "handler".} = object
|
|
||||||
`methods`*: Methods
|
|
||||||
`path`*: Path
|
|
||||||
`entity`* {.preservesEmbedded.}: Preserve[void]
|
|
||||||
|
|
||||||
`Method`* {.preservesOr, pure.} = enum
|
|
||||||
`GET`, `HEAD`, `POST`, `PUT`, `DELETE`, `CONNECT`, `OPTIONS`, `TRACE`,
|
|
||||||
`PATCH`
|
|
||||||
Request* {.preservesRecord: "http".} = object
|
|
||||||
`handle`*: BiggestInt
|
|
||||||
`method`*: Method
|
|
||||||
`headers`*: Headers
|
|
||||||
`path`*: Path
|
|
||||||
`body`*: string
|
|
||||||
|
|
||||||
Methods* = set[Method]
|
|
||||||
proc `$`*(x: Path | Headers | Response | Listener | Handler | Request | Methods): string =
|
|
||||||
`$`(toPreserve(x))
|
|
||||||
|
|
||||||
proc encode*(x: Path | Headers | Response | Listener | Handler | Request |
|
|
||||||
Methods): seq[byte] =
|
|
||||||
encode(toPreserve(x))
|
|
|
@ -5,7 +5,7 @@ author = "Emery Hemingway"
|
||||||
description = "Utilites for Syndicated Actors and Synit"
|
description = "Utilites for Syndicated Actors and Synit"
|
||||||
license = "unlicense"
|
license = "unlicense"
|
||||||
srcDir = "src"
|
srcDir = "src"
|
||||||
bin = @["http_translator", "json_socket_translator", "json_translator", "msg"]
|
bin = @["json_socket_translator", "json_translator", "msg"]
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|
Loading…
Reference in New Issue