Last active
March 11, 2025 03:07
-
-
Save guest271314/c1974f24fff86fe4708f901651be8079 to your computer and use it in GitHub Desktop.
Deno HTTP/3 WebTransport server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | |
// https://raw.githubusercontent.com/denoland/deno/dce204af32e4b56681be4f9a034256d979a3ce4b/tests/specs/run/webtransport/main.ts | |
const cert = Deno.readTextFileSync("./certificate.pem"); | |
const key = Deno.readTextFileSync("./certificate.key"); | |
const certBase64 = cert.split("\n").slice(1, -2).join(""); | |
const certBytes = | |
await (await fetch(`data:application/octet-stream;base64,${certBase64}`)) | |
.bytes(); | |
const certHash = await crypto.subtle.digest("SHA-256", certBytes); | |
const server = new Deno.QuicEndpoint({ | |
hostname: "localhost", | |
port: 4433, | |
}); | |
const listener = server.listen({ | |
cert, | |
key, | |
alpnProtocols: ["h3"], | |
}); | |
let requests = 0; | |
async function handle(wt) { | |
try { | |
console.log(wt); | |
const encoder = new TextEncoder(); | |
await wt.ready; | |
for await ( | |
const { readable, writable } of wt.incomingBidirectionalStreams | |
) { | |
for await (const value of readable.pipeThrough(new TextDecoderStream())) { | |
console.log(value); | |
await new Response(value.toUpperCase()).body | |
.pipeTo(writable, { preventClose: true }); | |
} | |
await writable.close().then(() => console.log("writable close")); | |
console.log(writable); | |
await new Promise((r) => setTimeout(r)); | |
wt.close(); | |
break; | |
} | |
} catch (e) { | |
console.log(e); | |
console.trace(); | |
} finally { | |
return wt.closed.then(() => ({ | |
code: 0, | |
reason: `Done streaming request ${requests++}`, | |
})); | |
} | |
} | |
for await (const conn of listener) { | |
const wt = await Deno.upgradeWebTransport(conn); | |
try { | |
handle(wt) | |
.then((session) => console.log(session)) | |
.catch((e) => console.log(e)); | |
} catch (e) { | |
console.log(e); | |
} finally { | |
continue; | |
} | |
} | |
server.close(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const client = new WebTransport( | |
`https://localhost:4433/path`, | |
/* | |
{ | |
serverCertificateHashes: [{ | |
algorithm: "sha-256", | |
value: certHash, | |
}], | |
}, | |
*/ | |
); | |
await client.ready; | |
const encoder = new TextEncoder(); | |
const { readable, writable } = await client.createBidirectionalStream(); | |
const stream = readable.pipeThrough(new TextDecoderStream()) | |
.pipeTo( | |
new WritableStream({ | |
write(value, controller) { | |
console.log(value); | |
}, | |
close() { | |
console.log("WritableStream close"); | |
}, | |
abort(reason) { | |
console.log({ reason }); | |
}, | |
}), | |
).catch((e) => e.message); | |
const write = async (encoded, preventClose = true) => | |
await new Response(encoded).body | |
.pipeTo(writable, { preventClose }); | |
let str = "abcdefghijklmnopqrstuvwxyz"; | |
for (let i = 0; i < 26; i++) { | |
let preventClose = i < str.length - 1; | |
await write(encoder.encode(str.at(i)), preventClose); | |
} | |
if (!navigator.userAgent.includes("Deno")) { | |
await Promise.allSettled([client.closed, stream]) | |
.then(console.log); | |
} else { | |
if (navigator.userAgent.includes("Deno")) { | |
// Deno doesn't close on writer.close() | |
await new Promise((r) => setTimeout(r, 5)); | |
client.close(); | |
await Promise.allSettled([client.closed, stream]) | |
.then(console.log); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment