Puppeteer hangs when implementing request.respond with an intercepted request

Viewed 1099

I am attempting to get past Client authentication in Puppeteer. There is a solution proposed in https://github.com/puppeteer/puppeteer/issues/1319#issuecomment-371503788 that I am attempting to implement.

I have had to modify the solution somewhat - to use got instead of request.

When this is run though I am finding that the browser just hangs. Eventually quitting with the error:

(node:16672) UnhandledPromiseRejectionWarning: TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at Object.main (/Users/boyded01/workspace/watson/lib/debug.js:138:22)
(node:16672) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:16672) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

My function is:

async function checkPage(parsedUrl, config, number, total) {

  const browser = await puppeteer.launch({
    headless: false,
    executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
  });

  const page = await browser.newPage();

  // Enable Request Interception
  await page.setRequestInterception(true);

  page.on('request', interceptedRequest => {
    // Intercept Request, pull out request options, add in client cert
    const options = {
      url: interceptedRequest.url(),
      method: interceptedRequest.method(),
      headers: interceptedRequest.headers(),
      https: {
        certificateAuthority: fs.readFileSync('/Users/------/Downloads/cloud-ca.pem'),
        certificate: fs.readFileSync('/Users/------/certs/client.crt'),
        key: fs.readFileSync('/Users/------/certs/client.key')
      }
    };

    // Fire off the request manually
    got(options, function(err, resp, body) {
      // Abort interceptedRequest on error
      if (err) {
          console.error(`Unable to call ${options.url}`, err);
          return interceptedRequest.abort('connectionrefused');
      }

      // Return retrieved response to interceptedRequest
      interceptedRequest.respond({
          status: resp.statusCode,
          contentType: resp.headers['content-type'],
          headers: resp.headers,
          body: body
      });
    });
  });

  await page
    .goto(parsedUrl.toString())
    .catch(error => console.log(chalk.red(`Error loading page: ${error.message}`)));

  await browser.close();
}

Any help here in getting this to work is appreciated. The solution is quite advanced and I am struggling to get to the bottom of what I am doing wrong here.

1 Answers

I realised I was not using got correctly.

      const resp = await got(options)

      // Return retrieved response to interceptedRequest
      interceptedRequest.respond({
          status: resp.statusCode,
          contentType: 'text/html;charset=utf-8',
          headers: resp.headers,
          body: resp.body
      });
    }

Was how it should be.

Related