http_driver: add 504 binding timeouts

This commit is contained in:
Emery Hemingway 2024-04-08 20:38:49 +01:00
parent 6a4854110c
commit 6487ef65d0
1 changed files with 19 additions and 5 deletions

View File

@ -2,7 +2,7 @@
# SPDX-License-Identifier: Unlicense
import std/[httpcore, options, parseutils, sets, streams, strutils, tables, times, uri]
import preserves, ../../syndicate, ../bags
import preserves, ../../syndicate, ../bags, ./timers
import ../protocols/http
import taps
@ -114,7 +114,7 @@ proc lenLine(chunk: Chunk): string =
type
Driver = ref object
facet: Facet
ds: Cap
ds, timers: Cap
bindings: Bag[Value]
# cannot make a bag of HttpBinding, no `==` operator
sequenceNumber: BiggestInt
@ -128,6 +128,7 @@ type
req: HttpRequest
stream: StringStream
mode: HttpResponseKind
active: bool
proc send[T: byte|char](ses: Session; data: openarray[T]) =
ses.conn.send(addr data[0], data.len, endOfMessage = false)
@ -187,6 +188,7 @@ method message(e: Exchange; turn: var Turn; a: AssertionRef) =
of HttpResponseKind.status:
if e.mode == res.orKind:
e.active = true
e.ses.conn.startBatch()
e.stream.write(
SupportedVersion, " ", res.status.code, " ", res.status.message, CRLF,
@ -239,10 +241,21 @@ proc service(turn: var Turn; exch: Exchange) =
if handler.isNone:
stop(turn)
else:
publish(turn, handler.get, HttpContext(
let
cap = newCap(turn, exch)
ctx = publish(turn, handler.get, HttpContext(
req: exch.req,
res: embed newCap(turn, exch),
res: embed cap,
))
const timeout = initDuration(seconds = 4)
after(turn, exch.ses.driver.timers, timeout) do (turn: var Turn):
if not exch.active:
var res = HttpResponse(orKind: HttpResponseKind.status)
res.status.code = 504
res.status.message = "Binding timeout"
message(turn, cap, res)
res = HttpResponse(orKind: HttpResponseKind.done)
message(turn, cap, res)
proc service(ses: Session) =
## Service a connection to an HTTP client.
@ -302,7 +315,8 @@ proc httpListen(turn: var Turn; driver: Driver; port: Port): Listener =
listener
proc httpDriver(turn: var Turn; ds: Cap) =
let driver = Driver(facet: turn.facet, ds: ds)
let driver = Driver(facet: turn.facet, ds: ds, timers: turn.newDataspace)
spawnTimerDriver(turn, driver.timers)
during(turn, ds, HttpBinding?:{
1: grab(),