簡體   English   中英

nodejs的套接字掛斷錯誤

[英]socket hang up error with nodejs

我想為一些我不是管理員的 XYZ 服務器設置代理。 然后我想對請求和響應標頭進行一些分析,然后還要對請求和響應主體進行分析。 所以我使用 http-proxy https://github.com/nodejitsu/node-http-proxy

這就是我正在做的:

  var proxy = httpProxy.createProxyServer();


  connect.createServer(
    connect.bodyParser(),
    require('connect-restreamer')(),
    function (req, res) {
      proxy.web(req, res, { target : 'XYZserver' });
    }
  ).listen(config.listenPort);

到 GET 請求,一切都很好,但是每當發出帶有某些正文(如 POST、PATCH、PUT 等請求)的請求時,我都會收到錯誤消息:

Error: socket hang up
    at createHangUpError (http.js:1472:15)
    at Socket.socketCloseListener (http.js:1522:23)
    at Socket.EventEmitter.emit (events.js:95:17)
    at TCP.close (net.js:466:12)

我谷歌了很多,但不知道發生了什么問題。 我使用 'proxy.web' 的 'ws:true' 選項啟用了套接字代理,但仍然出現相同的錯誤。

我有一個類似的問題,並通過將我的代理代碼移到其他節點中間件之上來解決它。

例如這個:

var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
app.use("/someroute", function(req, res) {
    apiProxy.web(req, res, { target: 'http://someurl.com'})
});

app.use(someMiddleware);

不是這個:

app.use(someMiddleware);

var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer();
app.use("/someroute", function(req, res) {
    proxy.web(req, res, { target: 'http://someurl.com'})
});

我的具體問題是代理上方的 BodyParser 中間件。 我沒有做太多挖掘,但它一定以某種方式修改了請求,從而在請求最終到達時破壞了代理庫。

只是為了完整起見,正如線程中所述,模塊body-parserhttp-proxy之間確實存在集成問題。

如果不能改變中間件的順序; 您可以在代理請求之前重新流式傳輸解析的正文。

// restream parsed body before proxying
proxy.on('proxyReq', function(proxyReq, req, res, options) {
    if (req.body) {
        let bodyData = JSON.stringify(req.body);
        // incase if content-type is application/x-www-form-urlencoded -> we need to change to application/json
        proxyReq.setHeader('Content-Type','application/json');
        proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
        // stream the content
        proxyReq.write(bodyData);
    }
}

我已經在這個該死的問題上浪費了 2 天時間。 希望能幫助到你!

需要捕捉代理的錯誤:

var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({ target: argv.proxy_url })

proxy.on('error', function(err, req, res) {
    res.end();
})

在浪費了一天多的時間並遵循了nodejitsu/node-http-proxy 問題中的一些帖子之后,我能夠使其正常工作,這要歸功於 riccardo.cardin。 我決定發布完整的示例以節省您的時間。 下面的示例使用 server expressbody-parser (req.body 中間件)和當然的http-proxy來代理和轉發請求到 3rd 方服務器。

const webapitargetUrl = 'https://posttestserver.com/post.php'; 

var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json()); // support json encoded bodies

var https = require('https');
  var stamproxy = httpProxy.createProxyServer({
      target: 'https://localhost:8888',
      changeOrigin: true,
      agent  : https.globalAgent, 
      toProxy : true,
      secure: false,
      headers: {
      'Content-Type': 'application/json'
      } 
    });

  stamproxy.on('proxyReq', function(proxyReq, req, res, options) {
      console.log("proxying for",req.url);
      if (req.body) {
        console.log("prxyReq req.body: ",req.body);
        // modify the request. Here i just by removed ip field from the request you can alter body as you want
        delete req.body.ip;
        let bodyData = JSON.stringify(req.body);
        // in case if content-type is application/x-www-form-urlencoded -> we need to change to application/json
        proxyReq.setHeader('Content-Type','application/json');
        proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
        // stream the content
        console.log("prxyReq bodyData: ",bodyData);
        proxyReq.write(bodyData);
      }
      console.log('proxy request forwarded succesfully');
  });

  stamproxy.on('proxyRes', function(proxyRes, req, res){    
    proxyRes.on('data' , function(dataBuffer){
        var data = dataBuffer.toString('utf8');
        console.log("This is the data from target server : "+ data);
    }); 
  });


app.use(compression());
app.use(favicon(path.join(__dirname, '..', 'static', 'favicon.ico')));

app.use(Express.static(path.join(__dirname, '..', 'static')));


var sessions = require("client-sessions");
app.use(sessions({
  secret: 'blargadeeblargblarg',
  cookieName: 'mysession'
}));

app.use('/server/setserverip', (req, res) => {

    console.log('------------ Server.js /server/setserverip  ---------------------------------');
    req.mysession.serverip += 1;

    console.log('session data:');
    console.log(req.mysession.serverip)
    console.log('req.body:');
    console.log(req.body);

    // Proxy forwarding   
    stamproxy.web(req, res, {target: webapitargetUrl});
    console.log('After calling proxy serverip');

});

http-proxy似乎與body-parser中間件不兼容。 您可能希望在body-parser之前移動http-proxy中間件或停止使用body-parser

另請參閱: 向 Node-http-proxy Node.js 發布請求時套接字掛斷

我在postputdelete 上遇到了這個問題,但是在從chimurai / http-proxy-middleware閱讀了這個問題之后,我已經做到了。
1-添加onProxyReqhttps : //github.com/chimurai/http-proxy-middleware/issues/40#issuecomment-249430255
2-請注意,您必須將Content-Type: application/json 添加到請求的標頭
3- body-parser 沒有改變順序

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM