summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/dts/lib.deno.unstable.d.ts14
-rw-r--r--cli/tests/unit/http_test.ts44
2 files changed, 58 insertions, 0 deletions
diff --git a/cli/dts/lib.deno.unstable.d.ts b/cli/dts/lib.deno.unstable.d.ts
index 9ab9b5761..a61d672f7 100644
--- a/cli/dts/lib.deno.unstable.d.ts
+++ b/cli/dts/lib.deno.unstable.d.ts
@@ -1333,6 +1333,20 @@ declare namespace Deno {
* Make the timer of the given id not blocking the event loop from finishing
*/
export function unrefTimer(id: number): void;
+
+ /** **UNSTABLE**: new API, yet to be vetter.
+ *
+ * Allows to "hijack" a connection that the request is associated with.
+ * Can be used to implement protocols that build on top of HTTP (eg.
+ * WebSockets).
+ *
+ * The returned promise returns underlying connection and first packet
+ * received. The promise shouldn't be awaited before responding to the
+ * `request`, otherwise event loop might deadlock.
+ */
+ export function upgradeHttp(
+ request: Request,
+ ): Promise<[Deno.Conn, Uint8Array]>;
}
declare function fetch(
diff --git a/cli/tests/unit/http_test.ts b/cli/tests/unit/http_test.ts
index 65ee55577..fd8d49947 100644
--- a/cli/tests/unit/http_test.ts
+++ b/cli/tests/unit/http_test.ts
@@ -5,6 +5,7 @@ import {
BufWriter,
} from "../../../test_util/std/io/buffer.ts";
import { TextProtoReader } from "../../../test_util/std/textproto/mod.ts";
+import { serve } from "../../../test_util/std/http/server.ts";
import {
assert,
assertEquals,
@@ -1738,6 +1739,49 @@ Deno.test({
},
});
+Deno.test("upgradeHttp", async () => {
+ async function client() {
+ const tcpConn = await Deno.connect({ port: 4501 });
+ await tcpConn.write(
+ new TextEncoder().encode(
+ "CONNECT server.example.com:80 HTTP/1.1\r\n\r\nbla bla bla\nbla bla\nbla\n",
+ ),
+ );
+ setTimeout(async () => {
+ await tcpConn.write(
+ new TextEncoder().encode(
+ "bla bla bla\nbla bla\nbla\n",
+ ),
+ );
+ tcpConn.close();
+ }, 500);
+ }
+
+ const abortController = new AbortController();
+ const signal = abortController.signal;
+
+ const server = serve((req) => {
+ const p = Deno.upgradeHttp(req);
+
+ (async () => {
+ const [conn, firstPacket] = await p;
+ const buf = new Uint8Array(1024);
+ const firstPacketText = new TextDecoder().decode(firstPacket);
+ assertEquals(firstPacketText, "bla bla bla\nbla bla\nbla\n");
+ const n = await conn.read(buf);
+ assert(n != null);
+ const secondPacketText = new TextDecoder().decode(buf.slice(0, n));
+ assertEquals(secondPacketText, "bla bla bla\nbla bla\nbla\n");
+ abortController.abort();
+ conn.close();
+ })();
+
+ return new Response(null, { status: 101 });
+ }, { port: 4501, signal });
+
+ await Promise.all([server, client()]);
+});
+
function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader {
// Based on https://tools.ietf.org/html/rfc2616#section-19.4.6
const tp = new TextProtoReader(r);