Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(unstable): remove Deno.upgradeHttp API #21856

Merged
merged 4 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
292 changes: 41 additions & 251 deletions cli/tests/integration/lsp_tests.rs

Large diffs are not rendered by default.

4 changes: 0 additions & 4 deletions cli/tests/testdata/run/unstable_http.disabled.out
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ main undefined
main undefined
main undefined
main undefined
main undefined
main undefined
worker undefined
worker undefined
worker undefined
worker undefined
worker undefined
Expand Down
4 changes: 0 additions & 4 deletions cli/tests/testdata/run/unstable_http.enabled.out
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,10 @@ main [Function: createHttpClient]
main [class HttpConn]
main Symbol("[[associated_ws]]")
main [Function: serve]
main [Function: upgradeHttp]
main [Function: upgradeWebSocket]
main [Function: upgradeHttp]
worker [class HttpClient]
worker [Function: createHttpClient]
worker [class HttpConn]
worker Symbol("[[associated_ws]]")
worker [Function: serve]
worker [Function: upgradeHttp]
worker [Function: upgradeWebSocket]
worker [Function: upgradeHttp]
2 changes: 0 additions & 2 deletions cli/tests/testdata/run/unstable_http.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ console.log(scope, Deno.createHttpClient);
console.log(scope, Deno.http?.HttpConn);
console.log(scope, Deno.http?._ws);
console.log(scope, Deno.http?.serve);
console.log(scope, Deno.http?.upgradeHttp);
console.log(scope, Deno.http?.upgradeWebSocket);
console.log(scope, Deno.upgradeHttp);

if (scope === "worker") {
postMessage("done");
Expand Down
157 changes: 0 additions & 157 deletions cli/tests/unit/http_test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { Buffer, BufReader, BufWriter } from "../../../test_util/std/io/mod.ts";
import { TextProtoReader } from "../testdata/run/textproto.ts";
import { serve, serveTls } from "../../../test_util/std/http/server.ts";
import {
assert,
assertEquals,
Expand Down Expand Up @@ -2181,162 +2180,6 @@ Deno.test({
},
});

Deno.test("upgradeHttp tcp", async () => {
async function client() {
const tcpConn = await Deno.connect({ port: listenPort });
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: listenPort, signal });

await Promise.all([server, client()]);
});

Deno.test(
"upgradeHttp tls",
{ permissions: { net: true, read: true } },
async () => {
async function client() {
const caCerts = [
await Deno.readTextFile("cli/tests/testdata/tls/RootCA.pem"),
];
const tlsConn = await Deno.connectTls({
hostname: "localhost",
port: listenPort,
caCerts,
});
await tlsConn.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 tlsConn.write(
new TextEncoder().encode(
"bla bla bla\nbla bla\nbla\n",
),
);
tlsConn.close();
}, 500);
}

const abortController = new AbortController();
const signal = abortController.signal;
const certFile = "cli/tests/testdata/tls/localhost.crt";
const keyFile = "cli/tests/testdata/tls/localhost.key";

const server = serveTls((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 });
}, { hostname: "localhost", port: listenPort, signal, keyFile, certFile });

await Promise.all([server, client()]);
},
);

Deno.test("upgradeHttp unix", {
permissions: { read: true, write: true },
ignore: Deno.build.os === "windows",
}, async () => {
const filePath = tmpUnixSocketPath();
const { promise, resolve } = Promise.withResolvers<void>();

async function client() {
const unixConn = await Deno.connect({ path: filePath, transport: "unix" });
await unixConn.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 unixConn.write(
new TextEncoder().encode(
"bla bla bla\nbla bla\nbla\n",
),
);
unixConn.close();
resolve();
}, 500);
await promise;
}

const server = (async () => {
const listener = Deno.listen({ path: filePath, transport: "unix" });
const conn = await listener.accept();
listener.close();
const httpConn = Deno.serveHttp(conn);
const reqEvent = await httpConn.nextRequest();
assert(reqEvent);
const { request, respondWith } = reqEvent;
const p = Deno.upgradeHttp(request);

const promise = (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");
conn.close();
})();

const resp = new Response(null, { status: 101 });
await respondWith(resp);
await promise;
httpConn!.close();
})();

await Promise.all([server, client()]);
});

