Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket not emitting data when proxy fails #87

Closed
alefwmm opened this issue Nov 20, 2019 · 1 comment
Closed

Socket not emitting data when proxy fails #87

alefwmm opened this issue Nov 20, 2019 · 1 comment

Comments

@alefwmm
Copy link

alefwmm commented Nov 20, 2019

Hello guys,

I have one problem currently and a possible solution for it.
I am using node-https-proxy-agent#3.0.1 with axios#0.19.0.

It works properly when the proxy connects successfully. The problem comes when my proxy provider gives me an error response like HTTP/1.1 502 Proxy Error during the connection process. When this happens, I am unable to catch this response and then, a timeout is thrown by my axios instance.

This is the case for all version beyond node-https-proxy-agent#2.2.1, the one that fixed a major security flaw. Reading axios code, I saw that it does not handle the closed socket properly, expecting the normal stream events to properly execute.

This way, I chose to do the following:

// ...
// Replaced the following
// socket.push(buffers)
// with
socket.emit('data', buffers);
socket.emit('end');
// ...

Here a way to reproduce the problem:

const axios = require("axios");
const HttpsProxyAgent = require("https-proxy-agent");

const agent = new HttpsProxyAgent("a:b@zproxy.lum-superproxy.io:22225");

const instance = axios.create({
    baseURL: `https://example.com`,
    timeout: 10000,
    httpsAgent: agent,
    validateStatus: () => true // Accepts all status codes
});

instance.get().then(response => {
    // Expected a response with the proxy error here
    // It should give a response with a 407 Invalid Auth status
    console.log(response);
}).catch(error => {
    // A timeout error is thrown instead
    // Error: timeout of 10000ms exceeded...
    console.error(error)
});

Using the solution explained before, it worked. I would like to know if this is the best way to do this.

I am currently using this branch

@watson
Copy link

watson commented Jan 17, 2020

I'm seeing the same issue (with both the latest version and v2.2.3+).

Here's a simple program to reproduce:

const http = require('http')
const https = require('https')
const HttpsProxyAgent = require('https-proxy-agent')

const server = http.createServer()

server.on('connect', (req, socket, head) => {
  console.log('proxy got request for', req.url)
  socket.end('HTTP/1.1 500 Internal Server Error\r\n\r\n')
})

server.listen(() => {
  const opts = {
    host: 'example.com',
    agent: new HttpsProxyAgent('http://localhost:' + server.address().port)
  }

  https.get(opts, res => {
    console.log('client got response:', res.statusCode)
    res.resume()
    res.on('end', () => {
      console.log('client detected end of response')
    })
  })
})

If using the latest version res will never emit an end event. If using v2.2.2 it will.

lpinca added a commit to lpinca/node-https-proxy-agent that referenced this issue Jan 27, 2020
Allow the `'end'` event to be emitted on the `http.IncomingMessage`
instance.

Fixes: TooTallNate#87
TooTallNate added a commit that referenced this issue Feb 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants