Bug#64766: apt: The apt program does not obey the HTTP/1.1 RFC
Package: apt
Version: 0.3.18
Severity: normal
The http method that comes with apt claims to be HTTP/1.1 compliant, but
checking the behaviour against the RFC indicates non-compliances that may cause
it to fail with HTTP/1.0 servers.
Compliance Check
----------------
In the following text the quotes from the HTTP/1.1 RFC (RFC2616) are shown with
a '|' in the left margin.
| 8 Connections
|
| 8.1 Persistent Connections
|
| 8.1.1 Purpose
This is a description of persistent connections and why they are a good thing.
I have skipped the next few paragraphs.
| HTTP implementations SHOULD implement persistent connections.
apt does this.
| 8.1.2 Overall Operation
|
| A significant difference between HTTP/1.1 and earlier versions of
| HTTP is that persistent connections are the default behavior of any
| HTTP connection. That is, unless otherwise indicated, the client
| SHOULD assume that the server will maintain a persistent connection,
| even after error responses from the server.
apt does this.
| Persistent connections provide a mechanism by which a client and a
| server can signal the close of a TCP connection. This signaling takes
| place using the Connection header field (section 14.10). Once a close
| has been signaled, the client MUST NOT send any more requests on that
| connection.
I think that apt does this.
| 8.1.2.1 Negotiation
|
| An HTTP/1.1 server MAY assume that a HTTP/1.1 client intends to
| maintain a persistent connection unless a Connection header including
| the connection-token "close" was sent in the request. If the server
| chooses to close the connection immediately after sending the
| response, it SHOULD send a Connection header including the
| connection-token close.
|
| An HTTP/1.1 client MAY expect a connection to remain open, but would
| decide to keep it open based on whether the response from a server
| contains a Connection header with the connection-token close. In case
| the client does not want to maintain a connection for more than that
| request, it SHOULD send a Connection header including the
| connection-token close.
apt does not send "Connection: close" headers because it wants to use persistent
connections where possible.
| If either the client or the server sends the close token in the
| Connection header, that request becomes the last one for the
| connection.
## Non-compliance ##
apt ignores the "Connection: close" header that comes from the server if there
is one.
| Clients and servers SHOULD NOT assume that a persistent connection is
| maintained for HTTP versions less than 1.1 unless it is explicitly
| signaled. See section 19.6.2 for more information on backward
| compatibility with HTTP/1.0 clients.
## Non-compliance ##
apt assumes that HTTP/1.0 servers will have persistent connections.
| In order to remain persistent, all messages on the connection MUST
| have a self-defined message length (i.e., one not defined by closure
| of the connection), as described in section 4.4.
apt does not send requests with bodies so this is not applicable.
| 8.1.2.2 Pipelining
|
| A client that supports persistent connections MAY "pipeline" its
| requests (i.e., send multiple requests without waiting for each
| response). A server MUST send its responses to those requests in the
| same order that the requests were received.
This applies to servers and not clients, apt expects the server to behave
correctly.
| Clients which assume persistent connections and pipeline immediately
| after connection establishment SHOULD be prepared to retry their
| connection if the first pipelined attempt fails. If a client does
| such a retry, it MUST NOT pipeline before it knows the connection is
| persistent. Clients MUST also be prepared to resend their requests if
| the server closes the connection before sending all of the
| corresponding responses.
## Non-compliance ##
apt will not retry if the there is a failure. There also seem to be conditions
with HTTP/1.0 servers where apt apt expects persistent connections, but failure
to read the second set of data is seen as a server failure.
| Clients SHOULD NOT pipeline requests using non-idempotent methods or
| non-idempotent sequences of methods (see section 9.1.2). Otherwise, a
| premature termination of the transport connection could lead to
| indeterminate results. A client wishing to send a non-idempotent
| request SHOULD wait to send that request until it has received the
| response status for the previous request.
Not applicable to apt.
| 19.6.2 Compatibility with HTTP/1.0 Persistent Connections
|
| Some clients and servers might wish to be compatible with some
| previous implementations of persistent connections in HTTP/1.0
| clients and servers. Persistent connections in HTTP/1.0 are
| explicitly negotiated as they are not the default behavior.
## Non-compliance ##
apt assumes that persistent connections are the default to HTTP/1.0 servers.
There is no way that apt will consider a connection to be non-persistent.
Summary
-------
When apt is talking to a server it needs to determine if the server can support
persistent connections. This should be done by looking at the header of the
reply.
Header line Persistent?
HTTP/1.1 yes
HTTP/1.0 no
Connection: close no
Currently apt assumes that all servers will support persistent connections.
This is true if the server supports HTTP/1.1 but the default for HTTP/1.0
servers should be that the connection is not persistent and that pipelining
cannot be performed. If a persistent connection is required to an HTTP/1.0
server then RFC2068 should be consulted and the appropriate header used.
Reply to: