Limit download size for icons to 5 MB

This commit is contained in:
Philipp Heckel 2022-09-10 23:18:11 -04:00
parent 89d12cb3ce
commit a66fd62374

View file

@ -2,15 +2,10 @@ package io.heckel.ntfy.msg
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.webkit.MimeTypeMap
import android.widget.Toast
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.work.Worker import androidx.work.Worker
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import io.heckel.ntfy.BuildConfig import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application import io.heckel.ntfy.app.Application
import io.heckel.ntfy.db.* import io.heckel.ntfy.db.*
import io.heckel.ntfy.util.Log import io.heckel.ntfy.util.Log
@ -46,16 +41,14 @@ class DownloadIconWorker(private val context: Context, params: WorkerParameters)
icon = notification.icon ?: return Result.failure() icon = notification.icon ?: return Result.failure()
try { try {
val iconFile = createIconFile(icon) val iconFile = createIconFile(icon)
val yesterdayTimestamp = Date().time - 1000*60*60*24 // now Unix timestamp - 24 hours val yesterdayTimestamp = Date().time - MAX_CACHE_MILLIS
if (!iconFile.exists() || iconFile.lastModified() < yesterdayTimestamp) { if (!iconFile.exists() || iconFile.lastModified() < yesterdayTimestamp) {
downloadIcon(iconFile) downloadIcon(iconFile)
} else { } else {
Log.d(TAG, "Loading icon from cache: ${icon.url}") Log.d(TAG, "Loading icon from cache: $iconFile")
val iconUri = createIconUri(iconFile) val iconUri = createIconUri(iconFile)
this.uri = iconUri // Required for cleanup in onStopped() this.uri = iconUri // Required for cleanup in onStopped()
save(icon.copy( save(icon.copy(contentUri = iconUri.toString()))
contentUri = iconUri.toString()
))
} }
} catch (e: Exception) { } catch (e: Exception) {
failed(e) failed(e)
@ -70,18 +63,16 @@ class DownloadIconWorker(private val context: Context, params: WorkerParameters)
private fun downloadIcon(iconFile: File) { private fun downloadIcon(iconFile: File) {
Log.d(TAG, "Downloading icon from ${icon.url}") Log.d(TAG, "Downloading icon from ${icon.url}")
try { try {
val request = Request.Builder() val request = Request.Builder()
.url(icon.url) .url(icon.url)
.addHeader("User-Agent", ApiService.USER_AGENT) .addHeader("User-Agent", ApiService.USER_AGENT)
.build() .build()
client.newCall(request).execute().use { response -> client.newCall(request).execute().use { response ->
Log.d(TAG, "Download: headers received: $response") Log.d(TAG, "Headers received: $response, Content-Length: ${response.headers["Content-Length"]}")
if (!response.isSuccessful || response.body == null) { if (!response.isSuccessful || response.body == null) {
throw Exception("Unexpected response: ${response.code}") throw Exception("Unexpected response: ${response.code}")
} } else if (shouldAbortDownload(response)) {
if (shouldAbortDownload(response)) {
Log.d(TAG, "Aborting download: Content-Length is larger than auto-download setting") Log.d(TAG, "Aborting download: Content-Length is larger than auto-download setting")
return return
} }
@ -106,7 +97,6 @@ class DownloadIconWorker(private val context: Context, params: WorkerParameters)
bytes = fileIn.read(buffer) bytes = fileIn.read(buffer)
} }
} }
// TODO: Resize icon if >5MB, so it can be previewed. Right now it'll just not be shown.
Log.d(TAG, "Icon download: successful response, proceeding with download") Log.d(TAG, "Icon download: successful response, proceeding with download")
save(icon.copy(contentUri = uri.toString())) save(icon.copy(contentUri = uri.toString()))
} }
@ -145,9 +135,9 @@ class DownloadIconWorker(private val context: Context, params: WorkerParameters)
private fun getDownloadLimit(): Long { private fun getDownloadLimit(): Long {
return if (repository.getAutoDownloadMaxSize() != Repository.AUTO_DOWNLOAD_NEVER && repository.getAutoDownloadMaxSize() != Repository.AUTO_DOWNLOAD_ALWAYS) { return if (repository.getAutoDownloadMaxSize() != Repository.AUTO_DOWNLOAD_NEVER && repository.getAutoDownloadMaxSize() != Repository.AUTO_DOWNLOAD_ALWAYS) {
repository.getAutoDownloadMaxSize() Math.min(repository.getAutoDownloadMaxSize(), MAX_ICON_DOWNLOAD_BYTES)
} else { } else {
MAX_ICON_DOWNLOAD_SIZE.toLong() DEFAULT_MAX_ICON_DOWNLOAD_BYTES
} }
} }
@ -167,10 +157,12 @@ class DownloadIconWorker(private val context: Context, params: WorkerParameters)
companion object { companion object {
const val INPUT_DATA_ID = "id" const val INPUT_DATA_ID = "id"
const val FILE_PROVIDER_AUTHORITY = BuildConfig.APPLICATION_ID + ".provider" // See AndroidManifest.xml const val FILE_PROVIDER_AUTHORITY = BuildConfig.APPLICATION_ID + ".provider" // See AndroidManifest.xml
const val MAX_ICON_DOWNLOAD_SIZE = 300000 const val DEFAULT_MAX_ICON_DOWNLOAD_BYTES = 307_200L // 300 KB
const val MAX_ICON_DOWNLOAD_BYTES = 5_242_880L // 5 MB
const val MAX_CACHE_MILLIS = 1000*60*60*24 // 24 hours
const val ICON_CACHE_DIR = "icons"
private const val TAG = "NtfyIconDownload" private const val TAG = "NtfyIconDownload"
const val ICON_CACHE_DIR = "icons"
private const val BUFFER_SIZE = 8 * 1024 private const val BUFFER_SIZE = 8 * 1024
} }
} }