httptoolkit / mockttp

Powerful friendly HTTP mock server & proxy library
https://httptoolkit.com
Apache License 2.0
786 stars 88 forks source link

Proxy sending CONNECT requests for http requests #183

Open smckee-r7 opened 3 hours ago

smckee-r7 commented 3 hours ago

Hey, while using mockttp, we noticed mockttp sending CONNECT requests for http:// requests. My understanding is CONNECT request should only be used for https:// requests? Here's a script that shows the behaviour clearly:

const mockttp = require('mockttp');

// Create server to detect CONNECT method requests
const server = require('http').createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Default request');
});
server.on('connect', (req, socket) => {
  console.log('CONNECT Request received');
  socket.end();
});
server.listen(3011, () => console.log('Server listening'));

// Create mockttp passthrough proxy that forwards to our CONNECT detection server
(async () => {
  const https = await mockttp.generateCACertificate()
  const externalproxy = mockttp.getLocal({ https });
  await externalproxy.start(3010);

  console.log(`Mockttp Proxy server running on port ${externalproxy.port}`);
  externalproxy.forAnyRequest().thenPassThrough({
    ignoreHostHttpsErrors: true,
    proxyConfig: { proxyUrl: `http://127.0.0.1:3011` }
  });
})();

Both these curl request trigger a CONNECT request: curl -k --proxy http://127.0.0.1:3010 http://demo.testfire.net/ curl -k --proxy http://127.0.0.1:3010 https://demo.testfire.net/

When we don't proxy via mockttp, we only see a CONNECT request for https://demo.testfire.net which is what I'd expect: curl -k --proxy http://127.0.0.1:3011 http://demo.testfire.net/ curl -k --proxy http://127.0.0.1:3011 https://demo.testfire.net/

My question would be is there a reason mockttp behaves like this because it seems unexpected that mockttp would send CONNECT requests for http requests?

pimterry commented 3 hours ago

CONNECT is only required for HTTPS, but it's perfectly valid for HTTP too (or actually any other protocol at all - it's just a generic tunnel) and it's generally preferable to use it for everything since there's no downside and it keeps the tunnelling approach consistent. There are also plenty of proxies who only support CONNECT (who don't accept direct requests for other URLs) so it's better for compatibility.

Is there a specific reason you don't want this to happen?

smckee-r7 commented 3 hours ago

Thanks for the quick response, it would be useful to have an option to disable this CONNECT request for http request, as we know of at least one application where the CONNECT request is used to flag if the connection is secure or not