denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
94.45k stars 5.24k forks source link

"Deno.serve()" - Better UX for 103 Early Hints on HTTP server #15827

Open ayame113 opened 2 years ago

ayame113 commented 2 years ago

Edit: In practice Chrome only supports 103 Early Hints over HTTP/2, so I realized there is no point in sending Early Hints with the current flash server. I would appreciate it if you could introduce this in the future when HTTP/2 can be used with Deno.serve().

https://chromium.googlesource.com/chromium/src/+/master/docs/early-hints.md#what_s-not-supported


Flash server can return 103 Early Hints response. It's great, but I wish there was a better UX.

// the way i currently do
import { writeAll } from "https://deno.land/std@0.154.0/streams/mod.ts";

const encoder = new TextEncoder();
const ok = (body: string) => {
  const { byteLength } = encoder.encode(body);
  const text = [
    "HTTP/1.1 103 Early Hints",
    "Link: </style.css>; rel=preload",
    "Link: </script.js>; rel=preload",
    "",
    "",
    "HTTP/1.1 200 OK",
    "Content-Type: text/plain",
    `Content-Length: ${byteLength}`,
    "",
    body,
    "",
  ].map((str) => `${str}\r\n`).join("");
  return encoder.encode(text);
};

const handler = (async (req: Request) => {
  const [conn, _firstPacket] = Deno.upgradeHttpRaw(req);

  const res = ok("hello");
  await writeAll(conn, res);

  conn.close();
}) as unknown as Deno.ServeHandler;

Deno.serve(handler);

I think it would be great if we could write something like the following instead of the less versatile style above. (And it should also improve performance.)

Deno.serve((req, ctx) => {
  ctx.respondInformationalResponse(
    new Response(null, {
      status: 103,
      headers: {...},
    }),
  );
  return new Response("hello");
});

For your reference:

bartlomieju commented 1 year ago

@ayame113 using cs.github.com I noticed you are the only user of Deno.upgradeHttpRaw. This API is gonna get removed in the next minor release of Deno (though it will start throwing and error in the next patch release). Deno.serve() got rewritten to use Deno.serveHttp() in https://github.com/denoland/deno/commit/2846bbe0a3de0cc366006f97023ce146112c40c9 and I believe this feature would currently not be supported. I'm happy to explore this and hope @mmastrac could chime in

ayame113 commented 1 year ago

using cs.github.com I noticed you are the only user of Deno.upgradeHttpRaw.

Thank you for letting me know about that!! As I wrote in the comment above, I found that 103 Early Hints cannot be sent with the combination of Deno.upgradeHttpRaw and HTTP/1.1. So I'm not using this anymore so removing this is fine for me.