From 053b6f15442d0a21a773a0c5477ae9f1823dcdf7 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Sat, 25 May 2019 20:14:08 -0400 Subject: [PATCH] Adopt idiomatic Kotlin in HttpLoggingInterceptor --- .../okhttp3/logging/HttpLoggingInterceptor.kt | 67 ++++++------------- .../src/main/java/okhttp3/logging/utf8.kt | 44 ++++++++++++ ...torKotlinTest.kt => IsProbablyUtf8Test.kt} | 19 +++--- 3 files changed, 75 insertions(+), 55 deletions(-) create mode 100644 okhttp-logging-interceptor/src/main/java/okhttp3/logging/utf8.kt rename okhttp-logging-interceptor/src/test/java/okhttp3/logging/{HttpLoggingInterceptorKotlinTest.kt => IsProbablyUtf8Test.kt} (56%) diff --git a/okhttp-logging-interceptor/src/main/java/okhttp3/logging/HttpLoggingInterceptor.kt b/okhttp-logging-interceptor/src/main/java/okhttp3/logging/HttpLoggingInterceptor.kt index 94b222bd6..f9bc91fa9 100644 --- a/okhttp-logging-interceptor/src/main/java/okhttp3/logging/HttpLoggingInterceptor.kt +++ b/okhttp-logging-interceptor/src/main/java/okhttp3/logging/HttpLoggingInterceptor.kt @@ -24,7 +24,6 @@ import okhttp3.internal.platform.Platform import okhttp3.internal.platform.Platform.Companion.INFO import okio.Buffer import okio.GzipSource -import java.io.EOFException import java.io.IOException import java.nio.charset.Charset import java.nio.charset.StandardCharsets.UTF_8 @@ -44,7 +43,8 @@ class HttpLoggingInterceptor @JvmOverloads constructor( @Volatile private var headersToRedact = emptySet() - @Volatile @set:JvmName("-deprecated_setLevel") var level = Level.NONE + @set:JvmName("level") + @Volatile var level = Level.NONE enum class Level { /** No logs. */ @@ -129,16 +129,24 @@ class HttpLoggingInterceptor @JvmOverloads constructor( fun redactHeader(name: String) { val newHeadersToRedact = TreeSet(String.CASE_INSENSITIVE_ORDER) - newHeadersToRedact.addAll(headersToRedact) - newHeadersToRedact.add(name) + newHeadersToRedact += headersToRedact + newHeadersToRedact += name headersToRedact = newHeadersToRedact } + @Deprecated( + message = "Moved to var. Replace setLevel(...) with level(...) to fix Java", + replaceWith = ReplaceWith(expression = "apply { this.level = level }"), + level = DeprecationLevel.WARNING) fun setLevel(level: Level) = apply { this.level = level } - @JvmName("-deprecated_getLevel") + @JvmName("-deprecated_level") + @Deprecated( + message = "moved to var", + replaceWith = ReplaceWith(expression = "level"), + level = DeprecationLevel.WARNING) fun getLevel(): Level = level @Throws(IOException::class) @@ -176,16 +184,13 @@ class HttpLoggingInterceptor @JvmOverloads constructor( } val headers = request.headers - var i = 0 - val count = headers.size - while (i < count) { + for (i in 0 until headers.size) { val name = headers.name(i) // Skip headers from the request body as they are explicitly logged above. - if (!"Content-Type".equals(name, ignoreCase = true) && !"Content-Length".equals(name, - ignoreCase = true)) { + if (!"Content-Type".equals(name, ignoreCase = true) && + !"Content-Length".equals(name, ignoreCase = true)) { logHeader(headers, i) } - i++ } if (!logBody || requestBody == null) { @@ -202,7 +207,7 @@ class HttpLoggingInterceptor @JvmOverloads constructor( val charset: Charset = contentType?.charset(UTF_8) ?: UTF_8 logger.log("") - if (buffer.isUtf8()) { + if (buffer.isProbablyUtf8()) { logger.log(buffer.readString(charset)) logger.log("--> END ${request.method} (${requestBody.contentLength()}-byte body)") } else { @@ -256,7 +261,7 @@ class HttpLoggingInterceptor @JvmOverloads constructor( val contentType = responseBody.contentType() val charset: Charset = contentType?.charset(UTF_8) ?: UTF_8 - if (!buffer.isUtf8()) { + if (!buffer.isProbablyUtf8()) { logger.log("") logger.log("<-- END HTTP (binary ${buffer.size}-byte body omitted)") return response @@ -283,37 +288,9 @@ class HttpLoggingInterceptor @JvmOverloads constructor( logger.log(headers.name(i) + ": " + value) } - companion object { - /** - * Returns true if the body in question probably contains human readable text. Uses a small - * sample of code points to detect unicode control characters commonly used in binary file - * signatures. - */ - internal fun Buffer.isUtf8(): Boolean { - try { - val prefix = Buffer() - val byteCount = size.coerceAtMost(64) - copyTo(prefix, 0, byteCount) - for (i in 0 until 16) { - if (prefix.exhausted()) { - break - } - val codePoint = prefix.readUtf8CodePoint() - if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) { - return false - } - } - return true - } catch (e: EOFException) { - return false // Truncated UTF-8 sequence. - } - } - - private fun bodyHasUnknownEncoding(headers: Headers): Boolean { - val contentEncoding = headers["Content-Encoding"] - return (contentEncoding != null && - !contentEncoding.equals("identity", ignoreCase = true) && - !contentEncoding.equals("gzip", ignoreCase = true)) - } + private fun bodyHasUnknownEncoding(headers: Headers): Boolean { + val contentEncoding = headers["Content-Encoding"] ?: return false + return !contentEncoding.equals("identity", ignoreCase = true) && + !contentEncoding.equals("gzip", ignoreCase = true) } } diff --git a/okhttp-logging-interceptor/src/main/java/okhttp3/logging/utf8.kt b/okhttp-logging-interceptor/src/main/java/okhttp3/logging/utf8.kt new file mode 100644 index 000000000..d8ebe52e1 --- /dev/null +++ b/okhttp-logging-interceptor/src/main/java/okhttp3/logging/utf8.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 Square, Inc. + * + * 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 okhttp3.logging + +import okio.Buffer +import java.io.EOFException + +/** + * Returns true if the body in question probably contains human readable text. Uses a small + * sample of code points to detect unicode control characters commonly used in binary file + * signatures. + */ +internal fun Buffer.isProbablyUtf8(): Boolean { + try { + val prefix = Buffer() + val byteCount = size.coerceAtMost(64) + copyTo(prefix, 0, byteCount) + for (i in 0 until 16) { + if (prefix.exhausted()) { + break + } + val codePoint = prefix.readUtf8CodePoint() + if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) { + return false + } + } + return true + } catch (_: EOFException) { + return false // Truncated UTF-8 sequence. + } +} diff --git a/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorKotlinTest.kt b/okhttp-logging-interceptor/src/test/java/okhttp3/logging/IsProbablyUtf8Test.kt similarity index 56% rename from okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorKotlinTest.kt rename to okhttp-logging-interceptor/src/test/java/okhttp3/logging/IsProbablyUtf8Test.kt index 05d63c968..c31d99012 100644 --- a/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorKotlinTest.kt +++ b/okhttp-logging-interceptor/src/test/java/okhttp3/logging/IsProbablyUtf8Test.kt @@ -15,19 +15,18 @@ */ package okhttp3.logging -import okhttp3.logging.HttpLoggingInterceptor.Companion.isUtf8 import okio.Buffer import org.assertj.core.api.Assertions.assertThat import org.junit.Test -class HttpLoggingInterceptorKotlinTest { - @Test fun isPlaintext() { - assertThat(Buffer().isUtf8()).isTrue() - assertThat(Buffer().writeUtf8("abc").isUtf8()).isTrue() - assertThat(Buffer().writeUtf8("new\r\nlines").isUtf8()).isTrue() - assertThat(Buffer().writeUtf8("white\t space").isUtf8()).isTrue() - assertThat(Buffer().writeByte(0x80).isUtf8()).isTrue() - assertThat(Buffer().writeByte(0x00).isUtf8()).isFalse() - assertThat(Buffer().writeByte(0xc0).isUtf8()).isFalse() +class IsProbablyUtf8Test { + @Test fun isProbablyUtf8() { + assertThat(Buffer().isProbablyUtf8()).isTrue() + assertThat(Buffer().writeUtf8("abc").isProbablyUtf8()).isTrue() + assertThat(Buffer().writeUtf8("new\r\nlines").isProbablyUtf8()).isTrue() + assertThat(Buffer().writeUtf8("white\t space").isProbablyUtf8()).isTrue() + assertThat(Buffer().writeByte(0x80).isProbablyUtf8()).isTrue() + assertThat(Buffer().writeByte(0x00).isProbablyUtf8()).isFalse() + assertThat(Buffer().writeByte(0xc0).isProbablyUtf8()).isFalse() } }