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 /src/loader | |
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.)
Diffstat (limited to 'src/loader')
-rw-r--r-- | src/loader/loader.nim | 56 | ||||
-rw-r--r-- | src/loader/response.nim | 6 |
2 files changed, 39 insertions, 23 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".} = |