diff options
author | bptato <nincsnevem662@gmail.com> | 2024-07-19 18:12:44 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-07-19 18:16:12 +0200 |
commit | 0d08ee8959d126d652fc42e9af63dbc8cc1d93ba (patch) | |
tree | 1b597924989f1eb3e4b96714c69e385af97d7186 | |
parent | f94b84bde340739647ffe7dd92cfcefb6686eca2 (diff) | |
download | chawan-0d08ee8959d126d652fc42e9af63dbc8cc1d93ba.tar.gz |
loader: async status/headers for fetch
The status code & headers are no longer guaranteed to be sent right after res/outputId, so read them asynchronously instead. (This is pretty much the same code as the buffer connection handler in pager. Hopefully we can merge the two at some point.)
-rw-r--r-- | src/loader/loader.nim | 56 | ||||
-rw-r--r-- | src/loader/response.nim | 6 | ||||
-rw-r--r-- | src/local/pager.nim | 9 |
3 files changed, 41 insertions, 30 deletions
diff --git a/src/loader/loader.nim b/src/loader/loader.nim index 29913031..f773936f 100644 --- a/src/loader/loader.nim +++ b/src/loader/loader.nim @@ -72,7 +72,14 @@ type # (FreeBSD only) fd for the socket directory so we can connectat() on it sockDirFd*: int - ConnectData = object + ConnectDataState = enum + cdsBeforeResult, cdsBeforeStatus, cdsBeforeHeaders + + ConnectData = ref object + state: ConnectDataState + status: uint16 + res: int + outputId: int promise: Promise[JSResult[Response]] stream*: SocketStream request: Request @@ -1018,17 +1025,32 @@ proc onConnected*(loader: FileLoader; fd: int) = let stream = connectData.stream let promise = connectData.promise let request = connectData.request - # delete before resolving the promise - loader.connecting.del(fd) var r = stream.initPacketReader() - var res: int - r.sread(res) # packet 1 - if res == 0: - let response = newResponse(res, request, stream) - r.sread(response.outputId) # packet 1 - r = stream.initPacketReader() - r.sread(response.status) # packet 2 - r = stream.initPacketReader() + case connectData.state + of cdsBeforeResult: + var res: int + r.sread(res) # packet 1 + if res == 0: + r.sread(connectData.outputId) # packet 1 + inc connectData.state + else: + var msg: string + # msg is discarded. + #TODO maybe print if called from trusted code (i.e. global == client)? + r.sread(msg) # packet 1 + loader.unregisterFun(fd) + loader.unregistered.add(fd) + stream.sclose() + # delete before resolving the promise + loader.connecting.del(fd) + let err = newTypeError("NetworkError when attempting to fetch resource") + promise.resolve(JSResult[Response].err(err)) + of cdsBeforeStatus: + r.sread(connectData.status) # packet 2 + inc connectData.state + of cdsBeforeHeaders: + let response = newResponse(connectData.res, request, stream, + connectData.outputId, connectData.status) r.sread(response.headers) # packet 3 # Only a stream of the response body may arrive after this point. response.body = stream @@ -1041,17 +1063,9 @@ proc onConnected*(loader: FileLoader; fd: int) = loader.resume(outputId) loader.ongoing[fd] = response stream.setBlocking(false) + # delete before resolving the promise + loader.connecting.del(fd) promise.resolve(JSResult[Response].ok(response)) - else: - var msg: string - # msg is discarded. - #TODO maybe print if called from trusted code (i.e. global == client)? - r.sread(msg) # packet 1 - loader.unregisterFun(fd) - loader.unregistered.add(fd) - stream.sclose() - let err = newTypeError("NetworkError when attempting to fetch resource") - promise.resolve(JSResult[Response].err(err)) proc onRead*(loader: FileLoader; fd: int) = let response = loader.ongoing.getOrDefault(fd) diff --git a/src/loader/response.nim b/src/loader/response.nim index 8b33621e..5531da9d 100644 --- a/src/loader/response.nim +++ b/src/loader/response.nim @@ -59,13 +59,15 @@ type jsDestructor(Response) -proc newResponse*(res: int; request: Request; stream: SocketStream): Response = +proc newResponse*(res: int; request: Request; stream: SocketStream; + outputId: int; status: uint16): Response = return Response( res: res, url: request.url, body: stream, bodyRead: EmptyPromise(), - outputId: -1 + outputId: outputId, + status: status ) func makeNetworkError*(): Response {.jsstfunc: "Response.error".} = diff --git a/src/local/pager.nim b/src/local/pager.nim index de990767..c77d724b 100644 --- a/src/local/pager.nim +++ b/src/local/pager.nim @@ -1970,13 +1970,8 @@ proc handleConnectingContainer*(pager: Pager; i: int) = inc item.state # continue of ccsBeforeHeaders: - let response = Response( - res: item.res, - outputId: item.outputId, - status: item.status, - url: container.request.url, - body: stream - ) + let response = newResponse(item.res, container.request, stream, + item.outputId, item.status) var r = stream.initPacketReader() r.sread(response.headers) # done |