server-replay icon indicating copy to clipboard operation
server-replay copied to clipboard

Support HTTPS proxying

Open RickyRomero opened this issue 6 years ago • 5 comments

I'm working on a project right now which requires both HAR replay and HTTPS proxying, so I've added the latter to this library. Let me know if there's anything you need from me to successfully merge this and push an update to npm.

RickyRomero avatar Mar 16 '18 21:03 RickyRomero

One thing that I haven't documented about this change is that in order to handle HTTPS proxying, we need to open 3 ports total:

  • The proxy itself [ex: 8080], responsible for delegating to servers
  • The HTTP server [ex: 8081]
  • The HTTPS server [ex: 8082]

The user only need concern themselves with the first port, since that's the one they connect to... but the servers themselves require two more ports which could be in use by other processes. The way those ports are assigned is by adding 1 and 2 to the proxy port. Not sure what the best way to communicate this change is in the README - should this be an option as well?

RickyRomero avatar Mar 19 '18 11:03 RickyRomero

Upon further reflection, this is an easily-solved problem - check if the port is available first. If not, keep iterating upward until we find one we can use. If the user manually specifies a port, we bypass this behavior and throw an error instead. WDYT?

RickyRomero avatar Mar 20 '18 19:03 RickyRomero

@Stuk I've gone ahead and made the change to randomly assign internal proxying ports. Feeling more confident about merging this now. Let me know if you want any other changes.

RickyRomero avatar Apr 06 '18 16:04 RickyRomero

The code looks good! One thing I'm wondering: when running from the command line how does the user know what the https port is? Should there be a default https port and some logging in cli.js, so the user has the option of using the http or https URL.

Sorry for the slow response!

Stuk avatar Apr 22 '18 19:04 Stuk

@Stuk Thanks for taking another look!

The user doesn't choose between HTTP or HTTPS proxies - that selection is done by the script based on the incoming request. All they do is specify the port they want the proxy on, and I have a network listener on that port which figures out what kind of request it is.

I instantiate that listener here: https://github.com/RickyRomero/server-replay/blob/16c27f68545896430ffa357c6ae103e36aba80df/index.js#L72-L75

The chooseProtocol() function takes the incoming requests and figures out which protocol is required.

Here's some pseudocode to illustrate what's happening:

let httpServer
let httpsServer

init () {
    let proxyDelegate = new Proxy(options.port) // The user's port, which was previously a bare HTTP server
    httpServer = new WebServer("http", 0) // Start on a random, unused port
    httpsServer = new WebServer("https", 0) // Start on a random, unused port

    proxyDelegate.on("connection", pickProtocol)
}

pickProtocol (event) {
    if (requestIsHTTPS(event)) {
        sendRequestTo(httpsServer, event)
    } else {
        sendRequestTo(httpServer, event)
    }
}

RickyRomero avatar Apr 22 '18 21:04 RickyRomero