-
-
Save bengl/585de1cf3fe13e94cdd8e97fe0a69e98 to your computer and use it in GitHub Desktop.
Just noodling on the future Node.js and http
This file contains 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
import http from 'http-next' | |
import fs from 'fs' | |
const server = http.createServer({ | |
allowHTTP1: true, | |
allowHTTP2: true, | |
allowHTTP3: true, | |
key: fs.readFileSync('localhost-privkey.pem'), | |
cert: fs.readFileSync('localhost-cert.pem') | |
}) | |
// Nixed a bunch of error handling to concentrate on the spirit of what I'm getting at here. | |
// That should totally be added back in. Sorry. | |
// Now it's just a simple echo server with a favicon since I didn't feel like writing the rest out :D | |
// Finally: note that I'm not arguing against any other options. Just throwing this out there. | |
for await (const session of server) { | |
;(async session => { | |
for await (const req of session) { | |
req.handle(() => { | |
// Two main things on this one: | |
// 1. All relevant stuff is in a callback which is simply never called in http1. | |
// 2. Returnable response objects, which I'll get to in a minute. | |
req.serverPush('/favicon.ico', () => { | |
const res = new http.ServerResponse() | |
fs.createReadStream('./public/favico.ico').pipe(res) | |
return res | |
} | |
const reqBody = await req.body() | |
const res = new http.ServerResponse(200) | |
res.write(reqBody) | |
return res // returning here also implicitly ends the writable stream if it has not been ended. | |
// Could also support returning buffers or strings | |
}) | |
} | |
})(session) | |
} | |
// tl;dr i really like the concept of returning a response. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have a few thoughts on this I would like to present, but I would like to focus on one, the idea of returning a ServerResponse.
I have a library, http-transform, that allows you to do this:
From here, you can call
makeResponse
to get anIncomingMessage
, and you can pipe it to aServerResponse
object:Doing this native in Node.js would require a significant undertaking because it has an asymmetrical interface for "Readable" and "Writable" streams. (f the interfaces were symmetrical, you would make data readable by calling
write()
—but you callpush()
. Why?)There are several problems with error propagation I've been unable to completely solve, because of bad assumptions that Node.js makes about event emitters and streams.
To properly implement this, Node.js would need a "Simplex Pair" object, where there is a single buffer that is filled from a
Writable
side, and drained from aReadable
side. (As it stands right now, this is not easy to do, and linking a Readable to a Writable will create at minimum two places where data is buffered.)