Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
nitely committed Feb 9, 2024
1 parent ea389ae commit 22f5125
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 26 deletions.
40 changes: 29 additions & 11 deletions src/hyperx/client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ when defined(hyperxTest):

const
preface = "PRI * HTTP/2.0\r\L\r\LSM\r\L\r\L"
statusLineLen = ":status: xxx\r\n".len
# https://httpwg.org/specs/rfc9113.html#SettingValues
stgHeaderTableSize = 4096'u32
stgMaxConcurrentStreams = uint32.high
Expand Down Expand Up @@ -242,9 +243,9 @@ proc readNaked(client: ClientContext, sid: StreamId): Future[MsgData] {.async.}
if frm.typ == frmtWindowUpdate:
check frm.payload.len > 0, newStrmError(errProtocolError)
if frm.typ == frmtData and
frm.payload.len > 0 and
frm.payloadLen.int > 0 and
frmfEndStream notin frm.flags:
let frmWs = newWindowUpdateFrame(sid.FrmSid, frm.payload.len)
let frmWs = newWindowUpdateFrame(sid.FrmSid, frm.payloadLen.int)
await client.write(frmWs)

proc read(client: ClientContext, sid: StreamId): Future[MsgData] {.async.} =
Expand Down Expand Up @@ -485,8 +486,8 @@ proc responseDispatcherNaked(client: ClientContext) {.async.} =
decode(frm.payload, headers, client.headersDec)
frm.shrink frm.payload.len
frm.s.add $headers
if frm.typ == frmtData and frm.payload.len > 0:
let frmWs = newWindowUpdateFrame(frmSidMain, frm.payload.len)
if frm.typ == frmtData and frm.payloadLen.int > 0:
let frmWs = newWindowUpdateFrame(frmSidMain, frm.payloadLen.int)
await client.write(frmWs)
# Process headers even if the stream
# does not exist
Expand Down Expand Up @@ -621,13 +622,30 @@ proc request(client: ClientContext, req: Request): Future[Response] {.async.} =
frm.flags.incl frmfEndHeaders
frm.add req.data
await client.write(frm)
# XXX read in loop, discard other frames
let msg = await client.read(sid)
doAssert msg.frm.typ == frmtHeaders
result.headers.add msg.frm.payload
let msg2 = await client.read(sid)
doAssert msg2.frm.typ == frmtData
result.data.s.add msg2.frm.payload
# https://httpwg.org/specs/rfc9113.html#HttpFraming
while true:
let msg = await client.read(sid)
check msg.frm.typ == frmtHeaders, newStrmError(errProtocolError)
check msg.frm.payload.len >= statusLineLen, newStrmError(errProtocolError)
#check msg.frm.payload.startsWith ":status: ", newStrmError(errProtocolError)
if msg.frm.payload[9] == '1'.byte:
check frmfEndStream notin msg.frm.flags, newStrmError(errProtocolError)
else:
result.headers.add msg.frm.payload
if frmfEndStream in msg.frm.flags:
return
break
while true:
let msg = await client.read(sid)
# XXX store trailer headers
# https://www.rfc-editor.org/rfc/rfc9110.html#section-6.5
if msg.frm.typ == frmtHeaders:
check frmfEndStream in msg.frm.flags, newStrmError(errProtocolError)
return
check msg.frm.typ == frmtData, newStrmError(errProtocolError)
result.data.s.add msg.frm.payload
if frmfEndStream in msg.frm.flags:
return

proc get*(
client: ClientContext,
Expand Down
30 changes: 15 additions & 15 deletions tests/testclient.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func toBytes(s: string): seq[byte] =
result.add c.byte

testAsync "simple response":
const headers = ":method: foobar\r\L"
const headers = ":status: 200\r\nfoo: foo\r\n"
const text = "foobar body"
var tc = newTestClient("foo.bar")
withConnection tc:
Expand All @@ -28,9 +28,9 @@ testAsync "simple response":

testAsync "multiple responses":
const
headers = ":method: foo\r\L"
headers = ":status: 200\r\nfoo: foo\r\n"
text = "foo body"
headers2 = ":method: bar\r\L"
headers2 = ":status: 200\r\nbar: bar\r\n"
text2 = "bar body"
var tc = newTestClient("foo.bar")
withConnection tc:
Expand All @@ -47,9 +47,9 @@ testAsync "multiple responses":

testAsync "multiple responses unordered":
const
headers = ":method: foo\r\L"
headers = ":status: 200\r\nfoo: foo\r\n"
text = "foo body"
headers2 = ":method: bar\r\L"
headers2 = ":status: 200\r\nbar: bar\r\n"
text2 = "bar body"
var tc = newTestClient("foo.bar")
withConnection tc:
Expand All @@ -69,7 +69,7 @@ testAsync "simple request":
withConnection tc:
await (
tc.get("/") and
tc.reply("foo: foo\r\L", "bar")
tc.reply(":status: 200\r\nfoo: foo\r\n", "bar")
)
let reqs = tc.sent()
doAssert reqs[0].frm.sid == frmsidMain
Expand All @@ -88,9 +88,9 @@ testAsync "multiple requests":
withConnection tc:
await (
tc.get("/1") and
tc.reply("foo: foo\r\L", "bar") and
tc.reply(":status: 200\r\nfoo: foo\r\n", "bar") and
tc.get("/2") and
tc.reply("foo: foo\r\L", "bar")
tc.reply(":status: 200\r\nbar: bar\r\n", "bar")
)
let reqs = tc.sent()
doAssert reqs[0].frm.sid == frmsidMain
Expand Down Expand Up @@ -140,9 +140,9 @@ testAsync "response with headers prio":
await tc.reply(frm2)
tc.sid += 2
const
headers = ":method: foo\r\L"
headers = ":status: 200\r\nfoo: foo\r\n"
text = "foo body"
headers2 = ":method: bar\r\L"
headers2 = ":status: 200\r\nbar: bar\r\n"
text2 = "bar body"
var tc = newTestClient("foo.bar")
withConnection tc:
Expand Down Expand Up @@ -188,9 +188,9 @@ testAsync "response with headers padding":
await tc.reply(frm2)
tc.sid += 2
const
headers = ":method: foo\r\L"
headers = ":status: 200\r\nfoo: foo\r\n"
text = "foo body"
headers2 = ":method: bar\r\L"
headers2 = ":status: 200\r\nbar: bar\r\n"
text2 = "bar body"
var tc = newTestClient("foo.bar")
withConnection tc:
Expand Down Expand Up @@ -247,7 +247,7 @@ testAsync "header table is populated":
withConnection tc:
await (
tc.get("/foo") and
tc.reply("foo: foo\r\L", "bar")
tc.reply(":status: 200\r\nfoo: foo\r\n", "bar")
)
let reqs = tc.sent()
doAssert tc.headersDec.len == 2
Expand All @@ -273,11 +273,11 @@ testAsync "header table size setting is applied":
await tc.recvTableSizeSetting(0)
await (
tc.get("/foo") and
tc.reply("foo: foo\r\L", "bar")
tc.reply(":status: 200\r\nfoo: foo\r\n", "bar")
)
await (
tc.get("/bar") and
tc.reply("foo2: foo2\r\L", "bar2")
tc.reply(":status: 200\r\nbar: bar\r\n", "bar2")
)
let reqs = tc.sent()
doAssert tc.headersDec.len == 0
Expand Down

0 comments on commit 22f5125

Please sign in to comment.