From 5833ae6677d98a6240681ce6f4f8ea335bc24d85 Mon Sep 17 00:00:00 2001 From: Anthony Restaino Date: Tue, 6 Apr 2021 13:50:23 -0400 Subject: [PATCH 1/2] Allow non ascii characters as a user agent --- api-core/build.gradle | 2 + .../interceptor/UserAgentHeaderInterceptor.kt | 5 +- .../UserAgentHeaderInterceptorTest.kt | 57 +++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 api-core/src/test/java/com/vimeo/networking2/internal/interceptor/UserAgentHeaderInterceptorTest.kt 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..a26f2c53e 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,9 @@ 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().run { + newBuilder().headers(headers().newBuilder().addUnsafeNonAscii(HEADER_USER_AGENT, userAgent).build()).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²" + ) + } +} From dc14643e1908a069e3d44665f61794270d0a26e8 Mon Sep 17 00:00:00 2001 From: Anthony Restaino Date: Thu, 8 Apr 2021 09:15:17 -0400 Subject: [PATCH 2/2] Improve readability of the intercept function --- .../internal/interceptor/UserAgentHeaderInterceptor.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 a26f2c53e..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,10 @@ 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().run { - newBuilder().headers(headers().newBuilder().addUnsafeNonAscii(HEADER_USER_AGENT, userAgent).build()).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 {