Configure user agent for all network request (#677)

This commit is contained in:
Benoit Marty 2023-06-26 21:43:19 +02:00 committed by Benoit Marty
parent 469b54f204
commit f4b4e4d316
12 changed files with 183 additions and 2 deletions

View file

@ -23,6 +23,7 @@ import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.network.interceptors.FormattedJsonHttpLogger
import io.element.android.libraries.network.interceptors.UserAgentInterceptor
import kotlinx.serialization.json.Json
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
@ -35,10 +36,12 @@ object NetworkModule {
@SingleIn(AppScope::class)
fun providesOkHttpClient(
buildMeta: BuildMeta,
userAgentInterceptor: UserAgentInterceptor,
): OkHttpClient = OkHttpClient.Builder().apply {
connectTimeout(30, TimeUnit.SECONDS)
readTimeout(60, TimeUnit.SECONDS)
writeTimeout(60, TimeUnit.SECONDS)
addInterceptor(userAgentInterceptor)
if (buildMeta.isDebuggable) addInterceptor(providesHttpLoggingInterceptor())
}.build()

View file

@ -0,0 +1,22 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.network.headers
internal object HttpHeaders {
const val Authorization = "Authorization"
const val UserAgent = "User-Agent"
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.network.interceptors
import io.element.android.libraries.network.headers.HttpHeaders
import io.element.android.libraries.network.useragent.UserAgentProvider
import okhttp3.Interceptor
import okhttp3.Response
import javax.inject.Inject
class UserAgentInterceptor @Inject constructor(
private val userAgentProvider: UserAgentProvider,
) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val newRequest = chain.request()
.newBuilder()
.header(HttpHeaders.UserAgent, userAgentProvider.provide())
.build()
return chain.proceed(newRequest)
}
}

View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.network.useragent
import android.os.Build
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.SingleIn
import javax.inject.Inject
@SingleIn(AppScope::class)
@ContributesBinding(AppScope::class)
class DefaultUserAgentProvider @Inject constructor(
private val buildMeta: BuildMeta,
) : UserAgentProvider {
private val userAgent: String by lazy { buildUserAgent() }
override fun provide(): String = userAgent
/**
* Create an user agent with the application version.
* Ex: Element X/1.5.0 (Xiaomi Mi 9T; Android 11; RKQ1.200826.002; Sdk 0.1.0)
*/
private fun buildUserAgent(): String {
val appName = buildMeta.applicationName
val appVersion = buildMeta.versionName
val deviceManufacturer = Build.MANUFACTURER
val deviceModel = Build.MODEL
val androidVersion = Build.VERSION.RELEASE
val deviceBuildId = Build.DISPLAY
val matrixSdkVersion = "TODO"
return buildString {
append(appName)
append("/")
append(appVersion)
append(" (")
append(deviceManufacturer)
append(" ")
append(deviceModel)
append("; ")
append("Android ")
append(androidVersion)
append("; ")
append(deviceBuildId)
append("; ")
append("Sdk ")
append(matrixSdkVersion)
append(")")
}
}
}

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.network.useragent
class SimpleUserAgentProvider(
private val userAgent: String = "User agent"
) : UserAgentProvider {
override fun provide(): String = userAgent
}

View file

@ -0,0 +1,21 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.network.useragent
interface UserAgentProvider {
fun provide(): String
}