node-http-proxyで通信内容を変更するローカルプロキシサーバーを構築する
フロントエンドの開発をしていて、APIサーバーへのリクエスト、レスポンスをプロキシして、そのヘッダーを変更したいことがある。Charlesみたいなツールでも同じことはできるが、変更内容を複数人で共有するのが面倒だったり、integration環境で動かすのが難しい。ということで、Nodeでリクエスト・レスポンスのヘッダーを変更するちょっとしたscriptを書いてみた。 node-http-proxy(GitHub - nodejitsu/node-http-proxy: A full-featured http proxy for node.js)を使う。このモジュール自体はリバースプロキシとして使われることを想定していそうだが、今回のような開発用のローカルプロキシとしても使える。
var express = require('express'); var httpProxy = require('http-proxy'); var app = express(); var proxy = httpProxy.createProxyServer({}); proxy.on('proxyReq', function(proxyReq, req, res) { // append proxyReq.setHeader('X-REQUEST-FOO', 'BAR'); }); proxy.on('proxyRes', function(proxyRes, req, res) { var originalSetHeader = res.setHeader.bind(res); // append res.setHeader('X-RESPONSE-FOO', 'BAR'); res.setHeader = function(name, value) { // overwrite if (name === 'X-RESPONSE-FOO') { originalSetHeader('X-RESPONSE-FOO', 'BAR'); return; } originalSetHeader(name, value); }; }); proxy.on('error', function(err, req, res) { res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('Something wrong.') }); app.get('*', function(req, res) { proxy.web(req, res, { target: 'https://api.example.dev', secure: false }); }); app.listen(8080);
後は、変更内容をyamlみたいな適当なフォーマットで記述して、起動時に読み込んで、リクエスト/レスポンスのヘッダーとして追加・上書きしてあげればよろしい。レスポンスのヘッダーの上書きがちょっとトリッキーで、proxyResイベントのイベントハンドラの後に元々のレスポンスのヘッダーに対して、setHeaderが呼ばれているようだったので、setHeaderをラップして、変更したいヘッダー名の場合は上書きするようにした。