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

proxy: enable HTTP CONNECT request support #1200

Merged
merged 1 commit into from
Jun 26, 2018
Merged

Conversation

seanmonstar
Copy link
Contributor

When the proxy receives a CONNECT request, the HTTP Upgrade pieces
are used since a CONNECT is very similar to an Upgrade. If the CONNECT
response back from the proxied client request is successful, the
connection is converted into a TCP proxy, just like with Upgrades.

(I couldn't find a related issue to link this with...)

When the proxy receives a `CONNECT` request, the HTTP Upgrade pieces
are used since a CONNECT is very similar to an Upgrade. If the CONNECT
response back from the proxied client request is successful, the
connection is converted into a TCP proxy, just like with Upgrades.

Signed-off-by: Sean McArthur <[email protected]>
@olix0r
Copy link
Member

olix0r commented Jun 26, 2018

I'm seeing an issue testing this:

:; CONDUIT_PROXY_LOG=conduit_proxy=info CONDUIT_PROXY_PRIVATE_FORWARD=tcp://127.0.0.1:4191 CONDUIT_PROXY_POD_NAMESPACE= cargo run -p conduit-proxy
    Finished dev [unoptimized + debuginfo] target(s) in 0.5 secs
     Running `target/debug/conduit-proxy`
INFO conduit_proxy using controller at None
INFO conduit_proxy routing on V4(127.0.0.1:4140)
INFO conduit_proxy proxying on V4(0.0.0.0:4143) to Some(Addr(V4(127.0.0.1:4191)))
INFO conduit_proxy serving Prometheus metrics on V4(127.0.0.1:4191)
INFO conduit_proxy protocol detection disabled for inbound ports {25, 3306}
INFO conduit_proxy protocol detection disabled for outbound ports {25, 3306}
INFO conduit_proxy::telemetry::metrics procinfo not supported on this operating system
ERR! proxy={server=out listen=127.0.0.1:4140 remote=127.0.0.1:56082} conduit_proxy turning Error caused by underlying HTTP/2 error: protocol error: unexpected internal error encountered into 500
:; https_proxy=127.0.0.1:4140 curl -vs https://google.com
* Rebuilt URL to: https://google.com/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 4140 (#0)
* Establish HTTP proxy tunnel to google.com:443
> CONNECT google.com:443 HTTP/1.1
> Host: google.com:443
> User-Agent: curl/7.54.0
> Proxy-Connection: Keep-Alive
> 
< HTTP/1.1 500 Internal Server Error
< content-length: 0
< date: Tue, 26 Jun 2018 21:56:54 GMT
< 
* Received HTTP code 500 from proxy after CONNECT
* Closing connection 0
:; tshark -i lo0 -d 'tcp.port==4140,http' -f 'tcp port 4140'                 
Capturing on 'Loopback'
    1   0.000000 56138 4140 TCP 68 56138 → 4140 [SYN] Seq=0 Win=65535 Len=0 MSS=16344 WS=32 TSval=1526661859 TSecr=0 SACK_PERM=1    127.0.0.1 → 127.0.0.1   
    2   0.000134 4140 56138 TCP 68 4140 → 56138 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=16344 WS=32 TSval=1526661859 TSecr=1526661859 SACK_PERM=1    127.0.0.1 → 127.0.0.1   
    3   0.000159 56138 4140 TCP 56 56138 → 4140 [ACK] Seq=1 Ack=1 Win=408288 Len=0 TSval=1526661859 TSecr=1526661859    127.0.0.1 → 127.0.0.1   
    4   0.000176 4140 56138 TCP 56 [TCP Window Update] 4140 → 56138 [ACK] Seq=1 Ack=1 Win=408288 Len=0 TSval=1526661859 TSecr=1526661859    127.0.0.1 → 127.0.0.1   
    5   0.000259 56138 4140 HTTP 168 CONNECT google.com:443 HTTP/1.1     127.0.0.1 → 127.0.0.1   
    6   0.000282 4140 56138 TCP 56 4140 → 56138 [ACK] Seq=1 Ack=113 Win=408160 Len=0 TSval=1526661859 TSecr=1526661859    127.0.0.1 → 127.0.0.1   
    7   0.022878 4140 56138 HTTP 150 HTTP/1.1 500 Internal Server Error     127.0.0.1 → 127.0.0.1   
    8   0.023030 56138 4140 TCP 56 56138 → 4140 [ACK] Seq=113 Ack=95 Win=408192 Len=0 TSval=1526661880 TSecr=1526661880    127.0.0.1 → 127.0.0.1   
    9   0.023824 56138 4140 TCP 56 56138 → 4140 [FIN, ACK] Seq=113 Ack=95 Win=408192 Len=0 TSval=1526661881 TSecr=1526661880    127.0.0.1 → 127.0.0.1   
   10   0.023853 4140 56138 TCP 56 4140 → 56138 [ACK] Seq=95 Ack=114 Win=408160 Len=0 TSval=1526661881 TSecr=1526661881    127.0.0.1 → 127.0.0.1   
   11   0.025126 4140 56138 TCP 56 4140 → 56138 [FIN, ACK] Seq=95 Ack=114 Win=408160 Len=0 TSval=1526661882 TSecr=1526661881    127.0.0.1 → 127.0.0.1   
   12   0.025170 56138 4140 TCP 56 56138 → 4140 [ACK] Seq=114 Ack=96 Win=408192 Len=0 TSval=1526661882 TSecr=1526661882    127.0.0.1 → 127.0.0.1 

Upping the log level, I see some additional information:

DBUG proxy={server=out listen=127.0.0.1:4140 remote=127.0.0.1:56211} conduit_proxy::transparency::client http/1 client error: an IO error occurred: Connection reset by peer (os error 54)
TRCE proxy={server=out listen=127.0.0.1:4140 remote=127.0.0.1:56211} conduit_proxy::transparency::upgrade HTTP/1.1 upgrade half missing
ERR! proxy={server=out listen=127.0.0.1:4140 remote=127.0.0.1:56211} conduit_proxy turning Error caused by underlying HTTP/2 error: protocol error: unexpected internal error encountered into 500

@seanmonstar
Copy link
Contributor Author

From the logs, it looks like the CONNECT is passed through to the service at port 4191, which then seems to close the connection (thus the client reports connection reset error).

@olix0r
Copy link
Member

olix0r commented Jun 26, 2018

Duh, my test checks whether the proxy terminates CONNECT streams. It does not. It forwards CONNECT streams. This seems to work as expected ;D

Copy link
Member

@olix0r olix0r left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me! I haven't tested this extensively, but I have confirmed that it forwards CONNECT requests as expected.

@seanmonstar seanmonstar merged commit e3d61c9 into master Jun 26, 2018
@seanmonstar seanmonstar deleted the proxy-http-connect branch June 26, 2018 23:45
hawkw pushed a commit that referenced this pull request Jun 27, 2018
When the proxy receives a `CONNECT` request, the HTTP Upgrade pieces
are used since a CONNECT is very similar to an Upgrade. If the CONNECT
response back from the proxied client request is successful, the
connection is converted into a TCP proxy, just like with Upgrades.
khappucino pushed a commit to Nordstrom/linkerd2 that referenced this pull request Mar 5, 2019
When the proxy receives a `CONNECT` request, the HTTP Upgrade pieces
are used since a CONNECT is very similar to an Upgrade. If the CONNECT
response back from the proxied client request is successful, the
connection is converted into a TCP proxy, just like with Upgrades.
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