diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/dts/lib.deno.ns.d.ts | 8 | ||||
-rw-r--r-- | cli/tests/unit/http_test.ts | 80 | ||||
-rw-r--r-- | cli/tests/unit/tls_test.ts | 27 |
3 files changed, 115 insertions, 0 deletions
diff --git a/cli/dts/lib.deno.ns.d.ts b/cli/dts/lib.deno.ns.d.ts index 9c645882d..c01ac80fb 100644 --- a/cli/dts/lib.deno.ns.d.ts +++ b/cli/dts/lib.deno.ns.d.ts @@ -4017,6 +4017,14 @@ declare namespace Deno { * } * ``` * + * Note that this function *consumes* the given connection passed to it, thus the + * original connection will be unusable after calling this. Additionally, you + * need to ensure that the connection is not being used elsewhere when calling + * this function in order for the connection to be consumed properly. + * For instance, if there is a `Promise` that is waiting for read operation on + * the connection to complete, it is considered that the connection is being + * used elsewhere. In such a case, this function will fail. + * * @category HTTP Server */ export function serveHttp(conn: Conn): HttpConn; diff --git a/cli/tests/unit/http_test.ts b/cli/tests/unit/http_test.ts index 63eae3ace..566efce6d 100644 --- a/cli/tests/unit/http_test.ts +++ b/cli/tests/unit/http_test.ts @@ -2373,6 +2373,86 @@ Deno.test( }, ); +Deno.test( + { + permissions: { net: true }, + }, + async function httpServerWithoutExclusiveAccessToTcp() { + const port = 4506; + const listener = Deno.listen({ port }); + + const [clientConn, serverConn] = await Promise.all([ + Deno.connect({ port }), + listener.accept(), + ]); + + const buf = new Uint8Array(128); + const readPromise = serverConn.read(buf); + assertThrows(() => Deno.serveHttp(serverConn), Deno.errors.BadResource); + + clientConn.close(); + listener.close(); + await readPromise; + }, +); + +Deno.test( + { + permissions: { net: true, read: true }, + }, + async function httpServerWithoutExclusiveAccessToTls() { + const hostname = "localhost"; + const port = 4507; + const listener = Deno.listenTls({ + hostname, + port, + certFile: "cli/tests/testdata/tls/localhost.crt", + keyFile: "cli/tests/testdata/tls/localhost.key", + }); + + const caCerts = [ + await Deno.readTextFile("cli/tests/testdata/tls/RootCA.pem"), + ]; + const [clientConn, serverConn] = await Promise.all([ + Deno.connectTls({ hostname, port, caCerts }), + listener.accept(), + ]); + await Promise.all([clientConn.handshake(), serverConn.handshake()]); + + const buf = new Uint8Array(128); + const readPromise = serverConn.read(buf); + assertThrows(() => Deno.serveHttp(serverConn), Deno.errors.BadResource); + + clientConn.close(); + listener.close(); + await readPromise; + }, +); + +Deno.test( + { + ignore: Deno.build.os === "windows", + permissions: { read: true, write: true }, + }, + async function httpServerWithoutExclusiveAccessToUnixSocket() { + const filePath = await Deno.makeTempFile(); + const listener = Deno.listen({ path: filePath, transport: "unix" }); + + const [clientConn, serverConn] = await Promise.all([ + Deno.connect({ path: filePath, transport: "unix" }), + listener.accept(), + ]); + + const buf = new Uint8Array(128); + const readPromise = serverConn.read(buf); + assertThrows(() => Deno.serveHttp(serverConn), Deno.errors.BadResource); + + clientConn.close(); + listener.close(); + await readPromise; + }, +); + 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); diff --git a/cli/tests/unit/tls_test.ts b/cli/tests/unit/tls_test.ts index cf335de49..860965e49 100644 --- a/cli/tests/unit/tls_test.ts +++ b/cli/tests/unit/tls_test.ts @@ -148,6 +148,33 @@ Deno.test( ); Deno.test( + { permissions: { net: true } }, + async function startTlsWithoutExclusiveAccessToTcpConn() { + const hostname = "localhost"; + const port = getPort(); + + const tcpListener = Deno.listen({ hostname, port }); + const [serverConn, clientConn] = await Promise.all([ + tcpListener.accept(), + Deno.connect({ hostname, port }), + ]); + + const buf = new Uint8Array(128); + const readPromise = clientConn.read(buf); + // `clientConn` is being used by a pending promise (`readPromise`) so + // `Deno.startTls` cannot consume the connection. + await assertRejects( + () => Deno.startTls(clientConn, { hostname }), + Deno.errors.BadResource, + ); + + serverConn.close(); + tcpListener.close(); + await readPromise; + }, +); + +Deno.test( { permissions: { read: true, net: true } }, async function dialAndListenTLS() { const resolvable = deferred(); |