can do
*experimental
*
@CascadiaJS
#csj19
#nodejs
#javascript
#http3
#quic
#hashtag
#seattle
#yolo
#love
#beautiful
#tbt
#cute
#happy
#followme
#selfie
#friends
#art
#fun
#smile
Trivikram Kamat
Software Development Engineer
@trivikram
@trivikr
Tree
Weak
Rum
+
+
Tri
vik
ram
.
.
What's your name again?
My history with Node.js
-
Have been using Node.js for 4 years
-
Started contributing to Node.js core in Oct 2017
-
providing HTTP/2 support
-
-
Became Node.js core collaborator in March 2018
-
Organized and mentored four Code+Learn events
What are we going to cover?
-
What's HTTP/1.1, and why HTTP/2 was required
-
What's HTTP/2, and why HTTP/3 was required
-
What's HTTP/3, and
-
Sample code!
when is it coming?
James Snell
is a Node.js TSC member, who is heading the work on implementing QUIC
Big Thanks to sponsors:
HTTP/0.9
Published: 1991
The one line protocol
GET /mypage.html
<HTML>
A very simple HTML page
</HTML>
HTTP/1.0
Published: May 1996
Building extensibility
GET /mypage.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)
200 OK
Date: Tue, 15 Nov 1994 08:12:31 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/html
<HTML>
A page with an image
<IMG src="/myimage.gif">
</HTML>
HTTP/1.1
Published: June 1999
The standardized protocol
GET /en-US/docs/Glossary/Simple_header HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header
Issue #1: Three roundtrips per request
Issue #2: Multiple TCP+TLS connections are created for concurrent requests
http/1.1 server
const https = require("https");
const fs = require("fs");
const options = {
key: fs.readFileSync("ssl/localhost.key"),
cert: fs.readFileSync("ssl/localhost.cert")
};
https
.createServer(options, (req, res) => {
if (req.url === "/") {
fs.createReadStream("./files/index.html").pipe(res);
} else if (req.url === "/style.css") {
fs.createReadStream("./files/style.css").pipe(res);
} else if (req.url === "/script.js") {
fs.createReadStream("./files/script.js").pipe(res);
} else if (req.url === "/globe.png") {
fs.createReadStream("./files/globe.png").pipe(res);
}
})
.listen(3000);
http/1.1 server
const https = require("https");
const fs = require("fs");
const options = {
key: fs.readFileSync("ssl/localhost.key"),
cert: fs.readFileSync("ssl/localhost.cert")
};
https
.createServer(options, (req, res) => {
if (req.url === "/") {
fs.createReadStream(`./files/index.html`).pipe(res);
} else {
// regular expression for filename requested
const re = /\/(\w+)*/;
const filename = req.url.replace(re, "$1");
fs.createReadStream(`./files/${filename}`).pipe(res);
}
})
.listen(3000);
index.html
<html>
<head>
<link rel="stylesheet" type="text/css"
href="./style.css" />
</head>
<body>
<span id="greeting">Hello World!</span>
<img id="image" src="./globe.png" />
<script type="text/javascript"
src="./script.js"></script>
</body>
</html>
style.css
#greeting {
font-size: 180px;
}
script.js
setTimeout(() => {
document.getElementById("greeting")
.innerHTML = "Hello #cjs19!";
document.getElementById("image")
.src = "./cjs.png";
}, 1000);
globe.png
Load the webpage
examine TCP connections with netstat
examine TCP connections with netstat
Issues with HTTP/1.1
-
Three round-trips per request
-
Multiple TCP+TLS connections for concurrent requests
HTTP/2
Published: May 2015
http/2 server
const http2 = require("http2");
const fs = require("fs");
const options = {
key: fs.readFileSync("ssl/localhost.key"),
cert: fs.readFileSync("ssl/localhost.cert")
};
const server = http2.createSecureServer(options).listen(3000);
server.on("stream", (stream, headers) => {
if (headers[":path"] === "/") {
stream.respondWithFile("./files/index.html");
} else {
// regular expression for filename requested
const re = /\/(\w+)*/;
const filename = headers[":path"].replace(re, "$1");
stream.respondWithFile(`./files/${filename}`);
}
});
Load the webpage
examine TCP connections with netstat
examine TCP connections with netstat
Benefits of HTTP/2
-
Multiplexing and concurrency: different HTTP requests onto the same TCP connection
-
Stream dependencies: client can indicate to server which dependencies are important
-
Header compression: reduces HTTP Header size
-
Server push: server can send resources which client has not requested yet
Why do we need HTTP/3?
TCP head-of-line blocking
If a single packet is dropped, or lost in the network somewhere between two endpoints that speak HTTP/2, it means the entire TCP connection is brought to a halt while the lost packet is re-transmitted and finds its way to the destination
Chain metaphor
TCP connection
CSS packet
JS packet
HTTP/3 over QUIC
draft-23 as of Nov 2019
When setting up multiple streams over QUIC connection, they are treated independently so that if any packet goes missing for one of the streams, only that stream has to pause and wait for the missing packet to get retransmitted.
CSS stream
JS stream
QUIC is built on UDP
QUIC also reduces roundtrips
Credit: http://bit.ly/36CJ8GZ
Which apps will benefit from HTTP/3?
Learn from Jasper tomorrow at 10am on how QUIC can help manage swarm of drones
HTTP/3 IETF draft
http/3 server
const quic = require("quic");
const fs = require("fs");
const options = {
key: fs.readFileSync("ssl/localhost.key"),
cert: fs.readFileSync("ssl/localhost.cert")
};
const server = quic.createSocket({ port: 3000 });
server.listen(options);
server.on("session", session => {
session.on("stream", (stream, headers) => {
if (headers[":path"] === "/") {
stream.respondWithFile("./files/index.html");
} else {
// regular expression for filename requested
const re = /\/(\w+)*/;
const filename = headers[":path"].replace(re, "$1");
stream.respondWithFile(`./files/${filename}`);
}
});
});
Load the webpage
HTTP/3 over QUIC in Node.js is in early stages of development
You can help build it!
nodejs/quic progress
project board
How can I write unit tests?
git clone git@github.com:trivikr/quic.git
cd quic
./configure --experimental-quic --coverage
make -j4 coverage
Current state of JavaScript tests
Current state of C++ tests
Example webpage on QUIC
Summary
-
In HTTP/1.1, multiple TCP+TLS connections were required for concurrent requests
-
HTTP/2 added multiplexing in which multiple HTTP requests were sent onto the same TCP connection
-
TCP head-of-line blocking: the entire TCP connection is brought to halt if a single TCP packet is lost.
-
HTTP/3 over QUIC treats each stream independently, so if any packet goes missing in a stream - only that stream is affected
Thank you for listening!
Trivikram Kamat
@trivikram
@trivikr
HTTP/3: Node.js can do QUIC
By Trivikram Kamat
HTTP/3: Node.js can do QUIC
Slides for CascadiaJS talk from November 2019 https://2019.cascadiajs.com/speakers/trivikram-kamat
- 3,784