Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CONNECT method (Proof-of-Concept) #1482

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

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