xbps_fetch_file: simplify and use libfetch support for If-Modified-Since.

This commit is contained in:
Juan RP 2013-01-13 16:27:59 +01:00
parent ea2f2c7297
commit 336897d964

View File

@ -42,6 +42,7 @@
#include "xbps_api_impl.h"
#include "fetch.h"
#include "compat.h"
/**
* @file lib/download.c
@ -56,7 +57,7 @@ print_time(time_t *t)
struct tm tm;
static char buf[255];
localtime_r(t, &tm);
gmtime_r(t, &tm);
strftime(buf, sizeof(buf), "%d %b %Y %H:%M", &tm);
return buf;
}
@ -95,9 +96,10 @@ xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags)
struct url_stat url_st;
struct fetchIO *fio = NULL;
struct timespec ts[2];
off_t bytes_dload = -1;
ssize_t bytes_read = -1, bytes_written = -1;
char buf[4096], *filename, *tempfile;
off_t bytes_dload = 0;
ssize_t bytes_read = 0, bytes_written = 0;
char buf[4096], *filename, *tempfile = NULL;
char fetch_flags[8];
int fd = -1, rv = 0;
bool refetch = false, restart = false;
@ -107,13 +109,19 @@ xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags)
/* Extern vars declared in libfetch */
fetchLastErrCode = 0;
fetchTimeout = xhp->fetch_timeout;
fetchRestartCalls = 1;
if ((url = fetchParseURL(uri)) == NULL)
return -1;
strlcpy(fetch_flags, flags, 7);
/*
* Get the filename specified in URI argument.
*/
filename = strrchr(uri, '/') + 1;
if (filename == NULL)
return -1;
if (filename == NULL) {
rv = -1;
goto out;
}
tempfile = xbps_xasprintf("%s.part", filename);
/*
@ -135,64 +143,26 @@ xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags)
memset(&st, 0, sizeof(st));
if (stat(filename, &st) == 0) {
refetch = true;
restart = true;
url->last_modified = st.st_mtime;
strcat(fetch_flags, "i");
} else {
if (errno != ENOENT) {
rv = -1;
goto out;
}
}
/*
* Prepare stuff for libfetch.
*/
if ((url = fetchParseURL(uri)) == NULL) {
rv = -1;
goto out;
}
/*
* Check if we want to refetch from scratch a file.
*/
if (refetch) {
if (refetch && !restart) {
/* fetch the whole file, filename available */
stp = &st;
/*
* Issue a HEAD request to know size and mtime.
*/
if ((rv = fetchStat(url, &url_st, NULL)) == -1)
goto out;
/*
* If mtime and size match do nothing.
*/
if (restart && url_st.size && url_st.mtime &&
url_st.size == stp->st_size &&
url_st.mtime == stp->st_mtime)
goto out;
/*
* If size match do nothing.
*/
if (restart && url_st.size && url_st.size == st.st_size)
goto out;
/*
* Remove current file (if exists).
*/
restart = false;
url->offset = 0;
/*
* Issue the GET request to refetch.
*/
fio = fetchGet(url, flags);
} else {
/*
* Issue a GET and skip the HEAD request, some servers
* (googlecode.com) return a 404 in HEAD requests!
*/
/* resume transfer, partial file found */
stp = &st_tmpfile;
url->offset = stp->st_size;
fio = fetchXGet(url, &url_st, flags);
}
/*
* Issue a GET request.
*/
fio = fetchXGet(url, &url_st, fetch_flags);
/* debug stuff */
xbps_dbg_printf(xhp, "st.st_size: %zd\n", (ssize_t)stp->st_size);
@ -210,16 +180,10 @@ xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags)
xbps_dbg_printf(xhp, "url_stat.atime: %s\n", print_time(&url_st.atime));
xbps_dbg_printf(xhp, "url_stat.mtime: %s\n", print_time(&url_st.mtime));
if (fio == NULL && fetchLastErrCode != FETCH_OK) {
if (!refetch && restart && fetchLastErrCode == FETCH_UNAVAIL) {
/*
* In HTTP when 416 is returned and length==0
* means that local and remote file size match.
* Because we are requesting offset==st_size! grr,
* stupid http servers...
*/
if (url->length == 0)
goto out;
if (fio == NULL) {
if (fetchLastErrCode == FETCH_UNCHANGED) {
/* Last-Modified matched */
goto out;
}
rv = -1;
goto out;
@ -237,11 +201,6 @@ xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags)
"removing local file and refetching...\n", filename);
(void)remove(tempfile);
restart = false;
} else if (restart && url_st.mtime && url_st.size &&
url_st.size == stp->st_size &&
url_st.mtime == stp->st_mtime) {
/* Local and remote size/mtime match, do nothing. */
goto out;
}
/*
* If restarting, open the file for appending otherwise create it.
@ -288,11 +247,13 @@ xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags)
errno = EIO;
rv = -1;
goto out;
}
if (fd == -1) {
} else if ((bytes_dload + url->offset) != url_st.size) {
xbps_dbg_printf(xhp, "file %s is truncated\n", filename);
errno = EIO;
rv = -1;
goto out;
}
/*
* Let the fetch progress callback know that the file
* has been fetched.
@ -313,6 +274,7 @@ xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags)
/* sync and close fd */
(void)fsync(fd);
(void)close(fd);
fd = -1;
/* File downloaded successfully, rename to destfile */
if (rename(tempfile, filename) == -1) {
@ -324,10 +286,10 @@ xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags)
rv = 1;
out:
if (fd != -1)
(void)close(fd);
if (fio != NULL)
fetchIO_close(fio);
if (fd != -1)
(void)close(fd);
if (url != NULL)
fetchFreeURL(url);
if (tempfile != NULL)