Skip to content

Conversation

@zuiderkwast
Copy link
Contributor

I've been experimenting with CONNECT to write a proxy server: https://github.com/zuiderkwast/deputy. (Is the name Deputy already taken or reserved for something else in the Cowboy world?) I've tested it only manually by configuring it as a proxy running on localhost in Firefox.

Feel free to pick selected stuff from this PR, now or later. I don't really need it for any serious project.

Changes to Cowboy:

  • Request parsing and validation for CONNECT update in cowboy_http and cowboy_http2 and restrictions forbidding CONNECT removed. Path is set to "/" rather than omitted, to make the request pass through cowboy_router and cowboy_handler unmodified. (It's a hack.)
  • A cowboy_tunnel modelled after cowboy_websocket is added.
  • Adaptations to cowboy_http for taking over the connection process without sending 101 Switching Protocols.

The flow, in short:

  1. Handler:init is called. For CONNECT requests, it may return {cowboy_tunnel, ...}.
  2. cowboy_tunnel:upgrade is called. It calls cowboy_http with a new command {takeover, ...} which has the same effect as {switch_protocol, ...}, except 101 is not sent. Takover is called in the connection process.
  3. cowboy_tunnel calls Handler:tunnel_init in the connection process. Here, a TCP connection (tunnel) is supposed to be created.
  4. If successful, cowboy_tunnel sends 200 OK to the client and the tunnel is open.
  5. On info (such as incoming TCP tunnel data from the peer) Handler:tunnel_info is called. On data from the client, Handler:tunnel_handle is called.

TODO:

  • Decide how the interface should actually look like
  • Test cases
  • Remove commented-out code

@essen
Copy link
Member

essen commented Nov 5, 2020

Just answering the comments you made, didn't look at the code yet:

  • Yes deputy is fair game.
  • The path hack is definitely not good. I was thinking a CONNECT handler should be configured in the protocol options, question is where exactly (in env probably, in which case cowboy_router can just take it from there or abort if none is configured).
  • Perhaps switch_protocol can be replaced by takeover entirely.
  • I'm not convinced a special handler is needed otherwise. cowboy_loop should be enough once initialization is done. And it can use "read_body auto" to receive packets from the socket as they come (or better cowboy_stream_h problems in grpc streaming #1430 (comment) but the code doesn't currently exist).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants