summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Wilson <jwilson@squareup.com>2024-04-01 21:44:15 -0400
committerGitHub <noreply@github.com>2024-04-01 21:44:15 -0400
commit4c6240137351cf2a4c65c74c9e83cb04fcd81d70 (patch)
treec68fa66bf78b947fcdb9a6ba4e0f06a997c64735
parent3cde79c505c0c936d1d4365b79073600682d1d0d (diff)
downloadokhttp4-4c6240137351cf2a4c65c74c9e83cb04fcd81d70.tar.gz
Tidy the tls survey code (#8324)
* Tidy the tls survey code * Spotless
-rw-r--r--samples/tlssurvey/src/main/kotlin/okhttp3/survey/CipherSuiteSurvey.kt9
-rw-r--r--samples/tlssurvey/src/main/kotlin/okhttp3/survey/Clients.kt78
-rw-r--r--samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt18
-rw-r--r--samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt121
-rw-r--r--samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsApi.kt (renamed from samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Record.kt)15
-rw-r--r--samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsClient.kt (renamed from samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsScrape.kt)35
-rw-r--r--samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsService.kt12
-rw-r--r--samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/UserAgentCapabilities.kt15
-rw-r--r--samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Client.kt4
-rw-r--r--samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/SuiteId.kt2
-rw-r--r--samples/tlssurvey/src/main/resources/okhttp_3.11.txt (renamed from samples/tlssurvey/src/main/resources/okhttp_3_11.txt)0
-rw-r--r--samples/tlssurvey/src/main/resources/okhttp_3.13.txt (renamed from samples/tlssurvey/src/main/resources/okhttp_3_13.txt)0
-rw-r--r--samples/tlssurvey/src/main/resources/okhttp_3.14.txt (renamed from samples/tlssurvey/src/main/resources/okhttp_3_14.txt)0
-rw-r--r--samples/tlssurvey/src/main/resources/okhttp_3.9.txt (renamed from samples/tlssurvey/src/main/resources/okhttp_3_9.txt)0
-rw-r--r--samples/tlssurvey/src/main/resources/okhttp_4.10.txt (renamed from samples/tlssurvey/src/main/resources/okhttp_4_10.txt)0
15 files changed, 153 insertions, 156 deletions
diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/CipherSuiteSurvey.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/CipherSuiteSurvey.kt
index 51d619958..f6036b614 100644
--- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/CipherSuiteSurvey.kt
+++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/CipherSuiteSurvey.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Square, Inc.
+ * Copyright (C) 2022 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,13 +46,6 @@ class CipherSuiteSurvey(
val index = client.enabled.indexOfFirst { it.matches(suiteId) }
if (index != -1) {
print(index + 1)
- } else if (client.supported.find { it.matches(suiteId) } != null) {
- // Not currently supported, as since 3.9.x we filter to a list
- // that is a subset of the platforms.
- // The correct answer for developers who override ConnectionSpec,
- // it would be the platform defaults, so look at Java and Android
- // for the answers.
- print("□")
}
}
println()
diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Clients.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Clients.kt
index ea3140619..3c8ba19ae 100644
--- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Clients.kt
+++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Clients.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Square, Inc.
+ * Copyright (C) 2022 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
*/
package okhttp3.survey
-import java.io.IOException
import javax.net.ssl.SSLSocket
import javax.net.ssl.SSLSocketFactory
import okhttp3.ConnectionSpec
@@ -27,39 +26,49 @@ import okio.Path.Companion.toPath
import org.conscrypt.Conscrypt
fun currentOkHttp(ianaSuites: IanaSuites): Client {
- val supportedSuites =
- buildList {
- for (suite in ConnectionSpec.COMPATIBLE_TLS.cipherSuites!!) {
- add(ianaSuites.fromJavaName(suite.javaName))
- }
- }
- val enabledSuites =
- buildList {
- for (suite in ConnectionSpec.MODERN_TLS.cipherSuites!!) {
- add(ianaSuites.fromJavaName(suite.javaName))
- }
- }
-
- return Client("OkHttp", OkHttp.VERSION, null, enabledSuites, supportedSuites)
+ return Client(
+ userAgent = "OkHttp",
+ version = OkHttp.VERSION,
+ enabled =
+ ConnectionSpec.MODERN_TLS.cipherSuites!!.map {
+ ianaSuites.fromJavaName(it.javaName)
+ },
+ supported =
+ ConnectionSpec.COMPATIBLE_TLS.cipherSuites!!.map {
+ ianaSuites.fromJavaName(it.javaName)
+ },
+ )
}
fun historicOkHttp(version: String): Client {
val enabled =
- FileSystem.RESOURCES.read("okhttp_${version.replace(".", "_")}.txt".toPath()) {
+ FileSystem.RESOURCES.read("okhttp_$version.txt".toPath()) {
this.readUtf8().lines().filter { it.isNotBlank() }.map {
- SuiteId(null, it.trim())
+ SuiteId(id = null, name = it.trim())
}
}
- return Client("OkHttp", version, null, enabled = enabled)
+ return Client(
+ userAgent = "OkHttp",
+ version = version,
+ enabled = enabled,
+ )
}
fun currentVm(ianaSuites: IanaSuites): Client {
- return systemDefault(System.getProperty("java.vm.name"), System.getProperty("java.version"), ianaSuites)
+ return systemDefault(
+ name = System.getProperty("java.vm.name"),
+ version = System.getProperty("java.version"),
+ ianaSuites = ianaSuites,
+ )
}
fun conscrypt(ianaSuites: IanaSuites): Client {
val version = Conscrypt.version()
- return systemDefault("Conscrypt", "" + version.major() + "." + version.minor(), ianaSuites)
+ return systemDefault(
+ name = "Conscrypt",
+ version = "${version.major()}.${version.minor()}",
+ ianaSuites = ianaSuites,
+ )
}
fun systemDefault(
@@ -67,24 +76,13 @@ fun systemDefault(
version: String,
ianaSuites: IanaSuites,
): Client {
- return try {
- val socketFactory = SSLSocketFactory.getDefault() as SSLSocketFactory
- val sslSocket = socketFactory.createSocket() as SSLSocket
- val supportedSuites =
- buildList {
- for (suite in sslSocket.supportedCipherSuites) {
- add(ianaSuites.fromJavaName(suite))
- }
- }
- val enabledSuites =
- buildList {
- for (suite in sslSocket.enabledCipherSuites) {
- add(ianaSuites.fromJavaName(suite))
- }
- }
+ val socketFactory = SSLSocketFactory.getDefault() as SSLSocketFactory
+ val sslSocket = socketFactory.createSocket() as SSLSocket
- Client(name, version, null, enabledSuites, supportedSuites)
- } catch (e: IOException) {
- throw RuntimeException(e)
- }
+ return Client(
+ userAgent = name,
+ version = version,
+ enabled = sslSocket.enabledCipherSuites.map { ianaSuites.fromJavaName(it) },
+ supported = sslSocket.supportedCipherSuites.map { ianaSuites.fromJavaName(it) },
+ )
}
diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt
index 2b774f5ee..5427864e7 100644
--- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt
+++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Square, Inc.
+ * Copyright (C) 2022 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.executeAsync
import okhttp3.survey.types.SuiteId
-import okio.ByteString
import okio.ByteString.Companion.decodeHex
import okio.IOException
@@ -30,7 +29,7 @@ val IANA_CSV_PATTERN = "\"0x(\\w\\w),0x(\\w\\w)\",(\\w+).*".toRegex()
fun parseIanaCsvRow(s: String): SuiteId? {
if (s.contains("Reserved") || s.contains("Unassigned")) return null
val matcher = IANA_CSV_PATTERN.matchEntire(s) ?: return null
- val id: ByteString = (matcher.groupValues[1] + matcher.groupValues[2]).decodeHex()
+ val id = (matcher.groupValues[1] + matcher.groupValues[2]).decodeHex()
return SuiteId(id, matcher.groupValues[3])
}
@@ -39,13 +38,9 @@ class IanaSuites(
val suites: List<SuiteId>,
) {
fun fromJavaName(javaName: String): SuiteId {
- for (suiteId in suites) {
- val alternateName = "TLS_" + javaName.substring(4)
- if (suiteId.name == javaName || suiteId.name == alternateName) {
- return suiteId
- }
- }
- throw IllegalArgumentException("No such suite: $javaName")
+ return suites.firstOrNull {
+ it.name == javaName || it.name == "TLS_${javaName.drop(4)}"
+ } ?: throw IllegalArgumentException("No such suite: $javaName")
}
}
@@ -60,7 +55,8 @@ suspend fun fetchIanaSuites(okHttpClient: OkHttpClient): IanaSuites {
throw IOException("Failed ${it.code} ${it.message}")
}
it.body.string().lines()
- }.mapNotNull { parseIanaCsvRow(it) }
+ .mapNotNull { parseIanaCsvRow(it) }
+ }
return IanaSuites("current", suites)
}
diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt
index ced4cf205..dfb272b72 100644
--- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt
+++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Square, Inc.
+ * Copyright (C) 2022 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package okhttp3.survey
import java.security.Security
import okhttp3.Cache
import okhttp3.OkHttpClient
-import okhttp3.survey.ssllabs.SslLabsScraper
+import okhttp3.survey.ssllabs.SslLabsClient
import okhttp3.survey.types.Client
import okhttp3.survey.types.SuiteId
import okio.FileSystem
@@ -34,76 +34,69 @@ suspend fun main() {
.cache(Cache("build/okhttp_cache".toPath(), 100_000_000, FileSystem.SYSTEM))
.build()
- val sslLabsScraper = SslLabsScraper(client)
+ val sslLabsClients = SslLabsClient(client).clients()
+ val ianaSuitesNew = fetchIanaSuites(client)
- try {
- val ianaSuitesNew = fetchIanaSuites(client)
+ val android5 = sslLabsClients.first { it.userAgent == "Android" && it.version == "5.0.0" }
+ val android9 = sslLabsClients.first { it.userAgent == "Android" && it.version == "9.0" }
+ val chrome33 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "33" }
+ val chrome57 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "57" }
+ val chrome80 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "80" }
+ val firefox34 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "34" }
+ val firefox53 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "53" }
+ val firefox73 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "73" }
+ val java7 = sslLabsClients.first { it.userAgent == "Java" && it.version == "7u25" }
+ val java12 = sslLabsClients.first { it.userAgent == "Java" && it.version == "12.0.1" }
+ val safari12iOS = sslLabsClients.first { it.userAgent == "Safari" && it.platform == "iOS 12.3.1" }
+ val safari12Osx =
+ sslLabsClients.first { it.userAgent == "Safari" && it.platform == "MacOS 10.14.6 Beta" }
- val sslLabsClients = sslLabsScraper.query()
+ val okhttp = currentOkHttp(ianaSuitesNew)
- val android5 = sslLabsClients.first { it.userAgent == "Android" && it.version == "5.0.0" }
- val android9 = sslLabsClients.first { it.userAgent == "Android" && it.version == "9.0" }
- val chrome33 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "33" }
- val chrome57 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "57" }
- val chrome80 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "80" }
- val firefox34 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "34" }
- val firefox53 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "53" }
- val firefox73 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "73" }
- val java7 = sslLabsClients.first { it.userAgent == "Java" && it.version == "7u25" }
- val java12 = sslLabsClients.first { it.userAgent == "Java" && it.version == "12.0.1" }
- val safari12iOS = sslLabsClients.first { it.userAgent == "Safari" && it.platform == "iOS 12.3.1" }
- val safari12Osx = sslLabsClients.first { it.userAgent == "Safari" && it.platform == "MacOS 10.14.6 Beta" }
+ val okHttp_4_10 = historicOkHttp("4.10")
+ val okHttp_3_14 = historicOkHttp("3.14")
+ val okHttp_3_13 = historicOkHttp("3.13")
+ val okHttp_3_11 = historicOkHttp("3.11")
+ val okHttp_3_9 = historicOkHttp("3.9")
- val okhttp = currentOkHttp(ianaSuitesNew)
+ val currentVm = currentVm(ianaSuitesNew)
- val okHttp_4_10 = historicOkHttp("4.10")
- val okHttp_3_14 = historicOkHttp("3.14")
- val okHttp_3_13 = historicOkHttp("3.13")
- val okHttp_3_11 = historicOkHttp("3.11")
- val okHttp_3_9 = historicOkHttp("3.9")
+ val conscrypt =
+ if (includeConscrypt) {
+ Security.addProvider(Conscrypt.newProvider())
+ conscrypt(ianaSuitesNew)
+ } else {
+ Client("Conscrypt", "Disabled", null, listOf())
+ }
- val currentVm = currentVm(ianaSuitesNew)
+ val clients =
+ listOf(
+ okhttp,
+ chrome80,
+ firefox73,
+ android9,
+ safari12iOS,
+ conscrypt,
+ currentVm,
+ okHttp_3_9,
+ okHttp_3_11,
+ okHttp_3_13,
+ okHttp_3_14,
+ okHttp_4_10,
+ android5,
+ java7,
+ java12,
+ firefox34,
+ firefox53,
+ chrome33,
+ chrome57,
+ safari12Osx,
+ )
- val conscrypt =
- if (includeConscrypt) {
- Security.addProvider(Conscrypt.newProvider())
- conscrypt(ianaSuitesNew)
- } else {
- Client("Conscrypt", "Disabled", null, listOf())
- }
+ val orderBy = okhttp.enabled + chrome80.enabled + safari12Osx.enabled + rest(clients)
+ val survey = CipherSuiteSurvey(clients = clients, ianaSuites = ianaSuitesNew, orderBy = orderBy)
- val clients =
- listOf(
- okhttp,
- chrome80,
- firefox73,
- android9,
- safari12iOS,
- conscrypt,
- currentVm,
- okHttp_3_9,
- okHttp_3_11,
- okHttp_3_13,
- okHttp_3_14,
- okHttp_4_10,
- android5,
- java7,
- java12,
- firefox34,
- firefox53,
- chrome33,
- chrome57,
- safari12Osx,
- )
-
- val orderBy = okhttp.enabled + chrome80.enabled + safari12Osx.enabled + rest(clients)
- val survey = CipherSuiteSurvey(clients = clients, ianaSuites = ianaSuitesNew, orderBy = orderBy)
-
- survey.printGoogleSheet()
- } finally {
- client.dispatcher.executorService.shutdown()
- client.connectionPool.evictAll()
- }
+ survey.printGoogleSheet()
}
fun rest(clients: List<Client>): List<SuiteId> {
diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Record.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsApi.kt
index af4f05f4d..ea3909e11 100644
--- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Record.kt
+++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsApi.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Square, Inc.
+ * Copyright (C) 2022 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package okhttp3.survey.types
+package okhttp3.survey.ssllabs
-data class Record(val java: String, val android: String)
+import retrofit2.http.GET
+
+interface SslLabsApi {
+ @GET("getClients")
+ suspend fun clients(): List<UserAgentCapabilities>
+
+ companion object {
+ const val BASE_URL = "https://api.ssllabs.com/api/v3/"
+ }
+}
diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsScrape.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsClient.kt
index 7b7c0168c..68808d169 100644
--- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsScrape.kt
+++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsClient.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Square, Inc.
+ * Copyright (C) 2022 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,8 +23,8 @@ import okhttp3.survey.types.SuiteId
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
-class SslLabsScraper(
- private val callFactory: Call.Factory,
+class SslLabsClient(
+ callFactory: Call.Factory,
) {
private val moshi = Moshi.Builder().build()
@@ -32,27 +32,32 @@ class SslLabsScraper(
private val retrofit =
Retrofit.Builder()
- .baseUrl(SslLabsService.BASE_URL)
+ .baseUrl(SslLabsApi.BASE_URL)
.addConverterFactory(moshiConverterFactory)
.callFactory(callFactory)
.build()
- private val api = retrofit.create(SslLabsService::class.java)
+ private val sslLabsApi = retrofit.create(SslLabsApi::class.java)
- suspend fun query(): List<Client> {
- return api.clients().map { userAgent ->
- Client(userAgent.name, userAgent.version, userAgent.platform, enabled = userAgent.suiteNames.map { SuiteId(null, it) })
+ suspend fun clients(): List<Client> {
+ return sslLabsApi.clients().map { userAgent ->
+ Client(
+ userAgent = userAgent.name,
+ version = userAgent.version,
+ platform = userAgent.platform,
+ enabled = userAgent.suiteNames.map { SuiteId(null, it) },
+ )
}
}
}
suspend fun main() {
- val client = OkHttpClient()
+ val sslLabsClient =
+ SslLabsClient(
+ callFactory = OkHttpClient(),
+ )
- val scraper = SslLabsScraper(client)
-
- println(scraper.query())
-
- client.connectionPool.evictAll()
- client.dispatcher.executorService.shutdown()
+ for (client in sslLabsClient.clients()) {
+ println(client)
+ }
}
diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsService.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsService.kt
deleted file mode 100644
index 4715de7e7..000000000
--- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsService.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package okhttp3.survey.ssllabs
-
-import retrofit2.http.GET
-
-interface SslLabsService {
- @GET("getClients")
- suspend fun clients(): List<UserAgentCapabilities>
-
- companion object {
- const val BASE_URL = "https://api.ssllabs.com/api/v3/"
- }
-}
diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/UserAgentCapabilities.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/UserAgentCapabilities.kt
index 26f61e4a9..b68b6ae74 100644
--- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/UserAgentCapabilities.kt
+++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/UserAgentCapabilities.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2022 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.survey.ssllabs
import com.squareup.moshi.JsonClass
diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Client.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Client.kt
index 2e592b77d..9e5223276 100644
--- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Client.kt
+++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Client.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Square, Inc.
+ * Copyright (C) 2022 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package okhttp3.survey.types
data class Client(
val userAgent: String,
val version: String,
- val platform: String?,
+ val platform: String? = null,
val enabled: List<SuiteId> = listOf(),
val supported: List<SuiteId> = listOf(),
) {
diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/SuiteId.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/SuiteId.kt
index 13d566b56..a4dee2fd6 100644
--- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/SuiteId.kt
+++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/SuiteId.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Square, Inc.
+ * Copyright (C) 2022 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/samples/tlssurvey/src/main/resources/okhttp_3_11.txt b/samples/tlssurvey/src/main/resources/okhttp_3.11.txt
index 618db5fed..618db5fed 100644
--- a/samples/tlssurvey/src/main/resources/okhttp_3_11.txt
+++ b/samples/tlssurvey/src/main/resources/okhttp_3.11.txt
diff --git a/samples/tlssurvey/src/main/resources/okhttp_3_13.txt b/samples/tlssurvey/src/main/resources/okhttp_3.13.txt
index 0d8acaf93..0d8acaf93 100644
--- a/samples/tlssurvey/src/main/resources/okhttp_3_13.txt
+++ b/samples/tlssurvey/src/main/resources/okhttp_3.13.txt
diff --git a/samples/tlssurvey/src/main/resources/okhttp_3_14.txt b/samples/tlssurvey/src/main/resources/okhttp_3.14.txt
index 056852f1a..056852f1a 100644
--- a/samples/tlssurvey/src/main/resources/okhttp_3_14.txt
+++ b/samples/tlssurvey/src/main/resources/okhttp_3.14.txt
diff --git a/samples/tlssurvey/src/main/resources/okhttp_3_9.txt b/samples/tlssurvey/src/main/resources/okhttp_3.9.txt
index 41ed6ceae..41ed6ceae 100644
--- a/samples/tlssurvey/src/main/resources/okhttp_3_9.txt
+++ b/samples/tlssurvey/src/main/resources/okhttp_3.9.txt
diff --git a/samples/tlssurvey/src/main/resources/okhttp_4_10.txt b/samples/tlssurvey/src/main/resources/okhttp_4.10.txt
index 056852f1a..056852f1a 100644
--- a/samples/tlssurvey/src/main/resources/okhttp_4_10.txt
+++ b/samples/tlssurvey/src/main/resources/okhttp_4.10.txt