I've investigated this bug further, and found the problem. Here is a
walk-through of it, in apt-cacher 1.6.8:
1. First, in the handle_connection() subroutine (line 243), you read in
the request. apt-get(8) typically uses HTTP Keep-Alive for efficiency
(i.e. download multiple files in one TCP connection), so when you're
done with the CLIENTLINE: loop and have read in the first request, a
handful of subsequent requests remain in the buffer (see @reqLineBuf,
and the getRequestLine() subroutine as well) waiting to be serviced.
2. This normally works well. A file is requested, the file gets sent,
apt-cacher loops back to the top of the REQUEST: loop (line 338), and
proceeds to service the next request in the buffer.
3. When a Translation-en_US* file is requested, apt-cacher sees that it
doesn't have this file, and proceeds to request it from the upstream
repository. The repository returns 404, because---as we already
know---
Translation-en_US* files don't exist.
4. But here's what happens: Look in return_file(), line 839. Here, it
checks the HTTP status code ($code) from the upstream server, and
because it's 404, and $concloseflag is false, it sets
$concloseflag to true.
5. This has effect way back up in handle_connection(), line 339. The
loop condition is no longer true, so it exits. No further requests
are read in, and the connection is subsequently closed.
6. Just one small problem---there are still a number of outstanding
requests in @reqLineBuf waiting to be serviced! The "Connection reset
by peer" error message reflects apt-get(8)'s confusion at seeing the
connection closed prematurely.
The following modification narrowly fixes the behavior as described in
the original bug report:
--- apt-cacher-1.6.8/apt-cacher2 2009-02-22 15:30:20.000000000
-0500
+++ apt-cacher-1.6.8/apt-cacher2.fixed 2009-08-14 13:30:37.000000000
-0400
@@ -836,7 +836,7 @@
# keep alive or not?
# If error, force close
- if ($code!=200 && !$concloseflag) {
+ if ($code!=200 && $code!=404 && !$concloseflag) {
debug_message("Got $code error. Going to close connection.");
$concloseflag=1;
}
More generally, I believe this very notion of closing the (client)
connection on an upstream server error is faulty---a client making use
of Keep-Alive will expect the HTTP error header to be returned, and then
further requests to be fulfilled on the same connection. Maybe there are
some instances where you do want to drop the connection immediately, but
I can't think offhand of any problem [that is specific to the upstream
server] that should trigger this.
P.S.: A workaround for this bug, that doesn't involve source
modifications or locale tinkering, is to disable apt-get(8)'s use of
Keep-Alive by setting
Acquire::http::Pipeline-Depth "0";
in e.g. /etc/apt/apt.conf.d/99workaround-for-bug517761 .
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]