Deno.test(
{ permissions: { net: true } },
async function httpServerReadLargeBodyWithContentLength() {
Expand Down
1 change: 0 additions & 1 deletion cli/tsc/99_main_compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ delete Object.prototype.__proto__;
"listen",
"listenDatagram",
"openKv",
"upgradeHttp",
"umask",
]);
const unstableMsgSuggestion =
Expand Down
28 changes: 0 additions & 28 deletions cli/tsc/dts/lib.deno.unstable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1187,34 +1187,6 @@ declare namespace Deno {
*/
export function funlockSync(rid: number): void;

/** **UNSTABLE**: New API, yet to be vetted.
*
* Allows "hijacking" the connection that the request is associated with. This
* can be used to implement protocols that build on top of HTTP (eg.
* {@linkcode WebSocket}).
*
* 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.
*
* ```ts
* function handler(req: Request): Response {
* Deno.upgradeHttp(req).then(([conn, firstPacket]) => {
* // ...
* });
* return new Response(null, { status: 101 });
* }
* ```
*
* This method can only be called on requests originating the
* {@linkcode Deno.serveHttp} server.
*
* @category HTTP Server
*/
export function upgradeHttp(
request: Request,
): Promise<[Deno.Conn, Uint8Array]>;

/** **UNSTABLE**: New API, yet to be vetted.
*
* Open a new {@linkcode Deno.Kv} connection to persist data.
Expand Down
6 changes: 0 additions & 6 deletions ext/http/00_serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,6 @@ class InnerRequest {
throw new Deno.errors.Http("already closed");
}

// upgradeHttp is async
// TODO(mmastrac)
if (upgradeType == "upgradeHttp") {
throw "upgradeHttp is unavailable in Deno.serve at this time";
}

// upgradeHttpRaw is sync
if (upgradeType == "upgradeHttpRaw") {
const external = this.#external;
Expand Down
40 changes: 1 addition & 39 deletions ext/http/01_http.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const {
op_http_accept,
op_http_headers,
op_http_shutdown,
op_http_upgrade,
op_http_upgrade_websocket,
op_http_websocket_accept_header,
op_http_write,
Expand All @@ -20,7 +19,6 @@ const {
ArrayPrototypeIncludes,
ArrayPrototypeMap,
ArrayPrototypePush,
Error,
ObjectPrototypeIsPrototypeOf,
SafeSet,
SafeSetIterator,
Expand Down Expand Up @@ -67,10 +65,7 @@ import {
SERVER,
WebSocket,
} from "ext:deno_websocket/01_websocket.js";
import { TcpConn, UnixConn } from "ext:deno_net/01_net.js";
import { TlsConn } from "ext:deno_net/02_tls.js";
import {
Deferred,
getReadableStreamResourceBacking,
readableStreamClose,
readableStreamForRid,
Expand All @@ -80,7 +75,6 @@ import { serve } from "ext:deno_http/00_serve.js";
import { SymbolDispose } from "ext:deno_web/00_infra.js";

const connErrorSymbol = Symbol("connError");
const _deferred = Symbol("upgradeHttpDeferred");

/** @type {(self: HttpConn, rid: number) => boolean} */
let deleteManagedResource;
Expand Down Expand Up @@ -174,9 +168,6 @@ class HttpConn {
const respondWith = createRespondWith(
this,
streamRid,
request,
this.#remoteAddr,
this.#localAddr,
abortController,
);

Expand Down Expand Up @@ -219,9 +210,6 @@ class HttpConn {
function createRespondWith(
httpConn,
streamRid,
request,
remoteAddr,
localAddr,
abortController,
) {
return async function respondWith(resp) {
Expand Down Expand Up @@ -379,22 +367,6 @@ function createRespondWith(
}
}

const deferred = request[_deferred];
if (deferred) {
const res = await op_http_upgrade(streamRid);
let conn;
if (res.connType === "tcp") {
conn = new TcpConn(res.connRid, remoteAddr, localAddr);
} else if (res.connType === "tls") {
conn = new TlsConn(res.connRid, remoteAddr, localAddr);
} else if (res.connType === "unix") {
conn = new UnixConn(res.connRid, remoteAddr, localAddr);
} else {
throw new Error("unreachable");
}

deferred.resolve([conn, res.readBuf]);
}
const ws = resp[_ws];
if (ws) {
const wsRid = await op_http_upgrade_websocket(
Expand Down Expand Up @@ -502,16 +474,6 @@ function upgradeWebSocket(request, options = {}) {
return { response, socket };
}

function upgradeHttp(req) {
const inner = toInnerRequest(req);
if (inner._wantsUpgrade) {
return inner._wantsUpgrade("upgradeHttp", arguments);
}

req[_deferred] = new Deferred();
return req[_deferred].promise;
}

const spaceCharCode = StringPrototypeCharCodeAt(" ", 0);
const tabCharCode = StringPrototypeCharCodeAt("\t", 0);
const commaCharCode = StringPrototypeCharCodeAt(",", 0);
Expand Down Expand Up @@ -589,4 +551,4 @@ function buildCaseInsensitiveCommaValueFinder(checkText) {
internals.buildCaseInsensitiveCommaValueFinder =
buildCaseInsensitiveCommaValueFinder;

export { _ws, HttpConn, serve, upgradeHttp, upgradeWebSocket };
export { _ws, HttpConn, serve, upgradeWebSocket };
2 changes: 0 additions & 2 deletions runtime/js/90_deno_ns.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ denoNsUnstableById[unstableIds.http] = {
createHttpClient: httpClient.createHttpClient,
// TODO(bartlomieju): why is it needed?
http,
upgradeHttp: http.upgradeHttp,
};

denoNsUnstableById[unstableIds.kv] = {
Expand Down Expand Up @@ -250,7 +249,6 @@ const denoNsUnstable = {
flockSync: fs.flockSync,
funlock: fs.funlock,
funlockSync: fs.funlockSync,
upgradeHttp: http.upgradeHttp,
openKv: kv.openKv,
AtomicOperation: kv.AtomicOperation,
Kv: kv.Kv,
Expand Down
Loading