Bug#617643: apt: https method breaks with ignored range requests
Package: apt
Version: 0.8.10.3
Severity: normal
Tags: patch
The https method make a range request for files that are already
partially downloaded. However, it does not handle the case where the
server ignores the range request and replies with the complete file
anyway, which is legal (status code 200 OK and not status code 206
Partial Content).
The attached patch fixes this by simply not making any range requests.
That's not optimal, of course, but better than corrupting files.
I haven't really looked at libcurl to see what it would take to properly
support range requests. If just the status code needs to be checked,
then it should be fairly easy, but I am not totally sure about that.
-- Package-specific info:
-- (no /etc/apt/preferences present) --
-- (/etc/apt/sources.list present, but not submitted) --
-- System Information:
Debian Release: 6.0
APT prefers squeeze-updates
APT policy: (500, 'squeeze-updates'), (500, 'stable')
Architecture: i386 (i686)
Kernel: Linux 2.6.32-5-686-bigmem (SMP w/4 CPU cores)
Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages apt depends on:
ii debian-archive-keyring 2010.08.28 GnuPG archive keys of the Debian a
ii gnupg 1.4.10-4 GNU privacy guard - a free PGP rep
ii libc6 2.11.2-10 Embedded GNU C Library: Shared lib
ii libgcc1 1:4.4.5-8 GCC support library
ii libstdc++6 4.4.5-8 The GNU Standard C++ Library v3
ii zlib1g 1:1.2.3.4.dfsg-3 compression library - runtime
apt recommends no packages.
Versions of packages apt suggests:
pn apt-doc <none> (no description available)
ii aptitude 0.6.3-3.2 terminal-based package manager (te
ii bzip2 1.0.5-6 high-quality block-sorting file co
ii dpkg-dev 1.15.8.10 Debian package development tools
pn lzma <none> (no description available)
ii python-apt 0.7.100.1 Python interface to libapt-pkg
ii synaptic 0.70~pre1+b1 Graphical package manager
-- no debconf information
Index: apt/methods/https.cc
===================================================================
--- apt.orig/methods/https.cc 2011-03-09 15:54:49.000000000 +0200
+++ apt/methods/https.cc 2011-03-09 15:56:51.000000000 +0200
@@ -99,7 +99,6 @@
bool HttpsMethod::Fetch(FetchItem *Itm)
{
stringstream ss;
- struct stat SBuf;
struct curl_slist *headers=NULL;
char curl_errorstr[CURL_ERROR_SIZE];
long curl_responsecode;
@@ -249,25 +248,20 @@
// error handling
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errorstr);
- // if we have the file send an if-range query with a range header
- if (stat(Itm->DestFile.c_str(),&SBuf) >= 0 && SBuf.st_size > 0)
- {
- char Buf[1000];
- sprintf(Buf,"Range: bytes=%li-\r\nIf-Range: %s\r\n",
- (long)SBuf.st_size - 1,
- TimeRFC1123(SBuf.st_mtime).c_str());
- headers = curl_slist_append(headers, Buf);
- }
- else if(Itm->LastModified > 0)
+ if(Itm->LastModified > 0)
{
curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
curl_easy_setopt(curl, CURLOPT_TIMEVALUE, Itm->LastModified);
}
- // go for it - if the file exists, append on it
+ // go for it
+
+ // XXX - If the file exists, we replace it completely. using a
+ // range request would be better, but then we need to handle
+ // all the possible responses to it, which doesn't seem to be
+ // entirely trivial.
+
File = new FileFd(Itm->DestFile, FileFd::WriteAny);
- if (File->Size() > 0)
- File->Seek(File->Size() - 1);
// keep apt updated
Res.Filename = Itm->DestFile;
Reply to: