cache all downloads based on canonical URL, not download URL

This makes the download cache be shared across all mirrors used to download
rather than having a cache per-mirror.
This commit is contained in:
Hans-Christoph Steiner 2019-02-19 14:26:13 +01:00
parent dd14b9e315
commit 14b4a7e00a
4 changed files with 15 additions and 13 deletions

View File

@ -115,7 +115,8 @@ public class ApkCache {
/**
* Get the full path for where an APK URL will be downloaded into.
*/
public static SanitizedFile getApkDownloadPath(Context context, Uri uri) {
public static SanitizedFile getApkDownloadPath(Context context, String urlString) {
Uri uri = Uri.parse(urlString);
File dir = new File(getApkCacheDir(context), uri.getHost() + "-" + uri.getPort());
if (!dir.exists()) {
dir.mkdirs();

View File

@ -209,7 +209,7 @@ public class InstallManagerService extends Service {
getObb(urlString, apk.getMainObbUrl(), apk.getMainObbFile(), apk.obbMainFileSha256);
getObb(urlString, apk.getPatchObbUrl(), apk.getPatchObbFile(), apk.obbPatchFileSha256);
File apkFilePath = ApkCache.getApkDownloadPath(this, intent.getData());
File apkFilePath = ApkCache.getApkDownloadPath(this, apk.getUrl());
long apkFileSize = apkFilePath.length();
if (!apkFilePath.exists() || apkFileSize < apk.size) {
Utils.debugLog(TAG, "download " + urlString + " " + apkFilePath);

View File

@ -198,10 +198,10 @@ public class DownloaderService extends Service {
*/
private void handleIntent(Intent intent) {
final Uri uri = intent.getData();
final SanitizedFile localFile = ApkCache.getApkDownloadPath(this, uri);
long repoId = intent.getLongExtra(Downloader.EXTRA_REPO_ID, 0);
String originalUrlString = intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL);
sendBroadcast(uri, Downloader.ACTION_STARTED, localFile, repoId, originalUrlString);
String canonicalUrlString = intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL);
final SanitizedFile localFile = ApkCache.getApkDownloadPath(this, canonicalUrlString);
sendBroadcast(uri, Downloader.ACTION_STARTED, localFile, repoId, canonicalUrlString);
try {
downloader = DownloaderFactory.create(this, uri, localFile);
@ -219,22 +219,22 @@ public class DownloaderService extends Service {
downloader.download();
if (downloader.isNotFound()) {
sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, localFile, getString(R.string.download_404),
repoId, originalUrlString);
repoId, canonicalUrlString);
} else {
sendBroadcast(uri, Downloader.ACTION_COMPLETE, localFile, repoId, originalUrlString);
sendBroadcast(uri, Downloader.ACTION_COMPLETE, localFile, repoId, canonicalUrlString);
}
} catch (InterruptedException e) {
sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, localFile, repoId, originalUrlString);
sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, localFile, repoId, canonicalUrlString);
} catch (ConnectException | HttpRetryException | NoRouteToHostException | SocketTimeoutException
| SSLHandshakeException | SSLKeyException | SSLPeerUnverifiedException | SSLProtocolException
| ProtocolException | UnknownHostException e) {
// if the above list of exceptions changes, also change it in IndexV1Updater.update()
Log.e(TAG, e.getLocalizedMessage());
sendBroadcast(uri, Downloader.ACTION_CONNECTION_FAILED, localFile, repoId, originalUrlString);
sendBroadcast(uri, Downloader.ACTION_CONNECTION_FAILED, localFile, repoId, canonicalUrlString);
} catch (IOException e) {
e.printStackTrace();
sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, localFile,
e.getLocalizedMessage(), repoId, originalUrlString);
e.getLocalizedMessage(), repoId, canonicalUrlString);
} finally {
if (downloader != null) {
downloader.close();

View File

@ -27,7 +27,6 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.nostra13.universalimageloader.core.ImageLoader;
import org.fdroid.fdroid.views.AppDetailsActivity;
import org.fdroid.fdroid.AppUpdateStatusManager;
import org.fdroid.fdroid.AppUpdateStatusManager.AppUpdateStatus;
import org.fdroid.fdroid.R;
@ -39,6 +38,7 @@ import org.fdroid.fdroid.installer.ApkCache;
import org.fdroid.fdroid.installer.InstallManagerService;
import org.fdroid.fdroid.installer.Installer;
import org.fdroid.fdroid.installer.InstallerFactory;
import org.fdroid.fdroid.views.AppDetailsActivity;
import org.fdroid.fdroid.views.updates.DismissResult;
import java.io.File;
@ -483,8 +483,8 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder {
}
if (currentStatus != null && currentStatus.status == AppUpdateStatusManager.Status.ReadyToInstall) {
Uri apkDownloadUri = Uri.parse(currentStatus.apk.getUrl());
File apkFilePath = ApkCache.getApkDownloadPath(activity, apkDownloadUri);
String urlString = currentStatus.apk.getUrl();
File apkFilePath = ApkCache.getApkDownloadPath(activity, urlString);
Utils.debugLog(TAG, "skip download, we have already downloaded " + currentStatus.apk.getUrl() +
" to " + apkFilePath);
@ -505,6 +505,7 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder {
}
};
Uri apkDownloadUri = Uri.parse(urlString);
broadcastManager.registerReceiver(receiver, Installer.getInstallIntentFilter(apkDownloadUri));
Installer installer = InstallerFactory.create(activity, currentStatus.apk);
installer.installPackage(Uri.parse(apkFilePath.toURI().toString()), apkDownloadUri);