Http2 - 使用nodejs pushStream方法的服务器推送不起作用

时间:2018-03-22 10:50:08

标签: node.js http2 server-push push-promise pushstream

我正在http2上学习nodejs,但发现问题pushStream方法无效(client side do not show "Pushed/[fileName]" on developer tool) 我想知道原因是nodejs版本(我安装了最新版本的v9.8.0)

我的代码如下:

server.js

'use strict'

const fs = require('fs');
const path = require('path');
const http2 = require('http2');
const utils = require('./utils');

const { HTTP2_HEADER_PATH } = http2.constants;

const PORT = process.env.PORT || 3000;

// The files are pushed to stream here
function push(stream, path) {
  const file = utils.getFile(path);
  if (!file) {
    return;
  }
  stream.pushStream({ [HTTP2_HEADER_PATH]: path}, (err, pushStream, headers) => {
    if (err) throw err;
    pushStream.respondWithFD(file.content, file.headers)
  });
}

// Request handler
function onRequest(req, res) {
  const reqPath = req.headers[':path'] === '/' ? '/index.html' : req.headers[':path']
  const file = utils.getFile(reqPath);

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

  // Push with index.html
  if (reqPath === '/index.html') {
    push(res.stream, '/assets/main.js');
    push(res.stream, '/assets/style.css');
  } else {
    console.log("requiring non index.html")
  }

  // Serve file
  res.stream.respondWithFD(file.content, file.headers);
}

// creating an http2 server
const server = http2.createSecureServer({
  cert: fs.readFileSync(path.join(__dirname, '/certificate.crt')),
  key: fs.readFileSync(path.join(__dirname, '/privateKey.key'))
}, onRequest);

// start listening
server.listen(PORT, (err) => {
  if (err) {
    console.error(err);
    return -1;
  }
  console.log(`Server listening to port ${PORT}`);
});

utils.js

'use strict';
const fs = require('fs');
const mime = require('mime');

module.exports = {
  getFile: function (path) {
    const filePath = `${__dirname}/public${path}`;
    try {
      const content = fs.openSync(filePath, 'r');
      const contentType = mime.getType(filePath);
      return {
        content,
        headers: {
          'content-type': contentType
        }
      };
    } catch (e) {
      return null;
    }
  }
}

1 个答案:

答案 0 :(得分:0)

我没有尝试运行您的代码,但注意到Chrome不允许使用不受信任的HTTPS证书进行HTTP / 2推送(例如,尚未添加到信任存储区的自签名证书)。 Raised a bug with the Chrome team

如果你有红色不安全的挂锁项目,那么你也可能遇到这个问题。将证书添加到您的信任存储区,重新启动Chrome并重新加载您应该获得绿色挂锁的网站。

注意Chrome需要一个证书,其主题备用名称(SAN)字段与域匹配,因此如果您刚刚获得较旧的主题字段,那么即使将其添加到您的信任存储区也不会变为绿色。

另一种选择是通过在您的网址中输入以下内容来查看Chrome HTTP2框架:

.vec

如果您看到推送保证帧(带有chrome://net- internals/#http2 ),然后是promised_stream_id上的标题和数据,那么您就知道服务器端正在运行。