diff --git a/hyperx.nimble b/hyperx.nimble index d7178b0..6dfe2ee 100644 --- a/hyperx.nimble +++ b/hyperx.nimble @@ -9,7 +9,7 @@ skipDirs = @["tests"] requires "nim >= 2.0.0" #requires "hpack >= 0.2.0" -requires "https://github.com/nitely/nim-hpack#update_size" +requires "https://github.com/nitely/nim-hpack#head" task test, "Test": exec "nim c -r src/hyperx/utils.nim" diff --git a/src/hyperx/client.nim b/src/hyperx/client.nim index de4d91e..3dfa80a 100644 --- a/src/hyperx/client.nim +++ b/src/hyperx/client.nim @@ -125,6 +125,7 @@ type MsgData = object frm: Frame Stream = object + # XXX: add body stream, if set stream data through it id: StreamId state: StreamState msgs: QueueAsync[MsgData] @@ -341,6 +342,8 @@ proc read(client: ClientContext, frm: Frame) {.async.} = payloadLen -= paddingLen check isValidSize(frm, payloadLen), newConnError(errFrameSizeError) if payloadLen > 0: + # XXX recv into Stream.bodyStream if typ is frmtData + # XXX recv in chunks and discard if stream does not exists frm.grow payloadLen let payloadRln = await client.sock.recvInto( frm.rawPayloadBytesPtr, payloadLen @@ -378,12 +381,9 @@ proc handshake(client: ClientContext) {.async.} = # XXX: allow sending some params let sid = client.openMainStream() doAssert sid == frmSidMain.StreamId - var frm = newFrame() - frm.setTyp frmtSettings - frm.setSid frmSidMain + var frm = newSettingsFrame() frm.addSetting frmsEnablePush, stgDisablePush frm.addSetting frmsInitialWindowSize, stgMaxWindowSize - frm.setPayloadLen frm.payload.len.FrmPayloadLen var blob = newSeqOfCap[byte](preface.len+frm.len) blob.add preface blob.add frm.s @@ -433,7 +433,6 @@ const connFrmAllowed = { } proc consumeMainStream(client: ClientContext, frm: Frame) {.async.} = - # XXX process settings, window updates, etc case frm.typ of frmtWindowUpdate: check frm.payload.len > 0, newConnError(errProtocolError) @@ -462,8 +461,8 @@ proc consumeMainStream(client: ClientContext, frm: Frame) {.async.} = discard else: # ignore unknown setting - debugInfo "unknown setting recived" - # XXX send ack + debugInfo "unknown setting received" + await client.write newSettingsFrame() of frmtPing: discard of frmtGoAway: discard else: diff --git a/src/hyperx/frame.nim b/src/hyperx/frame.nim index d2b8b3c..6012af8 100644 --- a/src/hyperx/frame.nim +++ b/src/hyperx/frame.nim @@ -238,11 +238,20 @@ func newWindowUpdateFrame*( result.setPayloadLen frmWindowUpdateSize.FrmPayloadLen result.s.assignAt(frmHeaderSize, increment.uint32) +func newSettingsFrame*(ack = false): Frame {.inline, raises: [].} = + result = newFrame() + result.setTyp frmtSettings + result.setSid frmSidMain + if ack: + result.flags.incl frmfAck + func addSetting*( frm: Frame, id: FrmSetting, value: uint32 ) {.inline, raises: [].} = + doAssert frm.typ == frmtSettings + doAssert frmfAck notin frm.flags let i = frm.len frm.grow frmSettingsSize frm.setPayloadLen frm.payload.len.FrmPayloadLen diff --git a/tests/testclient.nim b/tests/testclient.nim index 9bafa76..6d7dd3d 100644 --- a/tests/testclient.nim +++ b/tests/testclient.nim @@ -289,9 +289,10 @@ testAsync "header table size setting is applied": ":path: /foo\r\L" & ":authority: foo.bar\r\L" # XXX reqs[2] window size update - doAssert reqs[3].frm.sid.int == 3 - doAssert reqs[3].frm.typ == frmtHeaders - doAssert reqs[3].payload == + # XXX reqs[3] ack window size update + doAssert reqs[4].frm.sid.int == 3 + doAssert reqs[4].frm.typ == frmtHeaders + doAssert reqs[4].payload == ":method: GET\r\L" & ":scheme: https\r\L" & ":path: /bar\r\L" &