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

proxy.close() does not close the proxy completely - which make the test suite hang after test completion.

Open hjain60 opened this issue 6 years ago • 8 comments

Hi,

I am running a test using mocha, selenium-webdriver and http-mitm-proxy.

I set proxy using selenium to divert https traffic to the mitm-proxy. After my test cases are done, I call proxy.close() in after() method to close proxy. However, whenever any https traffic is sent to the proxy, the proxy does not get closed.

I tried to manually kill all the ports and close ssl servers however still no luck.

stop: function () {
    if (process.env.NODE_ENV && process.env.NODE_ENV === 'local') {
      Utils.resetSystemProxy(proxySet);
    }

    if (proxy) {
      try {

        console.log(proxy.sslServers);
        (Object.keys(proxy.sslServers)).forEach(function (srvName) {
          console.log(srvName);
          killPort(proxy.sslServers[srvName].port);
          proxy.sslServers[srvName].server.close();
          delete proxy.sslServers[srvName];
          console.log('HTTPS Server: "' + srvName + '" closed.');
        });

        killPort(proxy.options.port);
        proxy.close();
      } catch (e) {
        Logger.warn('Unable to close Proxy Server' + e.message);
      }
    }

    Logger.info('returning controll....');
    return 0;
  }

I would really appreciate any help as I am completely stuck and cannot run my test cases in CI/CD env.

hjain60 avatar Feb 15 '19 03:02 hjain60

While proxy.close() should be fixed so it doesn't cause the process to continue running, an easy fix is to just use mocha --exit or just call process.exit() yourself.

freewil avatar Feb 26 '19 20:02 freewil

Hi freewil - I am using the mocha -exit flag however not everyone uses mocha. In case of nightwatch tests for iOS this is causing the issue.

Would appreciate if this could be fixed.

hjain60 avatar Apr 05 '19 18:04 hjain60

Hi @hjain60 - I have experienced something similar.

Are you using keep-alive? Keep-alive agents won't drop their connections on proxy.close(). In this case you could pass in your own agent as an option to the proxy, and then do agent.destroy() when you are done.

Also, I just added #194 which could be interesting for you. It provides a callback from proxy.close() when all connections have been closed.

bjowes avatar May 26 '19 21:05 bjowes

#194 is a bit delayed due to testing issues. But #196 was just merged and that one helps in some scenarios when the proxy wouldn’t quit. Try it out.

bjowes avatar May 30 '19 16:05 bjowes

I still expereince this issue in the most current npm version ... so in fact both mentioned PRs are merged and I expect also released ... anyone have an idea?

Apollon77 avatar Mar 24 '21 14:03 Apollon77

It might help to know that the proxy acts just like the Node HttpServer on close - it stops accepting new incoming connections, but keeps executing until all ongoing connections have been terminated. The close call does not initiate closing of connections. Try to make your clients kill their connections.

bjowes avatar Mar 24 '21 17:03 bjowes

Ok, but in the end thats not that "end user friendly" ;-)) But if it is that way ... should it then not work to destroy the sockets on close? Effectively I added already the following to proxy.onRequest:

                ctx.onResponse((ctx, callback) => {
                    ctx.proxyToServerRequest.socket.once('close', () => {
                        ctx.clientToProxyRequest.socket.destroy()
                    });
                    return callback();
                });

But it seems not enough ...

Or do I need to "collect" all sockets from all sorts and destroy them all by myself on close? What would be the best place for that?

Apollon77 avatar Mar 24 '21 20:03 Apollon77

Maybe a new issue would be better to discuss this further. I would need some more info about your use case (what are the clients and what are the servers) to give some recommendation.

I think the code you added shouldn't be needed. It will forward a socket close event from the socket between the proxy and the server by destroying the socket between the client and the proxy. Generally this would be taken care of by the applications without this custom code. To clarify - calling close() on the proxy will not close the "proxy to server" sockets. Such a close would need to be initiated by the server.

bjowes avatar Mar 24 '21 21:03 bjowes