Skip to content

Commit

Permalink
chore(package): initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Marton committed Aug 16, 2017
0 parents commit fc7aa97
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# http2-push-example

## Requirements

- Node.js > 9.4

## Run

```sh
node --expose-http2 app.js
```

## Result

![HTTP/2 push](/network.png)
90 changes: 90 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
'use strict'

const http2 = require('http2')
const fs = require('fs')
const mime = require('mime')

const { HTTP2_HEADER_PATH } = http2.constants

// https://stackoverflow.com/questions/12871565/how-to-create-pem-files-for-https-web-server
// openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
const cert = fs.readFileSync('./cert.pem')
const key = fs.readFileSync('./key.pem')

const server = http2.createSecureServer({ cert, key, allowHTTP1: true }, onRequest)
const port = process.env.PORT || 3000

// Cache files
const files = new Map()
fs.readdirSync('./public').forEach((fileName) => {
const filePath = `./public/${fileName}`
const fileDescriptor = fs.openSync(filePath, 'r')
const stat = fs.fstatSync(fileDescriptor)
const contentType = mime.lookup(filePath)

files.set(`/${fileName}`, { fileDescriptor, stat, contentType })
})

// Helpers
function getFileHeaders (file) {
return {
'content-length': file.stat.size,
'last-modified': file.stat.mtime.toUTCString(),
'content-type': file.contentType
}
}

// Push file
function push (stream, path) {
const file = files.get(path)

if (!file) {
return
}

stream.pushStream({ [HTTP2_HEADER_PATH]: path }, (pushStream) => {
const stat = fs.fstatSync(file.fileDescriptor)
pushStream.respondWithFD(file.fileDescriptor, getFileHeaders(file))
})
}

// Request handler
function onRequest(req, res) {
const reqPath = req.path === '/' ? '/index.html' : req.path
const file = files.get(reqPath)

// File not found
if (!file) {
res.statusCode = 404
res.end()
return
}

// Detects if it is a HTTPS req or HTTP/2
const { socket: { alpnProtocol } } = req.httpVersion === '2.0' ? req.stream.session : req

// HTTP/2
if (req.httpVersion === '2.0') {
if (reqPath == '/index.html') {
push(res.stream, '/bundle1.js')
push(res.stream, '/bundle2.js')
}

res.stream.respondWithFD(file.fileDescriptor, getFileHeaders(file))
return
}

// HTTP/1
res.writeHead(200, getFileHeaders(file))
res.write(file.fileDescriptor, 'binary')
res.end()
}

