diff options
Diffstat (limited to 'ext/http/01_http.js')
-rw-r--r-- | ext/http/01_http.js | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/ext/http/01_http.js b/ext/http/01_http.js index 217bfc061..152241522 100644 --- a/ext/http/01_http.js +++ b/ext/http/01_http.js @@ -32,7 +32,8 @@ } = window.__bootstrap.webSocket; const { TcpConn, UnixConn } = window.__bootstrap.net; const { TlsConn } = window.__bootstrap.tls; - const { Deferred } = window.__bootstrap.streams; + const { Deferred, getReadableStreamRid, readableStreamClose } = + window.__bootstrap.streams; const { ArrayPrototypeIncludes, ArrayPrototypePush, @@ -235,7 +236,6 @@ typeof respBody === "string" || ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, respBody) ); - try { await core.opAsync( "op_http_write_headers", @@ -269,16 +269,19 @@ ) { throw new TypeError("Unreachable"); } - const reader = respBody.getReader(); - while (true) { - const { value, done } = await reader.read(); - if (done) break; - if (!ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, value)) { - await reader.cancel(new TypeError("Value not a Uint8Array")); - break; + const resourceRid = getReadableStreamRid(respBody); + if (resourceRid) { + if (respBody.locked) { + throw new TypeError("ReadableStream is locked."); } + const reader = respBody.getReader(); // Aquire JS lock. try { - await core.opAsync("op_http_write", streamRid, value); + await core.opAsync( + "op_http_write_resource", + streamRid, + resourceRid, + ); + readableStreamClose(respBody); // Release JS lock. } catch (error) { const connError = httpConn[connErrorSymbol]; if ( @@ -291,12 +294,37 @@ await reader.cancel(error); throw error; } - } - try { - await core.opAsync("op_http_shutdown", streamRid); - } catch (error) { - await reader.cancel(error); - throw error; + } else { + const reader = respBody.getReader(); + while (true) { + const { value, done } = await reader.read(); + if (done) break; + if (!ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, value)) { + await reader.cancel(new TypeError("Value not a Uint8Array")); + break; + } + try { + await core.opAsync("op_http_write", streamRid, value); + } catch (error) { + const connError = httpConn[connErrorSymbol]; + if ( + ObjectPrototypeIsPrototypeOf(BadResourcePrototype, error) && + connError != null + ) { + // deno-lint-ignore no-ex-assign + error = new connError.constructor(connError.message); + } + await reader.cancel(error); + throw error; + } + } + + try { + await core.opAsync("op_http_shutdown", streamRid); + } catch (error) { + await reader.cancel(error); + throw error; + } } } |