diff --git a/mobile/android/app/build.gradle b/mobile/android/app/build.gradle index 7ea6f4e2da..f4cd8cb1ff 100644 --- a/mobile/android/app/build.gradle +++ b/mobile/android/app/build.gradle @@ -48,6 +48,7 @@ android { } buildFeatures { + buildConfig true compose true } diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImagesImpl.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImagesImpl.kt index ad45723171..42eed0f4ba 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImagesImpl.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImagesImpl.kt @@ -7,6 +7,7 @@ import android.graphics.ColorSpace import android.graphics.ImageDecoder import android.os.Build import android.os.CancellationSignal +import app.alextran.immich.BuildConfig import app.alextran.immich.core.SSLConfig import com.google.net.cronet.okhttptransport.CronetCallFactory import okhttp3.Call @@ -24,12 +25,27 @@ import java.nio.ByteBuffer import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.Executors import java.util.concurrent.TimeUnit +import okhttp3.Interceptor data class RemoteRequest( val callback: (Result>) -> Unit, val cancellationSignal: CancellationSignal, ) +class UserAgentInterceptor : Interceptor { + companion object { + const val USER_AGENT = "Immich_Android_${BuildConfig.VERSION_NAME}" + } + + override fun intercept(chain: Interceptor.Chain): Response { + return chain.proceed( + chain.request().newBuilder() + .header("User-Agent", USER_AGENT) + .build() + ) + } +} + class RemoteImagesImpl(context: Context) : RemoteImageApi { private val requestMap = ConcurrentHashMap() private val lockedBitmaps = ConcurrentHashMap() @@ -96,6 +112,7 @@ class RemoteImagesImpl(context: Context) : RemoteImageApi { .enableBrotli(true) .setStoragePath(storageDir.absolutePath) .enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK, CACHE_SIZE_BYTES) + .setUserAgent(UserAgentInterceptor.USER_AGENT) .build() .also { cronetEngine = it } @@ -111,6 +128,7 @@ class RemoteImagesImpl(context: Context) : RemoteImageApi { ) val builder = OkHttpClient.Builder() + .addInterceptor(UserAgentInterceptor()) .dispatcher(Dispatcher().apply { maxRequestsPerHost = MAX_REQUESTS_PER_HOST }) .connectionPool(connectionPool) diff --git a/mobile/ios/Runner/Images/RemoteImagesImpl.swift b/mobile/ios/Runner/Images/RemoteImagesImpl.swift index 78b6cca996..f3433bd385 100644 --- a/mobile/ios/Runner/Images/RemoteImagesImpl.swift +++ b/mobile/ios/Runner/Images/RemoteImagesImpl.swift @@ -20,6 +20,8 @@ class RemoteImageApiImpl: NSObject, RemoteImageApi { private static let delegate = RemoteImageApiDelegate() static let session = { let config = URLSessionConfiguration.default + let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "unknown" + config.httpAdditionalHeaders = ["User-Agent": "Immich_iOS_\(version)"] let thumbnailPath = FileManager.default.temporaryDirectory.appendingPathComponent("thumbnails", isDirectory: true) try! FileManager.default.createDirectory(at: thumbnailPath, withIntermediateDirectories: true) config.urlCache = URLCache(