HTTP/2のサーバープッシュを自動化するNode.jsライブラリを作った
そろそろRFCとして公表されるHTTP/2ですが、GoogleがHTTP/2を使ったRPCフレームワークを出してみたりとか、その界隈は大盛り上がりですね!
HTTP/2の目玉機能と言ったら、やっぱりPUSH_PROMISE!
PUSH_PROMISEと言えば、「index.htmlが必要だったらapp.jsとかstyle.cssも要るよね!」とサーバ側で勝手に判断して送りつける、というのが良くある説明なのだが、それを自動でやってくれるわけではないので、Node.jsサーバ用にライブラリを作ってみた。
npmにもpublishしたので、npm install auto-push
可能。
やっていることは、レスポンスの直前にHTMLをパースして、必要そうなJavaScriptなりCSSなり画像なりをプッシュする。それだけ。
HTML Importsにもたぶん対応してるけど、まだちゃんとテストしていない。
サーバーに組み込む
典型的な使い方。
var fs = require('fs'); var autoPush = require('auto-push'); var http2 = require('http2'); var ecstatic = require('ecstatic'); var options = { key: fs.readFileSync(__dirname + '/ssl/key.pem'), cert: fs.readFileSync(__dirname + '/ssl/cert.pem') }; http2.createServer(options, autoPush(ecstatic(__dirname + '/public'))).listen(8443);
Express.js上でもいけると思ったけど意外とトラブルに見舞われているので、対応にはもう少しかかりそう。
プロキシとして使う
var autoPush = require('auto-push'); var http = require('http'); var ecstatic = require('ecstatic'); var request = require('request'); var fs = require('fs'); var http2 = require('http2'); // server http.createServer(ecstatic(__dirname + '/public')).listen(8080); // proxy var options = { key: fs.readFileSync(__dirname + '/ssl/key.pem'), cert: fs.readFileSync(__dirname + '/ssl/cert.pem') }; http2.createServer(options, autoPush(function(req, res) { request({ method: req.method, url: 'http://localhost:8080' + req.url, headers: req.headers }).pipe(res); })).listen(8443);
プロキシならNode.js以外のサーバにも対応できる。
課題
304(Not Modified)をどう扱えばいいのか分からない。 具体的には、クライアントから直接リクエストされたもの以外のif-modified-sinceヘッダ情報が無いので、適当にHTMLファイルと同じ情報を使いまわすとまあバグる。 仕方が無いので、現在は更新があろうと無かろうと200で送り返すという雑なことをしている。
その辺の仕様的に妥当な処置とか、教えてもらえたら喜びます。
まとめ
たぶん既に誰かやってるとは思う。