Subject: #158: Proxy-Connection and Keep-alive

From: Mark Nottingham <[email-masked]>
Date: Mon, 28 Nov 2011 15:44:40 +1100

<http://trac.tools.ietf.org/wg/httpbis/trac/ticket/158>

Description: 

> The Keep-Alive header is referred to in a few places, but not defined as a HTTP/1.1 header. This should be addressed (e.g., in an appendix).
> 
> Likewise, Proxy-Connection is still (!) in common use, but has been deprecated for at least a decade. A few words in an appendix may encourage implementers to stop this practice.

We already have text in p1 about Keep-Alive, so it seemed best to just modify it slightly to also cover Proxy-Connection. I made a proposal on-ticke:

> Proposal - replace p1 A.1.2 with:
> 
> Most HTTP/1.0 implementations use a separate connection for each request. However, some implement persistent connections using the Keep-Alive negotiation mechanism described in Section 19.7.1 of [RFC2068].
> 
> In contrast, persistent connections are the default for HTTP/1.1; they do not need to be explicitly negotiated, as in HTTP/1.0. This is because there were various interoperability problems in the implementations of HTTP/1.0 persistent connections, especially when a proxy is involved.
> 
> For example, some existing HTTP/1.0 clients might send Keep-Alive to a proxy server that doesn't understand Connection, which would then erroneously forward it to the next inbound server, which would establish the Keep-Alive connection and result in a hung HTTP/1.0 proxy waiting for the close on the response. The result is that HTTP/1.0 clients must be prevented from using Keep-Alive when talking to proxies.
> 
> However, talking to proxies is the most important use of persistent connections, so that prohibition is clearly unacceptable. Some early attempts to correct this was to use the Proxy-Connection request header, but this approach was also unworkable, for similar reasons.
> 
> Therefore, some other mechanism for indicating a persistent connection was needed -- one that is safe to use even when talking to an old proxy that ignores Connection. Persistent connections are the default for HTTP/1.1 messages; we introduce a new keyword (Connection: close) for declaring non-persistence. See Section 8.1.
> 
> As a result, HTTP/1.1 clients ought not to send the Proxy-Connection or Keep-Alive header; at best, they will waste bytes in requests, and at worst they can cause interoperability problems.

We should also probably register Proxy-Connection with a status of "obsoleted".

Comments?

--
Mark Nottingham   http://www.mnot.net/

---

From: Willy Tarreau <[email-masked]>
Date: Mon, 28 Nov 2011 08:01:48 +0100

Hi Mark,

> We should also probably register Proxy-Connection with a status of "obsoleted".

I like this. Shouldn't we add something like this :

  A proxy receiving an HTTP/1.1 request must ignore Proxy-Connection and
  Keep-Alive headers and consider only the Connection header.

and :

  A client wishing to use persistent connections with a proxy running an
  unknown HTTP version may explicitly send "Connection: keep-alive". This
  statement will be silently ignored by 1.1 proxies and will enable use of
  persistent connections on 1.0 proxies which understand the Connection header.

I've encountered a number of issues when deploying haproxy as an intermediary
between some clients and ancient Squid versions which made me use the
Proxy-Connection header only in this case because the Connection header was
not always usable. From what I recall, the issue appeared if haproxy only
altered the connection header and not the proxy-connection, because both the
proxy and the client would consider only the later.

It's easy to notice in a response that it's HTTP/1.0, but in the request,
the client speaks 1.1 and the intermediary does not know the next hop will
prefer Proxy-Connection over Connection.

For instance, if I send this to my local squid 2.6-stable13 :

  HEAD http://www.yahoo.fr/ HTTP/1.1
  Host: www.yahoo.fr
  Proxy-connection: keep-alive
  Connection: close

The connection remains alive in the response :

  HTTP/1.0 301 Moved Permanently
  Date: Mon, 28 Nov 2011 06:39:55 GMT
  P3P: policyref="http://info.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE LOC GOV"
  Cache-Control: max-age=3600
  Location: http://fr.yahoo.com/
  Vary: Accept-Encoding
  Content-Type: text/html; charset=utf-8
  Age: 165
  Content-Length: 81
  Server: YTS/1.19.5
  X-Cache: MISS from px.home.local
  Via: HTTP/1.1 rc1.ops.ird.yahoo.com (YahooTrafficServer/1.19.5 [cHs f ]), 1.0 px.home.local:3128 (squid/2.6.STABLE13)
  Proxy-Connection: keep-alive

But at least it seems that Squid falls back to Connection if it does not
see Proxy-Connection. It just defaults to close if neither is present,
which makes a difference with standard HTTP/1.1, so clients will be tempted
to continue to send "Proxy-Connection: keep-alive" with such proxies. While
Squid is quite smart and interoperable, I suspect that other proxies are
harder to get right when it comes to the Connection header. So probably that
the Proxy-Connection header will still live for a long time because of this
if we don't suggest an alternative solution as above.

Best regards,
Willy

---

From: Amos Jeffries <[email-masked]>
Date: Mon, 28 Nov 2011 23:20:38 +1300

>    Keep-Alive headers and consider only the Connection header.

Which brings up the old problem of "Proxy-Connection: keep-alive" 
passing through middleware which ignores and relays it. End-to-end trouble.

Better to mandate that they are both obsolete and thus dropped. Leading 
to other troubles, but less damaging ones.

For the record Squid drops Keep-Alive ... no problems.

