node-http-proxy icon indicating copy to clipboard operation
node-http-proxy copied to clipboard

The response will be cut sometimes when the response size is more

Open 546200350 opened this issue 4 years ago • 3 comments
trafficstars

This is my example code!

const http = require('http');
const httpProxy = require('http-proxy');
const proxy = httpProxy.createProxyServer();
const proxyServer = http.createServer((req, res) => {
  proxy.web(req, res, {
    target: 'http://10.5.18.203:9999/',
  });
});
proxyServer.listen(8088, () => {
  console.log('proxy server is running ');
});

with the same target, i request direct, it`s ok.

and i have tried another way to proxy, it`s ok;

code like this:

const http = require('http')
const parseUrl = require('url').parse

class ProxyServer {
  constructor (options) {
    options.target = parseUrl(options.target)
    this.options = options
  }

  // 创建代理服务
  _createServer () {
    // 仅支持 http 协议
    this._server = http.createServer(this._requestListener.bind(this))

    return this._server
  }

  // 代理请求监听
  _requestListener (req, res) {
    const options = helpers.getRequestOptions(this.options, req)

    // 使用 http.request 请求目标 url
    const proxyReq = http.request(options)

    req.pipe(proxyReq)

    proxyReq.on('response', proxyRes => {
      // 设置响应头内容为代理的响应头内容
      helpers.setHeads(res, proxyRes)
      // 写入状态码
      helpers.writeStatusCode(res, proxyRes)
      // 传递内容
      proxyRes.pipe(res)
    })
  }

  listen (port) {
    this._createServer().listen(port)
  }
}

const helpers = {
  /**   * 设置响应头内容为代理的响应头内容   * @param {Object} res 响应体   * @param {Object} proxyRes 代理响应体    */
  setHeads (res, proxyRes) {
    Object.keys(proxyRes.headers).forEach(key => {
      const header = proxyRes.headers[key]

      res.setHeader(String(key).trim(), header)
    })
  },
  /**   * 写入响应状态码   * @param {Object} res 响应体   * @param {Object} proxyRes 代理响应体   */
  writeStatusCode (res, proxyRes) {
    if (proxyRes.statusMessage) {
      res.writeHead(proxyRes.statusCode, proxyRes.statusMessage)
    } else {
      res.writeHead(proxyRes.statusCode)
    }
  },
  /**   * 获取代理的请求选项   * @param {Object} opts 选项   * @param {Object} req 请求体   */
  getRequestOptions (opts, req) {
    const options = {
      port: helpers.getPort(opts.target),
      host: opts.target.host,
      hostname: opts.target.hostname,
      method: req.method,
      path: req.url,
      headers: Object.assign(
        {},
        req.headers,
        opts.config ? opts.config.headers : null
      ),
      agent: false
    }

    if (opts.config) {
      const config = Object.assign({}, opts.config)

      delete config.headers

      Object.assign(options, config)
    }

    return options
  },
  getPort (target) {
    return target.port || (target.protocol === 'https:' ? 443 : 80)
  }
}

// example
new ProxyServer({
  target: 'http://10.5.18.203:9999/'
}).listen(8002)
console.log('http proxy server started on port 8005')

So, I think something is wrong by use http-proxy!

546200350 avatar Jul 30 '21 04:07 546200350

Same issue here, firstly, I've suspected my update to Debian 11. So, I tryied to restore my oldest backup from 08/22/2021 with Debian 10 but I encountered the same issue... Before this date, http-proxy working well for me but I don't know when it was broken.

MatMoul avatar Sep 03 '21 23:09 MatMoul

Same issue here, firstly, I've suspected my update to Debian 11. So, I tryied to restore my oldest backup from 08/22/2021 with Debian 10 but I encountered the same issue... Before this date, http-proxy working well for me but I don't know when it was broken.

You can set the config 'agent' to deal the problem. it's OK for me

546200350 avatar Sep 04 '21 03:09 546200350

@546200350 Thanks for the info but it doesn't seem to be working for me.

I did some further investigation and found the trigger, it happened when I updated my backend server from Debian10 + apache2.4.38 to Debian11 + apache2.4.48. I continue the investigations ...

MatMoul avatar Sep 05 '21 00:09 MatMoul