async function screenshotMiddleware(request, response, next) {
    const pathname = request._parsedUrl.pathname;

    if (pathname == '/screenshot/isSupported') {
      const params = getParams(request);
      const browser = getBrowser(params.id);
      const webDriverClient = getWebDriverClient(browser);

      let isSupported = false;
      if (webDriverClient) {
        // Some platforms in our Selenium grid can't take screenshots.  We don't
        // have a good way to check for this in the platform capabilities
        // reported by Selenium, so we have to take a screenshot to find out.
        // The result is cached for the sake of performance.
        if (webDriverClient.canTakeScreenshot === undefined) {
          try {
            await getScreenshot(browser.spec, webDriverClient);
            webDriverClient.canTakeScreenshot = true;
          } catch (error) {
            webDriverClient.canTakeScreenshot = false;
          }
        }

        isSupported = webDriverClient.canTakeScreenshot;
      }

      response.setHeader('Content-Type', 'application/json');
      response.end(JSON.stringify(isSupported));
    } else if (pathname == '/screenshot/diff') {
      const params = getParams(request);
      const browser = getBrowser(params.id);
      if (!browser) {
        response.writeHead(404);
        response.end('No such browser!');
        return;
      }

      // Check the URL parameters.
      const requiredParams = [
        'x', 'y', 'width', 'height', 'bodyWidth', 'bodyHeight', 'name',
      ];
      for (const k of requiredParams) {
        if (!params[k]) {
          response.writeHead(400);
          response.end(`Screenshot param ${k} is missing!`);
          return;
        }
      }

      // To avoid creating an open HTTP endpoint where anyone can write to any
      // path on the filesystem, only accept alphanumeric names (plus
      // underscore and dash).  No colons, periods, forward slashes, or
      // backslashes should ever be added to this regex, as any of those could
      // be used on some platform to write outside of the screenshots folder.
      if (!params.name.match(/[a-zA-Z0-9_-]+/)) {
        response.writeHead(400);
        response.end(`Screenshot name not valid: "${params.name}"`);
        return;
      }

      try {
        const pixelsChanged = await diffScreenshot(browser, params);
        response.setHeader('Content-Type', 'application/json');
        response.end(JSON.stringify(pixelsChanged));
      } catch (error) {
        console.error(error);
        response.writeHead(500);
        response.end('Screenshot error: ' + JSON.stringify(error));
      }
    } else {
      // Requests for paths that we don't handle are passed on to the next
      // middleware in the system.
      next();
    }
  }
This function is the middleware.  It gets request and response objects and
a next() callback which passes control off to the next middleware in the
system.  This is similar to how expressjs works.

@param {karma.MiddleWare.Request} request
@param {karma.MiddleWare.Response} response
@param {function()} next