update misinterprets 304 response on Packages.gz

Bug #1750625 reported by robocoder
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
apt (Ubuntu)
Confirmed
Undecided
Unassigned

Bug Description

Description: Ubuntu 16.04.3 LTS
Release: 16.04

ii apt 1.2.24 amd64 commandline package manager
ii apt-transport-https 1.2.24 amd64 https download transport for APT
ii apt-utils 1.2.24 amd64 package management related utility programs
ii libapt-inst2.0:amd64 1.2.24 amd64 deb package format runtime library
ii libapt-pkg5.0:amd64 1.2.24 amd64 package management runtime library

Expected behaviour:

If apt-get gets a 304 Not Modified when requesting Packages.gz, it should ignore the package list (i.e., there's no update).

Observed behaviour:

Added a local repository to /etc/apt/sources.list.d/instafreight_php.list:

> deb [arch=amd64 trusted=yes] http://ubuntu/instafreight xenial php

The first time running apt-get update succeeds; in addition, apache.log shows:

> 10.0.4.72 - - [20/Feb/2018:12:01:39 -0500] "GET /instafreight/dists/xenial/php/binary-amd64/Packages.gz HTTP/1.1" 200 745 "-" "Debian APT-HTTP/1.3 (1.2.24)"

I am able to install packages from that repo without error.

Running apt-get a 2nd time succeeds. apache.log doesn't show a request for Packages.gz

Running apt-get a 3rd time, apache.log shows:

> 10.0.4.72 - - [20/Feb/2018:12:04:45 -0500] "GET /instafreight/dists/xenial/php/binary-amd64/Packages.gz HTTP/1.1" 304 124 "-" "Debian APT-HTTP/1.3 (1.2.24)"

However, on the console where I ran apt-get, the corresponding output is:

> Err:15 http://ubuntu/instafreight xenial/php amd64 Packages
> 404 Not Found
> ...
> E: Failed to fetch http://ubuntu/instafreight/dists/xenial/php/binary-amd64/Packages.gz 404 Not Found
> E: Some index files failed to download. They have been ignored, or old ones used instead.

Tags: xenial
Revision history for this message
robocoder (apang) wrote :

In trusty, this works as expected.

ii apt 1.0.1ubuntu2.1 amd64 commandline package manager
ii apt-transport-https 1.0.1ubuntu2.1 amd64 https download transport for APT
ii apt-utils 1.0.1ubuntu2.1 amd64 package management related utility programs
ii libapt-inst1.5:amd64 1.0.1ubuntu2.1 amd64 deb package format runtime library
ii libapt-pkg4.12:amd64 1.0.1ubuntu2.1 amd64 package management runtime library

Running "apt-get update" the first time, apache returns 200:

> 10.0.4.72 - - [20/Feb/2018:13:49:27 -0500] "GET /instafreight/dists/trusty/php/binary-amd64/Packages.gz HTTP/1.1" 200 951 "-" "Debian APT-HTTP/1.3 (1.0.1ubuntu2)"

Running "apt-get update" the second time:

> 10.0.4.72 - - [20/Feb/2018:13:49:53 -0500] "GET /instafreight/dists/trusty/php/binary-amd64/Packages.gz HTTP/1.1" 304 124 "-" "Debian APT-HTTP/1.3 (1.0.1ubuntu2)"

> Hit http://ubuntu.pp trusty/php amd64 Packages

... and third time:

> 10.0.4.72 - - [20/Feb/2018:13:49:59 -0500] "GET /instafreight/dists/trusty/php/binary-amd64/Packages.gz HTTP/1.1" 304 124 "-" "Debian APT-HTTP/1.3 (1.0.1ubuntu2)"

> Hit http://ubuntu.pp trusty/main amd64 Packages

Revision history for this message
robocoder (apang) wrote :

Still occurring in xenial with apt 1.2.25

Revision history for this message
robocoder (apang) wrote :
tags: added: xenial
Revision history for this message
Julian Andres Klode (juliank) wrote :

I think a problem is that your Release file is missing a Date field. APT should not be trying to redownload unmodified files.

Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in apt (Ubuntu):
status: New → Confirmed
Revision history for this message
Hontvári József Levente (hontvari) wrote :

This is a bug in 20.04 as well. I have no Release file, this is a private, unsigned repository, only Packages.xz. On first run, apt update first works. On the second run apt update issues a HTTP GET with an If-Modified-Since header:

GET /deb/Packages.xz HTTP/1.1
Host: XXX
Cache-Control: max-age=0
If-Modified-Since: Sat, 18 Apr 2020 14:19:16 GMT
User-Agent: Debian APT-HTTP/1.3 (1.6.12)

Apache HTTPD correctly responds that there was no change:

HTTP/1.1 304 Not Modified
Date: Sun, 19 Apr 2020 20:53:02 GMT
Server: Apache/2.4.18 (Ubuntu)
ETag: "960-5a39159dd8574"

Instead of using the existing downloaded version apt update tries to download Packages.bz2 etc. and finally it displays:

root@pipa11:~# apt update
Hit:1 http://mirror.hk.leaseweb.net/ubuntu bionic InRelease
Hit:2 http://mirror.hk.leaseweb.net/ubuntu bionic-updates InRelease
Hit:3 http://mirror.hk.leaseweb.net/ubuntu bionic-backports InRelease
Ign:4 http://XXX/deb InRelease
Ign:5 http://XXX/deb Release
Hit:6 http://security.ubuntu.com/ubuntu bionic-security InRelease
Hit:7 http://XXX/deb Packages
Ign:7 http://XXX/deb Packages
Ign:7 http://XXX/deb Packages
Ign:7 http://XXX/deb Packages
Ign:7 http://XXX/deb Packages
Ign:7 http://XXX/deb Packages
Ign:7 http://fXXX/deb Packages
Err:7 http://fXXX/deb Packages
  lzma_read: Read error (7)
Reading package lists... Done
E: Failed to fetch http://XXX/deb/Packages lzma_read: Read error (7)
E: Some index files failed to download. They have been ignored, or old ones used instead.

The exit code is 100.

Revision history for this message
Julian Andres Klode (juliank) wrote :

I guess that's good to know that it does not really work without a release file now anyway, it is a good argument for removing support for such repos completely. I made a plan a year or two ago, but have not acted on it yet :/

Please add a Release file. It gives you download progress, hash checks, and avoids all kinds of tries for files that don't exist. Then sign it so apt can verify it fetched it correctly, which is beneficial even in a trusted environment.

Revision history for this message
Julian Andres Klode (juliank) wrote :

I think the answer is simple: We should stop sending If-Modified-Since. There's no advantage to sending that compared to getting back the same release file, and it's a bad design.

Revision history for this message
Hontvári József Levente (hontvari) wrote :

I actually tried to add a Release file without signing it, because it would be simple, only a single command:

  apt-ftparchive release . > Release

But that did not work either. The apt update command exits with error:

root@pipa11:~# apt update
Hit:1 http://mirror.hk.leaseweb.net/ubuntu bionic InRelease
Hit:2 http://mirror.hk.leaseweb.net/ubuntu bionic-updates InRelease
Hit:3 http://mirror.hk.leaseweb.net/ubuntu bionic-backports InRelease
Ign:4 http://XXX/deb InRelease
Hit:5 http://security.ubuntu.com/ubuntu bionic-security InRelease
Hit:6 http://XXX/deb Release
Ign:7 http://XXX/deb Release.gpg
Reading package lists... Done
Building dependency tree
Reading state information... Done
All packages are up to date.
W: Skipping acquire of configured file 'Packages' as repository 'http://XXX/deb InRelease' does not seem to provide it (sources.list entry misspelt?)

This is only a warning, the exit code is 0, but 'apt install' does not find any packages in the private repo.

The setup seems to be valid, here is the HTTP log:

[20/Apr/2020:09:43:32 +0200] "GET /deb/InRelease HTTP/1.1" 404 442 "-" "Debian APT-HTTP/1.3 (1.6.12)"
[20/Apr/2020:09:43:32 +0200] "GET /deb/Release HTTP/1.1" 200 1111 "-" "Debian APT-HTTP/1.3 (1.6.12)"
[20/Apr/2020:09:43:32 +0200] "GET /deb/Release.gpg HTTP/1.1" 404 442 "-" "Debian APT-HTTP/1.3 (1.6.12)"

apt update actually stores the release file, which seems to be valid:

root@pipa11:~# cat /var/lib/apt/lists/fa_deb_Release
Date: Mon, 20 Apr 2020 07:42:24 UTC
MD5Sum:
 b531ad26ae3d375d18cb8d8bb2460102 2400 Packages.xz
 b317cbfe3c8f98153ff8b531764dab80 36 Release
SHA1:
 d45be5187c0ee43bb002cee304428f23b889fcc4 2400 Packages.xz
 af287f2a445167dd64b3af88ccfa78f4363dcb29 36 Release
SHA256:
 7466d08346b7986267dd39c3e25359402d40693d2b75f9a9ebd797a9f206c6e2 2400 Packages.xz
 43a8eb775cee00e6ca2b8ffa58d26e08fff7bd52b560a68e82d4c6765879a8b7 36 Release
SHA512:
 0395b40f19e7589682e9d29b5e39b92c3f9a9a88f75770d5ba8417f77b1d4ffb3ff9b9a5a78bd78ecea970e72e19b6744c566fd55fadc11125c547a4a14b5a8a 2400 Packages.xz
 1a8a46da3d3d2c3344d87c37acdbd32888b35b4bde58b6f249db57fb5b016a41b821c701a7a748e34511bc098adb66510603578442145cd3d176d60e8732be5f 36 Release

The Packages.xz file is there and valid (apt update reads and uses it, if there is no Release file).

My sources file contains trusted=yes:

  deb [trusted=yes lang=none pdiffs=no] http://XXX:/deb/ /

I think it I only guess that it would work if there were a signature file. I think
had problems with it. I do not remember was not sure why Even if my

Revision history for this message
Julian Andres Klode (juliank) wrote :

That release file is sort of invalid, as we also need the uncompressed Packages file hashed, because we check hashes after decompression too.

So usually you generate Packages, compress it (having both around), then create Release file, and then delete the uncompressed Packages file if you don't need it anymore.

I guess this should work more automatically, apt-ftparchive could transparently decompress compressed files to add them to Release file.

Revision history for this message
Hontvári József Levente (hontvari) wrote :

Yes, it worked that way. Thank you!

For the record:
The most simple, currently working way to create a private, unsigned directory:

  cd /srv/deb
  apt-ftparchive packages . > Packages
  apt-ftparchive release . > Release

Assuming that the document root of the HTTP server is /srv/ and deb is the directory with your .deb files.

on your machines which will use the repo:

  nano /etc/apt/sources.list.d/myserver
insert into the file:
  deb [trusted=yes] http://myserver:/deb/ /

Assuming that the host name of your HTTP server is myserver.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.