Merge branch 'etag-fix' into 'master'

switch etag cache check to purely client-side

Closes #562

See merge request !574
This commit is contained in:
Peter Serwylo 2017-09-04 20:22:02 +00:00
commit aa2d791531
6 changed files with 23 additions and 74 deletions

View File

@ -89,11 +89,6 @@ public class IndexV1Updater extends RepoUpdater {
if (downloader.isNotFound()) {
return false;
}
if (downloader.isCached()) {
// The index is unchanged since we last read it. We just mark
// everything that came from this repo as being updated.
Utils.debugLog(TAG, "Repo index for " + dataUri + " is up to date (by etag)");
}
hasChanged = downloader.hasChanged();
if (!hasChanged) {

View File

@ -132,12 +132,6 @@ public class RepoUpdater {
downloader.setListener(downloadListener);
downloader.download();
if (downloader.isCached()) {
// The index is unchanged since we last read it. We just mark
// everything that came from this repo as being updated.
Utils.debugLog(TAG, "Repo index for " + indexUrl + " is up to date (by etag)");
}
} catch (IOException e) {
if (downloader != null && downloader.outputFile != null) {
if (!downloader.outputFile.delete()) {

View File

@ -84,14 +84,6 @@ public class BluetoothDownloader extends Downloader {
connection.closeQuietly();
}
@Override
public boolean isCached() {
FileDetails details = getFileDetails();
return details != null &&
details.getCacheTag() != null &&
details.getCacheTag().equals(getCacheTag());
}
@Override
protected void close() {
if (connection != null) {

View File

@ -75,18 +75,12 @@ public abstract class Downloader {
this.cacheTag = cacheTag;
}
boolean wantToCheckCache() {
return cacheTag != null;
}
public abstract boolean hasChanged();
protected abstract int totalDownloadSize();
public abstract void download() throws IOException, InterruptedException;
public abstract boolean isCached();
/**
* @return whether the requested file was not found in the repo (e.g. HTTP 404 Not Found)
*/

View File

@ -1,7 +1,8 @@
package org.fdroid.fdroid.net;
import android.text.TextUtils;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import info.guardianproject.netcipher.NetCipher;
import org.apache.commons.io.FileUtils;
import org.fdroid.fdroid.BuildConfig;
import org.fdroid.fdroid.FDroidApp;
@ -17,18 +18,15 @@ import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import info.guardianproject.netcipher.NetCipher;
public class HttpDownloader extends Downloader {
private static final String TAG = "HttpDownloader";
private static final String HEADER_IF_NONE_MATCH = "If-None-Match";
private static final String HEADER_FIELD_ETAG = "ETag";
private final String username;
private final String password;
private HttpURLConnection connection;
private int statusCode = -1;
private boolean newFileAvailableOnServer;
HttpDownloader(URL url, File destFile)
throws FileNotFoundException, MalformedURLException {
@ -70,24 +68,33 @@ public class HttpDownloader extends Downloader {
}
/**
* Get a remote file, checking the HTTP response code. If 'etag' is not
* {@code null}, it's passed to the server as an If-None-Match header, in
* which case expect a 304 response if nothing changed. In the event of a
* 200 response ONLY, 'retag' (which should be passed empty) may contain
* an etag value for the response, or it may be left empty if none was
* available.
* Get a remote file, checking the HTTP response code and the {@code etag}.
* In order to prevent the {@code etag} from being used as a form of tracking
* cookie, this code never sends the {@code etag} to the server. Instead, it
* uses a {@code HEAD} request to get the {@code etag} from the server, then
* only issues a {@code GET} if the {@code etag} has changed.
*
* @see <a href="http://lucb1e.com/rp/cookielesscookies">Cookieless cookies</a>
*/
@Override
public void download() throws IOException, InterruptedException {
// get the file size from the server
HttpURLConnection tmpConn = getConnection();
tmpConn.setRequestMethod("HEAD");
String etag = tmpConn.getHeaderField(HEADER_FIELD_ETAG);
int contentLength = -1;
int statusCode = tmpConn.getResponseCode();
tmpConn.disconnect();
newFileAvailableOnServer = false;
switch (statusCode) {
case 200:
contentLength = tmpConn.getContentLength();
if (!TextUtils.isEmpty(etag) && etag.equals(cacheTag)) {
Utils.debugLog(TAG, sourceUrl + " is cached, not downloading");
return;
}
newFileAvailableOnServer = true;
break;
case 404:
notFound = true;
@ -96,6 +103,7 @@ public class HttpDownloader extends Downloader {
Utils.debugLog(TAG, "HEAD check of " + sourceUrl + " returned " + statusCode + ": "
+ tmpConn.getResponseMessage());
}
boolean resumable = false;
long fileLength = outputFile.length();
if (fileLength > contentLength) {
@ -106,7 +114,9 @@ public class HttpDownloader extends Downloader {
resumable = true;
}
setupConnection(resumable);
doDownload(resumable);
Utils.debugLog(TAG, "downloading " + sourceUrl + " (is resumable: " + resumable + ")");
downloadFromStream(8192, resumable);
cacheTag = connection.getHeaderField(HEADER_FIELD_ETAG);
}
private boolean isSwapUrl() {
@ -147,37 +157,6 @@ public class HttpDownloader extends Downloader {
}
}
private void doDownload(boolean resumable) throws IOException, InterruptedException {
if (wantToCheckCache()) {
setupCacheCheck();
Utils.debugLog(TAG, "Checking cached status of " + sourceUrl);
statusCode = connection.getResponseCode();
}
if (isCached()) {
Utils.debugLog(TAG, sourceUrl + " is cached, so not downloading (HTTP " + statusCode + ")");
} else {
Utils.debugLog(TAG, "Need to download " + sourceUrl + " (is resumable: " + resumable + ")");
downloadFromStream(8192, resumable);
updateCacheCheck();
}
}
@Override
public boolean isCached() {
return wantToCheckCache() && statusCode == 304;
}
private void setupCacheCheck() {
if (cacheTag != null) {
connection.setRequestProperty(HEADER_IF_NONE_MATCH, cacheTag);
}
}
private void updateCacheCheck() {
cacheTag = connection.getHeaderField(HEADER_FIELD_ETAG);
}
// Testing in the emulator for me, showed that figuring out the
// filesize took about 1 to 1.5 seconds.
// To put this in context, downloading a repo of:
@ -193,7 +172,7 @@ public class HttpDownloader extends Downloader {
@Override
public boolean hasChanged() {
return this.statusCode != 304;
return newFileAvailableOnServer;
}
@Override

View File

@ -49,9 +49,4 @@ public class LocalFileDownloader extends Downloader {
notFound = true;
}
}
@Override
public boolean isCached() {
return false;
}
}