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

Port number incorrectly shared between requests when using HTTP Proxy with connection re-use #1887

Closed
oliland opened this Issue Sep 13, 2017 · 2 comments

Comments

Projects
None yet
3 participants
@oliland

oliland commented Sep 13, 2017

I did this

#!/bin/bash
curl -v -x http://proxy-webserver:80 http://website1:8090 --next -x http://proxy-webserver:80 http://website2

I expected the following

> Host: website1:8090
...
> Host: website2

What actually happened

When re-using a connection with an HTTP Proxy, curl will re-use the port number in the HOST header of website1 when requesting website2.

> Host: website1:8090
...
> Host: website2:8090

Full anonymised log: We use an internal proxy server, we did not share the proxy server that we used nor the destination endpoints of the example. Let me know if this is a hurdle:

* Rebuilt URL to: http://website1:8090/
*   Trying 10.76.31.109...
* Connected to proxy-webserver (10.76.31.109) port 80 (#0)
> GET http://website1:8090/ HTTP/1.1
> Host: website1:8090
> User-Agent: curl/7.47.0
> Accept: */*
> Proxy-Connection: Keep-Alive
> 
< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 12 Sep 2017 21:56:24 GMT
< Content-Type: text/plain; charset=UTF-8
< Content-Length: 86
< Connection: keep-alive
< Etag: "fa2d1f611c1047c6564784dab407bfa88e7da3bb"
< 
* Connection #0 to host proxy-webserver left intact
Hello, world!
* Rebuilt URL to: http://website2/
* Found bundle for host website2: 0x55ca17c02190 [can pipeline]
* Re-using existing connection! (#0) with proxy proxy-webserver
* Connected to proxy-webserver (10.76.31.109) port 80 (#0)
> GET http://website2/ HTTP/1.1
> Host: website2:8090 # This is incorrect
> User-Agent: curl/7.47.0
> Accept: */*
> Proxy-Connection: Keep-Alive
> 
< HTTP/1.1 502 Bad Gateway
< Server: nginx
< Date: Tue, 12 Sep 2017 21:56:34 GMT
< Content-Type: text/html
< Content-Length: 166
< Connection: keep-alive
< 
Proxy server returns error
* Connection #0 to host proxy-webserver left intact

curl/libcurl version

curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets 

I've verified that the latest version of curl master is also affected (7.56.0-DEV).

Further notes

I've proposed a workaround here, though this is not ideal we would like to re-use proxy connections while specifying a different port.

#1886

Disabling connection re-use is a workaround for this issue.

@maxdymond

This comment has been minimized.

Show comment
Hide comment
@maxdymond

maxdymond Sep 13, 2017

Contributor

I added some logs in. Looks like there's something squiffy going on in the connection reuse code.

Calling

PROXY="http://61.216.60.206:8080"; src/curl -v -x $PROXY http://portquiz.net:8080/ --next -x $PROXY http://portquiz.net

gave

MD: allocate_conn:4219 setting conn 0xff09f0 port to -1
MD: parse_remote_port:5834 setting conn 0xff09f0 port to 8080
*   Trying 61.216.60.206...
* TCP_NODELAY set
* Connected to 61.216.60.206 (61.216.60.206) port 8080 (#0)
MD: Curl_http:2097 using conn 0xff09f0 set host header to Host: portquiz.net:8080

> GET http://portquiz.net:8080/ HTTP/1.1
> Host: portquiz.net:8080
> User-Agent: curl/7.56.0-DEV
> Accept: */*
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 OK
< Content-Length: 50
< Content-Type: text/html
< Accept-Ranges: none
< Vary: Accept-Encoding
< Server: CachingProxy Microsoft-HTTPAPI/2.0
< X-Powered-By: PHP/5.4.45-0+deb7u8
< Date: Wed, 13 Sep 2017 14:13:12 GMT
<
Port 8080 test successful!
Your IP: 59.125.230.27
* Connection #0 to host 61.216.60.206 left intact
MD: allocate_conn:4219 setting conn 0xff1d40 port to -1
* Rebuilt URL to: http://portquiz.net/
MD: parse_remote_port:5849 setting conn 0xff1d40 port to 80
* Found bundle for host portquiz.net: 0xff1b60 [can pipeline]
* Re-using existing connection! (#0) with proxy 61.216.60.206
* Connected to 61.216.60.206 (61.216.60.206) port 8080 (#0)
MD: Curl_http:2097 using conn 0xff09f0 set host header to Host: portquiz.net:8080

> GET http://portquiz.net/ HTTP/1.1
> Host: portquiz.net:8080
> User-Agent: curl/7.56.0-DEV
> Accept: */*
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 OK
< Content-Length: 48
< Content-Type: text/html
< Accept-Ranges: none
< Vary: Accept-Encoding
< Server: CachingProxy Microsoft-HTTPAPI/2.0
< X-Powered-By: PHP/5.4.45-0+deb7u8
< Date: Wed, 13 Sep 2017 14:13:21 GMT
<
Port 80 test successful!
Your IP: 59.125.230.27
* Connection #0 to host 61.216.60.206 left intact

The port parsing in the second case is done on some random new connection, but then the old connection is used when building the Host header.

Contributor

maxdymond commented Sep 13, 2017

I added some logs in. Looks like there's something squiffy going on in the connection reuse code.

Calling

PROXY="http://61.216.60.206:8080"; src/curl -v -x $PROXY http://portquiz.net:8080/ --next -x $PROXY http://portquiz.net

gave

MD: allocate_conn:4219 setting conn 0xff09f0 port to -1
MD: parse_remote_port:5834 setting conn 0xff09f0 port to 8080
*   Trying 61.216.60.206...
* TCP_NODELAY set
* Connected to 61.216.60.206 (61.216.60.206) port 8080 (#0)
MD: Curl_http:2097 using conn 0xff09f0 set host header to Host: portquiz.net:8080

> GET http://portquiz.net:8080/ HTTP/1.1
> Host: portquiz.net:8080
> User-Agent: curl/7.56.0-DEV
> Accept: */*
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 OK
< Content-Length: 50
< Content-Type: text/html
< Accept-Ranges: none
< Vary: Accept-Encoding
< Server: CachingProxy Microsoft-HTTPAPI/2.0
< X-Powered-By: PHP/5.4.45-0+deb7u8
< Date: Wed, 13 Sep 2017 14:13:12 GMT
<
Port 8080 test successful!
Your IP: 59.125.230.27
* Connection #0 to host 61.216.60.206 left intact
MD: allocate_conn:4219 setting conn 0xff1d40 port to -1
* Rebuilt URL to: http://portquiz.net/
MD: parse_remote_port:5849 setting conn 0xff1d40 port to 80
* Found bundle for host portquiz.net: 0xff1b60 [can pipeline]
* Re-using existing connection! (#0) with proxy 61.216.60.206
* Connected to 61.216.60.206 (61.216.60.206) port 8080 (#0)
MD: Curl_http:2097 using conn 0xff09f0 set host header to Host: portquiz.net:8080

> GET http://portquiz.net/ HTTP/1.1
> Host: portquiz.net:8080
> User-Agent: curl/7.56.0-DEV
> Accept: */*
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 OK
< Content-Length: 48
< Content-Type: text/html
< Accept-Ranges: none
< Vary: Accept-Encoding
< Server: CachingProxy Microsoft-HTTPAPI/2.0
< X-Powered-By: PHP/5.4.45-0+deb7u8
< Date: Wed, 13 Sep 2017 14:13:21 GMT
<
Port 80 test successful!
Your IP: 59.125.230.27
* Connection #0 to host 61.216.60.206 left intact

The port parsing in the second case is done on some random new connection, but then the old connection is used when building the Host header.

@bagder

This comment has been minimized.

Show comment
Hide comment
@bagder

bagder Sep 14, 2017

Member

I believe it is simply the Host: header (wrongly) being re-used for the same connection.

Member

bagder commented Sep 14, 2017

I believe it is simply the Host: header (wrongly) being re-used for the same connection.

@bagder bagder closed this in 22708ea Sep 15, 2017

@lock lock bot locked as resolved and limited conversation to collaborators May 6, 2018

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