node-http-proxy修改响应结果

最近在项目中使用node-http-proxy遇到需要修改代理服务器响应结果需求,该库已提供修改响应格式为html的方案:Harmon,而项目中返回格式统一为json,使用它感觉太笨重了,所以自己写了个可解析和修改json格式的库,

期间也遇到了之前未关注的问题:http传输编码、node流的相关处理。下面是实现代码:

var zlib = require('zlib');
var concatStream = require('concat-stream');

/**
 * Modify the response of json
 * @param res {Response} The http response
 * @param contentEncoding {String} The http header content-encoding: gzip/deflate
 * @param callback {Function} Custom modified logic
 */
module.exports = function modifyResponse(res, contentEncoding, callback) {
    var unzip, zip;
    // Now only deal with the gzip and deflate content-encoding.
    if (contentEncoding === 'gzip') {
        unzip = zlib.Gunzip();
        zip = zlib.Gzip();
    } else if (contentEncoding === 'deflate') {
        unzip = zlib.Inflate();
        zip = zlib.Deflate();
    }

    // The cache response method can be called after the modification.
    var _write = res.write;
    var _end = res.end;

    if (unzip) {
        unzip.on('error', function (e) {
            console.log('Unzip error: ', e);
            _end.call(res);
        });
    } else {
        console.log('Not supported content-encoding: ' + contentEncoding);
        return;
    }

    // The rewrite response method is replaced by unzip stream.
    res.write = function (data) {
        unzip.write(data);
    };

    res.end = function (data) {
        unzip.end(data);
    };

    // Concat the unzip stream.
    var concatWrite = concatStream(function (data) {
        var body;
        try {
            body = JSON.parse(data.toString());
        } catch (e) {
            body = data.toString();
            console.log('JSON.parse error:', e);
        }

        // Custom modified logic
        if (typeof callback === 'function') {
            body = callback(body);
        }

        // Converts the JSON to buffer.
        body = new Buffer(JSON.stringify(body));

        // Call the response method and recover the content-encoding.
        zip.on('data', function (chunk) {
            _write.call(res, chunk);
        });
        zip.on('end', function () {
            _end.call(res);
        });

        zip.write(body);
        zip.end();
    });
    unzip.pipe(concatWrite);
};

项目地址:node-http-proxy-json,欢迎大家试用提意见,同时不要吝啬Star。

在该库的实现过程中越发觉得理论知识的重要性,所谓理论是行动的先导,之前都是使用第三方库,也没去关心一些底层的细节处理。

后面有空一定要多看看底层的实现,否则遇到难搞问题就卡住了。

 

posted @ 2016-06-05 00:24  阿郎博客  阅读(1642)  评论(0编辑  收藏  举报