处理有条件的未使用的http.IncomingMessage

时间:2016-06-07 12:18:50

标签: node.js restify node-streams

我想通过restify服务器将上游的http.IncomingMessage转发给客户端。这就是我到现在为止所做的。它提供转发功能。但是我认为这可能会导致内存泄漏:

var server = restify.createServer()

server.get('/test', function(req, res, next) {
    var upstreamReq = createUpstreamReq() // just creates a http.ClientRequest

    upstreamReq.on('response', function(upstreamRes) {
        if (upstreamRes.statusCode === 404) {
            // (1) I guess this leaks the upstreamRes body ?
            return next(new restify.errors.NotFoundError())
        }
        if (upstreamRes.statusCode !== 200) {
            // (2) is there a better way than pipeing the response to /dev/null?
            // I guess the advantage of this approach is that we can reuse the connection (not closed) ?
            upstreamRes.pipe(fs.createWriteStream('/dev/null'))
            return next(new restify.errors.InternalServerError())
        }
        res.setHeader('Content-Type', upstreamRes.header('Content-Type'))
        res.setHeader('Content-Length', upstreamRes.header('Content-Length'))
        upstreamRes.pipe(res)
        return next()
    })

    upstreamReq.end()
})
  • 我假设在上游404的情况下,此代码会泄漏upstreamRes正文(1),因为它从未被消费(没有pipe(somewhere))?
  • 不应泄漏upstreamRes正文的一个明显的解决方案(2)是将其传递给/dev/null。是否有替代/更好的解决方案来解决这个问题?

1 个答案:

答案 0 :(得分:0)

我似乎跳过了有关http.ClientRequest的文档中的重要部分:

  

如果没有添加“响应”处理程序,那么响应将是完全的   丢弃。但是,如果您添加“响应”事件处理程序,那么您   必须通过调用来消耗响应对象中的数据   每当有'可读'事件时,或者通过添加一个   'data'处理程序,或通过调用.resume()方法。直到数据   消耗,'结束'事件不会开火。此外,直到读取数据   它将消耗内存,最终可能导致“进程”   记忆错误。

https://nodejs.org/api/http.html#http_class_http_clientrequest

所以正确答案似乎是:

  • 您需要使用每个http.IncomingMessage
  • 的回复(http.ClientRequest
  • 如果您对返回的数据不感兴趣,建议的方法是致电upstreamRes.resume()。即使没有连接消费者,这也会启动数据流。