diff options
author | Bartek Iwańczuk <biwanczuk@gmail.com> | 2022-08-19 14:36:01 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-19 14:36:01 +0200 |
commit | 5beec3f106b0890cc76150d0e3b3661c576d4c3b (patch) | |
tree | 9692e24bdb5a7e1d1c883b91961cdacff3e6708c | |
parent | 1848c7e361f1a3a33487b60ab6fcb61ed1f62273 (diff) |
feat(unstable): change Deno.serve() API (#15498)
- Merge "Deno.serve()" and "Deno.serveTls()" API
- Remove first argument and use "fetch" field options instead
- Update type declarations
- Add more documentation
-rw-r--r-- | cli/bench/http/deno_flash_hono_router.js | 2 | ||||
-rw-r--r-- | cli/bench/http/deno_flash_send_file.js | 4 | ||||
-rw-r--r-- | cli/bench/http/deno_http_flash.js | 5 | ||||
-rw-r--r-- | cli/bench/http/deno_reactdom_ssr_flash.jsx | 9 | ||||
-rw-r--r-- | cli/bench/testdata/deno_upgrade_http.js | 5 | ||||
-rw-r--r-- | cli/diagnostics.rs | 1 | ||||
-rw-r--r-- | cli/dts/lib.deno.unstable.d.ts | 113 | ||||
-rw-r--r-- | cli/tests/unit/flash_test.ts | 496 | ||||
-rw-r--r-- | ext/flash/01_http.js | 26 | ||||
-rw-r--r-- | ext/flash/README.md | 2 | ||||
-rw-r--r-- | ext/flash/lib.rs | 7 | ||||
-rw-r--r-- | runtime/js/90_deno_ns.js | 1 |
12 files changed, 347 insertions, 324 deletions
diff --git a/cli/bench/http/deno_flash_hono_router.js b/cli/bench/http/deno_flash_hono_router.js index af6adc9ba..4c3336c63 100644 --- a/cli/bench/http/deno_flash_hono_router.js +++ b/cli/bench/http/deno_flash_hono_router.js @@ -7,4 +7,4 @@ const [hostname, port] = addr.split(":"); const app = new Hono(); app.get("/", (c) => c.text("Hello, World!")); -Deno.serve(app.fetch, { port: Number(port), hostname }); +Deno.serve({ fetch: app.fetch, port: Number(port), hostname }); diff --git a/cli/bench/http/deno_flash_send_file.js b/cli/bench/http/deno_flash_send_file.js index db2ad7a82..81e8c4991 100644 --- a/cli/bench/http/deno_flash_send_file.js +++ b/cli/bench/http/deno_flash_send_file.js @@ -6,9 +6,9 @@ const { serve } = Deno; const path = new URL("../testdata/128k.bin", import.meta.url).pathname; -function handler() { +function fetch() { const file = Deno.openSync(path); return new Response(file.readable); } -serve(handler, { hostname, port: Number(port) }); +serve({ fetch, hostname, port: Number(port) }); diff --git a/cli/bench/http/deno_http_flash.js b/cli/bench/http/deno_http_flash.js index 5d3de68f4..3823bb9cd 100644 --- a/cli/bench/http/deno_http_flash.js +++ b/cli/bench/http/deno_http_flash.js @@ -4,11 +4,12 @@ const addr = Deno.args[0] || "127.0.0.1:4500"; const [hostname, port] = addr.split(":"); const { serve } = Deno; -function handler() { +function fetch() { return new Response("Hello World"); } -serve(handler, { +serve({ + fetch, hostname, port, }); diff --git a/cli/bench/http/deno_reactdom_ssr_flash.jsx b/cli/bench/http/deno_reactdom_ssr_flash.jsx index 571545b27..0d749c634 100644 --- a/cli/bench/http/deno_reactdom_ssr_flash.jsx +++ b/cli/bench/http/deno_reactdom_ssr_flash.jsx @@ -19,8 +19,11 @@ const headers = { }; serve( - async () => { - return new Response(await renderToReadableStream(<App />), headers); + { + fetch: async () => { + return new Response(await renderToReadableStream(<App />), headers); + }, + hostname, + port, }, - { hostname, port }, ); diff --git a/cli/bench/testdata/deno_upgrade_http.js b/cli/bench/testdata/deno_upgrade_http.js index 638761cf6..e3252ffd1 100644 --- a/cli/bench/testdata/deno_upgrade_http.js +++ b/cli/bench/testdata/deno_upgrade_http.js @@ -1,13 +1,14 @@ const { serve, upgradeHttp } = Deno; const u8 = Deno.core.encode("HTTP/1.1 101 Switching Protocols\r\n\r\n"); -async function handler(req) { +async function fetch(req) { const [conn, _firstPacket] = upgradeHttp(req); await conn.write(u8); await conn.close(); } -serve(handler, { +serve({ + fetch, hostname: "127.0.0.1", port: 9000, }); diff --git a/cli/diagnostics.rs b/cli/diagnostics.rs index 7af64d843..6100bc9d5 100644 --- a/cli/diagnostics.rs +++ b/cli/diagnostics.rs @@ -64,7 +64,6 @@ const UNSTABLE_DENO_PROPS: &[&str] = &[ "ChildStatus", "SpawnOutput", "serve", - "serveTls", "ServeInit", "ServeTlsInit", "Handler", diff --git a/cli/dts/lib.deno.unstable.d.ts b/cli/dts/lib.deno.unstable.d.ts index 8de2ecf70..9cd6aec03 100644 --- a/cli/dts/lib.deno.unstable.d.ts +++ b/cli/dts/lib.deno.unstable.d.ts @@ -1212,28 +1212,26 @@ declare namespace Deno { export function unrefTimer(id: number): void; /** - * A handler for HTTP requests. Consumes a request and returns a response. - * - * Handler allows `void` or `Promise<void>` return type to enable - * request upgrades using `Deno.upgradeHttp()` API. It is callers responsibility - * to write response manually to the returned connection. Failing to do so - * (or not returning a response without an upgrade) will cause the connection - * to hang. - * - * If a handler throws, the server calling the handler will assume the impact - * of the error is isolated to the individual request. It will catch the error - * and close the underlying connection. - * - * @category HTTP Server - */ - export type ServeHandler = ( - request: Request, - ) => Response | Promise<Response> | void | Promise<void>; - - /** * @category HTTP Server */ export interface ServeInit extends Partial<Deno.ListenOptions> { + /** + * A handler for HTTP requests. Consumes a request and returns a response. + * + * Handler allows `void` or `Promise<void>` return type to enable + * request upgrades using `Deno.upgradeHttp()` API. It is callers responsibility + * to write response manually to the returned connection. Failing to do so + * (or not returning a response without an upgrade) will cause the connection + * to hang. + * + * If a handler throws, the server calling the handler will assume the impact + * of the error is isolated to the individual request. It will catch the error + * and close the underlying connection. + */ + fetch: ( + request: Request, + ) => Response | Promise<Response> | void | Promise<void>; + /** An AbortSignal to close the server and all connections. */ signal?: AbortSignal; @@ -1263,14 +1261,36 @@ declare namespace Deno { * The below example serves with the port 9000. * * ```ts - * Deno.serve((_req) => new Response("Hello, world")); + * Deno.serve({ + * fetch: (_req) => new Response("Hello, world") + * }); * ``` * * You can change the listening address by the `hostname` and `port` options. * The below example serves with the port 3000. * * ```ts - * Deno.serve((_req) => new Response("Hello, world"), { port: 3000 }); + * Deno.serve({ + * fetch: (_req) => new Response("Hello, world"), + * port: 3000 + * }); + * ``` + * + * You can close the server by passing a `signal` option. To wait for the server + * to close, await the promise returned from the `Deno.serve` API. + * + * ```ts + * const ac = new AbortController(); + * + * Deno.serve({ + * fetch: (_req) => new Response("Hello, world"), + * signal: ac.signal + * }).then(() => { + * console.log("Server closed"); + * }); + * + * console.log("Closing server..."); + * ac.abort(); * ``` * * `Deno.serve` function prints the message `Listening on http://<hostname>:<port>/` @@ -1278,7 +1298,8 @@ declare namespace Deno { * `onListen` option to override it. * * ```ts - * Deno.serve((_req) => new Response("Hello, world"), { + * Deno.serve({ + * fetch: (_req) => new Response("Hello, world"), * onListen({ port, hostname }) { * console.log(`Server started at http://${hostname}:${port}`); * // ... more info specific to your server .. @@ -1286,57 +1307,23 @@ declare namespace Deno { * }); * ``` * - * @param handler The handler for individual HTTP requests. - * @param options The options. See `ServeInit` documentation for details. - * - * @category HTTP Server - */ - export function serve( - handler: ServeHandler, - options?: ServeInit, - ): Promise<void>; - - /** Serves HTTPS requests with the given handler. - * - * You must specify `key` and `cert` options. - * - * You can specify an object with a port and hostname option, which is the - * address to listen on. The default is port 9000 on hostname "127.0.0.1". - * - * The below example serves with the default port 8443. + * To enable TLS you must specify `key` and `cert` options. * * ```ts * const cert = "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n"; * const key = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"; - * Deno.serveTls((_req) => new Response("Hello, world"), { cert, key }); - * - * ``` - * - * `Deno.serveTls` function prints the message `Listening on https://<hostname>:<port>/` - * on start-up by default. If you like to change this message, you can specify - * `onListen` option to override it. - * - * ```ts - * const cert = "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n"; - * const key = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"; - * Deno.serveTls((_req) => new Response("Hello, world"), { + * Deno.serve({ + * fetch: (_req) => new Response("Hello, world"), * cert, - * key, - * onListen({ port, hostname }) { - * console.log(`Server started at https://${hostname}:${port}`); - * // ... more info specific to your server .. - * }, + * key * }); - * ``` * - * @param handler The handler for individual HTTPS requests. - * @param options The options. See `ServeTlsInit` documentation for details. + * @param options The options. See `ServeInit` and `ServeTlsInit` documentation for details. * * @category HTTP Server */ - export function serveTls( - handler: ServeHandler, - options?: ServeTlsInit, + export function serve( + options?: ServeInit | ServeTlsInit, ): Promise<void>; /** **UNSTABLE**: new API, yet to be vetter. diff --git a/cli/tests/unit/flash_test.ts b/cli/tests/unit/flash_test.ts index 51534c79b..1b979812f 100644 --- a/cli/tests/unit/flash_test.ts +++ b/cli/tests/unit/flash_test.ts @@ -41,15 +41,16 @@ Deno.test({ permissions: { net: true } }, async function httpServerBasic() { const promise = deferred(); const listeningPromise = deferred(); - const server = Deno.serve(async (request) => { - // FIXME(bartlomieju): - // make sure that request can be inspected - console.log(request); - assertEquals(new URL(request.url).href, "http://127.0.0.1:4501/"); - assertEquals(await request.text(), ""); - promise.resolve(); - return new Response("Hello World", { headers: { "foo": "bar" } }); - }, { + const server = Deno.serve({ + fetch: async (request) => { + // FIXME(bartlomieju): + // make sure that request can be inspected + console.log(request); + assertEquals(new URL(request.url).href, "http://127.0.0.1:4501/"); + assertEquals(await request.text(), ""); + promise.resolve(); + return new Response("Hello World", { headers: { "foo": "bar" } }); + }, port: 4501, signal: ac.signal, onListen: onListen(listeningPromise), @@ -80,12 +81,13 @@ Deno.test( const ac = new AbortController(); let headers: Headers; - const server = Deno.serve(async (request) => { - await request.text(); - headers = request.headers; - promise.resolve(); - return new Response(""); - }, { + const server = Deno.serve({ + fetch: async (request) => { + await request.text(); + headers = request.headers; + promise.resolve(); + return new Response(""); + }, port: 2333, signal: ac.signal, onListen: onListen(listeningPromise), @@ -116,12 +118,13 @@ Deno.test( const listeningPromise = deferred(); let req: Request; - const server = Deno.serve(async (request) => { - await request.text(); - req = request; - promise.resolve(); - return new Response("Hello World"); - }, { + const server = Deno.serve({ + fetch: async (request) => { + await request.text(); + req = request; + promise.resolve(); + return new Response("Hello World"); + }, port: 2334, signal: ac.signal, onListen: onListen(listeningPromise), @@ -159,11 +162,12 @@ Deno.test( const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve((request) => { - assertEquals(request.body, null); - promise.resolve(); - return new Response("", { headers: {} }); - }, { + const server = Deno.serve({ + fetch: (request) => { + assertEquals(request.body, null); + promise.resolve(); + return new Response("", { headers: {} }); + }, port: 4501, signal: ac.signal, onListen: onListen(listeningPromise), @@ -202,11 +206,11 @@ Deno.test( const listeningPromise = deferred(); const ac = new AbortController(); - - const server = Deno.serve((request) => { - assert(!request.body); - return new Response(stream.readable); - }, { + const server = Deno.serve({ + fetch: (request) => { + assert(!request.body); + return new Response(stream.readable); + }, port: 4501, signal: ac.signal, onListen: onListen(listeningPromise), @@ -232,11 +236,12 @@ Deno.test( writer.close(); const listeningPromise = deferred(); const ac = new AbortController(); - const server = Deno.serve(async (request) => { - const reqBody = await request.text(); - assertEquals("hello world", reqBody); - return new Response("yo"); - }, { + const server = Deno.serve({ + fetch: async (request) => { + const reqBody = await request.text(); + assertEquals("hello world", reqBody); + return new Response("yo"); + }, port: 4501, signal: ac.signal, onListen: onListen(listeningPromise), @@ -259,7 +264,8 @@ Deno.test( Deno.test({ permissions: { net: true } }, async function httpServerClose() { const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(() => new Response("ok"), { + const server = Deno.serve({ + fetch: () => new Response("ok"), port: 4501, signal: ac.signal, onListen: onListen(listeningPromise), @@ -278,7 +284,8 @@ Deno.test( async function httpServerEmptyBlobResponse() { const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(() => new Response(new Blob([])), { + const server = Deno.serve({ + fetch: () => new Response(new Blob([])), port: 4501, signal: ac.signal, onListen: onListen(listeningPromise), @@ -298,18 +305,19 @@ Deno.test( Deno.test({ permissions: { net: true } }, async function httpServerWebSocket() { const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(async (request) => { - const { - response, - socket, - } = Deno.upgradeWebSocket(request); - socket.onerror = () => fail(); - socket.onmessage = (m) => { - socket.send(m.data); - socket.close(1001); - }; - return response; - }, { + const server = Deno.serve({ + fetch: async (request) => { + const { + response, + socket, + } = Deno.upgradeWebSocket(request); + socket.onerror = () => fail(); + socket.onmessage = (m) => { + socket.send(m.data); + socket.close(1001); + }; + return response; + }, port: 4501, signal: ac.signal, onListen: onListen(listeningPromise), @@ -337,11 +345,12 @@ Deno.test( const ac = new AbortController(); let headers: Headers; - const server = Deno.serve(async (request) => { - headers = request.headers; - promise.resolve(); - return new Response(""); - }, { + const server = Deno.serve({ + fetch: async (request) => { + headers = request.headers; + promise.resolve(); + return new Response(""); + }, port: 2333, signal: ac.signal, onListen: onListen(listeningPromise), @@ -375,12 +384,13 @@ Deno.test( let headers: Headers; let text: string; - const server = Deno.serve(async (request) => { - headers = request.headers; - text = await request.text(); - promise.resolve(); - return new Response(""); - }, { + const server = Deno.serve({ + fetch: async (request) => { + headers = request.headers; + text = await request.text(); + promise.resolve(); + return new Response(""); + }, port: 2333, signal: ac.signal, onListen: onListen(listeningPromise), @@ -419,10 +429,11 @@ Deno.test( const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(() => { - promise.resolve(); - return new Response(""); - }, { + const server = Deno.serve({ + fetch: () => { + promise.resolve(); + return new Response(""); + }, port: 2333, signal: ac.signal, onListen: onListen(listeningPromise), @@ -568,10 +579,11 @@ Deno.test( }).pipeThrough(new TextEncoderStream()); } - const finished = Deno.serve(() => { - promise.resolve(); - return new Response(periodicStream()); - }, { + const finished = Deno.serve({ + fetch: () => { + promise.resolve(); + return new Response(periodicStream()); + }, port: 4501, signal: ac.signal, onListen: onListen(listeningPromise), @@ -598,11 +610,12 @@ Deno.test( const listeningPromise = deferred(); const promise = deferred(); const ac = new AbortController(); - const server = Deno.serve((request) => { - assertEquals(request.headers.get("X-Header-Test"), "á"); - promise.resolve(); - return new Response("hello", { headers: { "X-Header-Test": "Æ" } }); - }, { + const server = Deno.serve({ + fetch: (request) => { + assertEquals(request.headers.get("X-Header-Test"), "á"); + promise.resolve(); + return new Response("hello", { headers: { "X-Header-Test": "Æ" } }); + }, port: 4501, signal: ac.signal, onListen: onListen(listeningPromise), @@ -643,13 +656,14 @@ Deno.test( const listeningPromise = deferred(); const ac = new AbortController(); - const server = Deno.serve(async (request) => { - // FIXME: - // assertEquals(new URL(request.url).href, "http://127.0.0.1:4501/"); - assertEquals(await request.text(), ""); - promise.resolve(); - return new Response("11"); - }, { + const server = Deno.serve({ + fetch: async (request) => { + // FIXME: + // assertEquals(new URL(request.url).href, "http://127.0.0.1:4501/"); + assertEquals(await request.text(), ""); + promise.resolve(); + return new Response("11"); + }, port: 4501, signal: ac.signal, onListen: onListen(listeningPromise), @@ -696,12 +710,13 @@ Deno.test( const listeningPromise = deferred(); const ac = new AbortController(); - const server = Deno.serve(async (request) => { - assertEquals(await request.text(), ""); - assertEquals(request.headers.get("cookie"), "foo=bar, bar=foo"); - promise.resolve(); - return new Response("ok"); - }, { + const server = Deno.serve({ + fetch: async (request) => { + assertEquals(await request.text(), ""); + assertEquals(request.headers.get("cookie"), "foo=bar, bar=foo"); + promise.resolve(); + return new Response("ok"); + }, port: 4501, signal: ac.signal, onListen: onListen(listeningPromise), @@ -738,11 +753,12 @@ Deno.test( await file.write(new Uint8Array(70 * 1024).fill(1)); // 70kb sent in 64kb + 6kb chunks file.close(); - const server = Deno.serve(async (request) => { - const f = await Deno.open(tmpFile, { read: true }); - promise.resolve(); - return new Response(f.readable); - }, { + const server = Deno.serve({ + fetch: async (request) => { + const f = await Deno.open(tmpFile, { read: true }); + promise.resolve(); + return new Response(f.readable); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -773,10 +789,11 @@ Deno.test( const hostname = "localhost"; const port = 4501; - const server = Deno.serve(() => { - promise.resolve(); - return new Response("ok"); - }, { + const server = Deno.serve({ + fetch: () => { + promise.resolve(); + return new Response("ok"); + }, port: port, signal: ac.signal, onListen: onListen(listeningPromise), @@ -807,11 +824,12 @@ Deno.test( const listeningPromise = deferred(); const ac = new AbortController(); - const server = Deno.serve(async (request) => { - assertEquals(request.body, null); - promise.resolve(); - return new Response(new Uint8Array([128])); - }, { + const server = Deno.serve({ + fetch: async (request) => { + assertEquals(request.body, null); + promise.resolve(); + return new Response(new Uint8Array([128])); + }, port: 4501, signal: ac.signal, onListen: onListen(listeningPromise), @@ -837,8 +855,7 @@ Deno.test("upgradeHttp tcp", async () => { const promise2 = deferred(); const ac = new AbortController(); const signal = ac.signal; - - const server = Deno.serve(async (req) => { + const fetch = async (req: Request) => { const [conn, _] = await Deno.upgradeHttp(req); await conn.write( @@ -856,7 +873,9 @@ Deno.test("upgradeHttp tcp", async () => { promise2.resolve(); conn.close(); - }, { + }; + const server = Deno.serve({ + fetch, port: 4501, signal, onListen: onListen(listeningPromise), @@ -897,12 +916,13 @@ Deno.test( const listeningPromise = deferred(); const ac = new AbortController(); - const server = Deno.serve(async (request) => { - assertEquals(request.method, "GET"); - assertEquals(request.headers.get("host"), "deno.land"); - promise.resolve(); - return new Response("ok"); - }, { + const server = Deno.serve({ + fetch: async (request) => { + assertEquals(request.method, "GET"); + assertEquals(request.headers.get("host"), "deno.land"); + promise.resolve(); + return new Response("ok"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -930,12 +950,13 @@ Deno.test( const listeningPromise = deferred(); const ac = new AbortController(); - const server = Deno.serve(async (request) => { - assertEquals(request.method, "GET"); - assertEquals(request.headers.get("server"), "hello\tworld"); - promise.resolve(); - return new Response("ok"); - }, { + const server = Deno.serve({ + fetch: async (request) => { + assertEquals(request.method, "GET"); + assertEquals(request.headers.get("server"), "hello\tworld"); + promise.resolve(); + return new Response("ok"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -963,12 +984,13 @@ Deno.test( const listeningPromise = deferred(); const ac = new AbortController(); - const server = Deno.serve(async (request) => { - assertEquals(request.method, "GET"); - assertEquals(await request.text(), ""); - promise.resolve(); - return new Response("ok"); - }, { + const server = Deno.serve({ + fetch: async (request) => { + assertEquals(request.method, "GET"); + assertEquals(await request.text(), ""); + promise.resolve(); + return new Response("ok"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -998,12 +1020,13 @@ Deno.test( const listeningPromise = deferred(); const ac = new AbortController(); - const server = Deno.serve(async (request) => { - assertEquals(request.method, "POST"); - assertEquals(await request.text(), "I'm a good request."); - promise.resolve(); - return new Response("ok"); - }, { + const server = Deno.serve({ + fetch: async (request) => { + assertEquals(request.method, "POST"); + assertEquals(await request.text(), "I'm a good request."); + promise.resolve(); + return new Response("ok"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1043,11 +1066,12 @@ function createServerLengthTest(name: string, testCase: TestCase) { const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(async (request) => { - assertEquals(request.method, "GET"); - promise.resolve(); - return new Response(testCase.body, testCase.headers ?? {}); - }, { + const server = Deno.serve({ + fetch: async (request) => { + assertEquals(request.method, "GET"); + promise.resolve(); + return new Response(testCase.body, testCase.headers ?? {}); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1174,12 +1198,13 @@ Deno.test( const listeningPromise = deferred(); const ac = new AbortController(); - const server = Deno.serve(async (request) => { - assertEquals(request.method, "GET"); - promises[reqCount].resolve(); - reqCount++; - return new Response(reqCount <= 1 ? stream("foo bar baz") : "zar quux"); - }, { + const server = Deno.serve({ + fetch: async (request) => { + assertEquals(request.method, "GET"); + promises[reqCount].resolve(); + reqCount++; + return new Response(reqCount <= 1 ? stream("foo bar baz") : "zar quux"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1236,13 +1261,14 @@ Deno.test( const listeningPromise = deferred(); const ac = new AbortController(); - const server = Deno.serve(async (request) => { - assertEquals(request.method, "POST"); - assertEquals(request.headers.get("content-length"), "5"); - assertEquals(await request.text(), "hello"); - promise.resolve(); - return new Response("ok"); - }, { + const server = Deno.serve({ + fetch: async (request) => { + assertEquals(request.method, "POST"); + assertEquals(request.headers.get("content-length"), "5"); + assertEquals(await request.text(), "hello"); + promise.resolve(); + return new Response("ok"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1271,9 +1297,10 @@ Deno.test( async function httpServerPostWithInvalidPrefixContentLength() { const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(() => { - throw new Error("unreachable"); - }, { + const server = Deno.serve({ + fetch: () => { + throw new Error("unreachable"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1310,12 +1337,13 @@ Deno.test( const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(async (request) => { - assertEquals(request.method, "POST"); - assertEquals(await request.text(), "qwert"); - promise.resolve(); - return new Response("ok"); - }, { + const server = Deno.serve({ + fetch: async (request) => { + assertEquals(request.method, "POST"); + assertEquals(await request.text(), "qwert"); + promise.resolve(); + return new Response("ok"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1346,11 +1374,12 @@ Deno.test( const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(async (r) => { - promise.resolve(); - assertEquals(await r.text(), "12345"); - return new Response("ok"); - }, { + const server = Deno.serve({ + fetch: async (r) => { + promise.resolve(); + assertEquals(await r.text(), "12345"); + return new Response("ok"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1381,10 +1410,11 @@ Deno.test( const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(() => { - promise.resolve(); - return new Response("foo bar baz"); - }, { + const server = Deno.serve({ + fetch: () => { + promise.resolve(); + return new Response("foo bar baz"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1428,11 +1458,12 @@ Deno.test( const data = new Uint8Array(70 * 1024).fill(1); await file.write(data); file.close(); - const server = Deno.serve(async () => { - const f = await Deno.open(tmpFile, { read: true }); - promise.resolve(); - return new Response(f.readable, { status: 200 }); - }, { + const server = Deno.serve({ + fetch: async () => { + const f = await Deno.open(tmpFile, { read: true }); + promise.resolve(); + return new Response(f.readable, { status: 200 }); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1462,11 +1493,12 @@ Deno.test( await file.write(data); file.close(); - const server = Deno.serve(async (request) => { - assertEquals(new Uint8Array(await request.arrayBuffer()), data); - promise.resolve(); - return new Response("ok"); - }, { + const server = Deno.serve({ + fetch: async (request) => { + assertEquals(new Uint8Array(await request.arrayBuffer()), data); + promise.resolve(); + return new Response("ok"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1497,11 +1529,9 @@ Deno.test( const listeningPromise = deferred(); const hostname = "127.0.0.1"; const port = 4501; - function handler() { - return new Response("Hello World"); - } - const server = Deno.serveTls(handler, { + const server = Deno.serve({ + fetch: () => new Response("Hello World"), hostname, port, signal: ac.signal, @@ -1535,11 +1565,12 @@ Deno.test( const listeningPromise = deferred(); const promise = deferred(); - const server = Deno.serve(async (req) => { - assertEquals(await req.text(), ""); - promise.resolve(); - return new Response("ok"); - }, { + const server = Deno.serve({ + fetch: async (req) => { + assertEquals(await req.text(), ""); + promise.resolve(); + return new Response("ok"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1569,9 +1600,10 @@ Deno.test( const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(() => { - throw new Error("oops"); - }, { + const server = Deno.serve({ + fetch: () => { + throw new Error("oops"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1617,10 +1649,11 @@ Deno.test( const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(() => { - promise.resolve(); - return new Response(null, { status: 304 }); - }, { + const server = Deno.serve({ + fetch: () => { + promise.resolve(); + return new Response(null, { status: 304 }); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1660,11 +1693,12 @@ Deno.test( const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(async (req) => { - promise.resolve(); - assertEquals(await req.text(), "hello"); - return new Response(null, { status: 304 }); - }, { + const server = Deno.serve({ + fetch: async (req) => { + promise.resolve(); + assertEquals(await req.text(), "hello"); + return new Response(null, { status: 304 }); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1720,11 +1754,12 @@ Deno.test( const listeningPromise = deferred(); const ac = new AbortController(); - const server = Deno.serve(async (req) => { - promise.resolve(); - assertEquals(await req.text(), ""); - return new Response(null, { status: 304 }); - }, { + const server = Deno.serve({ + fetch: async (req) => { + promise.resolve(); + assertEquals(await req.text(), ""); + return new Response(null, { status: 304 }); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1773,9 +1808,10 @@ for (const [name, req] of badRequests) { const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(() => { - throw new Error("oops"); - }, { + const server = Deno.serve({ + fetch: () => { + throw new Error("oops"); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1817,7 +1853,8 @@ Deno.test( const ac = new AbortController(); const listeningPromise = deferred(); - const server = Deno.serve(() => new Response(null), { + const server = Deno.serve({ + fetch: () => new Response(null), port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), @@ -1856,32 +1893,33 @@ Deno.test( let reqCount = -1; let timerId: number | undefined; - const server = Deno.serve(async (req) => { - reqCount++; - if (reqCount === 0) { - const msg = new TextEncoder().encode("data: hello\r\n\r\n"); - // SSE - const body = new ReadableStream({ - start(controller) { - timerId = setInterval(() => { - controller.enqueue(msg); - }, 1000); - }, - cancel() { - if (typeof timerId === "number") { - clearInterval(timerId); - } - }, - }); - return new Response(body, { - headers: { - "Content-Type": "text/event-stream", - }, - }); - } + const server = Deno.serve({ + fetch: async (req) => { + reqCount++; + if (reqCount === 0) { + const msg = new TextEncoder().encode("data: hello\r\n\r\n"); + // SSE + const body = new ReadableStream({ + start(controller) { + timerId = setInterval(() => { + controller.enqueue(msg); + }, 1000); + }, + cancel() { + if (typeof timerId === "number") { + clearInterval(timerId); + } + }, + }); + return new Response(body, { + headers: { + "Content-Type": "text/event-stream", + }, + }); + } - return new Response(`hello ${reqCount}`); - }, { + return new Response(`hello ${reqCount}`); + }, port: 4503, signal: ac.signal, onListen: onListen(listeningPromise), diff --git a/ext/flash/01_http.js b/ext/flash/01_http.js index 19920da58..d850a1520 100644 --- a/ext/flash/01_http.js +++ b/ext/flash/01_http.js @@ -185,18 +185,19 @@ return hostname === "0.0.0.0" ? "localhost" : hostname; } - function serve(handler, opts = {}) { - delete opts.key; - delete opts.cert; - return serveInner(handler, opts, false); - } - - function serveTls(handler, opts = {}) { - return serveInner(handler, opts, true); - } - - function serveInner(handler, opts, useTls) { - opts = { hostname: "127.0.0.1", port: 9000, useTls, ...opts }; + function serve(opts = {}) { + if (!("fetch" in opts)) { + throw new TypeError("Options is missing 'fetch' handler"); + } + if ("cert" in opts && !("key" in opts)) { + throw new TypeError("Options is missing 'key' field"); + } + if ("key" in opts && !("cert" in opts)) { + throw new TypeError("Options is missing 'cert' field"); + } + opts = { hostname: "127.0.0.1", port: 9000, ...opts }; + const handler = opts.fetch; + delete opts.fetch; const signal = opts.signal; delete opts.signal; const onError = opts.onError ?? function (error) { @@ -570,6 +571,5 @@ window.__bootstrap.flash = { serve, - serveTls, }; })(this); diff --git a/ext/flash/README.md b/ext/flash/README.md index 465c60d47..bc3c12065 100644 --- a/ext/flash/README.md +++ b/ext/flash/README.md @@ -3,5 +3,5 @@ Flash is a fast HTTP/1.1 server implementation for Deno. ```js -serve((req) => new Response("Hello World")); +serve({ fetch: (req) => new Response("Hello World") }); ``` diff --git a/ext/flash/lib.rs b/ext/flash/lib.rs index 8f3cb341a..abd8502d0 100644 --- a/ext/flash/lib.rs +++ b/ext/flash/lib.rs @@ -935,7 +935,6 @@ pub struct ListenOpts { key: Option<String>, hostname: String, port: u16, - use_tls: bool, } fn run_server( @@ -1239,11 +1238,7 @@ fn op_flash_serve<P>( where P: FlashPermissions + 'static, { - if opts.use_tls { - check_unstable(state, "Deno.serveTls"); - } else { - check_unstable(state, "Deno.serve"); - } + check_unstable(state, "Deno.serve"); state .borrow_mut::<P>() .check_net(&(&opts.hostname, Some(opts.port)))?; diff --git a/runtime/js/90_deno_ns.js b/runtime/js/90_deno_ns.js index b97c05556..dfca9d5bc 100644 --- a/runtime/js/90_deno_ns.js +++ b/runtime/js/90_deno_ns.js @@ -154,6 +154,5 @@ spawn: __bootstrap.spawn.spawn, spawnSync: __bootstrap.spawn.spawnSync, serve: __bootstrap.flash.serve, - serveTls: __bootstrap.flash.serveTls, }; })(this); |