diff --git a/api-core/build.gradle b/api-core/build.gradle index 3b5d6ea78..cc3a4ca35 100644 --- a/api-core/build.gradle +++ b/api-core/build.gradle @@ -22,6 +22,8 @@ dependencies { // Okio used by Moshi implementation "com.squareup.okio:okio:$okioVersion" + // Test dependencies + testImplementation "junit:junit:$junitVersion" } compileKotlin { diff --git a/api-core/src/main/java/com/vimeo/networking2/internal/interceptor/UserAgentHeaderInterceptor.kt b/api-core/src/main/java/com/vimeo/networking2/internal/interceptor/UserAgentHeaderInterceptor.kt index 12f2eb3f8..4e6188a1d 100644 --- a/api-core/src/main/java/com/vimeo/networking2/internal/interceptor/UserAgentHeaderInterceptor.kt +++ b/api-core/src/main/java/com/vimeo/networking2/internal/interceptor/UserAgentHeaderInterceptor.kt @@ -32,8 +32,11 @@ import okhttp3.Response * @param userAgent The user agent that should be sent with every request. */ class UserAgentHeaderInterceptor(private val userAgent: String) : Interceptor { - override fun intercept(chain: Interceptor.Chain): Response = - chain.proceed(chain.request().newBuilder().header(HEADER_USER_AGENT, userAgent).build()) + override fun intercept(chain: Interceptor.Chain): Response = chain.proceed(chain.request().let { request -> + val updatedHeaders = request.headers().newBuilder().addUnsafeNonAscii(HEADER_USER_AGENT, userAgent).build() + + request.newBuilder().headers(updatedHeaders).build() + }) companion object { private const val HEADER_USER_AGENT = "User-Agent" diff --git a/api-core/src/test/java/com/vimeo/networking2/internal/interceptor/UserAgentHeaderInterceptorTest.kt b/api-core/src/test/java/com/vimeo/networking2/internal/interceptor/UserAgentHeaderInterceptorTest.kt new file mode 100644 index 000000000..9daa66f2d --- /dev/null +++ b/api-core/src/test/java/com/vimeo/networking2/internal/interceptor/UserAgentHeaderInterceptorTest.kt @@ -0,0 +1,57 @@ +package com.vimeo.networking2.internal.interceptor + +import okhttp3.Call +import okhttp3.Connection +import okhttp3.Interceptor +import okhttp3.Protocol +import okhttp3.Request +import okhttp3.Response +import org.junit.Assert.assertEquals +import org.junit.Test +import java.util.concurrent.TimeUnit + +class UserAgentHeaderInterceptorTest { + + private fun createChain(): Interceptor.Chain = object : Interceptor.Chain { + override fun request(): Request = Request.Builder().url("https://vimeo.com").build() + + override fun proceed(request: Request): Response = Response.Builder() + .request(request) + .protocol(Protocol.HTTP_2) + .code(200) + .message("hello") + .build() + + override fun connection(): Connection = error("Unsupported") + + override fun call(): Call = error("Unsupported") + + override fun connectTimeoutMillis(): Int = error("Unsupported") + + override fun withConnectTimeout(timeout: Int, unit: TimeUnit): Interceptor.Chain = error("Unsupported") + + override fun readTimeoutMillis(): Int = error("Unsupported") + + override fun withReadTimeout(timeout: Int, unit: TimeUnit): Interceptor.Chain = error("Unsupported") + + override fun writeTimeoutMillis(): Int = error("Unsupported") + + override fun withWriteTimeout(timeout: Int, unit: TimeUnit): Interceptor.Chain = error("Unsupported") + } + + @Test + fun `normal characters are supported`() { + assertEquals( + UserAgentHeaderInterceptor(userAgent = "test").intercept(createChain()).request().header("User-Agent"), + "test" + ) + } + + @Test + fun `special characters are supported`() { + assertEquals( + UserAgentHeaderInterceptor(userAgent = "test²").intercept(createChain()).request().header("User-Agent"), + "test²" + ) + } +}