Proxy-Connection is another story. On Marks request we started dropping 
it on relayed requests a few years back. Lots of admin questions about 
where its gone and problems appeared with IIS and a mix of other 
Microsoft software not handling Connection: in responses to requests 
sending Proxy-Connection. Yes, I dare to point the finger at MS server 
software being the sole obvious culprits here, non-MS server software 
seems to have no problems. Client software is a different story altogther.

Reports seem to have declined recently, but there are still signs that 
all this trouble software are still depending on Proxy-Connection acting 
like Connection. Mostly in the form of traffic traces with 
Proxy-Connection: and no Connection header.

> which makes a difference with standard HTTP/1.1, so clients will be tempted

Since Squid versions which do that are 1.0. That is expected yes?

The newer versions advertising 1.1 assume keep-alive unless 
Proxy-Connection, Connection or the config file says otherwise (in that 
order today). There was a bug in POST/PUT/DELETE keep-alive which we 
have now resolved.

> if we don't suggest an alternative solution as above.

If the agreement here is that it is safe to ignore and drop 
Proxy-Connection Squid can implement that immediately. The only thing 
I'm against is ignoring it completely (implying passing it thru).

Amos

---

From: Willy Tarreau <[email-masked]>
Date: Mon, 28 Nov 2011 11:52:30 +0100

Hi Amos,

> passing through middleware which ignores and relays it. End-to-end trouble.

You're right, I was in fact not meaning "relaying it", but "ignoring it when
deciding whether to use persistent connections or not". I'm all for cleaning
up everything we can in the traffic to avoid such trouble.

> to other troubles, but less damaging ones.

Removing it from relayed requests is important. We can just not expect it to
be removed from browser requests without proposing a working alternative,
otherwise browser vendors will get complains that connection to proxies
suddenly break after an update and they will revert it back. For instance,
there are some networks where persistent connectinos are mandatory due to
NTLM auth... I would like to ensure we can help the browser vendors to get
rid of the header without losing persistent conns even when facing old
proxies.

> seems to have no problems.

I too recall having observed nasty behaviour on MS software related to this.

> Client software is a different story altogther.

Unfortunately, the client has to adapt to the deployed infrastructure and to
remain compatible with existing bugs. That's why I'm saying that we need to
help clients safely get rid of it first.

> Proxy-Connection: and no Connection header.

Agreed, that's what I observed too, and precisely the reason I had to add
an option to haproxy to choose between either header.

> Since Squid versions which do that are 1.0. That is expected yes?

Yes, 100% agreed.

> I'm against is ignoring it completely (implying passing it thru).

I agree on this point, and I was not clear in my first response.

Ideally we should try to enumerate the matrix of requests and responses
containing various combinations of Proxy-Connection and Connection values.
It should help match clients' intents with proxies' capabilities. I'm
pretty sure that starting from Squid's behaviour is a good approach as it
has become the de-facto standard, mimmicked by many commercial products.

Regards,
Willy

---

From: Amos Jeffries <[email-masked]>
Date: Tue, 29 Nov 2011 00:42:15 +1300

> has become the de-facto standard, mimmicked by many commercial products.

We seem not to have any troubles nowdays emitting only Connection. The 
problems are on satisfying the sources who send Proxy-Connection still. 
IMO it would be nice to have a guideline to point at stating that 
Connection overrides Proxy-Connection and the latter should be ignored 
for processing and never emitted.

Amos

---

From: Willy Tarreau <[email-masked]>
Date: Mon, 28 Nov 2011 13:29:33 +0100

> for processing and never emitted.

The issue for a client is that emitting nothing does not behave equally on
all proxies. Older Squid assume a close and newer 1.1 products will behave
with an implicit keep-alive. In theory sending "Connection: keep-alive" is
useless, except that in this case it can be the solution for those products.
Probably that the guideline should say that a client should explicitly send
"Connection: keep-alive" if it does not know whether the proxy is 1.1 or 1.0
and not use Proxy-Connection at all. I'm insisting on this point because
just saying that Connection overrides Proxy-Connection can be confusing
since the default behaviour for the Connection header differs from what
clients have expected for a long time with Proxy-Connection.

I would thus suggest the following rule for clients :

Proxy's HTTP version                 Desired behaviour
                              persistent             close

1.0                    Connection: keep-alive       nothing/close
Unknown                Connection: keep-alive       Connection: close
1.1                    nothing/keep-alive           Connection: close

However the issue remains for responses. In the example I sent this morning,
my old squid 2.6-stable13 was only returning Proxy-Connection: keep-alive
and no "connection" header. This will force clients to still consider the
Proxy-Connection in responses from 1.0 proxies. The real issue precisely is
exactly this case, where Connection is absent and Proxy-Connection returns
something which differs from the implicit connection mode (1.0 without header
means close).

So we can't totally ignore this header but we should be able to prevent it
from being emitted at least.

Regards,
Willy

---

From: Amos Jeffries <[email-masked]>
Date: Tue, 29 Nov 2011 19:01:08 +1300

> from being emitted at least.

Okay I'm with you on all points there.

How about is for prose:
"
  Proxy-Connection is now obsolete. Clients must not produce it on 
HTTP/1.1 requests or responses.
  NP: existing software still uses a mixture of HTTP/1.0 and obsolete 
Proxy-Connection keep-alive mechanisms which differ in behaviour from 
HTTP/1.1. Clients should always explicitly send Connection: keep-alive 
or Connection: close when contacting servers having HTTP/1.0 or unknown 
HTTP version numbers.
"

AYJ

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 29 Nov 2011 07:50:14 +0100

> or Connection: close when contacting servers having HTTP/1.0 or unknown 

Works for me with a minor variation : "It must not be emitted it any
HTTP/1.1 requests or response" (since clients do not produce responses).

Regards,
Willy