Skip to content

Fix external AppStream ETag handling, leaving empty files behind

The relevant commits:

gs_download_file_async() is used by the external AppStream code to
download files with extra AppStream data. It supports two modes:

 * User, where external AppStream files are downloaded and
   installed into ~/.cache/gnome-software/external-appstream

 * System, where external AppStream files are downloaded and
   installed into /var/cache/swcatalog/xml

When gs_download_file_async() is called, it first reads the ETag
of the local file, if it exists, and passes that to Soup so that
Soup can compare the ETag against the server file's ETag. This
works well for user installations, since the download folder is
also the installation folder.

For system-wide installations, however, this does not work. That's
because GNOME Software downloads the AppStream file into the user
directory (~/.cache/gnome-software/external-appstream), then moves
the downloaded file into the system folder. In practice, for system
installations, the ETag is always NULL, because the local file never
exists.

Fix that by doing most of what gs_download_file_async() inside of
gs_external_appstream_refresh_async(). Namely, it created necessary
folders; read the ETag of *the correct file*; replaces the local
output file; then finally uses gs_download_stream_async() to fetch
and install the AppStream file.

This allows Soup to compare the correct ETag with the server file,
and skip the download entirely if they match.

This commit also exposes another bug in the external AppStream code
where it leaves behind an empty file when the download is skipped,
which follow-up commits will fix.

Related: GNOME/gnome-software#1902

and

On system-wide AppStream installations, if the external AppStream
file has an ETag that matches that of the server, GNOME Software
does not remove the temporary file which is created right before
the download operation started.

Now that we know when such cases happen, through the new error
id GS_DOWNLOAD_ERROR_NOT_MODIFIED, remove the temporary download
file if it's a system-wide installation.

Closes GNOME/gnome-software#1902
Edited by Georges Basile Stavracas Neto

Merge request reports