server.listen(port, (err) => {
if (err) {
console.error(err)
return
}

console.log(`Server listening on ${port}`)
})
22 changes: 22 additions & 0 deletions cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDtTCCAp2gAwIBAgIJAN9jdYICeY33MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTcwODE2MTMyNDA2WhcNMjcwODE0MTMyNDA2WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA4NGiIEgDf3NdOlpGAROY8ZNPJrhR6gNPTAIZKz314wDUJTF54a8ioeUn
rsKL0Z5H67MmZ5LcsZO9jprrBaSFAIyFdiqQKOSWkXA+LZCEhqaCR0cOIOy0TEKb
MxsABW+6hSoBXk1tK3IQntEcs22qQZll+Y++jUBck+XaCwAmpsk4ofqfLPHcvidj
gHOYkKQg/fFIm81M1NKgdbQpW2/akob56kdh4scZrpwa6MxEylKppTjZ0jfF0cnv
rrs4QTWvoIowfAMrrd/TJV5P8Ei5KcckJe8shlgoEOxtRrAjhIEUmZOT0yho7BcA
C+Zudul0XJhcAPjbHirQ0+G4Agy3FwIDAQABo4GnMIGkMB0GA1UdDgQWBBQqMeql
vTY7xAXbu5YXhnD4lBK1xjB1BgNVHSMEbjBsgBQqMeqlvTY7xAXbu5YXhnD4lBK1
xqFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV
BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAN9jdYICeY33MAwGA1UdEwQF
MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAEm90w4C0rFqxVVVojAYXrcvLD0E5iwA
3eEn+uD1dMy56he0LZNXlf3s3mZlRYE8+oGvydcMuXrmisVcvIuFQlES2M6y8S2b
CW6xeir4+VKWR97c3p+M48rUfV8YGb2d6YBLNlekAT/S55Bhfy15sYWt+9LIi4i+
ToqywlIfiMcwpBZLD1UTPs7b66Rx7LHmMFXpNfDugp8JHphLJRmXFNgZNNmi0Re0
vDMgUWlgVzV9oMTjp0Ioafbtqcykg0JS+3KsXHWVQPWrw1wsBjje4XJLIIY1+W75
tHBk3PL42xP5vPgRJ/8X22pFXnC/0MK6fKg5VdvwJQDBlYxbpcM3W+g=
-----END CERTIFICATE-----
27 changes: 27 additions & 0 deletions key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA4NGiIEgDf3NdOlpGAROY8ZNPJrhR6gNPTAIZKz314wDUJTF5
4a8ioeUnrsKL0Z5H67MmZ5LcsZO9jprrBaSFAIyFdiqQKOSWkXA+LZCEhqaCR0cO
IOy0TEKbMxsABW+6hSoBXk1tK3IQntEcs22qQZll+Y++jUBck+XaCwAmpsk4ofqf
LPHcvidjgHOYkKQg/fFIm81M1NKgdbQpW2/akob56kdh4scZrpwa6MxEylKppTjZ
0jfF0cnvrrs4QTWvoIowfAMrrd/TJV5P8Ei5KcckJe8shlgoEOxtRrAjhIEUmZOT
0yho7BcAC+Zudul0XJhcAPjbHirQ0+G4Agy3FwIDAQABAoIBAHHi4B04PcVffHel
6VZ8RfsCY5M6xgwklxPq8DMOlTPkZJNex95CqOmYOwz1cnzCkK5et3K6W9/89oZ6
Bdp66AFKLgWZNCPzAC82y9irH+dSDCbtYMPfBMqo5xPxdoZKfhMdH0pVMJtUkgTR
65cdU6UdfyH35lCJrRwi0NzHu8y6qMyH5tOcNOIXwn/LfZ6ZwVx2lKAjthmac2z0
35qknvCNfgadrsl5PLWZBYwy3qx208pUUojMciL9RtfO17F6ofMhueOoChnaHv6h
Lra3NpcuJlYdTTt3tgkTvfMXiZCMsWoV9q1+y9AcSojDJk4V6qiy0Nu8uQmSCRX8
g/2ilqECgYEA/9yejCxaUfgHlA6LkFFMNNkgh3AwHxfIiEBzCDxkUPlu0J1z+65S
UJLGLIgQoZN0UmN6a0YHHDxh0oxIvxoq+wc4PPIr9mmSsEt6YTUjYbYNIJ/5978b
CH+41VGCszqzd0NSJTW7aKL3XFE34kDascgTiDd82KmqaC5chShCoZECgYEA4PC4
qoNnAzILI9yM9hJcolrW9hf4pUXqG9orO7pr5/ETDVi74pNdKkb7MKE1snjTQBdu
rV5q09wu9+Owa5AoHLkvTify+EXlUrc4UeVxEdlOfoc/laONZkGaENxn4DTH4rMj
6nlzMNPcR0Hxud/UqLpWiI20I+dJwVzBA3z3eicCgYEAqNb+LQPLqlGhNpuOj3KG
dk1dwOJQbwQzyW22OxYXILQo4zMz6T50hUUFzzcOuoDifse0bfutD33tE5KNIsZy
3Go8O0OXrSinqvxzypfVPFJ1QTUwL8OFZEtcPjBmrj0rVqUvHOzjOb5ouxvBY+Vm
K3EbKoVrNlJn6A3H8frKVXECgYEAsnQnfRdcbTuRfPTnW/07Qo6gxYJFABGUZl5S
OENwggVOoSMJg/p3Sigf9fefWyTiK5Gre51RURz4oi8f8mXefNMpxW6KIw+InHPB
Ga/WYVuuG1F/T17+ueZHrSK+wi/9eEu4rbeGfHFH67xUYqtB0k5qglExXd6LM/07
H2JQD7cCgYAeU4FtW0VZdEtUkBLJhHHZ0l/UBtN/XhkpFjdrG9uJryX/2rnA8Zoh
vKhSG5iWdTDak4R2dt9yJrTr1sriI5P176t76eAR4jg0F3xeRpiaDDk7wdznwh9F
OKOJlLEHd9G2gryXAtUU4KPii3/Awgj/Kd37j7fssuMTQLB9bWIygQ==
-----END RSA PRIVATE KEY-----
Binary file added network.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "http2-push-example",
"version": "1.0.0",
"description": "HTTP/2 Push example",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "RisingStack, Inc.",
"license": "MIT",
"dependencies": {
"mime": "1.3.6"
}
}
1 change: 1 addition & 0 deletions public/bundle1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('Bundle 1')
1 change: 1 addition & 0 deletions public/bundle2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('Bundle 2')
7 changes: 7 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<html>
<body>
<script src="bundle1.js"/></script>
<h1>HTTP2 Push!</h1>
</body>
<script src="bundle2.js"/></script>
</html>

0 comments on commit fc7aa97

Please sign in to comment.