diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000000..8ade6e48f023 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,19 @@ +{ + "image": "mcr.microsoft.com/devcontainers/java:21-bookworm", + "features": { + "ghcr.io/devcontainers/features/java:1": { + "version": "17" + } + }, + "customizations": { + "vscode": { + "settings": { + "java.server.launchMode": "Standard" + }, + "extensions": [ + "vscjava.vscode-java-pack", + "vscjava.vscode-gradle" + ] + } + } +} diff --git a/.github/renovate.json b/.github/renovate.json index 36df25c9d60b..04f314dd52f3 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,11 +1,13 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ - "config:base", + "config:recommended", ":dependencyDashboard", "schedule:weekly" ], - "labels": ["renovate"], + "labels": [ + "renovate" + ], "ignoreDeps": [ "com.squareup.okhttp3:okhttp", "com.squareup.okhttp3:okhttp-tls", @@ -13,28 +15,36 @@ ], "packageRules": [ { - "matchPackageNames": ["org.objenesis:objenesis"], + "groupName": "bnd", + "matchPackageNames": [ + "/biz.*/" + ] + }, + { + "groupName": "graalvm", + "matchPackageNames": [ + "/org.graalvm.*/" + ] + }, + { + "matchPackageNames": [ + "org.objenesis:objenesis" + ], "allowedVersions": "<=2.6" }, { - "matchPackageNames": ["org.eclipse.jetty:jetty-client"], + "matchPackageNames": [ + "org.eclipse.jetty:jetty-client" + ], "allowedVersions": "<10.0", "description": "JDK 11 requirement" }, { - "matchPackageNames": ["org.junit-pioneer:junit-pioneer"], + "matchPackageNames": [ + "org.junit-pioneer:junit-pioneer" + ], "allowedVersions": "<2.0.0", "description": "JDK 11 requirement" - }, - { - "matchPackageNames": ["gradle"], - "allowedVersions": "<8.0", - "description": "Recent release, not compatible with pinned AGP and Kotlin versions yet. Wait for AGP 8?" - }, - { - "matchPackageNames": ["com.android.tools.build:gradle"], - "allowedVersions": "<7.4", - "description": "Recent release, no compatible Intellij stable release (2023.1)" } ] } diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 01c62d5f301e..38fb2d6f3b9d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Upload Artifacts run: ./gradlew clean publish --stacktrace @@ -49,7 +49,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: gradle/wrapper-validation-action@v2 + - uses: gradle/actions/wrapper-validation@v4 - name: Validate Renovate uses: rinchsan/renovate-config-validator@v0.2.0 with: @@ -78,8 +78,17 @@ jobs: distribution: 'zulu' java-version: 17 + - uses: graalvm/setup-graalvm@v1 + with: + distribution: 'graalvm' + java-version: 21 + github-token: ${{ secrets.GITHUB_TOKEN }} + cache: 'gradle' + native-image-job-reports: true + components: 'native-image' + - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Checks run: ./gradlew check -PandroidBuild=true -PgraalBuild=true -x test -x test @@ -108,14 +117,14 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Checks run: ./gradlew test -Dtest.java.version=11 - name: Publish Test Report if: github.repository == 'square/okhttp' && github.ref == 'refs/heads/master' - uses: mikepenz/action-junit-report@v4 + uses: mikepenz/action-junit-report@v5 with: report_paths: '**/build/test-results/*/TEST-*.xml' check_name: OpenJDK 11 Test Report @@ -150,7 +159,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Checks run: ./gradlew test -Dtest.java.version=11 @@ -178,7 +187,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Checks run: ./gradlew test -Dtest.java.version=8 @@ -212,7 +221,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Checks run: ./gradlew test -Dtest.java.version=8 -Dokhttp.platform=jdk8alpn -Dalpn.boot.version=8.1.13.v20181017 -Dorg.gradle.java.installations.paths=/opt/hostedtoolcache/Java_Adopt_jdk/8.0.242-8.1/x64 @@ -240,7 +249,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Checks run: ./gradlew test -Dtest.java.version=8 -Dokhttp.platform=openjsse @@ -268,7 +277,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Checks run: ./gradlew test -Dokhttp.platform=conscrypt @@ -296,7 +305,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Checks run: ./gradlew test -Dokhttp.platform=bouncycastle @@ -325,7 +334,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Checks run: ./gradlew test -Dokhttp.platform=corretto @@ -354,7 +363,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Checks run: ./gradlew test -Dtest.java.version=17 @@ -389,7 +398,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Checks run: ./gradlew test -Dtest.java.version=21 @@ -418,7 +427,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Test run: ./gradlew test @@ -446,20 +455,26 @@ jobs: distribution: 'zulu' java-version: 17 + - uses: graalvm/setup-graalvm@v1 + with: + distribution: 'graalvm' + java-version: 21 + github-token: ${{ secrets.GITHUB_TOKEN }} + cache: 'gradle' + native-image-job-reports: true + components: 'native-image' + - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Build okcurl - run: ./gradlew okcurl:nativeImage + run: ./gradlew okcurl:nativeBuild - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - - name: Build ConsoleLauncher - run: ./gradlew -PgraalBuild=true native-image-tests:nativeImage - - - name: Run Checks - run: ./native-image-tests/build/graal/ConsoleLauncher + - name: Run native-image tests + run: ./gradlew -PgraalBuild=true native-image-tests:nativeTest testandroid: runs-on: ubuntu-latest @@ -500,10 +515,10 @@ jobs: sudo udevadm trigger --name-match=kvm - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Gradle cache - run: ./gradlew -PandroidBuild=true :okhttp-android:test + run: ./gradlew -PandroidBuild=true :android-test:test - name: AVD cache uses: actions/cache@v4 @@ -530,7 +545,7 @@ jobs: with: api-level: ${{ matrix.api-level }} arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }} - script: ./gradlew -PandroidBuild=true :okhttp-android:connectedCheck :android-test:connectedCheck + script: ./gradlew -PandroidBuild=true :android-test:connectedCheck env: API_LEVEL: ${{ matrix.api-level }} @@ -572,7 +587,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Checks run: ./gradlew test -Dokhttp.platform=loom -Dtest.java.version=21 -PcontainerTests=true @@ -616,7 +631,7 @@ jobs: sudo udevadm trigger --name-match=kvm - name: Gradle cache - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: AVD cache uses: actions/cache@v4 diff --git a/.github/workflows/containers.yml b/.github/workflows/containers.yml index 0b058c3dd2df..580d67493f1c 100644 --- a/.github/workflows/containers.yml +++ b/.github/workflows/containers.yml @@ -33,7 +33,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Run Container Tests run: ./gradlew container-tests:test -PcontainerTests=true diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000000..849f79e6b5e0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.compile.nullAnalysis.mode": "automatic" +} diff --git a/CHANGELOG.md b/CHANGELOG.md index a36ad2a9d13e..f68d7f99177b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,84 @@ Change Log See [4.x Change log](https://square.github.io/okhttp/changelogs/changelog_4x/) for the stable version changelogs. +## Version 5.0.0-alpha.14 + +_2024-04-17_ + + * Breaking: Move coroutines extensions to okhttp3.coroutines. Previously this artifact shared the + `okhttp3` package name with our core module, which is incompatible with the Java Platform Module + System. + + * Fix in okhttp-coroutines: Publish a valid artifact. The coroutines JAR file in 5.0.0-alpha.13 + was corrupt and should not be used. + + +## Version 5.0.0-alpha.13 + +_2024-04-16_ + + * Breaking: Tag unstable new APIs as `@ExperimentalOkHttpApi`. We intend to release OkHttp 5.0 + without stabilizing these new APIs first. + + Do not use these experimental APIs in modules that may be executed using a version of OkHttp + different from the version that the module was compiled with. Do not use them in published + libraries. Do not use them if you aren't willing to track changes to them. + + * Breaking: Drop support for Kotlin Multiplatform. + + We planned to support multiplatform in OkHttp 5.0, but after building it, we weren't happy with + the implementation trade-offs. We can't use our HTTP client engine on Kotlin/JS, and we weren't + prepared to build a TLS API for Kotlin/Native. + + We'd prefer a multiplatform HTTP client API that's backed by OkHttp on Android and JVM, and + other engines on other platforms. [Ktor] does this pretty well today! + + * Breaking: Use `kotlin.time.Duration` in APIs like `OkHttpClient.Builder.callTimeout()`. This + update also drops support for the `DurationUnit` functions introduced in earlier alpha releases + of OkHttp 5. + + * Breaking: Reorder the parameters in the Cache constructor that was introduced in 5.0.0-alpha.3. + + * New: `Request.Builder.cacheUrlOverride()` customizes the cache key used for a request. This can + be used to make canonical URLs for the cache that omit insignificant query parameters or other + irrelevant data. + + This feature may be used with `POST` requests to cache their responses. In such cases the + request body is not used to determine the cache key, so you must manually add cache-relevant + data to the override URL. For example, you could add a `request-body-sha256` query parameter so + requests with the same POST data get the same cache entry. + + * New: `HttpLoggingInterceptor.redactQueryParams()` configures the query parameters to redact + in logs. For best security, don't put sensitive information in query parameters. + + * New: `ConnectionPool.setPolicy()` configures a minimum connection pool size for a target + address. Use this to proactively open HTTP connections. + + Connections opened to fulfill this policy are subject to the connection pool's + `keepAliveDuration` but do not count against the pool-wide `maxIdleConnections` limit. + + This feature increases the client's traffic and the load on the server. Talking to your server's + operators before adopting it. + + * New in okhttp-android: `HttpLoggingInterceptor.androidLogging()` and + `LoggingEventListener.androidLogging()` write HTTP calls or events to Logcat. + + * New: `OkHttpClient.webSocketCloseTimeout` configures how long a web socket connection will wait + for a graceful shutdown before it performs an abrupt shutdown. + + * Fix: Honor `RequestBody.isOneShot()` in `MultipartBody` + + * Fix in `okhttp-coroutines`: Don't leak response bodies in `executeAsync()`. We had a bug where + we didn't call `Response.close()` if the coroutine was canceled before its response was + returned. + + * Upgrade: [Okio 3.9.0][okio_3_9_0]. + + * Upgrade: [Kotlin 1.9.23][kotlin_1_9_23]. + + * Upgrade: [Unicode® IDNA 15.1.0][idna_15_1_0] + + ## Version 5.0.0-alpha.12 _2023-12-17_ @@ -357,20 +435,25 @@ Note that this was originally released on 2020-10-06 as 4.10.0-RC1. The only cha release is the version name. +[Ktor]: https://ktor.io/ [assertk]: https://github.com/willowtreeapps/assertk [graalvm]: https://www.graalvm.org/ [graalvm_21]: https://www.graalvm.org/release-notes/21_0/ [graalvm_22]: https://www.graalvm.org/release-notes/22_2/ +[idna_15_1_0]: https://www.unicode.org/reports/tr46/#Modifications [kotlin_1_4_20]: https://github.com/JetBrains/kotlin/releases/tag/v1.4.20 [kotlin_1_5_31]: https://github.com/JetBrains/kotlin/releases/tag/v1.5.31 [kotlin_1_6_10]: https://github.com/JetBrains/kotlin/releases/tag/v1.6.10 [kotlin_1_6_21]: https://github.com/JetBrains/kotlin/releases/tag/v1.6.21 [kotlin_1_7_10]: https://github.com/JetBrains/kotlin/releases/tag/v1.7.10 [kotlin_1_9_21]: https://github.com/JetBrains/kotlin/releases/tag/v1.9.21 +[kotlin_1_9_23]: https://github.com/JetBrains/kotlin/releases/tag/v1.9.23 +[loom]: https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html [okio_2_9_0]: https://square.github.io/okio/changelog/#version-290 [okio_3_0_0]: https://square.github.io/okio/changelog/#version-300 [okio_3_1_0]: https://square.github.io/okio/changelog/#version-310 [okio_3_2_0]: https://square.github.io/okio/changelog/#version-320 [okio_3_7_0]: https://square.github.io/okio/changelog/#version-370 +[okio_3_9_0]: https://square.github.io/okio/changelog/#version-390 [rfc_8305]: https://tools.ietf.org/html/rfc8305 [uts46]: https://www.unicode.org/reports/tr46 diff --git a/README.md b/README.md index e70c426cc535..f3ffebb74f45 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,27 @@ configured to fall back for broad connectivity. Using OkHttp is easy. Its request/response API is designed with fluent builders and immutability. It supports both synchronous blocking calls and async calls with callbacks. +A well behaved user agent +------------------------- + +OkHttp follows modern HTTP specifications such as + +* HTTP/1.1 - [RFC 7231](https://datatracker.ietf.org/doc/html/rfc7231) +* HTTP/2 - [RFC 9113](https://datatracker.ietf.org/doc/html/rfc9113) +* Websockets - [RFC 6455](https://datatracker.ietf.org/doc/html/rfc6455) +* SSE - [Server-sent events](https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events) + +Where the spec is ambiguous, OkHttp follows modern user agents such as popular Browsers or common HTTP Libraries. + +OkHttp is principled and avoids being overly configurable, especially when such configuration is +to workaround a buggy server, test invalid scenarios or that contradict the relevant RFC. +Other HTTP libraries exist that fill that gap allowing extensive customisation including potentially +invalid requests. + +Example Limitations + +* Does not allow GET with a body. +* Cache is not an interface with alternative implementations. Get a URL --------- @@ -129,6 +150,11 @@ The latest release is available on [Maven Central](https://search.maven.org/arti testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0") ``` +MockWebServer is used for firstly for internal testing, and for basic testing of apps using OkHttp client. +It is not a full featured HTTP testing library that is developed standalone. It is not being actively developed +for new features. As such you might find your needs outgrow MockWebServer and you may which to use a +more full featured testing library such as [MockServer](https://www.mock-server.com/). + GraalVM Native Image -------------------- diff --git a/android-test-app/build.gradle.kts b/android-test-app/build.gradle.kts index da419a24d774..901d70056735 100644 --- a/android-test-app/build.gradle.kts +++ b/android-test-app/build.gradle.kts @@ -41,7 +41,6 @@ android { dependencies { implementation(libs.playservices.safetynet) implementation(projects.okhttp) - implementation(projects.okhttpAndroid) implementation(libs.androidx.activity) androidTestImplementation(libs.androidx.junit) diff --git a/android-test-app/src/main/kotlin/okhttp/android/testapp/MainActivity.kt b/android-test-app/src/main/kotlin/okhttp/android/testapp/MainActivity.kt index d9ed518156ff..cf896359b4b1 100644 --- a/android-test-app/src/main/kotlin/okhttp/android/testapp/MainActivity.kt +++ b/android-test-app/src/main/kotlin/okhttp/android/testapp/MainActivity.kt @@ -23,6 +23,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response +import okhttp3.internal.platform.AndroidPlatform import okio.IOException class MainActivity : ComponentActivity() { @@ -31,6 +32,9 @@ class MainActivity : ComponentActivity() { val client = OkHttpClient() + // Ensure we are compiling against the right variant + println(AndroidPlatform.isSupported) + val url = "https://github.com/square/okhttp".toHttpUrl() println(url.topPrivateDomain()) diff --git a/android-test/build.gradle.kts b/android-test/build.gradle.kts index c2aec16a1eb6..1dc021fd47b2 100644 --- a/android-test/build.gradle.kts +++ b/android-test/build.gradle.kts @@ -61,7 +61,20 @@ dependencies { implementation(libs.kotlin.reflect) implementation(libs.playservices.safetynet) implementation(projects.okhttp) - implementation(projects.okhttpAndroid) + + testImplementation(libs.junit) + testImplementation(libs.junit.ktx) + testImplementation(libs.assertk) + testImplementation(projects.okhttpTls) + testImplementation(projects.loggingInterceptor) + testImplementation(libs.androidx.test.runner) + testImplementation(libs.robolectric) + testImplementation(libs.androidx.espresso.core) + testImplementation(libs.squareup.okio.fakefilesystem) + testImplementation(projects.okhttpTestingSupport) + testImplementation(rootProject.libs.conscrypt.openjdk) + testImplementation(rootProject.libs.junit.jupiter.engine) + testImplementation(rootProject.libs.junit.vintage.engine) androidTestImplementation(projects.okhttpTestingSupport) { exclude("org.openjsse", "openjsse") @@ -72,13 +85,13 @@ dependencies { androidTestImplementation(libs.bouncycastle.bcprov) androidTestImplementation(libs.bouncycastle.bctls) androidTestImplementation(libs.conscrypt.android) + androidTestImplementation(projects.mockwebserver3Junit4) androidTestImplementation(projects.mockwebserver3Junit5) androidTestImplementation(projects.okhttpBrotli) androidTestImplementation(projects.okhttpDnsoverhttps) androidTestImplementation(projects.loggingInterceptor) androidTestImplementation(projects.okhttpSse) androidTestImplementation(projects.okhttpTls) - androidTestImplementation(projects.okhttpAndroid) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(libs.httpClient5) diff --git a/okhttp-android/src/androidTest/kotlin/okhttp3/android/AndroidAsyncDnsTest.kt b/android-test/src/androidTest/java/okhttp/android/test/AndroidAsyncDnsTest.kt similarity index 98% rename from okhttp-android/src/androidTest/kotlin/okhttp3/android/AndroidAsyncDnsTest.kt rename to android-test/src/androidTest/java/okhttp/android/test/AndroidAsyncDnsTest.kt index 22a17ad11690..c144f7912bdb 100644 --- a/okhttp-android/src/androidTest/kotlin/okhttp3/android/AndroidAsyncDnsTest.kt +++ b/android-test/src/androidTest/java/okhttp/android/test/AndroidAsyncDnsTest.kt @@ -14,7 +14,7 @@ * limitations under the License. * */ -package okhttp3.android +package okhttp.android.test import android.content.Context import android.net.ConnectivityManager @@ -36,6 +36,7 @@ import okhttp3.AsyncDns import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.OkHttpClient import okhttp3.Request +import okhttp3.android.AndroidAsyncDns import okhttp3.tls.HandshakeCertificates import okhttp3.tls.HeldCertificate import okio.IOException diff --git a/android-test/src/androidTest/java/okhttp/android/test/OkHttpTest.kt b/android-test/src/androidTest/java/okhttp/android/test/OkHttpTest.kt index 82625ab745ac..1064756cb74d 100644 --- a/android-test/src/androidTest/java/okhttp/android/test/OkHttpTest.kt +++ b/android-test/src/androidTest/java/okhttp/android/test/OkHttpTest.kt @@ -15,7 +15,9 @@ */ package okhttp.android.test +import android.content.Context import android.os.Build +import androidx.test.core.app.ApplicationProvider import androidx.test.platform.app.InstrumentationRegistry import com.google.android.gms.common.GooglePlayServicesNotAvailableException import com.google.android.gms.security.ProviderInstaller @@ -63,6 +65,7 @@ import okhttp3.internal.http2.Http2 import okhttp3.internal.platform.Android10Platform import okhttp3.internal.platform.AndroidPlatform import okhttp3.internal.platform.Platform +import okhttp3.internal.platform.PlatformRegistry import okhttp3.logging.LoggingEventListener import okhttp3.testing.PlatformRule import okhttp3.tls.HandshakeCertificates @@ -117,6 +120,9 @@ class OkHttpTest { @BeforeEach fun setup(server: MockWebServer) { + // Needed because of Platform.resetForTests + PlatformRegistry.applicationContext = ApplicationProvider.getApplicationContext() + this.server = server } diff --git a/android-test/src/main/AndroidManifest.xml b/android-test/src/main/AndroidManifest.xml index 739f89763934..9a74ac7f8e7d 100644 --- a/android-test/src/main/AndroidManifest.xml +++ b/android-test/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ xmlns:tools="http://schemas.android.com/tools" package="okhttp.android.test"> + diff --git a/okhttp-android/src/test/kotlin/okhttp3/android/AndroidAsyncDnsTest.kt b/android-test/src/test/kotlin/okhttp/android/test/AndroidAsyncDnsTest.kt similarity index 92% rename from okhttp-android/src/test/kotlin/okhttp3/android/AndroidAsyncDnsTest.kt rename to android-test/src/test/kotlin/okhttp/android/test/AndroidAsyncDnsTest.kt index 43d9e5f3dd63..da3b0876d62c 100644 --- a/okhttp-android/src/test/kotlin/okhttp3/android/AndroidAsyncDnsTest.kt +++ b/android-test/src/test/kotlin/okhttp/android/test/AndroidAsyncDnsTest.kt @@ -13,13 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package okhttp3.android +@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") + +package okhttp.android.test import assertk.assertFailure import assertk.assertions.hasMessage import assertk.assertions.isInstanceOf import java.net.UnknownHostException import okhttp3.AsyncDns +import okhttp3.android.AndroidAsyncDns import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner diff --git a/okhttp-android/src/test/kotlin/okhttp3/android/AndroidLoggingTest.kt b/android-test/src/test/kotlin/okhttp/android/test/AndroidLoggingTest.kt similarity index 83% rename from okhttp-android/src/test/kotlin/okhttp3/android/AndroidLoggingTest.kt rename to android-test/src/test/kotlin/okhttp/android/test/AndroidLoggingTest.kt index 38b3223c038c..7ff13ae9a1f7 100644 --- a/okhttp-android/src/test/kotlin/okhttp3/android/AndroidLoggingTest.kt +++ b/android-test/src/test/kotlin/okhttp/android/test/AndroidLoggingTest.kt @@ -14,7 +14,7 @@ * limitations under the License. * */ -package okhttp3.android +package okhttp.android.test import android.util.Log import assertk.assertThat @@ -26,6 +26,7 @@ import okhttp3.ConnectionSpec import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.OkHttpClient import okhttp3.Request +import okhttp3.internal.platform.AndroidPlatform import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.LoggingEventListener import org.junit.Test @@ -36,18 +37,16 @@ import org.robolectric.shadows.ShadowLog @RunWith(RobolectricTestRunner::class) class AndroidLoggingTest { val clientBuilder = - OkHttpClient.Builder() - .connectionSpecs(listOf(ConnectionSpec.CLEARTEXT)) - .dns { - throw UnknownHostException("shortcircuit") - } + OkHttpClient.Builder().connectionSpecs(listOf(ConnectionSpec.CLEARTEXT)).dns { + throw UnknownHostException("shortcircuit") + } val request = Request("http://google.com/robots.txt".toHttpUrl()) @Test fun testHttpLoggingInterceptor() { val interceptor = - HttpLoggingInterceptor.androidLogging(tag = "testHttpLoggingInterceptor").apply { + HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BASIC } @@ -59,7 +58,7 @@ class AndroidLoggingTest { // expected } - val logs = ShadowLog.getLogsForTag("testHttpLoggingInterceptor") + val logs = ShadowLog.getLogsForTag(AndroidPlatform.Tag) assertThat(logs.map { it.type }).containsOnly(Log.INFO) assertThat(logs.map { it.msg }).containsExactly( "--> GET http://google.com/robots.txt", @@ -71,8 +70,7 @@ class AndroidLoggingTest { @Test fun testLoggingEventListener() { - val client = - clientBuilder.eventListenerFactory(LoggingEventListener.androidLogging(tag = "testLoggingEventListener")).build() + val client = clientBuilder.eventListenerFactory(LoggingEventListener.Factory()).build() try { client.newCall(request).execute() @@ -80,7 +78,7 @@ class AndroidLoggingTest { // expected } - val logs = ShadowLog.getLogsForTag("testLoggingEventListener") + val logs = ShadowLog.getLogsForTag(AndroidPlatform.Tag) assertThat(logs.map { it.type }).containsOnly(Log.INFO) assertThat( logs.map { diff --git a/okhttp/src/test/java/okhttp3/internal/platform/android/AndroidSocketAdapterTest.kt b/android-test/src/test/kotlin/okhttp/android/test/AndroidSocketAdapterTest.kt similarity index 76% rename from okhttp/src/test/java/okhttp3/internal/platform/android/AndroidSocketAdapterTest.kt rename to android-test/src/test/kotlin/okhttp/android/test/AndroidSocketAdapterTest.kt index 0d1b3e57f0ec..2fe7b7513f4f 100644 --- a/okhttp/src/test/java/okhttp3/internal/platform/android/AndroidSocketAdapterTest.kt +++ b/android-test/src/test/kotlin/okhttp/android/test/AndroidSocketAdapterTest.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package okhttp3.internal.platform.android +package okhttp.android.test import java.security.Provider import javax.net.ssl.SSLContext @@ -22,7 +22,11 @@ import okhttp3.DelegatingSSLSocket import okhttp3.DelegatingSSLSocketFactory import okhttp3.Protocol.HTTP_1_1 import okhttp3.Protocol.HTTP_2 -import okhttp3.testing.PlatformRule +import okhttp3.internal.platform.android.AndroidSocketAdapter +import okhttp3.internal.platform.android.ConscryptSocketAdapter +import okhttp3.internal.platform.android.DeferredSocketAdapter +import okhttp3.internal.platform.android.SocketAdapter +import okhttp3.internal.platform.android.StandardAndroidSocketAdapter import org.conscrypt.Conscrypt import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull @@ -30,20 +34,13 @@ import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Assume.assumeFalse import org.junit.Assume.assumeTrue -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.extension.RegisterExtension -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.MethodSource - -class AndroidSocketAdapterTest { - @RegisterExtension @JvmField - val platform = PlatformRule() - - @BeforeEach - fun setUp() { - platform.assumeConscrypt() - } +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.ParameterizedRobolectricTestRunner +import org.robolectric.ParameterizedRobolectricTestRunner.Parameters +@RunWith(ParameterizedRobolectricTestRunner::class) +class AndroidSocketAdapterTest(val adapter: SocketAdapter) { val context: SSLContext by lazy { val provider: Provider = Conscrypt.newProviderBuilder().provideTrustManager(true).build() @@ -52,9 +49,8 @@ class AndroidSocketAdapterTest { } } - @ParameterizedTest - @MethodSource("data") - fun testMatchesSupportedSocket(adapter: SocketAdapter) { + @Test + fun testMatchesSupportedSocket() { val socketFactory = context.socketFactory val sslSocket = socketFactory.createSocket() as SSLSocket @@ -65,27 +61,24 @@ class AndroidSocketAdapterTest { assertNull(adapter.getSelectedProtocol(sslSocket)) } - @ParameterizedTest - @MethodSource("data") - fun testMatchesSupportedAndroidSocketFactory(adapter: SocketAdapter) { + @Test + fun testMatchesSupportedAndroidSocketFactory() { assumeTrue(adapter is StandardAndroidSocketAdapter) assertTrue(adapter.matchesSocketFactory(context.socketFactory)) assertNotNull(adapter.trustManager(context.socketFactory)) } - @ParameterizedTest - @MethodSource("data") - fun testDoesntMatchSupportedCustomSocketFactory(adapter: SocketAdapter) { + @Test + fun testDoesntMatchSupportedCustomSocketFactory() { assumeFalse(adapter is StandardAndroidSocketAdapter) assertFalse(adapter.matchesSocketFactory(context.socketFactory)) assertNull(adapter.trustManager(context.socketFactory)) } - @ParameterizedTest - @MethodSource("data") - fun testCustomSocket(adapter: SocketAdapter) { + @Test + fun testCustomSocket() { val socketFactory = DelegatingSSLSocketFactory(context.socketFactory) assertFalse(adapter.matchesSocketFactory(socketFactory)) @@ -101,6 +94,7 @@ class AndroidSocketAdapterTest { companion object { @JvmStatic + @Parameters(name = "{0}") fun data(): Collection { return listOfNotNull( DeferredSocketAdapter(ConscryptSocketAdapter.factory), diff --git a/okhttp-android/src/test/kotlin/okhttp3/android/RobolectricOkHttpClientTest.kt b/android-test/src/test/kotlin/okhttp/android/test/RobolectricOkHttpClientTest.kt similarity index 94% rename from okhttp-android/src/test/kotlin/okhttp3/android/RobolectricOkHttpClientTest.kt rename to android-test/src/test/kotlin/okhttp/android/test/RobolectricOkHttpClientTest.kt index 137c27fa7ed6..e4eba10e44ba 100644 --- a/okhttp-android/src/test/kotlin/okhttp3/android/RobolectricOkHttpClientTest.kt +++ b/android-test/src/test/kotlin/okhttp/android/test/RobolectricOkHttpClientTest.kt @@ -14,7 +14,7 @@ * limitations under the License. * */ -package okhttp3.android +package okhttp.android.test import android.app.Application import android.content.Context @@ -40,7 +40,7 @@ import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) @Config( - sdk = [30], + sdk = [21, 26, 30, 33, 35], ) class RobolectricOkHttpClientTest { private lateinit var context: Context @@ -51,7 +51,7 @@ class RobolectricOkHttpClientTest { context = ApplicationProvider.getApplicationContext() client = OkHttpClient.Builder() - .cache(Cache("/cache".toPath(), 10_000_000, FakeFileSystem())) + .cache(Cache(FakeFileSystem(), "/cache".toPath(), 10_000_000)) .build() } diff --git a/okhttp-android/src/test/kotlin/okhttp3/android/ShadowDnsResolver.kt b/android-test/src/test/kotlin/okhttp/android/test/ShadowDnsResolver.kt similarity index 98% rename from okhttp-android/src/test/kotlin/okhttp3/android/ShadowDnsResolver.kt rename to android-test/src/test/kotlin/okhttp/android/test/ShadowDnsResolver.kt index 6d5eac39afce..cf8b84f04df4 100644 --- a/okhttp-android/src/test/kotlin/okhttp3/android/ShadowDnsResolver.kt +++ b/android-test/src/test/kotlin/okhttp/android/test/ShadowDnsResolver.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package okhttp3.android +package okhttp.android.test import android.net.DnsResolver import android.net.Network diff --git a/build.gradle.kts b/build.gradle.kts index da74c4002860..dd647ba4fe41 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,18 +1,17 @@ @file:Suppress("UnstableApiUsage") -import com.diffplug.gradle.spotless.KotlinExtension import com.diffplug.gradle.spotless.SpotlessExtension import com.vanniktech.maven.publish.MavenPublishBaseExtension import com.vanniktech.maven.publish.SonatypeHost -import java.net.URI import kotlinx.validation.ApiValidationExtension import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.jetbrains.dokka.gradle.DokkaTaskPartial +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.kotlinExtension -import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper +import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.jetbrains.kotlin.js.translate.context.Namer.kotlin import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension +import java.net.URI buildscript { dependencies { @@ -21,7 +20,6 @@ buildscript { classpath(libs.gradlePlugin.kotlinSerialization) classpath(libs.gradlePlugin.androidJunit5) classpath(libs.gradlePlugin.android) - classpath(libs.gradlePlugin.graal) classpath(libs.gradlePlugin.bnd) classpath(libs.gradlePlugin.shadow) classpath(libs.gradlePlugin.animalsniffer) @@ -29,6 +27,8 @@ buildscript { classpath(libs.gradlePlugin.spotless) classpath(libs.gradlePlugin.mavenPublish) classpath(libs.gradlePlugin.binaryCompatibilityValidator) + classpath(libs.gradlePlugin.mavenSympathy) + classpath(libs.gradlePlugin.graalvmBuildTools) } repositories { @@ -44,6 +44,7 @@ apply(plugin = "com.diffplug.spotless") configure { kotlin { target("**/*.kt") + targetExclude("**/kotlinTemplates/**/*.kt") ktlint() } } @@ -57,7 +58,7 @@ allprojects { google() } - tasks.create("downloadDependencies") { + tasks.register("downloadDependencies") { description = "Download all dependencies to the Gradle cache" doLast { for (configuration in configurations) { @@ -77,6 +78,9 @@ allprojects { } } +val platform = System.getProperty("okhttp.platform", "jdk9") +val testJavaVersion = System.getProperty("test.java.version", "21").toInt() + /** Configure building for Java+Kotlin projects. */ subprojects { val project = this@subprojects @@ -90,15 +94,32 @@ subprojects { apply(plugin = "checkstyle") apply(plugin = "ru.vyarus.animalsniffer") - apply(plugin = "biz.aQute.bnd.builder") + + // The 'java' plugin has been applied, but it is not compatible with the Android plugins. + // These are applied inside the okhttp module for that case specifically + if (project.name != "okhttp") { + apply(plugin = "biz.aQute.bnd.builder") + apply(plugin = "io.github.usefulness.maven-sympathy") + } + + // Skip samples parent + if (project.buildFile.exists() && project.name != "okhttp") { + apply(plugin = "com.android.lint") + + dependencies { + "lintChecks"(rootProject.libs.androidx.lint.gradle) + } + } tasks.withType { options.encoding = Charsets.UTF_8.toString() } - configure { - toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) + if (plugins.hasPlugin(JavaBasePlugin::class.java)) { + extensions.configure { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } } } @@ -113,38 +134,54 @@ subprojects { } } - configure { - config = resources.text.fromArchiveEntry(checkstyleConfig, "google_checks.xml") - toolVersion = rootProject.libs.versions.checkStyle.get() - sourceSets = listOf(project.sourceSets["main"]) - } + // Handled in :okhttp directly + if (project.name != "okhttp") { + configure { + config = resources.text.fromArchiveEntry(checkstyleConfig, "google_checks.xml") + toolVersion = rootProject.libs.versions.checkStyle.get() + sourceSets = listOf(project.sourceSets["main"]) + } - // Animal Sniffer confirms we generally don't use APIs not on Java 8. - configure { - annotation = "okhttp3.internal.SuppressSignatureCheck" - sourceSets = listOf(project.sourceSets["main"]) + // Animal Sniffer confirms we generally don't use APIs not on Java 8. + configure { + annotation = "okhttp3.internal.SuppressSignatureCheck" + sourceSets = listOf(project.sourceSets["main"]) + } } - val signature: Configuration by configurations.getting dependencies { // No dependency requirements for testing-support. if (project.name == "okhttp-testing-support") return@dependencies + // okhttp configured specifically. + if (project.name == "okhttp") return@dependencies + if (project.name == "mockwebserver3-junit5") { // JUnit 5's APIs need java.util.function.Function and java.util.Optional from API 24. - signature(rootProject.libs.signature.android.apilevel24) { artifact { type = "signature" } } + "signature"(rootProject.libs.signature.android.apilevel24) { artifact { type = "signature" } } } else { // Everything else requires Android API 21+. - signature(rootProject.libs.signature.android.apilevel21) { artifact { type = "signature" } } + "signature"(rootProject.libs.signature.android.apilevel21) { artifact { type = "signature" } } } // OkHttp requires Java 8+. - signature(rootProject.libs.codehaus.signature.java18) { artifact { type = "signature" } } + "signature"(rootProject.libs.codehaus.signature.java18) { artifact { type = "signature" } } } + val javaVersionSetting = + if (testJavaVersion > 8 && (project.name == "okcurl" || project.name == "native-image-tests")) { + // Depends on native-image-tools which is 11+, but avoids on Java 8 tests + "11" + } else { + "1.8" + } + + val projectJvmTarget = JvmTarget.fromTarget(javaVersionSetting) + val projectJavaVersion = JavaVersion.toVersion(javaVersionSetting) + tasks.withType { - kotlinOptions { - jvmTarget = JavaVersion.VERSION_1_8.toString() + compilerOptions { + jvmTarget.set(projectJvmTarget) freeCompilerArgs = listOf( "-Xjvm-default=all", ) @@ -154,10 +191,12 @@ subprojects { val platform = System.getProperty("okhttp.platform", "jdk9") val testJavaVersion = System.getProperty("test.java.version", "21").toInt() - val testRuntimeOnly: Configuration by configurations.getting - dependencies { - testRuntimeOnly(rootProject.libs.junit.jupiter.engine) - testRuntimeOnly(rootProject.libs.junit.vintage.engine) + if (project.name != "okhttp") { + val testRuntimeOnly: Configuration by configurations.getting + dependencies { + testRuntimeOnly(rootProject.libs.junit.jupiter.engine) + testRuntimeOnly(rootProject.libs.junit.vintage.engine) + } } tasks.withType { @@ -190,31 +229,36 @@ subprojects { tasks.withType().configureEach { environment("OKHTTP_ROOT", rootDir) } + tasks.withType().configureEach { + environment("OKHTTP_ROOT", rootDir) + } - if (platform == "jdk8alpn") { - // Add alpn-boot on Java 8 so we can use HTTP/2 without a stable API. - val alpnBootVersion = alpnBootVersion() - if (alpnBootVersion != null) { - val alpnBootJar = configurations.detachedConfiguration( - dependencies.create("org.mortbay.jetty.alpn:alpn-boot:$alpnBootVersion") - ).singleFile - tasks.withType { - jvmArgs("-Xbootclasspath/p:${alpnBootJar}") + if (project.name != "okhttp") { + if (platform == "jdk8alpn") { + // Add alpn-boot on Java 8 so we can use HTTP/2 without a stable API. + val alpnBootVersion = alpnBootVersion() + if (alpnBootVersion != null) { + val alpnBootJar = configurations.detachedConfiguration( + dependencies.create("org.mortbay.jetty.alpn:alpn-boot:$alpnBootVersion") + ).singleFile + tasks.withType { + jvmArgs("-Xbootclasspath/p:${alpnBootJar}") + } + } + } else if (platform == "conscrypt") { + dependencies { +// testRuntimeOnly(rootProject.libs.conscrypt.openjdk) + } + } else if (platform == "openjsse") { + dependencies { +// testRuntimeOnly(rootProject.libs.openjsse) } - } - } else if (platform == "conscrypt") { - dependencies { - testRuntimeOnly(rootProject.libs.conscrypt.openjdk) - } - } else if (platform == "openjsse") { - dependencies { - testRuntimeOnly(rootProject.libs.openjsse) } } tasks.withType { - sourceCompatibility = JavaVersion.VERSION_1_8.toString() - targetCompatibility = JavaVersion.VERSION_1_8.toString() + sourceCompatibility = projectJavaVersion.toString() + targetCompatibility = projectJavaVersion.toString() } } @@ -225,6 +269,11 @@ subprojects { languageSettings.optIn("okhttp3.ExperimentalOkHttpApi") } } + plugins.withId("org.jetbrains.kotlin.multiplatform") { + kotlinExtension.sourceSets.configureEach { + languageSettings.optIn("okhttp3.ExperimentalOkHttpApi") + } + } plugins.withId("org.jetbrains.kotlin.android") { kotlinExtension.sourceSets.configureEach { languageSettings.optIn("okhttp3.ExperimentalOkHttpApi") @@ -254,7 +303,6 @@ subprojects { } plugins.withId("com.vanniktech.maven.publish.base") { - val publishingExtension = extensions.getByType(PublishingExtension::class.java) configure { publishToMavenCentral(SonatypeHost.S01, automaticRelease = true) signAllPublications() @@ -296,6 +344,14 @@ subprojects { } } +plugins.withId("org.jetbrains.kotlin.jvm") { + val test = tasks.named("test") + tasks.register("jvmTest") { + description = "Get 'gradlew jvmTest' to run the tests of JVM-only modules" + dependsOn(test) + } +} + tasks.wrapper { distributionType = Wrapper.DistributionType.ALL } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index e30c56b5d823..90a3bde87bea 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -23,5 +23,9 @@ repositories { } dependencies { - implementation("biz.aQute.bnd:biz.aQute.bnd.gradle:6.4.0") + // TODO (https://github.com/square/okhttp/issues/8612) we will need a consistent version + // 7.1.0 is used because it avoids this error + // Could not create an instance of type aQute.bnd.gradle.BundleTaskExtension. + // Cannot change attributes of configuration ':native-image-tests:compileClasspath' after it has been locked for mutation + implementation("biz.aQute.bnd:biz.aQute.bnd.gradle:7.1.0") } diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts new file mode 100644 index 000000000000..ae6fdeecb742 --- /dev/null +++ b/buildSrc/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "okhttp-buildSrc" diff --git a/container-tests/src/test/java/okhttp3/containers/BasicLoomTest.kt b/container-tests/src/test/java/okhttp3/containers/BasicLoomTest.kt index bf65399bcc06..4063a2e95033 100644 --- a/container-tests/src/test/java/okhttp3/containers/BasicLoomTest.kt +++ b/container-tests/src/test/java/okhttp3/containers/BasicLoomTest.kt @@ -49,6 +49,8 @@ class BasicLoomTest { @RegisterExtension val platform = PlatformRule() + // Use mock server so we are strictly testing OkHttp client only in this test. + // We should test MockWebServer later. @Container val mockServer: MockServerContainer = MockServerContainer(MOCKSERVER_IMAGE) @@ -71,6 +73,8 @@ class BasicLoomTest { executor = newVirtualThreadPerTaskExecutor() + // Capture non-deterministic but probable sysout warnings of pinned threads + // https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html System.setOut(PrintStream(capturedOut)) } diff --git a/docs/changelogs/changelog_4x.md b/docs/changelogs/changelog_4x.md index d5bfb30361bd..6019c35da441 100644 --- a/docs/changelogs/changelog_4x.md +++ b/docs/changelogs/changelog_4x.md @@ -6,9 +6,12 @@ OkHttp 4.x Change Log _2023-10-16_ * Fix: Don't hang taking headers for HTTP 103 responses. + * Fix: Recover gracefully when a cache entry's certificate is corrupted. + * Fix: Fail permanently when there's a failure loading the bundled public suffix database. This is the dataset that powers `HttpUrl.topPrivateDomain()`. + * Fix: Immediately update the connection's flow control window instead of waiting for the receiving stream to process it. @@ -16,9 +19,12 @@ _2023-10-16_ calls and that can receive data faster than they can process it. Previously, OkHttp limited HTTP/2 to 16 MiB of unacknowledged data per connection. With this fix there is a limit of 16 MiB of unacknowledged data per stream and no per-connection limit. + * Fix: Don't operate on a connection after it's been returned to the pool. This race occurred on failed web socket connection attempts. + * Upgrade: [Okio 3.6.0][okio_3_6_0]. + * Upgrade: [Kotlin 1.8.21][kotlin_1_8_21]. diff --git a/gradle.properties b/gradle.properties index d963d6a5a396..439ab99d084e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,13 +1,12 @@ org.gradle.caching=true -org.gradle.jvmargs='-Dfile.encoding=UTF-8' org.gradle.parallel=true -android.enableJetifier=true + android.useAndroidX=true -kotlin.mpp.stability.nowarn=true -kotlin.js.compiler=ir -kotlin.incremental.js.ir=true +kotlin.mpp.applyDefaultHierarchyTemplate=false + androidBuild=false graalBuild=false loomBuild=false containerTests=false -android.experimental.lint.version=8.2.0 + +org.gradle.jvmargs='-Dfile.encoding=UTF-8' diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 358debd3b74d..cb7d2b7f7725 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,66 +1,76 @@ [versions] +# 7.0.0 is JDK 17+ https://github.com/bndtools/bnd/wiki/Changes-in-7.0.0 biz-aQute-bnd = "6.4.0" -checkStyle = "10.15.0" -com-squareup-moshi = "1.15.1" -com-squareup-okio = "3.9.0" -de-mannodermaus-junit5 = "1.4.0" -graalvm = "22.3.2" -kotlinx-serialization = "1.6.3" +checkStyle = "10.21.1" +com-squareup-moshi = "1.15.2" +com-squareup-okio = "3.9.1" +de-mannodermaus-junit5 = "1.6.0" +graalvm = "24.1.1" +kotlinx-serialization = "1.7.3" +ksp = "2.1.0-1.0.29" +lintGradle = "1.0.0-alpha03" mockserverClient = "5.15.0" -org-bouncycastle = "1.76" +org-bouncycastle = "1.79" org-conscrypt = "2.5.2" -org-jetbrains-coroutines = "1.8.0" -org-jetbrains-kotlin = "1.9.23" -org-junit-jupiter = "5.10.2" -testcontainers = "1.19.7" +org-jetbrains-coroutines = "1.10.1" +org-jetbrains-kotlin = "2.1.0" +org-junit-jupiter = "5.11.4" +retrofit = "2.11.0" +startupRuntime = "1.2.0" +testcontainers = "1.20.4" [libraries] -amazonCorretto = "software.amazon.cryptools:AmazonCorrettoCryptoProvider:2.3.3" -androidx-activity = "androidx.activity:activity-ktx:1.8.2" -androidx-annotation = "androidx.annotation:annotation:1.7.1" -androidx-espresso-core = "androidx.test.espresso:espresso-core:3.5.1" -androidx-junit = "androidx.test.ext:junit:1.1.5" -androidx-test-runner = "androidx.test:runner:1.5.2" -animalsniffer-annotations = "org.codehaus.mojo:animal-sniffer-annotations:1.23" +amazonCorretto = "software.amazon.cryptools:AmazonCorrettoCryptoProvider:2.4.1" +androidx-activity = "androidx.activity:activity-ktx:1.9.3" +androidx-annotation = "androidx.annotation:annotation:1.9.1" +androidx-espresso-core = "androidx.test.espresso:espresso-core:3.6.1" +androidx-junit = "androidx.test.ext:junit:1.2.1" +androidx-lint-gradle = { module = "androidx.lint:lint-gradle", version.ref = "lintGradle" } +androidx-startup-runtime = { module = "androidx.startup:startup-runtime", version.ref = "startupRuntime" } +androidx-test-runner = "androidx.test:runner:1.6.2" +animalsniffer-annotations = "org.codehaus.mojo:animal-sniffer-annotations:1.24" aqute-resolve = { module = "biz.aQute.bnd:biz.aQute.resolve", version.ref = "biz-aQute-bnd" } -assertk = "com.willowtreeapps.assertk:assertk:0.28.0" +assertk = "com.willowtreeapps.assertk:assertk:0.28.1" bouncycastle-bcpkix = { module = "org.bouncycastle:bcpkix-jdk15to18", version.ref = "org-bouncycastle" } bouncycastle-bcprov = { module = "org.bouncycastle:bcprov-jdk15to18", version.ref = "org-bouncycastle" } bouncycastle-bctls = { module = "org.bouncycastle:bctls-jdk15to18", version.ref = "org-bouncycastle" } brotli-dec = "org.brotli:dec:0.1.2" checkStyle = { module = "com.puppycrawl.tools:checkstyle", version.ref = "checkStyle" } -clikt = "com.github.ajalt.clikt:clikt:4.3.0" +clikt = "com.github.ajalt.clikt:clikt:5.0.2" codehaus-signature-java18 = "org.codehaus.mojo.signature:java18:1.0" conscrypt-android = { module = "org.conscrypt:conscrypt-android", version.ref = "org-conscrypt" } conscrypt-openjdk = { module = "org.conscrypt:conscrypt-openjdk-uber", version.ref = "org-conscrypt" } -eclipseOsgi = "org.eclipse.platform:org.eclipse.osgi:3.19.0" +converter-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" } +eclipseOsgi = "org.eclipse.platform:org.eclipse.osgi:3.22.0" findbugs-jsr305 = "com.google.code.findbugs:jsr305:3.0.2" -gradlePlugin-android = "com.android.tools.build:gradle:8.2.0" -gradlePlugin-androidJunit5 = "de.mannodermaus.gradle.plugins:android-junit5:1.10.0.0" -gradlePlugin-animalsniffer = "ru.vyarus:gradle-animalsniffer-plugin:1.7.1" -gradlePlugin-binaryCompatibilityValidator = "org.jetbrains.kotlinx.binary-compatibility-validator:org.jetbrains.kotlinx.binary-compatibility-validator.gradle.plugin:0.14.0" +graal-sdk = { module = "org.graalvm.sdk:graal-sdk", version.ref = "graalvm" } +gradlePlugin-android = "com.android.tools.build:gradle:8.7.3" +gradlePlugin-androidJunit5 = "de.mannodermaus.gradle.plugins:android-junit5:1.11.3.0" +gradlePlugin-animalsniffer = "ru.vyarus:gradle-animalsniffer-plugin:1.7.2" +gradlePlugin-binaryCompatibilityValidator = "org.jetbrains.kotlinx.binary-compatibility-validator:org.jetbrains.kotlinx.binary-compatibility-validator.gradle.plugin:0.17.0" gradlePlugin-bnd = { module = "biz.aQute.bnd:biz.aQute.bnd.gradle", version.ref = "biz-aQute-bnd" } -gradlePlugin-dokka = "org.jetbrains.dokka:dokka-gradle-plugin:1.9.20" -gradlePlugin-errorprone = "net.ltgt.gradle:gradle-errorprone-plugin:3.1.0" -gradlePlugin-graal = "com.palantir.graal:gradle-graal:0.12.0" +gradlePlugin-dokka = "org.jetbrains.dokka:dokka-gradle-plugin:2.0.0" +gradlePlugin-errorprone = "net.ltgt.gradle:gradle-errorprone-plugin:4.1.0" +gradlePlugin-graalvmBuildTools = "org.graalvm.buildtools.native:org.graalvm.buildtools.native.gradle.plugin:0.10.4" gradlePlugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "org-jetbrains-kotlin" } gradlePlugin-kotlinSerialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "org-jetbrains-kotlin" } -gradlePlugin-mavenPublish = "com.vanniktech:gradle-maven-publish-plugin:0.28.0" +gradlePlugin-mavenPublish = "com.vanniktech:gradle-maven-publish-plugin:0.30.0" +gradlePlugin-mavenSympathy = "io.github.usefulness.maven-sympathy:io.github.usefulness.maven-sympathy.gradle.plugin:0.3.0" gradlePlugin-shadow = "gradle.plugin.com.github.johnrengelman:shadow:8.0.0" gradlePlugin-spotless = "com.diffplug.spotless:spotless-plugin-gradle:6.25.0" -guava-jre = "com.google.guava:guava:33.1.0-jre" -hamcrestLibrary = "org.hamcrest:hamcrest-library:2.2" -httpClient5 = "org.apache.httpcomponents.client5:httpclient5:5.3" -jettyClient = "org.eclipse.jetty:jetty-client:9.4.54.v20240208" -jnr-unixsocket = "com.github.jnr:jnr-unixsocket:0.38.22" -jsoup = "org.jsoup:jsoup:1.17.2" +guava-jre = "com.google.guava:guava:33.4.0-jre" +hamcrestLibrary = "org.hamcrest:hamcrest-library:3.0" +httpClient5 = "org.apache.httpcomponents.client5:httpclient5:5.4.1" +jettyClient = "org.eclipse.jetty:jetty-client:9.4.56.v20240826" +jnr-unixsocket = "com.github.jnr:jnr-unixsocket:0.38.23" +jsoup = "org.jsoup:jsoup:1.18.3" junit = "junit:junit:4.13.2" -junit-ktx = "androidx.test.ext:junit-ktx:1.1.5" +junit-ktx = "androidx.test.ext:junit-ktx:1.2.1" junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "org-junit-jupiter" } junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "org-junit-jupiter" } junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "org-junit-jupiter" } -junit-platform-console = "org.junit.platform:junit-platform-console:1.10.2" -junit-vintage-engine = "org.junit.vintage:junit-vintage-engine:5.10.2" +junit-platform-console = "org.junit.platform:junit-platform-console:1.11.4" +junit-vintage-engine = "org.junit.vintage:junit-vintage-engine:5.11.4" junit-pioneer = "org.junit-pioneer:junit-pioneer:1.9.1" junit5android-core = { module = "de.mannodermaus.junit5:android-test-core", version.ref = "de-mannodermaus-junit5" } junit5android-runner = { module = "de.mannodermaus.junit5:android-test-runner", version.ref = "de-mannodermaus-junit5" } @@ -70,7 +80,6 @@ kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = " kotlin-stdlib-osgi = { module = "org.jetbrains.kotlin:kotlin-osgi-bundle", version.ref = "org-jetbrains-kotlin" } kotlin-test-annotations = { module = "org.jetbrains.kotlin:kotlin-test-annotations-common", version.ref = "org-jetbrains-kotlin" } kotlin-test-common = { module = "org.jetbrains.kotlin:kotlin-test-common", version.ref = "org-jetbrains-kotlin" } -kotlin-test-js = { module = "org.jetbrains.kotlin:kotlin-test-js", version.ref = "org-jetbrains-kotlin" } kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "org-jetbrains-kotlin" } kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "org-jetbrains-coroutines" } kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "org-jetbrains-coroutines" } @@ -80,16 +89,17 @@ mockserver = { module = "org.testcontainers:mockserver", version.ref = "testcont mockserver-client = { module = "org.mock-server:mockserver-client-java-no-dependencies", version.ref = "mockserverClient" } nativeImageSvm = { module = "org.graalvm.nativeimage:svm", version.ref = "graalvm" } openjsse = "org.openjsse:openjsse:1.1.14" -playservices-safetynet = "com.google.android.gms:play-services-safetynet:18.0.1" -robolectric-android = "org.robolectric:android-all:14-robolectric-10818077" -robolectric = "org.robolectric:robolectric:4.12" +playservices-safetynet = "com.google.android.gms:play-services-safetynet:18.1.0" +retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" } +robolectric-android = "org.robolectric:android-all:15-robolectric-12650502" +robolectric = "org.robolectric:robolectric:4.14.1" signature-android-apilevel21 = "net.sf.androidscents.signature:android-api-level-21:5.0.1_r2" signature-android-apilevel24 = "net.sf.androidscents.signature:android-api-level-24:7.0_r2" squareup-moshi = { module = "com.squareup.moshi:moshi", version.ref = "com-squareup-moshi" } squareup-moshi-compiler = { module = "com.squareup.moshi:moshi-kotlin-codegen", version.ref = "com-squareup-moshi" } squareup-moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "com-squareup-moshi" } squareup-okhttp-icu = "com.squareup.okhttpicu:okhttp-icu:0.2.0" -squareup-kotlinPoet = "com.squareup:kotlinpoet:1.16.0" +squareup-kotlinPoet = "com.squareup:kotlinpoet:2.0.0" squareup-okio = { module = "com.squareup.okio:okio", version.ref = "com-squareup-okio" } squareup-okio-fakefilesystem = { module = "com.squareup.okio:okio-fakefilesystem", version.ref = "com-squareup-okio" } squareup-okio-nodefilesystem = { module = "com.squareup.okio:okio-nodefilesystem", version.ref = "com-squareup-okio" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd4917707..a4b76b9530d6 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e6aba2515d54..e0fd02028bca 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a426907..f3b75f3b0d4f 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 93e3f59f135d..9d21a21834d5 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/mkdocs.yml b/mkdocs.yml index 00b136820e2f..2490b3e5dd3b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -45,8 +45,8 @@ markdown_extensions: smart_enable: all - pymdownx.caret - pymdownx.emoji: - emoji_index: !!python/name:materialx.emoji.twemoji - emoji_generator: !!python/name:materialx.emoji.to_svg + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg - pymdownx.inlinehilite - pymdownx.magiclink - pymdownx.smartsymbols diff --git a/mockwebserver-junit4/build.gradle.kts b/mockwebserver-junit4/build.gradle.kts index ced54ebe9c95..389710bbe6d4 100644 --- a/mockwebserver-junit4/build.gradle.kts +++ b/mockwebserver-junit4/build.gradle.kts @@ -19,6 +19,7 @@ dependencies { api(libs.junit) testImplementation(libs.assertk) + testImplementation(libs.junit.vintage.engine) } mavenPublishing { diff --git a/mockwebserver/src/test/java/mockwebserver3/MockResponseSniTest.kt b/mockwebserver/src/test/java/mockwebserver3/MockResponseSniTest.kt index 1367de61c6cc..db3e63d32880 100644 --- a/mockwebserver/src/test/java/mockwebserver3/MockResponseSniTest.kt +++ b/mockwebserver/src/test/java/mockwebserver3/MockResponseSniTest.kt @@ -77,7 +77,10 @@ class MockResponseSniTest { assertThat(response.isSuccessful).isTrue() val recordedRequest = server.takeRequest() - assertThat(recordedRequest.handshakeServerNames).containsExactly(url.host) + // https://github.com/bcgit/bc-java/issues/1773 + if (!platform.isBouncyCastle()) { + assertThat(recordedRequest.handshakeServerNames).containsExactly(url.host) + } } /** @@ -126,7 +129,11 @@ class MockResponseSniTest { val recordedRequest = server.takeRequest() assertThat(recordedRequest.requestUrl!!.host).isEqualTo("header-host") - assertThat(recordedRequest.handshakeServerNames).containsExactly("url-host.com") + + // https://github.com/bcgit/bc-java/issues/1773 + if (!platform.isBouncyCastle()) { + assertThat(recordedRequest.handshakeServerNames).containsExactly("url-host.com") + } } /** No SNI for literal IPv6 addresses. */ @@ -149,7 +156,10 @@ class MockResponseSniTest { fun regularHostname() { val recordedRequest = requestToHostnameViaProxy("cash.app") assertThat(recordedRequest.requestUrl!!.host).isEqualTo("cash.app") - assertThat(recordedRequest.handshakeServerNames).containsExactly("cash.app") + // https://github.com/bcgit/bc-java/issues/1773 + if (!platform.isBouncyCastle()) { + assertThat(recordedRequest.handshakeServerNames).containsExactly("cash.app") + } } /** diff --git a/native-image-tests/README.md b/native-image-tests/README.md index b6a9ff6f5e7b..d0555882bcb0 100644 --- a/native-image-tests/README.md +++ b/native-image-tests/README.md @@ -3,21 +3,12 @@ Native Image Tests This executes OkHttp's test suite inside a Graalvm image. -Build the Native Image ----------------------- - -Compile the classes and metadata into a Graalvm native image. - -``` -./gradlew --info native-image-tests:nativeImage -``` - Execute ------- The native image runs JUnit 5 tests in the project. ``` -./native-image-tests/build/graal/ConsoleLauncher +./gradlew --info native-image-tests:nativeTest ``` diff --git a/native-image-tests/build.gradle.kts b/native-image-tests/build.gradle.kts index e585002458a8..250aea22ac39 100644 --- a/native-image-tests/build.gradle.kts +++ b/native-image-tests/build.gradle.kts @@ -1,10 +1,26 @@ -import org.apache.tools.ant.taskdefs.condition.Os - plugins { - id("com.palantir.graal") + id("org.graalvm.buildtools.native") kotlin("jvm") } +animalsniffer { + isIgnoreFailures = true +} + +val graal by sourceSets.creating + +sourceSets { + named("graal") {} + test { + java.srcDirs( + "../okhttp-brotli/src/test/java", + "../okhttp-dnsoverhttps/src/test/java", + "../okhttp-logging-interceptor/src/test/java", + "../okhttp-sse/src/test/java", + ) + } +} + dependencies { implementation(libs.junit.jupiter.api) implementation(libs.junit.jupiter.engine) @@ -21,7 +37,6 @@ dependencies { implementation(projects.mockwebserver3) implementation(projects.mockwebserver) implementation(projects.okhttpJavaNetCookiejar) - implementation(projects.mockwebserver3Junit4) implementation(projects.mockwebserver3Junit5) implementation(libs.aqute.resolve) implementation(libs.junit.jupiter.api) @@ -30,33 +45,24 @@ dependencies { implementation(libs.kotlin.test.common) implementation(libs.kotlin.test.junit) - implementation(libs.nativeImageSvm) - compileOnly(libs.findbugs.jsr305) -} -animalsniffer { - isIgnoreFailures = true + "graalCompileOnly"(libs.nativeImageSvm) + "graalCompileOnly"(libs.graal.sdk) + nativeImageTestCompileOnly(graal.output.classesDirs) } -sourceSets { - main { - java.srcDirs( - "../okhttp-brotli/src/test/java", - "../okhttp-dnsoverhttps/src/test/java", - "../okhttp-logging-interceptor/src/test/java", - "../okhttp-sse/src/test/java", - ) - } -} +graalvmNative { + testSupport = true -graal { - mainClass("okhttp3.RunTestsKt") - outputName("ConsoleLauncher") - graalVersion(libs.versions.graalvm.get()) - javaVersion("11") + binaries { + named("test") { + buildArgs.add("--features=okhttp3.nativeImage.TestRegistration") + buildArgs.add("--initialize-at-build-time=org.junit.platform.engine.TestTag") + buildArgs.add("--strict-image-heap") - option("--no-fallback") - option("--report-unsupported-elements-at-runtime") - option("-H:+ReportExceptionStackTraces") + // speed up development testing + buildArgs.add("-Ob") + } + } } diff --git a/native-image-tests/src/graal/java/okhttp3/nativeImage/TestRegistration.kt b/native-image-tests/src/graal/java/okhttp3/nativeImage/TestRegistration.kt new file mode 100644 index 000000000000..7f8f29f5b657 --- /dev/null +++ b/native-image-tests/src/graal/java/okhttp3/nativeImage/TestRegistration.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2020 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.nativeImage + +import org.graalvm.nativeimage.hosted.Feature + +class TestRegistration : Feature { + override fun beforeAnalysis(access: Feature.BeforeAnalysisAccess) { + } +} diff --git a/native-image-tests/src/main/kotlin/okhttp3/DotListener.kt b/native-image-tests/src/main/kotlin/okhttp3/DotListener.kt deleted file mode 100644 index ed1bb03a3b77..000000000000 --- a/native-image-tests/src/main/kotlin/okhttp3/DotListener.kt +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2020 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 - -import java.io.OutputStream -import java.io.PrintStream -import org.junit.platform.engine.TestExecutionResult -import org.junit.platform.launcher.TestExecutionListener -import org.junit.platform.launcher.TestIdentifier -import org.junit.platform.launcher.TestPlan - -object DotListener : TestExecutionListener { - private var originalSystemErr: PrintStream? = null - private var originalSystemOut: PrintStream? = null - private var testCount = 0 - - override fun executionSkipped( - testIdentifier: TestIdentifier, - reason: String, - ) { - printStatus("-") - } - - private fun printStatus(s: String) { - if (++testCount % 80 == 0) { - printStatus("\n") - } - originalSystemErr?.print(s) - } - - override fun executionFinished( - testIdentifier: TestIdentifier, - testExecutionResult: TestExecutionResult, - ) { - if (!testIdentifier.isContainer) { - when (testExecutionResult.status!!) { - TestExecutionResult.Status.ABORTED -> printStatus("-") - TestExecutionResult.Status.FAILED -> printStatus("F") - TestExecutionResult.Status.SUCCESSFUL -> printStatus(".") - } - } - } - - override fun testPlanExecutionFinished(testPlan: TestPlan) { - originalSystemErr?.println() - } - - fun install() { - originalSystemOut = System.out - originalSystemErr = System.err - - System.setOut(object : PrintStream(OutputStream.nullOutputStream()) {}) - System.setErr(object : PrintStream(OutputStream.nullOutputStream()) {}) - } - - fun uninstall() { - originalSystemOut.let { - System.setOut(it) - } - originalSystemErr.let { - System.setErr(it) - } - } -} diff --git a/native-image-tests/src/main/kotlin/okhttp3/GenerateClassList.kt b/native-image-tests/src/main/kotlin/okhttp3/GenerateClassList.kt deleted file mode 100644 index 109a2cd3828e..000000000000 --- a/native-image-tests/src/main/kotlin/okhttp3/GenerateClassList.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2019 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 - -import java.io.File -import org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor -import org.junit.platform.engine.discovery.DiscoverySelectors - -// TODO move to junit5 tags -val avoidedTests = - setOf( - "okhttp3.BouncyCastleTest", - "okhttp3.ConscryptTest", - "okhttp3.CorrettoTest", - "okhttp3.OpenJSSETest", - "okhttp3.internal.platform.Jdk8WithJettyBootPlatformTest", - "okhttp3.internal.platform.Jdk9PlatformTest", - "okhttp3.internal.platform.PlatformTest", - "okhttp3.internal.platform.android.AndroidSocketAdapterTest", - "okhttp3.osgi.OsgiTest", - // Hanging. - "okhttp3.CookiesTest", - // Hanging. - "okhttp3.WholeOperationTimeoutTest", - ) - -/** - * Run periodically to refresh the known set of working tests. - * - * TODO use filtering to allow skipping acceptable problem tests - */ -fun main() { - val knownTestFile = File("native-image-tests/src/main/resources/testlist.txt") - val testSelector = DiscoverySelectors.selectPackage("okhttp3") - val testClasses = - findTests(listOf(testSelector)) - .filter { it.isContainer } - .mapNotNull { (it as? ClassBasedTestDescriptor)?.testClass?.name } - .filterNot { it in avoidedTests } - .sorted() - .distinct() - knownTestFile.writeText(testClasses.joinToString("\n")) -} diff --git a/native-image-tests/src/main/kotlin/okhttp3/RunTests.kt b/native-image-tests/src/main/kotlin/okhttp3/RunTests.kt deleted file mode 100644 index 4fdd4c6b9651..000000000000 --- a/native-image-tests/src/main/kotlin/okhttp3/RunTests.kt +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2020 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 - -import java.io.File -import java.io.PrintWriter -import kotlin.system.exitProcess -import org.junit.jupiter.engine.JupiterTestEngine -import org.junit.platform.console.options.Theme -import org.junit.platform.engine.DiscoverySelector -import org.junit.platform.engine.TestDescriptor -import org.junit.platform.engine.TestEngine -import org.junit.platform.engine.discovery.DiscoverySelectors.selectClass -import org.junit.platform.launcher.Launcher -import org.junit.platform.launcher.LauncherDiscoveryRequest -import org.junit.platform.launcher.PostDiscoveryFilter -import org.junit.platform.launcher.TestExecutionListener -import org.junit.platform.launcher.core.EngineDiscoveryOrchestrator -import org.junit.platform.launcher.core.LauncherConfig -import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder -import org.junit.platform.launcher.core.LauncherFactory -import org.junit.platform.launcher.listeners.SummaryGeneratingListener - -/** - * Graal main method to run tests with minimal reflection and automatic settings. - * Uses the test list in native-image-tests/src/main/resources/testlist.txt. - */ -fun main(vararg args: String) { - System.setProperty("junit.jupiter.extensions.autodetection.enabled", "true") - - val inputFile = if (args.isNotEmpty()) File(args[0]) else null - val selectors = testSelectors(inputFile) - - val summaryListener = SummaryGeneratingListener() - val treeListener = treeListener() - - val jupiterTestEngine = buildTestEngine() - - val config = - LauncherConfig.builder() - .enableTestExecutionListenerAutoRegistration(false) - .enableTestEngineAutoRegistration(false) - .enablePostDiscoveryFilterAutoRegistration(false) - .addTestEngines(jupiterTestEngine) - .addTestExecutionListeners(DotListener, summaryListener, treeListener) - .build() - val launcher: Launcher = LauncherFactory.create(config) - - val request: LauncherDiscoveryRequest = buildRequest(selectors) - - DotListener.install() - - try { - launcher.execute(request) - } finally { - DotListener.uninstall() - } - - val summary = summaryListener.summary - summary.printTo(PrintWriter(System.out)) - - exitProcess(if (summary.testsFailedCount != 0L) -1 else 0) -} - -/** - * Builds the Junit Test Engine for the native image. - */ -fun buildTestEngine(): TestEngine = JupiterTestEngine() - -/** - * Returns a fixed set of test classes from testlist.txt, skipping any not found in the - * current classpath. The IDE runs with less classes to avoid conflicting module ownership. - */ -fun testSelectors(inputFile: File? = null): List { - val sampleTestClass = SampleTest::class.java - - val lines = - inputFile?.readLines() ?: sampleTestClass.getResource("/testlist.txt").readText().lines() - - val flatClassnameList = - lines - .filter { it.isNotBlank() } - - return flatClassnameList - .mapNotNull { - try { - selectClass(Class.forName(it, false, sampleTestClass.classLoader)) - } catch (cnfe: ClassNotFoundException) { - println("Missing test class: $cnfe") - null - } - } -} - -/** - * Builds a Junit Test Plan request for a fixed set of classes, or potentially a recursive package. - */ -fun buildRequest(selectors: List): LauncherDiscoveryRequest { - val request: LauncherDiscoveryRequest = - LauncherDiscoveryRequestBuilder.request() - // TODO replace junit.jupiter.extensions.autodetection.enabled with API approach. -// .enableImplicitConfigurationParameters(false) - .selectors(selectors) - .build() - return request -} - -/** - * Flattens a test filter into a list of specific test descriptors, usually individual method in a - * test class annotated with @Test. - */ -fun findTests(selectors: List): List { - val request: LauncherDiscoveryRequest = buildRequest(selectors) - val testEngine = buildTestEngine() - val filters = listOf() - val discoveryOrchestrator = EngineDiscoveryOrchestrator(listOf(testEngine), filters) - val discovered = discoveryOrchestrator.discover(request, EngineDiscoveryOrchestrator.Phase.EXECUTION) - - return discovered.getEngineTestDescriptor(testEngine).descendants.toList() -} - -/** - * Builds the awkwardly package private TreePrintingListener listener which we would like to use - * from ConsoleLauncher. - * - * https://github.com/junit-team/junit5/issues/2469 - */ -fun treeListener(): TestExecutionListener { - val colorPalette = - Class.forName("org.junit.platform.console.tasks.ColorPalette").getField("DEFAULT").apply { - isAccessible = true - }.get(null) - return Class.forName( - "org.junit.platform.console.tasks.TreePrintingListener", - ).declaredConstructors.first() - .apply { - isAccessible = true - } - .newInstance(PrintWriter(System.out), colorPalette, Theme.UNICODE) as TestExecutionListener -} diff --git a/native-image-tests/src/main/kotlin/okhttp3/TestRegistration.kt b/native-image-tests/src/main/kotlin/okhttp3/TestRegistration.kt deleted file mode 100644 index 0f882d4be118..000000000000 --- a/native-image-tests/src/main/kotlin/okhttp3/TestRegistration.kt +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2020 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 - -import com.oracle.svm.core.annotate.AutomaticFeature -import java.io.File -import java.lang.IllegalStateException -import org.graalvm.nativeimage.hosted.Feature -import org.graalvm.nativeimage.hosted.RuntimeClassInitialization -import org.graalvm.nativeimage.hosted.RuntimeReflection - -@AutomaticFeature -class TestRegistration : Feature { - override fun beforeAnalysis(access: Feature.BeforeAnalysisAccess) { - // Presumably needed for parsing the testlist.txt file. - RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("kotlin.text.Charsets")) - - registerKnownTests(access) - - registerJupiterClasses(access) - - registerParamProvider(access, "okhttp3.SampleTestProvider") - registerParamProvider(access, "okhttp3.internal.http.CancelModelParamProvider") - registerParamProvider(access, "okhttp3.internal.cache.FileSystemParamProvider") - registerParamProvider(access, "okhttp3.internal.http2.HttpOverHttp2Test\$ProtocolParamProvider") - registerParamProvider(access, "okhttp3.internal.cache.FileSystemParamProvider") - registerParamProvider(access, "okhttp3.WebPlatformUrlTest\$TestDataParamProvider") - } - - private fun registerParamProvider( - access: Feature.BeforeAnalysisAccess, - provider: String, - ) { - val providerClass = access.findClassByName(provider) - if (providerClass != null) { - registerTest(access, providerClass) - } else { - println("Missing $provider") - } - } - - private fun registerJupiterClasses(access: Feature.BeforeAnalysisAccess) { - registerStandardClass(access, "org.junit.jupiter.params.ParameterizedTestExtension") - registerStandardClass(access, "org.junit.platform.console.tasks.TreePrintingListener") - } - - private fun registerStandardClass( - access: Feature.BeforeAnalysisAccess, - name: String, - ) { - val clazz: Class<*> = access.findClassByName(name) ?: throw IllegalStateException("Missing class $name") - RuntimeReflection.register(clazz) - clazz.declaredConstructors.forEach { - RuntimeReflection.register(it) - } - } - - private fun registerKnownTests(access: Feature.BeforeAnalysisAccess) { - val knownTestFile = File("src/main/resources/testlist.txt").absoluteFile - knownTestFile.readLines().forEach { - try { - val testClass = access.findClassByName(it) - - if (testClass != null) { - access.registerAsUsed(testClass) - registerTest(access, testClass) - } - } catch (e: Exception) { - // If you throw an exception here then native image building fails half way through - // silently without rewriting the binary. So we report noisily, but keep going and prefer - // running most tests still. - e.printStackTrace() - } - } - } - - private fun registerTest( - access: Feature.BeforeAnalysisAccess, - java: Class<*>, - ) { - access.registerAsUsed(java) - RuntimeReflection.register(java) - java.constructors.forEach { - RuntimeReflection.register(it) - } - java.declaredMethods.forEach { - RuntimeReflection.register(it) - } - java.declaredFields.forEach { - RuntimeReflection.register(it) - } - java.methods.forEach { - RuntimeReflection.register(it) - } - } -} diff --git a/native-image-tests/src/main/resources/testlist.txt b/native-image-tests/src/main/resources/testlist.txt deleted file mode 100644 index fdf740f21105..000000000000 --- a/native-image-tests/src/main/resources/testlist.txt +++ /dev/null @@ -1,86 +0,0 @@ -okhttp3.AddressTest -okhttp3.CacheControlTest -okhttp3.CacheCorruptionTest -okhttp3.CacheTest -okhttp3.CallHandshakeTest -okhttp3.CallKotlinTest -okhttp3.CallTest -okhttp3.CertificateChainCleanerTest -okhttp3.CertificatePinnerKotlinTest -okhttp3.CertificatePinnerTest -okhttp3.CipherSuiteTest -okhttp3.ConnectionCoalescingTest -okhttp3.ConnectionReuseTest -okhttp3.ConnectionSpecTest -okhttp3.CookieTest -okhttp3.DispatcherTest -okhttp3.DuplexTest -okhttp3.EventListenerTest -okhttp3.FormBodyTest -okhttp3.HandshakeTest -okhttp3.HeadersKotlinTest -okhttp3.HeadersTest -okhttp3.HttpUrlTest -okhttp3.InsecureForHostTest -okhttp3.InterceptorTest -okhttp3.KotlinDeprecationErrorTest -okhttp3.KotlinSourceModernTest -okhttp3.MediaTypeGetTest -okhttp3.MediaTypeTest -okhttp3.MultipartBodyTest -okhttp3.MultipartReaderTest -okhttp3.OkHttpClientTest -okhttp3.OkHttpTest -okhttp3.ProtocolTest -okhttp3.PublicSuffixDatabaseTest -okhttp3.PublicInternalApiTest -okhttp3.RequestTest -okhttp3.ResponseBodyTest -okhttp3.ResponseTest -okhttp3.SampleTest -okhttp3.ServerTruncatesRequestTest -okhttp3.SocksProxyTest -okhttp3.URLConnectionTest -okhttp3.WebPlatformUrlTest -okhttp3.brotli.BrotliInterceptorJavaApiTest -okhttp3.brotli.BrotliInterceptorTest -okhttp3.dnsoverhttps.DnsOverHttpsTest -okhttp3.dnsoverhttps.DnsRecordCodecTest -okhttp3.internal.UtilTest -okhttp3.internal.authenticator.JavaNetAuthenticatorTest -okhttp3.internal.cache.DiskLruCacheTest -okhttp3.internal.cache2.FileOperatorTest -okhttp3.internal.cache2.RelayTest -okhttp3.internal.concurrent.TaskLoggerTest -okhttp3.internal.concurrent.TaskRunnerRealBackendTest -okhttp3.internal.concurrent.TaskRunnerTest -okhttp3.internal.connection.ConnectionPoolTest -okhttp3.internal.connection.ConnectionSpecSelectorTest -okhttp3.internal.connection.RouteExceptionTest -okhttp3.internal.connection.RouteSelectorTest -okhttp3.internal.http.CancelTest -okhttp3.internal.http.HttpDateTest -okhttp3.internal.http.StatusLineTest -okhttp3.internal.http.ThreadInterruptTest -okhttp3.internal.http2.FrameLogTest -okhttp3.internal.http2.HpackTest -okhttp3.internal.http2.Http2ConnectionTest -okhttp3.internal.http2.Http2Test -okhttp3.internal.http2.HttpOverHttp2Test -okhttp3.internal.http2.HuffmanTest -okhttp3.internal.http2.SettingsTest -okhttp3.internal.publicsuffix.PublicSuffixDatabaseTest -okhttp3.internal.tls.CertificatePinnerChainValidationTest -okhttp3.internal.tls.ClientAuthTest -okhttp3.internal.tls.HostnameVerifierTest -okhttp3.internal.ws.MessageDeflaterInflaterTest -okhttp3.internal.ws.RealWebSocketTest -okhttp3.internal.ws.WebSocketExtensionsTest -okhttp3.internal.ws.WebSocketHttpTest -okhttp3.internal.ws.WebSocketReaderTest -okhttp3.internal.ws.WebSocketWriterTest -okhttp3.logging.HttpLoggingInterceptorTest -okhttp3.logging.IsProbablyUtf8Test -okhttp3.logging.LoggingEventListenerTest -okhttp3.sse.internal.EventSourceHttpTest -okhttp3.sse.internal.ServerSentEventIteratorTest diff --git a/native-image-tests/src/test/kotlin/okhttp3/nativeImage/NativeImageTestsTest.kt b/native-image-tests/src/test/kotlin/okhttp3/nativeImage/NativeImageTestsTest.kt deleted file mode 100644 index 6ba5f223e5f7..000000000000 --- a/native-image-tests/src/test/kotlin/okhttp3/nativeImage/NativeImageTestsTest.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2020 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.nativeImage - -import okhttp3.SampleTest -import okhttp3.findTests -import okhttp3.testSelectors -import okhttp3.treeListener -import org.junit.jupiter.api.Assertions.assertNotNull -import org.junit.jupiter.api.Test -import org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor -import org.junit.platform.engine.discovery.DiscoverySelectors - -class NativeImageTestsTest { - @Test - fun testFindsFixedTestsForImage() { - val testSelector = testSelectors() - val x = findTests(testSelector) - - x.find { it is ClassBasedTestDescriptor && it.testClass == SampleTest::class.java } - } - - @Test - fun testFindsModuleTests() { - val testSelector = DiscoverySelectors.selectPackage("okhttp3") - val x = findTests(listOf(testSelector)) - - x.find { it is ClassBasedTestDescriptor && it.testClass == SampleTest::class.java } - } - - @Test - fun testFindsProjectTests() { - val testSelector = DiscoverySelectors.selectPackage("okhttp3") - val x = findTests(listOf(testSelector)) - - x.find { it is ClassBasedTestDescriptor && it.testClass == SampleTest::class.java } - } - - @Test - fun testTreeListener() { - val listener = treeListener() - - assertNotNull(listener) - } -} diff --git a/native-image-tests/src/main/kotlin/okhttp3/PublicSuffixDatabaseTest.kt b/native-image-tests/src/test/kotlin/okhttp3/nativeImage/PublicSuffixDatabaseTest.kt similarity index 75% rename from native-image-tests/src/main/kotlin/okhttp3/PublicSuffixDatabaseTest.kt rename to native-image-tests/src/test/kotlin/okhttp3/nativeImage/PublicSuffixDatabaseTest.kt index 98a452cd40dc..be9388bd9c36 100644 --- a/native-image-tests/src/main/kotlin/okhttp3/PublicSuffixDatabaseTest.kt +++ b/native-image-tests/src/test/kotlin/okhttp3/nativeImage/PublicSuffixDatabaseTest.kt @@ -13,15 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package okhttp3 +package okhttp3.nativeImage import assertk.assertThat import assertk.assertions.isEqualTo -import assertk.assertions.isGreaterThan import okhttp3.HttpUrl.Companion.toHttpUrl -import okhttp3.internal.publicsuffix.PublicSuffixDatabase import okhttp3.testing.PlatformRule -import okio.FileSystem import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.RegisterExtension @@ -36,12 +33,4 @@ class PublicSuffixDatabaseTest { assertThat(url.topPrivateDomain()).isEqualTo("twitter.com") } - - @Test - fun testPublicSuffixes() { - platform.assumeNotGraalVMImage() - - val metadata = FileSystem.RESOURCES.metadata(PublicSuffixDatabase.PUBLIC_SUFFIX_RESOURCE) - assertThat(metadata.size!!).isGreaterThan(30000) - } } diff --git a/native-image-tests/src/main/kotlin/okhttp3/SampleTest.kt b/native-image-tests/src/test/kotlin/okhttp3/nativeImage/SampleTest.kt similarity index 87% rename from native-image-tests/src/main/kotlin/okhttp3/SampleTest.kt rename to native-image-tests/src/test/kotlin/okhttp3/nativeImage/SampleTest.kt index 73c07198e738..2e40576afd3e 100644 --- a/native-image-tests/src/main/kotlin/okhttp3/SampleTest.kt +++ b/native-image-tests/src/test/kotlin/okhttp3/nativeImage/SampleTest.kt @@ -13,18 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package okhttp3 +package okhttp3.nativeImage import assertk.assertThat import assertk.assertions.isEqualTo import mockwebserver3.MockResponse import mockwebserver3.MockWebServer +import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.OkHttpClientTestRule +import okhttp3.Request +import okhttp3.SimpleProvider import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.ArgumentsSource +@ExtendWith(MockWebServerExtension::class) class SampleTest { @JvmField @RegisterExtension val clientRule = OkHttpClientTestRule() diff --git a/native-image-tests/src/main/resources/META-INF/native-image/okhttp/nit/resource-config.json b/native-image-tests/src/test/resources/META-INF/native-image/okhttp/nit/resource-config.json similarity index 69% rename from native-image-tests/src/main/resources/META-INF/native-image/okhttp/nit/resource-config.json rename to native-image-tests/src/test/resources/META-INF/native-image/okhttp/nit/resource-config.json index a91b6a761b04..500ef92fbef5 100644 --- a/native-image-tests/src/main/resources/META-INF/native-image/okhttp/nit/resource-config.json +++ b/native-image-tests/src/test/resources/META-INF/native-image/okhttp/nit/resource-config.json @@ -1,6 +1,5 @@ { "resources": [ - {"pattern": "testlist.txt"}, {"pattern": "web-platform-test-urltestdata.txt"} ] -} \ No newline at end of file +} diff --git a/okcurl/build.gradle.kts b/okcurl/build.gradle.kts index 77734c77c77d..0cfa1a5d19a2 100644 --- a/okcurl/build.gradle.kts +++ b/okcurl/build.gradle.kts @@ -1,18 +1,20 @@ import com.vanniktech.maven.publish.JavadocJar import com.vanniktech.maven.publish.KotlinJvm -import org.apache.tools.ant.taskdefs.condition.Os +import org.graalvm.buildtools.gradle.dsl.GraalVMExtension +import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension plugins { kotlin("jvm") id("org.jetbrains.dokka") id("com.vanniktech.maven.publish.base") - id("com.palantir.graal") id("com.github.johnrengelman.shadow") } +val testJavaVersion = System.getProperty("test.java.version", "21").toInt() + val copyResourcesTemplates = tasks.register("copyResourcesTemplates") { from("src/main/resources-templates") - into("$buildDir/generated/resources-templates") + into(layout.buildDirectory.dir("generated/resources-templates")) expand("projectVersion" to "${project.version}") filteringCharset = Charsets.UTF_8.toString() } @@ -38,7 +40,7 @@ dependencies { testImplementation(kotlin("test")) } -animalsniffer { +configure { isIgnoreFailures = true } @@ -53,19 +55,16 @@ tasks.shadowJar { mergeServiceFiles() } -graal { - mainClass("okhttp3.curl.MainCommandLineKt") - outputName("okcurl") - graalVersion(libs.versions.graalvm.get()) - javaVersion("11") - - option("--no-fallback") +if (testJavaVersion >= 11) { + apply(plugin = "org.graalvm.buildtools.native") - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - // May be possible without, but autodetection is problematic on Windows 10 - // see https://github.com/palantir/gradle-graal - // see https://www.graalvm.org/docs/reference-manual/native-image/#prerequisites - windowsVsVarsPath("C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat") + configure { + binaries { + named("main") { + imageName = "okcurl" + mainClass = "okhttp3.curl.MainCommandLineKt" + } + } } } diff --git a/okcurl/src/main/kotlin/okhttp3/curl/Main.kt b/okcurl/src/main/kotlin/okhttp3/curl/Main.kt index 126af4c31dbb..c9b09179334a 100644 --- a/okcurl/src/main/kotlin/okhttp3/curl/Main.kt +++ b/okcurl/src/main/kotlin/okhttp3/curl/Main.kt @@ -16,9 +16,12 @@ package okhttp3.curl import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.core.Context import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.arguments.help import com.github.ajalt.clikt.parameters.options.default import com.github.ajalt.clikt.parameters.options.flag +import com.github.ajalt.clikt.parameters.options.help import com.github.ajalt.clikt.parameters.options.multiple import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.types.int @@ -39,42 +42,54 @@ import okhttp3.internal.platform.Platform import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.LoggingEventListener -class Main : CliktCommand(name = NAME, help = "A curl for the next-generation web.") { - val method: String? by option("-X", "--request", help = "Specify request command to use") +class Main : CliktCommand(name = NAME) { + override val printHelpOnEmptyArgs = true - val data: String? by option("-d", "--data", help = "HTTP POST data") + override fun help(context: Context): String = "A curl for the next-generation web." - val headers: List? by option("-H", "--header", help = "Custom header to pass to server").multiple() + val method: String? by option("-X", "--request").help("Specify request command to use") - val userAgent: String by option("-A", "--user-agent", help = "User-Agent to send to server").default(NAME + "/" + versionString()) + val data: String? by option("-d", "--data").help("HTTP POST data") + + val headers: List? by option("-H", "--header").help("Custom header to pass to server").multiple() + + val userAgent: String by option( + "-A", + "--user-agent", + ).help( + "User-Agent to send to server", + ).default(NAME + "/" + versionString()) val connectTimeout: Int by option( "--connect-timeout", - help = "Maximum time allowed for connection (seconds)", + ).help( + "Maximum time allowed for connection (seconds)", ).int().default(DEFAULT_TIMEOUT) - val readTimeout: Int by option("--read-timeout", help = "Maximum time allowed for reading data (seconds)").int().default(DEFAULT_TIMEOUT) + val readTimeout: Int by option("--read-timeout").help("Maximum time allowed for reading data (seconds)").int() + .default(DEFAULT_TIMEOUT) val callTimeout: Int by option( "--call-timeout", - help = "Maximum time allowed for the entire call (seconds)", + ).help( + "Maximum time allowed for the entire call (seconds)", ).int().default(DEFAULT_TIMEOUT) - val followRedirects: Boolean by option("-L", "--location", help = "Follow redirects").flag() + val followRedirects: Boolean by option("-L", "--location").help("Follow redirects").flag() - val allowInsecure: Boolean by option("-k", "--insecure", help = "Allow connections to SSL sites without certs").flag() + val allowInsecure: Boolean by option("-k", "--insecure").help("Allow connections to SSL sites without certs").flag() - val showHeaders: Boolean by option("-i", "--include", help = "Include protocol headers in the output").flag() + val showHeaders: Boolean by option("-i", "--include").help("Include protocol headers in the output").flag() - val showHttp2Frames: Boolean by option("--frames", help = "Log HTTP/2 frames to STDERR").flag() + val showHttp2Frames: Boolean by option("--frames").help("Log HTTP/2 frames to STDERR").flag() - val referer: String? by option("-e", "--referer", help = "Referer URL") + val referer: String? by option("-e", "--referer").help("Referer URL") - val verbose: Boolean by option("-v", "--verbose", help = "Makes $NAME verbose during the operation").flag() + val verbose: Boolean by option("-v", "--verbose").help("Makes $NAME verbose during the operation").flag() - val sslDebug: Boolean by option(help = "Output SSL Debug").flag() + val sslDebug: Boolean by option("--sslDebug").help("Output SSL Debug").flag() - val url: String? by argument(name = "url", help = "Remote resource URL") + val url: String? by argument(name = "url").help("Remote resource URL") var client: Call.Factory? = null @@ -129,17 +144,20 @@ class Main : CliktCommand(name = NAME, help = "A curl for the next-generation we return prop.getProperty("version", "dev") } + @Suppress("TrustAllX509TrustManager", "CustomX509TrustManager") private fun createInsecureTrustManager(): X509TrustManager = object : X509TrustManager { override fun checkClientTrusted( chain: Array, authType: String, - ) {} + ) { + } override fun checkServerTrusted( chain: Array, authType: String, - ) {} + ) { + } override fun getAcceptedIssuers(): Array = arrayOf() } diff --git a/okcurl/src/main/kotlin/okhttp3/curl/MainCommandLine.kt b/okcurl/src/main/kotlin/okhttp3/curl/MainCommandLine.kt index 983048a8143d..b56011c07b9d 100644 --- a/okcurl/src/main/kotlin/okhttp3/curl/MainCommandLine.kt +++ b/okcurl/src/main/kotlin/okhttp3/curl/MainCommandLine.kt @@ -15,6 +15,7 @@ */ package okhttp3.curl +import com.github.ajalt.clikt.core.main import kotlin.system.exitProcess fun main(args: Array) { diff --git a/okcurl/src/test/kotlin/okhttp3/curl/MainTest.kt b/okcurl/src/test/kotlin/okhttp3/curl/MainTest.kt index 0a2598a2e694..ae31c41c2521 100644 --- a/okcurl/src/test/kotlin/okhttp3/curl/MainTest.kt +++ b/okcurl/src/test/kotlin/okhttp3/curl/MainTest.kt @@ -19,6 +19,7 @@ import assertk.assertThat import assertk.assertions.isEqualTo import assertk.assertions.isNull import assertk.assertions.startsWith +import com.github.ajalt.clikt.core.parse import java.io.IOException import kotlin.test.Test import okhttp3.RequestBody diff --git a/okcurl/src/test/kotlin/okhttp3/curl/OkcurlTest.kt b/okcurl/src/test/kotlin/okhttp3/curl/OkcurlTest.kt index d632e8bae9f8..f7a68dbcbc0a 100644 --- a/okcurl/src/test/kotlin/okhttp3/curl/OkcurlTest.kt +++ b/okcurl/src/test/kotlin/okhttp3/curl/OkcurlTest.kt @@ -15,6 +15,7 @@ */ package okhttp3.curl +import com.github.ajalt.clikt.core.main import kotlin.test.Test class OkcurlTest { diff --git a/okhttp-android/Module.md b/okhttp-android/Module.md deleted file mode 100644 index 4529ef4a1d60..000000000000 --- a/okhttp-android/Module.md +++ /dev/null @@ -1,3 +0,0 @@ -# Module okhttp-android - -OkHttp Android library. diff --git a/okhttp-android/README.md b/okhttp-android/README.md deleted file mode 100644 index 46efc377dd0d..000000000000 --- a/okhttp-android/README.md +++ /dev/null @@ -1,13 +0,0 @@ -OkHttp Android -============== - -Enhanced APIs for using OkHttp on Android. - -At the moment, this will mostly likely only be useful for fastFallback. - -Download --------- - -```kotlin -implementation("com.squareup.okhttp3:okhttp-android:4.12.0") -``` diff --git a/okhttp-android/api/okhttp-android.api b/okhttp-android/api/okhttp-android.api deleted file mode 100644 index a3884fa7c672..000000000000 --- a/okhttp-android/api/okhttp-android.api +++ /dev/null @@ -1,19 +0,0 @@ -public final class okhttp3/android/AndroidAsyncDns : okhttp3/AsyncDns { - public static final field Companion Lokhttp3/android/AndroidAsyncDns$Companion; - public fun (Lokhttp3/AsyncDns$DnsClass;Landroid/net/Network;)V - public synthetic fun (Lokhttp3/AsyncDns$DnsClass;Landroid/net/Network;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun query (Ljava/lang/String;Lokhttp3/AsyncDns$Callback;)V -} - -public final class okhttp3/android/AndroidAsyncDns$Companion { - public final fun getIPv4 ()Lokhttp3/android/AndroidAsyncDns; - public final fun getIPv6 ()Lokhttp3/android/AndroidAsyncDns; -} - -public final class okhttp3/android/AndroidLoggingKt { - public static final fun androidLogging (Lokhttp3/logging/HttpLoggingInterceptor$Companion;ILjava/lang/String;)Lokhttp3/logging/HttpLoggingInterceptor; - public static final fun androidLogging (Lokhttp3/logging/LoggingEventListener$Companion;ILjava/lang/String;)Lokhttp3/logging/LoggingEventListener$Factory; - public static synthetic fun androidLogging$default (Lokhttp3/logging/HttpLoggingInterceptor$Companion;ILjava/lang/String;ILjava/lang/Object;)Lokhttp3/logging/HttpLoggingInterceptor; - public static synthetic fun androidLogging$default (Lokhttp3/logging/LoggingEventListener$Companion;ILjava/lang/String;ILjava/lang/Object;)Lokhttp3/logging/LoggingEventListener$Factory; -} - diff --git a/okhttp-android/build.gradle.kts b/okhttp-android/build.gradle.kts deleted file mode 100644 index 59a27124e4ff..000000000000 --- a/okhttp-android/build.gradle.kts +++ /dev/null @@ -1,77 +0,0 @@ -@file:SuppressLint("OldTargetApi") - -import android.annotation.SuppressLint -import com.vanniktech.maven.publish.JavadocJar - -plugins { - id("com.android.library") - kotlin("android") - id("org.jetbrains.dokka") - id("com.vanniktech.maven.publish.base") - id("binary-compatibility-validator") -} - -android { - compileSdk = 34 - - namespace = "okhttp.android" - - defaultConfig { - minSdk = 21 - - // Make sure to use the AndroidJUnitRunner (or a sub-class) in order to hook in the JUnit 5 Test Builder - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - - buildFeatures { - buildConfig = false - } - - testOptions { - unitTests { - isIncludeAndroidResources = true - } - - targetSdk = 34 - } - } - - compileOptions { - targetCompatibility(JavaVersion.VERSION_11) - sourceCompatibility(JavaVersion.VERSION_11) - } - - kotlinOptions { - jvmTarget = JavaVersion.VERSION_11.toString() - } -} - -dependencies { - api(libs.squareup.okio) - api(projects.okhttp) - api(projects.loggingInterceptor) - compileOnly(libs.androidx.annotation) - compileOnly(libs.findbugs.jsr305) - debugImplementation(libs.androidx.annotation) - debugImplementation(libs.findbugs.jsr305) - compileOnly(libs.animalsniffer.annotations) - compileOnly(libs.robolectric.android) - - testImplementation(libs.junit) - testImplementation(libs.junit.ktx) - testImplementation(libs.assertk) - testImplementation(projects.okhttpTls) - testImplementation(libs.androidx.test.runner) - testImplementation(libs.robolectric) - testImplementation(libs.androidx.espresso.core) - testImplementation(libs.squareup.okio.fakefilesystem) - - androidTestImplementation(projects.okhttpTls) - androidTestImplementation(libs.assertk) - androidTestImplementation(projects.mockwebserver3Junit4) - androidTestImplementation(libs.androidx.test.runner) -} - -mavenPublishing { - // AGP 7.2 embeds Dokka 4, which breaks publishing. Android modules are hardcoded to generate Javadoc instead of Gfm. - configure(com.vanniktech.maven.publish.AndroidSingleVariantLibrary(publishJavadocJar=false)) -} diff --git a/okhttp-android/src/androidTest/AndroidManifest.xml b/okhttp-android/src/androidTest/AndroidManifest.xml deleted file mode 100644 index 4daaca67f7ef..000000000000 --- a/okhttp-android/src/androidTest/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/okhttp-android/src/main/AndroidManifest.xml b/okhttp-android/src/main/AndroidManifest.xml deleted file mode 100644 index 4fe7e5ca898e..000000000000 --- a/okhttp-android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/okhttp-android/src/main/kotlin/okhttp3/android/AndroidLogging.kt b/okhttp-android/src/main/kotlin/okhttp3/android/AndroidLogging.kt deleted file mode 100644 index f39cc43ccd0a..000000000000 --- a/okhttp-android/src/main/kotlin/okhttp3/android/AndroidLogging.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2022 Block, 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.android - -import android.util.Log -import okhttp3.logging.HttpLoggingInterceptor -import okhttp3.logging.LoggingEventListener - -/** - * An OkHttp [LoggingEventListener], with android Log as the target. - */ -fun LoggingEventListener.Companion.androidLogging( - priority: Int = Log.INFO, - tag: String = "OkHttp", -) = LoggingEventListener.Factory { Log.println(priority, tag, it) } - -/** - * An OkHttp [HttpLoggingInterceptor], with android Log as the target. - */ -fun HttpLoggingInterceptor.Companion.androidLogging( - priority: Int = Log.INFO, - tag: String = "OkHttp", -) = HttpLoggingInterceptor { Log.println(priority, tag, it) } diff --git a/okhttp-coroutines/api/okhttp-coroutines.api b/okhttp-coroutines/api/okhttp-coroutines.api index 4261ec3bb4b7..d8b28b46ce74 100644 --- a/okhttp-coroutines/api/okhttp-coroutines.api +++ b/okhttp-coroutines/api/okhttp-coroutines.api @@ -1,4 +1,4 @@ -public final class okhttp3/JvmCallExtensionsKt { +public final class okhttp3/coroutines/ExecuteAsyncKt { public static final fun executeAsync (Lokhttp3/Call;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } diff --git a/okhttp-coroutines/src/main/kotlin/okhttp3/JvmCallExtensions.kt b/okhttp-coroutines/src/main/kotlin/okhttp3/coroutines/ExecuteAsync.kt similarity index 93% rename from okhttp-coroutines/src/main/kotlin/okhttp3/JvmCallExtensions.kt rename to okhttp-coroutines/src/main/kotlin/okhttp3/coroutines/ExecuteAsync.kt index c301ddbc122d..07b976a2063b 100644 --- a/okhttp-coroutines/src/main/kotlin/okhttp3/JvmCallExtensions.kt +++ b/okhttp-coroutines/src/main/kotlin/okhttp3/coroutines/ExecuteAsync.kt @@ -15,11 +15,14 @@ * */ -package okhttp3 +package okhttp3.coroutines import kotlin.coroutines.resumeWithException import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.suspendCancellableCoroutine +import okhttp3.Call +import okhttp3.Callback +import okhttp3.Response import okhttp3.internal.closeQuietly import okio.IOException diff --git a/okhttp-coroutines/src/test/kotlin/okhttp3/SuspendCallTest.kt b/okhttp-coroutines/src/test/kotlin/okhttp3/coroutines/ExecuteAsyncTest.kt similarity index 95% rename from okhttp-coroutines/src/test/kotlin/okhttp3/SuspendCallTest.kt rename to okhttp-coroutines/src/test/kotlin/okhttp3/coroutines/ExecuteAsyncTest.kt index dcf6080f1e68..1a4d252ec1d2 100644 --- a/okhttp-coroutines/src/test/kotlin/okhttp3/SuspendCallTest.kt +++ b/okhttp-coroutines/src/test/kotlin/okhttp3/coroutines/ExecuteAsyncTest.kt @@ -14,10 +14,9 @@ * limitations under the License. * */ - @file:OptIn(ExperimentalCoroutinesApi::class) -package okhttp3 +package okhttp3.coroutines import assertk.assertThat import assertk.assertions.isEqualTo @@ -39,7 +38,14 @@ import kotlinx.coroutines.withTimeout import mockwebserver3.MockResponse import mockwebserver3.MockWebServer import mockwebserver3.SocketPolicy.DisconnectAfterRequest +import okhttp3.Callback +import okhttp3.FailingCall import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.OkHttpClientTestRule +import okhttp3.Protocol +import okhttp3.Request +import okhttp3.Response +import okhttp3.ResponseBody import okio.Buffer import okio.ForwardingSource import okio.buffer @@ -48,7 +54,7 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.api.fail -class SuspendCallTest { +class ExecuteAsyncTest { @RegisterExtension val clientTestRule = OkHttpClientTestRule() diff --git a/okhttp-dnsoverhttps/src/main/kotlin/okhttp3/dnsoverhttps/DnsOverHttps.kt b/okhttp-dnsoverhttps/src/main/kotlin/okhttp3/dnsoverhttps/DnsOverHttps.kt index cc3872e5e194..f164e23b863f 100644 --- a/okhttp-dnsoverhttps/src/main/kotlin/okhttp3/dnsoverhttps/DnsOverHttps.kt +++ b/okhttp-dnsoverhttps/src/main/kotlin/okhttp3/dnsoverhttps/DnsOverHttps.kt @@ -16,11 +16,9 @@ package okhttp3.dnsoverhttps import java.io.IOException -import java.net.HttpURLConnection import java.net.InetAddress import java.net.UnknownHostException import java.util.concurrent.CountDownLatch -import okhttp3.CacheControl import okhttp3.Call import okhttp3.Callback import okhttp3.Dns @@ -72,16 +70,17 @@ class DnsOverHttps internal constructor( @Throws(UnknownHostException::class) private fun lookupHttps(hostname: String): List { - val networkRequests = ArrayList(2) - val failures = ArrayList(2) - val results = ArrayList(5) + val networkRequests = + buildList { + add(client.newCall(buildRequest(hostname, DnsRecordCodec.TYPE_A))) - buildRequest(hostname, networkRequests, results, failures, DnsRecordCodec.TYPE_A) - - if (includeIPv6) { - buildRequest(hostname, networkRequests, results, failures, DnsRecordCodec.TYPE_AAAA) - } + if (includeIPv6) { + add(client.newCall(buildRequest(hostname, DnsRecordCodec.TYPE_AAAA))) + } + } + val failures = ArrayList(2) + val results = ArrayList(5) executeRequests(hostname, networkRequests, results, failures) return results.ifEmpty { @@ -89,21 +88,6 @@ class DnsOverHttps internal constructor( } } - private fun buildRequest( - hostname: String, - networkRequests: MutableList, - results: MutableList, - failures: MutableList, - type: Int, - ) { - val request = buildRequest(hostname, type) - val response = getCacheOnlyResponse(request) - - response?.let { processResponse(it, hostname, results, failures) } ?: networkRequests.add( - client.newCall(request), - ) - } - private fun executeRequests( hostname: String, networkRequests: List, @@ -186,44 +170,12 @@ class DnsOverHttps internal constructor( throw unknownHostException } - private fun getCacheOnlyResponse(request: Request): Response? { - if (client.cache != null) { - try { - // Use the cache without hitting the network first - // 504 code indicates that the Cache is stale - val onlyIfCached = - CacheControl.Builder() - .onlyIfCached() - .build() - - var cacheUrl = request.url - - val cacheRequest = - request.newBuilder() - .cacheControl(onlyIfCached) - .cacheUrlOverride(cacheUrl) - .build() - - val cacheResponse = client.newCall(cacheRequest).execute() - - if (cacheResponse.code != HttpURLConnection.HTTP_GATEWAY_TIMEOUT) { - return cacheResponse - } - } catch (ioe: IOException) { - // Failures are ignored as we can fallback to the network - // and hopefully repopulate the cache. - } - } - - return null - } - @Throws(Exception::class) private fun readResponse( hostname: String, response: Response, ): List { - if (response.cacheResponse == null && response.protocol !== Protocol.HTTP_2) { + if (response.cacheResponse == null && response.protocol !== Protocol.HTTP_2 && response.protocol !== Protocol.QUIC) { Platform.get().log("Incorrect protocol: ${response.protocol}", Platform.WARN) } diff --git a/okhttp-dnsoverhttps/src/test/java/okhttp3/dnsoverhttps/DnsOverHttpsTest.kt b/okhttp-dnsoverhttps/src/test/java/okhttp3/dnsoverhttps/DnsOverHttpsTest.kt index 78bbaaac78fc..76f1a3b5392b 100644 --- a/okhttp-dnsoverhttps/src/test/java/okhttp3/dnsoverhttps/DnsOverHttpsTest.kt +++ b/okhttp-dnsoverhttps/src/test/java/okhttp3/dnsoverhttps/DnsOverHttpsTest.kt @@ -31,10 +31,12 @@ import java.net.UnknownHostException import java.util.concurrent.TimeUnit import mockwebserver3.MockResponse import mockwebserver3.MockWebServer +import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.Cache import okhttp3.Dns import okhttp3.OkHttpClient import okhttp3.Protocol +import okhttp3.RecordingEventListener import okhttp3.testing.PlatformRule import okio.Buffer import okio.ByteString.Companion.decodeHex @@ -44,18 +46,22 @@ import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension @Tag("Slowish") +@ExtendWith(MockWebServerExtension::class) class DnsOverHttpsTest { @RegisterExtension val platform = PlatformRule() private lateinit var server: MockWebServer private lateinit var dns: Dns private val cacheFs = FakeFileSystem() + private val eventListener = RecordingEventListener() private val bootstrapClient = OkHttpClient.Builder() .protocols(listOf(Protocol.HTTP_2, Protocol.HTTP_1_1)) + .eventListener(eventListener) .build() @BeforeEach @@ -170,7 +176,7 @@ class DnsOverHttpsTest { // 5. unsuccessful response @Test fun usesCache() { - val cache = Cache("cache".toPath(), (100 * 1024).toLong(), cacheFs) + val cache = Cache(cacheFs, "cache".toPath(), (100 * 1024).toLong()) val cachedClient = bootstrapClient.newBuilder().cache(cache).build() val cachedDns = buildLocalhost(cachedClient, false) @@ -194,21 +200,27 @@ class DnsOverHttpsTest { assertThat(recordedRequest.path) .isEqualTo("/lookup?ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ") + assertThat(cacheEvents()).containsExactly("CacheMiss") + result = cachedDns.lookup("google.com") assertThat(server.takeRequest(1, TimeUnit.MILLISECONDS)).isNull() assertThat(result).isEqualTo(listOf(address("157.240.1.18"))) + assertThat(cacheEvents()).containsExactly("CacheHit") + result = cachedDns.lookup("www.google.com") assertThat(result).containsExactly(address("157.240.1.18")) recordedRequest = server.takeRequest() assertThat(recordedRequest.method).isEqualTo("GET") assertThat(recordedRequest.path) .isEqualTo("/lookup?ct&dns=AAABAAABAAAAAAAAA3d3dwZnb29nbGUDY29tAAABAAE") + + assertThat(cacheEvents()).containsExactly("CacheMiss") } @Test fun usesCacheEvenForPost() { - val cache = Cache("cache".toPath(), (100 * 1024).toLong(), cacheFs) + val cache = Cache(cacheFs, "cache".toPath(), (100 * 1024).toLong()) val cachedClient = bootstrapClient.newBuilder().cache(cache).build() val cachedDns = buildLocalhost(cachedClient, false, post = true) repeat(2) { @@ -231,16 +243,22 @@ class DnsOverHttpsTest { assertThat(recordedRequest.path) .isEqualTo("/lookup?ct") + assertThat(cacheEvents()).containsExactly("CacheMiss") + result = cachedDns.lookup("google.com") assertThat(server.takeRequest(0, TimeUnit.MILLISECONDS)).isNull() assertThat(result).isEqualTo(listOf(address("157.240.1.18"))) + assertThat(cacheEvents()).containsExactly("CacheHit") + result = cachedDns.lookup("www.google.com") assertThat(result).containsExactly(address("157.240.1.18")) recordedRequest = server.takeRequest(0, TimeUnit.MILLISECONDS)!! assertThat(recordedRequest.method).isEqualTo("POST") assertThat(recordedRequest.path) .isEqualTo("/lookup?ct") + + assertThat(cacheEvents()).containsExactly("CacheMiss") } @Test @@ -265,6 +283,9 @@ class DnsOverHttpsTest { assertThat(recordedRequest.path).isEqualTo( "/lookup?ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ", ) + + assertThat(cacheEvents()).containsExactly("CacheMiss") + Thread.sleep(2000) server.enqueue( dnsResponse( @@ -282,6 +303,14 @@ class DnsOverHttpsTest { assertThat(recordedRequest!!.method).isEqualTo("GET") assertThat(recordedRequest.path) .isEqualTo("/lookup?ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ") + + assertThat(cacheEvents()).containsExactly("CacheMiss") + } + + private fun cacheEvents(): List { + return eventListener.recordedEventTypes().filter { it.contains("Cache") }.also { + eventListener.clearAllEvents() + } } private fun dnsResponse(s: String): MockResponse { diff --git a/okhttp-idna-mapping-table/build.gradle.kts b/okhttp-idna-mapping-table/build.gradle.kts index 250c18a60af5..7154371ce8b2 100644 --- a/okhttp-idna-mapping-table/build.gradle.kts +++ b/okhttp-idna-mapping-table/build.gradle.kts @@ -9,6 +9,8 @@ dependencies { testImplementation(libs.assertk) testImplementation(libs.junit.jupiter.api) testImplementation(libs.junit.jupiter.params) + + testImplementation(rootProject.libs.junit.jupiter.engine) } animalsniffer { diff --git a/okhttp-logging-interceptor/api/logging-interceptor.api b/okhttp-logging-interceptor/api/logging-interceptor.api index 264c2e88fbce..b6b4d7e94399 100644 --- a/okhttp-logging-interceptor/api/logging-interceptor.api +++ b/okhttp-logging-interceptor/api/logging-interceptor.api @@ -8,6 +8,7 @@ public final class okhttp3/logging/HttpLoggingInterceptor : okhttp3/Interceptor public fun intercept (Lokhttp3/Interceptor$Chain;)Lokhttp3/Response; public final fun level (Lokhttp3/logging/HttpLoggingInterceptor$Level;)V public final fun redactHeader (Ljava/lang/String;)V + public final fun redactQueryParams ([Ljava/lang/String;)V public final fun setLevel (Lokhttp3/logging/HttpLoggingInterceptor$Level;)Lokhttp3/logging/HttpLoggingInterceptor; } diff --git a/okhttp-logging-interceptor/src/main/kotlin/okhttp3/logging/HttpLoggingInterceptor.kt b/okhttp-logging-interceptor/src/main/kotlin/okhttp3/logging/HttpLoggingInterceptor.kt index 5d03adb5c71c..99bcfc58ab68 100644 --- a/okhttp-logging-interceptor/src/main/kotlin/okhttp3/logging/HttpLoggingInterceptor.kt +++ b/okhttp-logging-interceptor/src/main/kotlin/okhttp3/logging/HttpLoggingInterceptor.kt @@ -22,6 +22,7 @@ import java.nio.charset.Charset import java.util.TreeSet import java.util.concurrent.TimeUnit import okhttp3.Headers +import okhttp3.HttpUrl import okhttp3.Interceptor import okhttp3.OkHttpClient import okhttp3.Response @@ -46,6 +47,8 @@ class HttpLoggingInterceptor ) : Interceptor { @Volatile private var headersToRedact = emptySet() + @Volatile private var queryParamsNameToRedact = emptySet() + @set:JvmName("level") @Volatile var level = Level.NONE @@ -132,6 +135,13 @@ class HttpLoggingInterceptor headersToRedact = newHeadersToRedact } + fun redactQueryParams(vararg name: String) { + val newQueryParamsNameToRedact = TreeSet(String.CASE_INSENSITIVE_ORDER) + newQueryParamsNameToRedact += queryParamsNameToRedact + newQueryParamsNameToRedact.addAll(name) + queryParamsNameToRedact = newQueryParamsNameToRedact + } + /** * Sets the level and returns this. * @@ -168,7 +178,7 @@ class HttpLoggingInterceptor val connection = chain.connection() var requestStartMessage = - ("--> ${request.method} ${request.url}${if (connection != null) " " + connection.protocol() else ""}") + ("--> ${request.method} ${redactUrl(request.url)}${if (connection != null) " " + connection.protocol() else ""}") if (!logHeaders && requestBody != null) { requestStartMessage += " (${requestBody.contentLength()}-byte body)" } @@ -251,7 +261,7 @@ class HttpLoggingInterceptor buildString { append("<-- ${response.code}") if (response.message.isNotEmpty()) append(" ${response.message}") - append(" ${response.request.url} (${tookMs}ms") + append(" ${redactUrl(response.request.url)} (${tookMs}ms") if (!logHeaders) append(", $bodySize body") append(")") }, @@ -312,6 +322,20 @@ class HttpLoggingInterceptor return response } + internal fun redactUrl(url: HttpUrl): String { + if (queryParamsNameToRedact.isEmpty() || url.querySize == 0) { + return url.toString() + } + return url.newBuilder().query(null).apply { + for (i in 0 until url.querySize) { + val parameterName = url.queryParameterName(i) + val newValue = if (parameterName in queryParamsNameToRedact) "██" else url.queryParameterValue(i) + + addEncodedQueryParameter(parameterName, newValue) + } + }.toString() + } + private fun logHeader( headers: Headers, i: Int, diff --git a/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorTest.kt b/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorTest.kt index bc93ac55d5fd..dd73d7b418b5 100644 --- a/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorTest.kt +++ b/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorTest.kt @@ -19,11 +19,12 @@ import assertk.assertThat import assertk.assertions.isEqualTo import assertk.assertions.isLessThan import assertk.assertions.isLessThanOrEqualTo -import assertk.assertions.isSameAs +import assertk.assertions.isSameInstanceAs import assertk.assertions.matches import java.net.UnknownHostException import mockwebserver3.MockResponse import mockwebserver3.MockWebServer +import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.HttpUrl import okhttp3.Interceptor import okhttp3.MediaType @@ -44,8 +45,10 @@ import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.Assumptions import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension +@ExtendWith(MockWebServerExtension::class) class HttpLoggingInterceptorTest { @RegisterExtension val platform = PlatformRule() @@ -104,7 +107,7 @@ class HttpLoggingInterceptorTest { @Test fun setLevelShouldReturnSameInstanceOfInterceptor() { for (level in Level.entries) { - assertThat(applicationInterceptor.setLevel(level)).isSameAs(applicationInterceptor) + assertThat(applicationInterceptor.setLevel(level)).isSameInstanceAs(applicationInterceptor) } } @@ -903,6 +906,104 @@ class HttpLoggingInterceptorTest { .assertNoMoreLogs() } + @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") + @Test + fun sensitiveQueryParamsAreRedacted() { + url = server.url("/api/login?user=test_user&authentication=basic&password=confidential_password") + val networkInterceptor = + HttpLoggingInterceptor(networkLogs).setLevel( + Level.BASIC, + ) + networkInterceptor.redactQueryParams("user", "passWord") + + val applicationInterceptor = + HttpLoggingInterceptor(applicationLogs).setLevel( + Level.BASIC, + ) + applicationInterceptor.redactQueryParams("user", "PassworD") + + client = + OkHttpClient.Builder() + .addNetworkInterceptor(networkInterceptor) + .addInterceptor(applicationInterceptor) + .build() + server.enqueue( + MockResponse.Builder() + .build(), + ) + val response = + client + .newCall( + request() + .build(), + ) + .execute() + response.body.close() + val redactedUrl = networkInterceptor.redactUrl(url) + val redactedUrlPattern = redactedUrl.replace("?", """\?""") + applicationLogs + .assertLogEqual("--> GET $redactedUrl") + .assertLogMatch(Regex("""<-- 200 OK $redactedUrlPattern \(\d+ms, \d+-byte body\)""")) + .assertNoMoreLogs() + networkLogs + .assertLogEqual("--> GET $redactedUrl http/1.1") + .assertLogMatch(Regex("""<-- 200 OK $redactedUrlPattern \(\d+ms, \d+-byte body\)""")) + .assertNoMoreLogs() + } + + @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") + @Test + fun preserveQueryParamsAfterRedacted() { + url = + server.url( + """/api/login? + |user=test_user& + |authentication=basic& + |password=confidential_password& + |authentication=rather simple login method + """.trimMargin(), + ) + val networkInterceptor = + HttpLoggingInterceptor(networkLogs).setLevel( + Level.BASIC, + ) + networkInterceptor.redactQueryParams("user", "passWord") + + val applicationInterceptor = + HttpLoggingInterceptor(applicationLogs).setLevel( + Level.BASIC, + ) + applicationInterceptor.redactQueryParams("user", "PassworD") + + client = + OkHttpClient.Builder() + .addNetworkInterceptor(networkInterceptor) + .addInterceptor(applicationInterceptor) + .build() + server.enqueue( + MockResponse.Builder() + .build(), + ) + val response = + client + .newCall( + request() + .build(), + ) + .execute() + response.body.close() + val redactedUrl = networkInterceptor.redactUrl(url) + val redactedUrlPattern = redactedUrl.replace("?", """\?""") + applicationLogs + .assertLogEqual("--> GET $redactedUrl") + .assertLogMatch(Regex("""<-- 200 OK $redactedUrlPattern \(\d+ms, \d+-byte body\)""")) + .assertNoMoreLogs() + networkLogs + .assertLogEqual("--> GET $redactedUrl http/1.1") + .assertLogMatch(Regex("""<-- 200 OK $redactedUrlPattern \(\d+ms, \d+-byte body\)""")) + .assertNoMoreLogs() + } + @Test fun duplexRequestsAreNotLogged() { platform.assumeHttp2Support() diff --git a/okhttp-logging-interceptor/src/test/java/okhttp3/logging/LoggingEventListenerTest.kt b/okhttp-logging-interceptor/src/test/java/okhttp3/logging/LoggingEventListenerTest.kt index 91b7463510f6..361ccd1cd973 100644 --- a/okhttp-logging-interceptor/src/test/java/okhttp3/logging/LoggingEventListenerTest.kt +++ b/okhttp-logging-interceptor/src/test/java/okhttp3/logging/LoggingEventListenerTest.kt @@ -23,6 +23,7 @@ import java.util.Arrays import mockwebserver3.MockResponse import mockwebserver3.MockWebServer import mockwebserver3.SocketPolicy.FailHandshake +import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.HttpUrl import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient @@ -36,9 +37,11 @@ import okhttp3.testing.PlatformRule import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension @Suppress("ktlint:standard:max-line-length") +@ExtendWith(MockWebServerExtension::class) class LoggingEventListenerTest { @RegisterExtension val platform = PlatformRule() diff --git a/okhttp-osgi-tests/build.gradle.kts b/okhttp-osgi-tests/build.gradle.kts new file mode 100644 index 000000000000..94b45096ebec --- /dev/null +++ b/okhttp-osgi-tests/build.gradle.kts @@ -0,0 +1,68 @@ +plugins { + kotlin("jvm") +} + +dependencies { + implementation(projects.okhttp) + implementation(projects.okhttpBrotli) + implementation(projects.okhttpCoroutines) + implementation(projects.okhttpDnsoverhttps) + implementation(projects.loggingInterceptor) + implementation(projects.okhttpSse) + implementation(projects.okhttpTls) + implementation(projects.okhttpUrlconnection) + + testImplementation(projects.okhttpTestingSupport) + testImplementation(libs.junit) + testImplementation(libs.kotlin.test.common) + testImplementation(libs.kotlin.test.junit) + testImplementation(libs.assertk) + + testImplementation(libs.aqute.resolve) +} + +normalization { + runtimeClasspath { + /* + - The below two ignored files are generated during test execution + by the test: okhttp/src/test/java/okhttp3/osgi/OsgiTest.java + + - The compressed index.xml file contains a timestamp property which + changes with every test execution, such that running the test + actually changes the test classpath itself. This means that it + can"t benefit from incremental build acceleration, because on every + execution it sees that the classpath has changed, and so to be + safe, it needs to re-run. + + - This is unfortunate, because actually it would be safe to declare + the task as up-to-date, because these two files, which are based on + the generated index.xml, are outputs, not inputs. We can be sure of + this because they are deleted in the @BeforeEach method of the + OsgiTest test class. + + - To enable the benefit of incremental builds, we can ask Gradle + to ignore these two files when considering whether the classpath + has changed. That is the purpose of this normalization block. + */ + ignore("okhttp3/osgi/workspace/cnf/repo/index.xml.gz") + ignore("okhttp3/osgi/workspace/cnf/repo/index.xml.gz.sha") + } +} + +// Expose OSGi jars to the test environment. +val osgiTestDeploy: Configuration by configurations.creating + +val test = tasks.named("test") +val copyOsgiTestDeployment = tasks.register("copyOsgiTestDeployment") { + from(osgiTestDeploy) + into(layout.buildDirectory.dir("resources/test/okhttp3/osgi/deployments")) +} + +test.configure { + dependsOn(copyOsgiTestDeployment) +} + +dependencies { + osgiTestDeploy(libs.eclipseOsgi) + osgiTestDeploy(libs.kotlin.stdlib.osgi) +} diff --git a/okhttp/src/test/java/okhttp3/osgi/OsgiTest.kt b/okhttp-osgi-tests/src/test/kotlin/okhttp3/osgi/OsgiTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/osgi/OsgiTest.kt rename to okhttp-osgi-tests/src/test/kotlin/okhttp3/osgi/OsgiTest.kt diff --git a/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourceHttpTest.kt b/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourceHttpTest.kt index d4fbca2a1d4c..6484ecdee1f0 100644 --- a/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourceHttpTest.kt +++ b/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourceHttpTest.kt @@ -21,6 +21,7 @@ import assertk.assertions.isEqualTo import java.util.concurrent.TimeUnit import mockwebserver3.MockResponse import mockwebserver3.MockWebServer +import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.OkHttpClientTestRule import okhttp3.RecordingEventListener import okhttp3.Request @@ -31,10 +32,12 @@ import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension import org.junitpioneer.jupiter.RetryingTest @Tag("Slowish") +@ExtendWith(MockWebServerExtension::class) class EventSourceHttpTest { @RegisterExtension val platform = PlatformRule() diff --git a/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourcesHttpTest.kt b/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourcesHttpTest.kt index 4b17e25665eb..3ceb99ea15d9 100644 --- a/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourcesHttpTest.kt +++ b/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourcesHttpTest.kt @@ -17,6 +17,7 @@ package okhttp3.sse.internal import mockwebserver3.MockResponse import mockwebserver3.MockWebServer +import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.OkHttpClientTestRule import okhttp3.Request import okhttp3.sse.EventSources.processResponse @@ -25,9 +26,11 @@ import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension @Tag("Slowish") +@ExtendWith(MockWebServerExtension::class) class EventSourcesHttpTest { @RegisterExtension val platform = PlatformRule() diff --git a/okhttp-testing-support/build.gradle.kts b/okhttp-testing-support/build.gradle.kts index 68d2cb4bc2ee..87c287063693 100644 --- a/okhttp-testing-support/build.gradle.kts +++ b/okhttp-testing-support/build.gradle.kts @@ -14,6 +14,8 @@ dependencies { api(libs.conscrypt.openjdk) api(libs.openjsse) + api(rootProject.libs.junit.jupiter.engine) + api(variantOf(libs.amazonCorretto) { classifier("linux-x86_64") }) diff --git a/okhttp-testing-support/src/main/kotlin/okhttp3/OkHttpClientTestRule.kt b/okhttp-testing-support/src/main/kotlin/okhttp3/OkHttpClientTestRule.kt index 275d09f6a0a7..8d222346e88e 100644 --- a/okhttp-testing-support/src/main/kotlin/okhttp3/OkHttpClientTestRule.kt +++ b/okhttp-testing-support/src/main/kotlin/okhttp3/OkHttpClientTestRule.kt @@ -25,9 +25,9 @@ import java.util.logging.Level import java.util.logging.LogManager import java.util.logging.LogRecord import java.util.logging.Logger -import kotlin.concurrent.withLock import okhttp3.internal.buildConnectionPool import okhttp3.internal.concurrent.TaskRunner +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.connection.RealConnectionPool import okhttp3.internal.http2.Http2 import okhttp3.internal.taskRunnerInternal @@ -234,7 +234,7 @@ class OkHttpClientTestRule : BeforeEachCallback, AfterEachCallback { // a test timeout failure. val waitTime = (entryTime + 1_000_000_000L - System.nanoTime()) if (!queue.idleLatch().await(waitTime, TimeUnit.NANOSECONDS)) { - TaskRunner.INSTANCE.lock.withLock { + TaskRunner.INSTANCE.withLock { TaskRunner.INSTANCE.cancelAll() } fail("Queue still active after 1000 ms") diff --git a/okhttp-testing-support/src/main/kotlin/okhttp3/TestUtilJvm.kt b/okhttp-testing-support/src/main/kotlin/okhttp3/TestUtilJvm.kt index 9bb5bcc6a419..42b4c6e51a93 100644 --- a/okhttp-testing-support/src/main/kotlin/okhttp3/TestUtilJvm.kt +++ b/okhttp-testing-support/src/main/kotlin/okhttp3/TestUtilJvm.kt @@ -20,6 +20,7 @@ import java.net.InetAddress import java.net.InetSocketAddress import java.net.UnknownHostException import java.util.Arrays +import java.util.concurrent.ThreadFactory import okhttp3.internal.http2.Header import okio.Buffer import okio.FileSystem @@ -122,6 +123,17 @@ object TestUtil { if (isGraalVmImage) return block(suppressed.toList()) } + + @JvmStatic + fun threadFactory(name: String): ThreadFactory { + return object : ThreadFactory { + private var nextId = 1 + + override fun newThread(runnable: Runnable): Thread { + return Thread(runnable, "$name-${nextId++}") + } + } + } } fun getEnv(name: String) = System.getenv(name) diff --git a/okhttp-testing-support/src/main/kotlin/okhttp3/TestValueFactory.kt b/okhttp-testing-support/src/main/kotlin/okhttp3/TestValueFactory.kt index bbc348fa8ab0..de57c4c5861f 100644 --- a/okhttp-testing-support/src/main/kotlin/okhttp3/TestValueFactory.kt +++ b/okhttp-testing-support/src/main/kotlin/okhttp3/TestValueFactory.kt @@ -36,6 +36,7 @@ import okhttp3.internal.concurrent.TaskFaker import okhttp3.internal.concurrent.TaskRunner import okhttp3.internal.connection.CallConnectionUser import okhttp3.internal.connection.FastFallbackExchangeFinder +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.connection.RealCall import okhttp3.internal.connection.RealConnection import okhttp3.internal.connection.RealConnectionPool @@ -93,7 +94,7 @@ class TestValueFactory : Closeable { socket = Socket(), idleAtNs = idleAtNanos, ) - synchronized(result) { pool.put(result) } + result.withLock { pool.put(result) } return result } diff --git a/okhttp-testing-support/src/main/kotlin/okhttp3/internal/concurrent/TaskFaker.kt b/okhttp-testing-support/src/main/kotlin/okhttp3/internal/concurrent/TaskFaker.kt index ae953c32d407..cfb099be2e0d 100644 --- a/okhttp-testing-support/src/main/kotlin/okhttp3/internal/concurrent/TaskFaker.kt +++ b/okhttp-testing-support/src/main/kotlin/okhttp3/internal/concurrent/TaskFaker.kt @@ -13,38 +13,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") + package okhttp3.internal.concurrent import assertk.assertThat -import assertk.assertions.isEmpty +import assertk.assertions.isEqualTo import java.io.Closeable import java.util.AbstractQueue import java.util.concurrent.BlockingQueue import java.util.concurrent.Executors -import java.util.concurrent.Semaphore import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicBoolean import java.util.logging.Logger -import kotlin.concurrent.withLock import okhttp3.OkHttpClient +import okhttp3.TestUtil.threadFactory +import okhttp3.internal.connection.Locks.withLock /** * Runs a [TaskRunner] in a controlled environment so that everything is sequential and * deterministic. * * This class ensures that at most one thread is running at a time. This is initially the JUnit test - * thread, which temporarily shares its execution privilege by calling [runTasks], [runNextTask], or - * [advanceUntil]. These methods wait for its task threads to stop executing before it returns. - * - * Task threads stall execution in these ways: + * thread, which yields its execution privilege while calling [runTasks], [runNextTask], or + * [advanceUntil]. These functions don't return until the task threads are all idle. * - * * By being ready to start. Newly-created tasks don't run immediately. - * * By finishing their work. This occurs when [Runnable.run] returns. - * * By waiting until the simulated clock reaches a specific time. - * * By requesting to wait by calling [TaskRunner.Backend.coordinatorWait]. + * Task threads release their execution privilege in these ways: * - * Most test methods start by unblocking task threads, then wait for those task threads to stall - * again before returning. + * * By yielding in [TaskRunner.Backend.coordinatorWait]. + * * By yielding in [BlockingQueue.poll]. + * * By completing. */ class TaskFaker : Closeable { @Suppress("NOTHING_TO_INLINE") @@ -64,38 +61,37 @@ class TaskFaker : Closeable { val logger = Logger.getLogger("TaskFaker." + instance++) /** Though this executor service may hold many threads, they are not executed concurrently. */ - private val tasksExecutor = Executors.newCachedThreadPool() - - /** The number of runnables known to [tasksExecutor]. Guarded by [taskRunner]. */ - private var tasksRunningCount = 0 - - /** - * Threads in this list are waiting for either [interruptCoordinatorThread] or [notifyAll]. - * Guarded by [taskRunner]. - */ - private val stalledTasks = mutableListOf() - - /** - * Released whenever a thread is either added to [stalledTasks] or completes. The test thread - * uses this to wait until all subject threads complete or stall. - */ - private val taskBecameStalled = Semaphore(0) + private val tasksExecutor = Executors.newCachedThreadPool(threadFactory("TaskFaker")) /** * True if this task faker has ever had multiple tasks scheduled to run concurrently. Guarded by - * [taskRunner]. + * [TaskRunner.lock]. */ var isParallel = false + /** Number of calls to [TaskRunner.Backend.execute]. Guarded by [TaskRunner.lock]. */ + var executeCallCount = 0 + /** Guarded by [taskRunner]. */ var nanoTime = 0L private set - /** The thread currently waiting for time to advance. Guarded by [taskRunner]. */ - private var waitingCoordinatorThread: Thread? = null + /** Backlog of tasks to run. Only one task runs at a time. Guarded by [TaskRunner.lock]. */ + private val serialTaskQueue = ArrayDeque() + + /** The task that's currently executing. Guarded by [TaskRunner.lock]. */ + private var currentTask: SerialTask = TestThreadSerialTask - /** True if new tasks should run immediately without stalling. Guarded by [taskRunner]. */ - private var isRunningAllTasks = false + /** The coordinator task if it's waiting, and how it will resume. Guarded by [TaskRunner.lock]. */ + private var waitingCoordinatorTask: SerialTask? = null + private var waitingCoordinatorInterrupted = false + private var waitingCoordinatorNotified = false + + /** How many times a new task has been started. Guarded by [TaskRunner.lock]. */ + private var contextSwitchCount = 0 + + /** Guarded by [TaskRunner.lock]. */ + private var activeThreads = 0 /** A task runner that posts tasks to this fake. Tasks won't be executed until requested. */ val taskRunner: TaskRunner = @@ -106,43 +102,34 @@ class TaskFaker : Closeable { runnable: Runnable, ) { taskRunner.assertThreadHoldsLock() - val acquiredTaskRunnerLock = AtomicBoolean() - - tasksExecutor.execute { - taskRunner.lock.withLock { - acquiredTaskRunnerLock.set(true) - taskRunner.condition.signalAll() - - tasksRunningCount++ - if (tasksRunningCount > 1) isParallel = true - try { - if (!isRunningAllTasks) { - stall() - } - runnable.run() - } catch (e: InterruptedException) { - if (!tasksExecutor.isShutdown) throw e // Ignore shutdown-triggered interruptions. - } finally { - tasksRunningCount-- - taskBecameStalled.release() - } - } - } - // Execute() must not return until the launched task stalls. - while (!acquiredTaskRunnerLock.get()) { - taskRunner.condition.await() - } + val queuedTask = RunnableSerialTask(runnable) + serialTaskQueue += queuedTask + executeCallCount++ + isParallel = serialTaskQueue.size > 1 } override fun nanoTime() = nanoTime override fun coordinatorNotify(taskRunner: TaskRunner) { taskRunner.assertThreadHoldsLock() - check(waitingCoordinatorThread != null) - - stalledTasks.remove(waitingCoordinatorThread) - taskRunner.condition.signalAll() + check(waitingCoordinatorTask != null) + + // Queue a task to resume the waiting coordinator. + serialTaskQueue += + object : SerialTask { + override fun start() { + taskRunner.assertThreadHoldsLock() + val coordinatorTask = waitingCoordinatorTask + if (coordinatorTask != null) { + waitingCoordinatorNotified = true + currentTask = coordinatorTask + taskRunner.condition.signalAll() + } else { + startNextTask() + } + } + } } override fun coordinatorWait( @@ -150,15 +137,24 @@ class TaskFaker : Closeable { nanos: Long, ) { taskRunner.assertThreadHoldsLock() - - check(waitingCoordinatorThread == null) + check(waitingCoordinatorTask == null) if (nanos == 0L) return - waitingCoordinatorThread = Thread.currentThread() - try { - stall() - } finally { - waitingCoordinatorThread = null + // Yield until notified, interrupted, or the duration elapses. + val waitUntil = nanoTime + nanos + val self = currentTask + waitingCoordinatorTask = self + waitingCoordinatorNotified = false + waitingCoordinatorInterrupted = false + yieldUntil { + waitingCoordinatorNotified || waitingCoordinatorInterrupted || nanoTime >= waitUntil + } + + waitingCoordinatorTask = null + waitingCoordinatorNotified = false + if (waitingCoordinatorInterrupted) { + waitingCoordinatorInterrupted = false + throw InterruptedException() } } @@ -167,30 +163,6 @@ class TaskFaker : Closeable { logger = logger, ) - /** Wait for the test thread to proceed. */ - private fun stall() { - taskRunner.assertThreadHoldsLock() - - val currentThread = Thread.currentThread() - taskBecameStalled.release() - stalledTasks += currentThread - try { - while (currentThread in stalledTasks) { - taskRunner.condition.await() - } - } catch (e: InterruptedException) { - stalledTasks.remove(currentThread) - throw e - } - } - - private fun unstallTasks() { - taskRunner.assertThreadHoldsLock() - - stalledTasks.clear() - taskRunner.condition.signalAll() - } - /** Runs all tasks that are ready. Used by the test thread only. */ fun runTasks() { advanceUntil(nanoTime) @@ -200,27 +172,10 @@ class TaskFaker : Closeable { fun advanceUntil(newTime: Long) { taskRunner.assertThreadDoesntHoldLock() - taskRunner.lock.withLock { - isRunningAllTasks = true + taskRunner.withLock { + check(currentTask == TestThreadSerialTask) nanoTime = newTime - unstallTasks() - } - - waitForTasksToStall() - } - - private fun waitForTasksToStall() { - taskRunner.assertThreadDoesntHoldLock() - - while (true) { - taskRunner.lock.withLock { - if (tasksRunningCount == stalledTasks.size) { - isRunningAllTasks = false - return@waitForTasksToStall // All stalled. - } - taskBecameStalled.drainPermits() - } - taskBecameStalled.acquire() + yieldUntil(ResumePriority.AfterOtherTasks) } } @@ -228,47 +183,49 @@ class TaskFaker : Closeable { fun assertNoMoreTasks() { taskRunner.assertThreadDoesntHoldLock() - taskRunner.lock.withLock { - assertThat(stalledTasks).isEmpty() + taskRunner.withLock { + assertThat(activeThreads).isEqualTo(0) } } /** Unblock a waiting task thread. Used by the test thread only. */ fun interruptCoordinatorThread() { taskRunner.assertThreadDoesntHoldLock() + require(currentTask == TestThreadSerialTask) - // Make sure the coordinator is ready to be interrupted. - runTasks() - - taskRunner.lock.withLock { - val toInterrupt = waitingCoordinatorThread ?: error("no thread currently waiting") - taskBecameStalled.drainPermits() - toInterrupt.interrupt() - } + // Queue a task to interrupt the waiting coordinator. + serialTaskQueue += + object : SerialTask { + override fun start() { + taskRunner.assertThreadHoldsLock() + waitingCoordinatorInterrupted = true + val coordinatorTask = waitingCoordinatorTask ?: error("no coordinator waiting") + currentTask = coordinatorTask + taskRunner.condition.signalAll() + } + } - waitForTasksToStall() + // Let the coordinator process its interruption. + runTasks() } /** Ask a single task to proceed. Used by the test thread only. */ fun runNextTask() { taskRunner.assertThreadDoesntHoldLock() - taskRunner.lock.withLock { - check(stalledTasks.size >= 1) { "no tasks to run" } - stalledTasks.removeFirst() - taskRunner.condition.signalAll() + taskRunner.withLock { + val contextSwitchCountBefore = contextSwitchCount + yieldUntil(ResumePriority.BeforeOtherTasks) { + contextSwitchCount > contextSwitchCountBefore + } } - - waitForTasksToStall() } /** Sleep until [durationNanos] elapses. For use by the task threads. */ fun sleep(durationNanos: Long) { - taskRunner.assertThreadHoldsLock() - - val waitUntil = nanoTime + durationNanos - while (nanoTime < waitUntil) { - stall() + taskRunner.withLock { + val sleepUntil = nanoTime + durationNanos + yieldUntil { nanoTime >= sleepUntil } } } @@ -277,7 +234,113 @@ class TaskFaker : Closeable { * simulate races in tasks that doesn't have a deterministic sequence. */ fun yield() { - stall() + taskRunner.assertThreadDoesntHoldLock() + taskRunner.withLock { + yieldUntil() + } + } + + /** Process the queue until [condition] returns true. */ + private tailrec fun yieldUntil( + strategy: ResumePriority = ResumePriority.AfterEnqueuedTasks, + condition: () -> Boolean = { true }, + ) { + taskRunner.assertThreadHoldsLock() + val self = currentTask + + val yieldCompleteTask = + object : SerialTask { + override fun isReady() = condition() + + override fun start() { + taskRunner.assertThreadHoldsLock() + currentTask = self + taskRunner.condition.signalAll() + } + } + + if (strategy == ResumePriority.BeforeOtherTasks) { + serialTaskQueue.addFirst(yieldCompleteTask) + } else { + serialTaskQueue.addLast(yieldCompleteTask) + } + + val startedTask = startNextTask() + val otherTasksStarted = startedTask != yieldCompleteTask + + try { + while (currentTask != self) { + taskRunner.condition.await() + } + } finally { + serialTaskQueue.remove(yieldCompleteTask) + } + + // If we're yielding until we're exhausted and a task run, keep going until a task doesn't run. + if (strategy == ResumePriority.AfterOtherTasks && otherTasksStarted) { + return yieldUntil(strategy, condition) + } + } + + private enum class ResumePriority { + /** Resumes as soon as the condition is satisfied. */ + BeforeOtherTasks, + + /** Resumes after the already-enqueued tasks. */ + AfterEnqueuedTasks, + + /** Resumes after all other tasks, including tasks enqueued while yielding. */ + AfterOtherTasks, + } + + /** Returns the task that was started, or null if there were no tasks to start. */ + private fun startNextTask(): SerialTask? { + taskRunner.assertThreadHoldsLock() + + val index = serialTaskQueue.indexOfFirst { it.isReady() } + if (index == -1) return null + + val nextTask = serialTaskQueue.removeAt(index) + currentTask = nextTask + contextSwitchCount++ + nextTask.start() + return nextTask + } + + private interface SerialTask { + /** Returns true if this task is ready to start. */ + fun isReady() = true + + /** Do this task's work, and then start another, such as by calling [startNextTask]. */ + fun start() + } + + private object TestThreadSerialTask : SerialTask { + override fun start() = error("unexpected call") + } + + inner class RunnableSerialTask( + private val runnable: Runnable, + ) : SerialTask { + override fun start() { + taskRunner.assertThreadHoldsLock() + require(currentTask == this) + activeThreads++ + + tasksExecutor.execute { + taskRunner.assertThreadDoesntHoldLock() + require(currentTask == this) + try { + runnable.run() + require(currentTask == this) { "unexpected current task: $currentTask" } + } finally { + taskRunner.withLock { + activeThreads-- + startNextTask() + } + } + } + } } /** @@ -289,28 +352,31 @@ class TaskFaker : Closeable { ) : AbstractQueue(), BlockingQueue { override val size: Int = delegate.size + private var editCount = 0 + override fun poll(): T = delegate.poll() override fun poll( timeout: Long, unit: TimeUnit, ): T? { - taskRunner.assertThreadHoldsLock() - - val waitUntil = nanoTime + unit.toNanos(timeout) - while (true) { - val result = poll() - if (result != null) return result - if (nanoTime >= waitUntil) return null - stall() + return taskRunner.withLock { + val waitUntil = nanoTime + unit.toNanos(timeout) + while (true) { + val result = poll() + if (result != null) return@withLock result + if (nanoTime >= waitUntil) return@withLock null + val editCountBefore = editCount + yieldUntil { nanoTime >= waitUntil || editCount > editCountBefore } + } } } override fun put(element: T) { - taskRunner.assertThreadHoldsLock() - - delegate.put(element) - unstallTasks() + taskRunner.withLock { + delegate.put(element) + editCount++ + } } override fun iterator() = error("unsupported") diff --git a/okhttp-testing-support/src/main/kotlin/okhttp3/internal/http/RecordingProxySelector.kt b/okhttp-testing-support/src/main/kotlin/okhttp3/internal/http/RecordingProxySelector.kt index b81d99857a18..a51e8afb74de 100644 --- a/okhttp-testing-support/src/main/kotlin/okhttp3/internal/http/RecordingProxySelector.kt +++ b/okhttp-testing-support/src/main/kotlin/okhttp3/internal/http/RecordingProxySelector.kt @@ -30,8 +30,8 @@ import okhttp3.internal.format class RecordingProxySelector : ProxySelector() { @JvmField val proxies = mutableListOf() - private val requestedUris = mutableListOf() - private val failures = mutableListOf() + val requestedUris = mutableListOf() + val failures = mutableListOf() override fun select(uri: URI): List { requestedUris.add(uri) diff --git a/okhttp-testing-support/src/main/kotlin/okhttp3/testing/PlatformRule.kt b/okhttp-testing-support/src/main/kotlin/okhttp3/testing/PlatformRule.kt index bbcda679fcfb..2b9f42d66439 100644 --- a/okhttp-testing-support/src/main/kotlin/okhttp3/testing/PlatformRule.kt +++ b/okhttp-testing-support/src/main/kotlin/okhttp3/testing/PlatformRule.kt @@ -26,6 +26,7 @@ import okhttp3.internal.platform.Jdk8WithJettyBootPlatform import okhttp3.internal.platform.Jdk9Platform import okhttp3.internal.platform.OpenJSSEPlatform import okhttp3.internal.platform.Platform +import okhttp3.internal.platform.PlatformRegistry import okhttp3.tls.HandshakeCertificates import okhttp3.tls.HeldCertificate import okhttp3.tls.internal.TlsUtil.localhost @@ -435,9 +436,14 @@ open class PlatformRule } @JvmStatic - fun getPlatformSystemProperty(): String { + fun getPlatformSystemProperty(): String? { var property: String? = System.getProperty(PROPERTY_NAME) + if (PlatformRegistry.isAndroid) { + // Platforms below are unavailable on Android + return null + } + if (property == null) { property = when (Platform.get()) { diff --git a/okhttp-testing-support/src/test/kotlin/okhttp3/testing/PlatformRuleTest.kt b/okhttp-testing-support/src/test/kotlin/okhttp3/testing/PlatformRuleTest.kt index 15535af42cbc..0479c694e379 100644 --- a/okhttp-testing-support/src/test/kotlin/okhttp3/testing/PlatformRuleTest.kt +++ b/okhttp-testing-support/src/test/kotlin/okhttp3/testing/PlatformRuleTest.kt @@ -20,7 +20,7 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.RegisterExtension /** - * Sanity test for checking which environment and IDE is picking up. + * Validates which environment is used by the IDE. */ class PlatformRuleTest { @RegisterExtension @JvmField diff --git a/okhttp-tls/src/main/kotlin/okhttp3/tls/internal/TlsUtil.kt b/okhttp-tls/src/main/kotlin/okhttp3/tls/internal/TlsUtil.kt index ad76e91bbf51..7b4fa57f96ec 100644 --- a/okhttp-tls/src/main/kotlin/okhttp3/tls/internal/TlsUtil.kt +++ b/okhttp-tls/src/main/kotlin/okhttp3/tls/internal/TlsUtil.kt @@ -96,7 +96,11 @@ object TlsUtil { keyStore.setKeyEntry("private", heldCertificate.keyPair.private, password, chain) } - val factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()) + // https://github.com/bcgit/bc-java/issues/1160 + val isBouncyCastle = keyStore.provider.name == "BC" + val algorithm = if (isBouncyCastle) "PKIX" else KeyManagerFactory.getDefaultAlgorithm() + + val factory = KeyManagerFactory.getInstance(algorithm) factory.init(keyStore, password) val result = factory.keyManagers!! check(result.size == 1 && result[0] is X509KeyManager) { diff --git a/okhttp-tls/src/test/java/okhttp3/tls/HandshakeCertificatesTest.kt b/okhttp-tls/src/test/java/okhttp3/tls/HandshakeCertificatesTest.kt index 26f4146aa6ce..53d58a43dbc2 100644 --- a/okhttp-tls/src/test/java/okhttp3/tls/HandshakeCertificatesTest.kt +++ b/okhttp-tls/src/test/java/okhttp3/tls/HandshakeCertificatesTest.kt @@ -30,6 +30,7 @@ import javax.net.SocketFactory import javax.net.ssl.SSLSocket import okhttp3.Handshake import okhttp3.Handshake.Companion.handshake +import okhttp3.TestUtil.threadFactory import okhttp3.internal.closeQuietly import okhttp3.testing.PlatformRule import okio.ByteString.Companion.toByteString @@ -47,7 +48,7 @@ class HandshakeCertificatesTest { private var serverSocket: ServerSocket? = null @BeforeEach fun setUp() { - executorService = Executors.newCachedThreadPool() + executorService = Executors.newCachedThreadPool(threadFactory("HandshakeCertificatesTest")) } @AfterEach fun tearDown() { diff --git a/okhttp/api/android/okhttp.api b/okhttp/api/android/okhttp.api new file mode 100644 index 000000000000..5dabeaa98ce9 --- /dev/null +++ b/okhttp/api/android/okhttp.api @@ -0,0 +1,1306 @@ +public final class okhttp3/Address { + public final fun -deprecated_certificatePinner ()Lokhttp3/CertificatePinner; + public final fun -deprecated_connectionSpecs ()Ljava/util/List; + public final fun -deprecated_dns ()Lokhttp3/Dns; + public final fun -deprecated_hostnameVerifier ()Ljavax/net/ssl/HostnameVerifier; + public final fun -deprecated_protocols ()Ljava/util/List; + public final fun -deprecated_proxy ()Ljava/net/Proxy; + public final fun -deprecated_proxyAuthenticator ()Lokhttp3/Authenticator; + public final fun -deprecated_proxySelector ()Ljava/net/ProxySelector; + public final fun -deprecated_socketFactory ()Ljavax/net/SocketFactory; + public final fun -deprecated_sslSocketFactory ()Ljavax/net/ssl/SSLSocketFactory; + public final fun -deprecated_url ()Lokhttp3/HttpUrl; + public fun (Ljava/lang/String;ILokhttp3/Dns;Ljavax/net/SocketFactory;Ljavax/net/ssl/SSLSocketFactory;Ljavax/net/ssl/HostnameVerifier;Lokhttp3/CertificatePinner;Lokhttp3/Authenticator;Ljava/net/Proxy;Ljava/util/List;Ljava/util/List;Ljava/net/ProxySelector;)V + public final fun certificatePinner ()Lokhttp3/CertificatePinner; + public final fun connectionSpecs ()Ljava/util/List; + public final fun dns ()Lokhttp3/Dns; + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I + public final fun hostnameVerifier ()Ljavax/net/ssl/HostnameVerifier; + public final fun protocols ()Ljava/util/List; + public final fun proxy ()Ljava/net/Proxy; + public final fun proxyAuthenticator ()Lokhttp3/Authenticator; + public final fun proxySelector ()Ljava/net/ProxySelector; + public final fun socketFactory ()Ljavax/net/SocketFactory; + public final fun sslSocketFactory ()Ljavax/net/ssl/SSLSocketFactory; + public fun toString ()Ljava/lang/String; + public final fun url ()Lokhttp3/HttpUrl; +} + +public abstract interface class okhttp3/AsyncDns { + public static final field Companion Lokhttp3/AsyncDns$Companion; + public static final field TYPE_A I + public static final field TYPE_AAAA I + public abstract fun query (Ljava/lang/String;Lokhttp3/AsyncDns$Callback;)V +} + +public abstract interface class okhttp3/AsyncDns$Callback { + public abstract fun onFailure (Ljava/lang/String;Ljava/io/IOException;)V + public abstract fun onResponse (Ljava/lang/String;Ljava/util/List;)V +} + +public final class okhttp3/AsyncDns$Companion { + public static final field TYPE_A I + public static final field TYPE_AAAA I + public final fun toDns ([Lokhttp3/AsyncDns;)Lokhttp3/Dns; +} + +public final class okhttp3/AsyncDns$DnsClass : java/lang/Enum { + public static final field IPV4 Lokhttp3/AsyncDns$DnsClass; + public static final field IPV6 Lokhttp3/AsyncDns$DnsClass; + public static fun getEntries ()Lkotlin/enums/EnumEntries; + public final fun getType ()I + public static fun valueOf (Ljava/lang/String;)Lokhttp3/AsyncDns$DnsClass; + public static fun values ()[Lokhttp3/AsyncDns$DnsClass; +} + +public abstract interface class okhttp3/Authenticator { + public static final field Companion Lokhttp3/Authenticator$Companion; + public static final field JAVA_NET_AUTHENTICATOR Lokhttp3/Authenticator; + public static final field NONE Lokhttp3/Authenticator; + public abstract fun authenticate (Lokhttp3/Route;Lokhttp3/Response;)Lokhttp3/Request; +} + +public final class okhttp3/Authenticator$Companion { +} + +public final class okhttp3/Cache : java/io/Closeable, java/io/Flushable { + public static final field Companion Lokhttp3/Cache$Companion; + public final fun -deprecated_directory ()Ljava/io/File; + public fun (Ljava/io/File;J)V + public fun (Lokio/FileSystem;Lokio/Path;J)V + public fun close ()V + public final fun delete ()V + public final fun directory ()Ljava/io/File; + public final fun directoryPath ()Lokio/Path; + public final fun evictAll ()V + public fun flush ()V + public final fun hitCount ()I + public final fun initialize ()V + public final fun isClosed ()Z + public static final fun key (Lokhttp3/HttpUrl;)Ljava/lang/String; + public final fun maxSize ()J + public final fun networkCount ()I + public final fun requestCount ()I + public final fun size ()J + public final fun urls ()Ljava/util/Iterator; + public final fun writeAbortCount ()I + public final fun writeSuccessCount ()I +} + +public final class okhttp3/Cache$Companion { + public final fun hasVaryAll (Lokhttp3/Response;)Z + public final fun key (Lokhttp3/HttpUrl;)Ljava/lang/String; + public final fun varyHeaders (Lokhttp3/Response;)Lokhttp3/Headers; + public final fun varyMatches (Lokhttp3/Response;Lokhttp3/Headers;Lokhttp3/Request;)Z +} + +public final class okhttp3/CacheControl { + public static final field Companion Lokhttp3/CacheControl$Companion; + public static final field FORCE_CACHE Lokhttp3/CacheControl; + public static final field FORCE_NETWORK Lokhttp3/CacheControl; + public final fun -deprecated_immutable ()Z + public final fun -deprecated_maxAgeSeconds ()I + public final fun -deprecated_maxStaleSeconds ()I + public final fun -deprecated_minFreshSeconds ()I + public final fun -deprecated_mustRevalidate ()Z + public final fun -deprecated_noCache ()Z + public final fun -deprecated_noStore ()Z + public final fun -deprecated_noTransform ()Z + public final fun -deprecated_onlyIfCached ()Z + public final fun -deprecated_sMaxAgeSeconds ()I + public final fun immutable ()Z + public final fun isPrivate ()Z + public final fun isPublic ()Z + public final fun maxAgeSeconds ()I + public final fun maxStaleSeconds ()I + public final fun minFreshSeconds ()I + public final fun mustRevalidate ()Z + public final fun noCache ()Z + public final fun noStore ()Z + public final fun noTransform ()Z + public final fun onlyIfCached ()Z + public static final fun parse (Lokhttp3/Headers;)Lokhttp3/CacheControl; + public final fun sMaxAgeSeconds ()I + public fun toString ()Ljava/lang/String; +} + +public final class okhttp3/CacheControl$Builder { + public fun ()V + public final fun build ()Lokhttp3/CacheControl; + public final fun immutable ()Lokhttp3/CacheControl$Builder; + public final fun maxAge (ILjava/util/concurrent/TimeUnit;)Lokhttp3/CacheControl$Builder; + public final fun maxAge-LRDsOJo (J)Lokhttp3/CacheControl$Builder; + public final fun maxStale (ILjava/util/concurrent/TimeUnit;)Lokhttp3/CacheControl$Builder; + public final fun maxStale-LRDsOJo (J)Lokhttp3/CacheControl$Builder; + public final fun minFresh (ILjava/util/concurrent/TimeUnit;)Lokhttp3/CacheControl$Builder; + public final fun minFresh-LRDsOJo (J)Lokhttp3/CacheControl$Builder; + public final fun noCache ()Lokhttp3/CacheControl$Builder; + public final fun noStore ()Lokhttp3/CacheControl$Builder; + public final fun noTransform ()Lokhttp3/CacheControl$Builder; + public final fun onlyIfCached ()Lokhttp3/CacheControl$Builder; +} + +public final class okhttp3/CacheControl$Companion { + public final fun parse (Lokhttp3/Headers;)Lokhttp3/CacheControl; +} + +public abstract interface class okhttp3/Call : java/lang/Cloneable { + public abstract fun cancel ()V + public abstract fun clone ()Lokhttp3/Call; + public abstract fun enqueue (Lokhttp3/Callback;)V + public abstract fun execute ()Lokhttp3/Response; + public abstract fun isCanceled ()Z + public abstract fun isExecuted ()Z + public abstract fun request ()Lokhttp3/Request; + public abstract fun timeout ()Lokio/Timeout; +} + +public abstract interface class okhttp3/Call$Factory { + public abstract fun newCall (Lokhttp3/Request;)Lokhttp3/Call; +} + +public abstract interface class okhttp3/Callback { + public abstract fun onFailure (Lokhttp3/Call;Ljava/io/IOException;)V + public abstract fun onResponse (Lokhttp3/Call;Lokhttp3/Response;)V +} + +public final class okhttp3/CertificatePinner { + public static final field Companion Lokhttp3/CertificatePinner$Companion; + public static final field DEFAULT Lokhttp3/CertificatePinner; + public final fun check (Ljava/lang/String;Ljava/util/List;)V + public final fun check (Ljava/lang/String;[Ljava/security/cert/Certificate;)V + public fun equals (Ljava/lang/Object;)Z + public final fun findMatchingPins (Ljava/lang/String;)Ljava/util/List; + public final fun getPins ()Ljava/util/Set; + public fun hashCode ()I + public static final fun pin (Ljava/security/cert/Certificate;)Ljava/lang/String; + public static final fun sha1Hash (Ljava/security/cert/X509Certificate;)Lokio/ByteString; + public static final fun sha256Hash (Ljava/security/cert/X509Certificate;)Lokio/ByteString; +} + +public final class okhttp3/CertificatePinner$Builder { + public fun ()V + public final fun add (Ljava/lang/String;[Ljava/lang/String;)Lokhttp3/CertificatePinner$Builder; + public final fun build ()Lokhttp3/CertificatePinner; + public final fun getPins ()Ljava/util/List; +} + +public final class okhttp3/CertificatePinner$Companion { + public final fun pin (Ljava/security/cert/Certificate;)Ljava/lang/String; + public final fun sha1Hash (Ljava/security/cert/X509Certificate;)Lokio/ByteString; + public final fun sha256Hash (Ljava/security/cert/X509Certificate;)Lokio/ByteString; +} + +public final class okhttp3/CertificatePinner$Pin { + public fun (Ljava/lang/String;Ljava/lang/String;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getHash ()Lokio/ByteString; + public final fun getHashAlgorithm ()Ljava/lang/String; + public final fun getPattern ()Ljava/lang/String; + public fun hashCode ()I + public final fun matchesCertificate (Ljava/security/cert/X509Certificate;)Z + public final fun matchesHostname (Ljava/lang/String;)Z + public fun toString ()Ljava/lang/String; +} + +public final class okhttp3/Challenge { + public final fun -deprecated_authParams ()Ljava/util/Map; + public final fun -deprecated_charset ()Ljava/nio/charset/Charset; + public final fun -deprecated_realm ()Ljava/lang/String; + public final fun -deprecated_scheme ()Ljava/lang/String; + public fun (Ljava/lang/String;Ljava/lang/String;)V + public fun (Ljava/lang/String;Ljava/util/Map;)V + public final fun authParams ()Ljava/util/Map; + public final fun charset ()Ljava/nio/charset/Charset; + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I + public final fun realm ()Ljava/lang/String; + public final fun scheme ()Ljava/lang/String; + public fun toString ()Ljava/lang/String; + public final fun withCharset (Ljava/nio/charset/Charset;)Lokhttp3/Challenge; +} + +public final class okhttp3/CipherSuite { + public static final field Companion Lokhttp3/CipherSuite$Companion; + public static final field TLS_AES_128_CCM_8_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_AES_128_CCM_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_AES_128_GCM_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_AES_256_GCM_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_CHACHA20_POLY1305_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_DSS_WITH_AES_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_DHE_DSS_WITH_AES_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_DSS_WITH_DES_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_RSA_WITH_AES_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_DHE_RSA_WITH_AES_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_DHE_RSA_WITH_DES_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 Lokhttp3/CipherSuite; + public static final field TLS_DH_anon_WITH_3DES_EDE_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DH_anon_WITH_AES_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DH_anon_WITH_AES_128_CBC_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_DH_anon_WITH_AES_128_GCM_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_DH_anon_WITH_AES_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DH_anon_WITH_AES_256_CBC_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_DH_anon_WITH_AES_256_GCM_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_DH_anon_WITH_DES_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_DH_anon_WITH_RC4_128_MD5 Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_ECDSA_WITH_NULL_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_ECDSA_WITH_RC4_128_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_RSA_WITH_NULL_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDHE_RSA_WITH_RC4_128_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_ECDH_ECDSA_WITH_NULL_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_ECDSA_WITH_RC4_128_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_RSA_WITH_AES_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_ECDH_RSA_WITH_AES_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_ECDH_RSA_WITH_NULL_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_RSA_WITH_RC4_128_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_anon_WITH_AES_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_anon_WITH_AES_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_anon_WITH_NULL_SHA Lokhttp3/CipherSuite; + public static final field TLS_ECDH_anon_WITH_RC4_128_SHA Lokhttp3/CipherSuite; + public static final field TLS_EMPTY_RENEGOTIATION_INFO_SCSV Lokhttp3/CipherSuite; + public static final field TLS_FALLBACK_SCSV Lokhttp3/CipherSuite; + public static final field TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 Lokhttp3/CipherSuite; + public static final field TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA Lokhttp3/CipherSuite; + public static final field TLS_KRB5_EXPORT_WITH_RC4_40_MD5 Lokhttp3/CipherSuite; + public static final field TLS_KRB5_EXPORT_WITH_RC4_40_SHA Lokhttp3/CipherSuite; + public static final field TLS_KRB5_WITH_3DES_EDE_CBC_MD5 Lokhttp3/CipherSuite; + public static final field TLS_KRB5_WITH_3DES_EDE_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_KRB5_WITH_DES_CBC_MD5 Lokhttp3/CipherSuite; + public static final field TLS_KRB5_WITH_DES_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_KRB5_WITH_RC4_128_MD5 Lokhttp3/CipherSuite; + public static final field TLS_KRB5_WITH_RC4_128_SHA Lokhttp3/CipherSuite; + public static final field TLS_PSK_WITH_3DES_EDE_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_PSK_WITH_AES_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_PSK_WITH_AES_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_PSK_WITH_RC4_128_SHA Lokhttp3/CipherSuite; + public static final field TLS_RSA_EXPORT_WITH_DES40_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_RSA_EXPORT_WITH_RC4_40_MD5 Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_3DES_EDE_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_AES_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_AES_128_CBC_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_AES_128_GCM_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_AES_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_AES_256_CBC_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_AES_256_GCM_SHA384 Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_CAMELLIA_128_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_CAMELLIA_256_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_DES_CBC_SHA Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_NULL_MD5 Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_NULL_SHA Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_NULL_SHA256 Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_RC4_128_MD5 Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_RC4_128_SHA Lokhttp3/CipherSuite; + public static final field TLS_RSA_WITH_SEED_CBC_SHA Lokhttp3/CipherSuite; + public final fun -deprecated_javaName ()Ljava/lang/String; + public synthetic fun (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public static final fun forJavaName (Ljava/lang/String;)Lokhttp3/CipherSuite; + public final fun javaName ()Ljava/lang/String; + public fun toString ()Ljava/lang/String; +} + +public final class okhttp3/CipherSuite$Companion { + public final fun forJavaName (Ljava/lang/String;)Lokhttp3/CipherSuite; +} + +public abstract interface class okhttp3/Connection { + public abstract fun handshake ()Lokhttp3/Handshake; + public abstract fun protocol ()Lokhttp3/Protocol; + public abstract fun route ()Lokhttp3/Route; + public abstract fun socket ()Ljava/net/Socket; +} + +public abstract class okhttp3/ConnectionListener { + public static final field Companion Lokhttp3/ConnectionListener$Companion; + public fun ()V + public fun connectEnd (Lokhttp3/Connection;Lokhttp3/Route;Lokhttp3/Call;)V + public fun connectFailed (Lokhttp3/Route;Lokhttp3/Call;Ljava/io/IOException;)V + public fun connectStart (Lokhttp3/Route;Lokhttp3/Call;)V + public fun connectionAcquired (Lokhttp3/Connection;Lokhttp3/Call;)V + public fun connectionClosed (Lokhttp3/Connection;)V + public fun connectionReleased (Lokhttp3/Connection;Lokhttp3/Call;)V + public fun noNewExchanges (Lokhttp3/Connection;)V +} + +public final class okhttp3/ConnectionListener$Companion { + public final fun getNONE ()Lokhttp3/ConnectionListener; +} + +public final class okhttp3/ConnectionPool { + public fun ()V + public fun (IJLjava/util/concurrent/TimeUnit;)V + public fun (IJLjava/util/concurrent/TimeUnit;Lokhttp3/ConnectionListener;)V + public synthetic fun (IJLjava/util/concurrent/TimeUnit;Lokhttp3/ConnectionListener;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun connectionCount ()I + public final fun evictAll ()V + public final fun idleConnectionCount ()I + public final fun setPolicy (Lokhttp3/Address;Lokhttp3/ConnectionPool$AddressPolicy;)V +} + +public final class okhttp3/ConnectionPool$AddressPolicy { + public final field backoffDelayMillis J + public final field backoffJitterMillis I + public final field minimumConcurrentCalls I + public fun ()V + public fun (IJI)V + public synthetic fun (IJIILkotlin/jvm/internal/DefaultConstructorMarker;)V +} + +public final class okhttp3/ConnectionSpec { + public static final field CLEARTEXT Lokhttp3/ConnectionSpec; + public static final field COMPATIBLE_TLS Lokhttp3/ConnectionSpec; + public static final field Companion Lokhttp3/ConnectionSpec$Companion; + public static final field MODERN_TLS Lokhttp3/ConnectionSpec; + public static final field RESTRICTED_TLS Lokhttp3/ConnectionSpec; + public final fun -deprecated_cipherSuites ()Ljava/util/List; + public final fun -deprecated_supportsTlsExtensions ()Z + public final fun -deprecated_tlsVersions ()Ljava/util/List; + public final fun cipherSuites ()Ljava/util/List; + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I + public final fun isCompatible (Ljavax/net/ssl/SSLSocket;)Z + public final fun isTls ()Z + public final fun supportsTlsExtensions ()Z + public final fun tlsVersions ()Ljava/util/List; + public fun toString ()Ljava/lang/String; +} + +public final class okhttp3/ConnectionSpec$Builder { + public fun (Lokhttp3/ConnectionSpec;)V + public final fun allEnabledCipherSuites ()Lokhttp3/ConnectionSpec$Builder; + public final fun allEnabledTlsVersions ()Lokhttp3/ConnectionSpec$Builder; + public final fun build ()Lokhttp3/ConnectionSpec; + public final fun cipherSuites ([Ljava/lang/String;)Lokhttp3/ConnectionSpec$Builder; + public final fun cipherSuites ([Lokhttp3/CipherSuite;)Lokhttp3/ConnectionSpec$Builder; + public final fun supportsTlsExtensions (Z)Lokhttp3/ConnectionSpec$Builder; + public final fun tlsVersions ([Ljava/lang/String;)Lokhttp3/ConnectionSpec$Builder; + public final fun tlsVersions ([Lokhttp3/TlsVersion;)Lokhttp3/ConnectionSpec$Builder; +} + +public final class okhttp3/ConnectionSpec$Companion { +} + +public final class okhttp3/Cookie { + public static final field Companion Lokhttp3/Cookie$Companion; + public final fun -deprecated_domain ()Ljava/lang/String; + public final fun -deprecated_expiresAt ()J + public final fun -deprecated_hostOnly ()Z + public final fun -deprecated_httpOnly ()Z + public final fun -deprecated_name ()Ljava/lang/String; + public final fun -deprecated_path ()Ljava/lang/String; + public final fun -deprecated_persistent ()Z + public final fun -deprecated_secure ()Z + public final fun -deprecated_value ()Ljava/lang/String; + public synthetic fun (Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;Ljava/lang/String;ZZZZLjava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun domain ()Ljava/lang/String; + public fun equals (Ljava/lang/Object;)Z + public final fun expiresAt ()J + public fun hashCode ()I + public final fun hostOnly ()Z + public final fun httpOnly ()Z + public final fun matches (Lokhttp3/HttpUrl;)Z + public final fun name ()Ljava/lang/String; + public final fun newBuilder ()Lokhttp3/Cookie$Builder; + public static final fun parse (Lokhttp3/HttpUrl;Ljava/lang/String;)Lokhttp3/Cookie; + public static final fun parseAll (Lokhttp3/HttpUrl;Lokhttp3/Headers;)Ljava/util/List; + public final fun path ()Ljava/lang/String; + public final fun persistent ()Z + public final fun sameSite ()Ljava/lang/String; + public final fun secure ()Z + public fun toString ()Ljava/lang/String; + public final fun value ()Ljava/lang/String; +} + +public final class okhttp3/Cookie$Builder { + public fun ()V + public final fun build ()Lokhttp3/Cookie; + public final fun domain (Ljava/lang/String;)Lokhttp3/Cookie$Builder; + public final fun expiresAt (J)Lokhttp3/Cookie$Builder; + public final fun hostOnlyDomain (Ljava/lang/String;)Lokhttp3/Cookie$Builder; + public final fun httpOnly ()Lokhttp3/Cookie$Builder; + public final fun name (Ljava/lang/String;)Lokhttp3/Cookie$Builder; + public final fun path (Ljava/lang/String;)Lokhttp3/Cookie$Builder; + public final fun sameSite (Ljava/lang/String;)Lokhttp3/Cookie$Builder; + public final fun secure ()Lokhttp3/Cookie$Builder; + public final fun value (Ljava/lang/String;)Lokhttp3/Cookie$Builder; +} + +public final class okhttp3/Cookie$Companion { + public final fun parse (Lokhttp3/HttpUrl;Ljava/lang/String;)Lokhttp3/Cookie; + public final fun parseAll (Lokhttp3/HttpUrl;Lokhttp3/Headers;)Ljava/util/List; +} + +public abstract interface class okhttp3/CookieJar { + public static final field Companion Lokhttp3/CookieJar$Companion; + public static final field NO_COOKIES Lokhttp3/CookieJar; + public abstract fun loadForRequest (Lokhttp3/HttpUrl;)Ljava/util/List; + public abstract fun saveFromResponse (Lokhttp3/HttpUrl;Ljava/util/List;)V +} + +public final class okhttp3/CookieJar$Companion { +} + +public final class okhttp3/Credentials { + public static final field INSTANCE Lokhttp3/Credentials; + public static final fun basic (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + public static final fun basic (Ljava/lang/String;Ljava/lang/String;Ljava/nio/charset/Charset;)Ljava/lang/String; + public static synthetic fun basic$default (Ljava/lang/String;Ljava/lang/String;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/lang/String; +} + +public final class okhttp3/Dispatcher { + public final fun -deprecated_executorService ()Ljava/util/concurrent/ExecutorService; + public fun ()V + public fun (Ljava/util/concurrent/ExecutorService;)V + public final fun cancelAll ()V + public final fun executorService ()Ljava/util/concurrent/ExecutorService; + public final fun getIdleCallback ()Ljava/lang/Runnable; + public final fun getMaxRequests ()I + public final fun getMaxRequestsPerHost ()I + public final fun queuedCalls ()Ljava/util/List; + public final fun queuedCallsCount ()I + public final fun runningCalls ()Ljava/util/List; + public final fun runningCallsCount ()I + public final fun setIdleCallback (Ljava/lang/Runnable;)V + public final fun setMaxRequests (I)V + public final fun setMaxRequestsPerHost (I)V +} + +public abstract interface class okhttp3/Dns { + public static final field Companion Lokhttp3/Dns$Companion; + public static final field SYSTEM Lokhttp3/Dns; + public abstract fun lookup (Ljava/lang/String;)Ljava/util/List; +} + +public final class okhttp3/Dns$Companion { +} + +public abstract class okhttp3/EventListener { + public static final field Companion Lokhttp3/EventListener$Companion; + public static final field NONE Lokhttp3/EventListener; + public fun ()V + public fun cacheConditionalHit (Lokhttp3/Call;Lokhttp3/Response;)V + public fun cacheHit (Lokhttp3/Call;Lokhttp3/Response;)V + public fun cacheMiss (Lokhttp3/Call;)V + public fun callEnd (Lokhttp3/Call;)V + public fun callFailed (Lokhttp3/Call;Ljava/io/IOException;)V + public fun callStart (Lokhttp3/Call;)V + public fun canceled (Lokhttp3/Call;)V + public fun connectEnd (Lokhttp3/Call;Ljava/net/InetSocketAddress;Ljava/net/Proxy;Lokhttp3/Protocol;)V + public fun connectFailed (Lokhttp3/Call;Ljava/net/InetSocketAddress;Ljava/net/Proxy;Lokhttp3/Protocol;Ljava/io/IOException;)V + public fun connectStart (Lokhttp3/Call;Ljava/net/InetSocketAddress;Ljava/net/Proxy;)V + public fun connectionAcquired (Lokhttp3/Call;Lokhttp3/Connection;)V + public fun connectionReleased (Lokhttp3/Call;Lokhttp3/Connection;)V + public fun dnsEnd (Lokhttp3/Call;Ljava/lang/String;Ljava/util/List;)V + public fun dnsStart (Lokhttp3/Call;Ljava/lang/String;)V + public fun proxySelectEnd (Lokhttp3/Call;Lokhttp3/HttpUrl;Ljava/util/List;)V + public fun proxySelectStart (Lokhttp3/Call;Lokhttp3/HttpUrl;)V + public fun requestBodyEnd (Lokhttp3/Call;J)V + public fun requestBodyStart (Lokhttp3/Call;)V + public fun requestFailed (Lokhttp3/Call;Ljava/io/IOException;)V + public fun requestHeadersEnd (Lokhttp3/Call;Lokhttp3/Request;)V + public fun requestHeadersStart (Lokhttp3/Call;)V + public fun responseBodyEnd (Lokhttp3/Call;J)V + public fun responseBodyStart (Lokhttp3/Call;)V + public fun responseFailed (Lokhttp3/Call;Ljava/io/IOException;)V + public fun responseHeadersEnd (Lokhttp3/Call;Lokhttp3/Response;)V + public fun responseHeadersStart (Lokhttp3/Call;)V + public fun satisfactionFailure (Lokhttp3/Call;Lokhttp3/Response;)V + public fun secureConnectEnd (Lokhttp3/Call;Lokhttp3/Handshake;)V + public fun secureConnectStart (Lokhttp3/Call;)V +} + +public final class okhttp3/EventListener$Companion { +} + +public abstract interface class okhttp3/EventListener$Factory { + public abstract fun create (Lokhttp3/Call;)Lokhttp3/EventListener; +} + +public abstract interface annotation class okhttp3/ExperimentalOkHttpApi : java/lang/annotation/Annotation { +} + +public final class okhttp3/FormBody : okhttp3/RequestBody { + public static final field Companion Lokhttp3/FormBody$Companion; + public final fun -deprecated_size ()I + public fun contentLength ()J + public fun contentType ()Lokhttp3/MediaType; + public final fun encodedName (I)Ljava/lang/String; + public final fun encodedValue (I)Ljava/lang/String; + public final fun name (I)Ljava/lang/String; + public final fun size ()I + public final fun value (I)Ljava/lang/String; + public fun writeTo (Lokio/BufferedSink;)V +} + +public final class okhttp3/FormBody$Builder { + public fun ()V + public fun (Ljava/nio/charset/Charset;)V + public synthetic fun (Ljava/nio/charset/Charset;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun add (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/FormBody$Builder; + public final fun addEncoded (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/FormBody$Builder; + public final fun build ()Lokhttp3/FormBody; +} + +public final class okhttp3/FormBody$Companion { +} + +public final class okhttp3/Handshake { + public static final field Companion Lokhttp3/Handshake$Companion; + public final fun -deprecated_cipherSuite ()Lokhttp3/CipherSuite; + public final fun -deprecated_localCertificates ()Ljava/util/List; + public final fun -deprecated_localPrincipal ()Ljava/security/Principal; + public final fun -deprecated_peerCertificates ()Ljava/util/List; + public final fun -deprecated_peerPrincipal ()Ljava/security/Principal; + public final fun -deprecated_tlsVersion ()Lokhttp3/TlsVersion; + public final fun cipherSuite ()Lokhttp3/CipherSuite; + public fun equals (Ljava/lang/Object;)Z + public static final fun get (Ljavax/net/ssl/SSLSession;)Lokhttp3/Handshake; + public static final fun get (Lokhttp3/TlsVersion;Lokhttp3/CipherSuite;Ljava/util/List;Ljava/util/List;)Lokhttp3/Handshake; + public fun hashCode ()I + public final fun localCertificates ()Ljava/util/List; + public final fun localPrincipal ()Ljava/security/Principal; + public final fun peerCertificates ()Ljava/util/List; + public final fun peerPrincipal ()Ljava/security/Principal; + public final fun tlsVersion ()Lokhttp3/TlsVersion; + public fun toString ()Ljava/lang/String; +} + +public final class okhttp3/Handshake$Companion { + public final fun -deprecated_get (Ljavax/net/ssl/SSLSession;)Lokhttp3/Handshake; + public final fun get (Ljavax/net/ssl/SSLSession;)Lokhttp3/Handshake; + public final fun get (Lokhttp3/TlsVersion;Lokhttp3/CipherSuite;Ljava/util/List;Ljava/util/List;)Lokhttp3/Handshake; +} + +public final class okhttp3/Headers : java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker { + public static final field Companion Lokhttp3/Headers$Companion; + public final fun -deprecated_size ()I + public final fun byteCount ()J + public fun equals (Ljava/lang/Object;)Z + public final fun get (Ljava/lang/String;)Ljava/lang/String; + public final fun getDate (Ljava/lang/String;)Ljava/util/Date; + public final fun getInstant (Ljava/lang/String;)Ljava/time/Instant; + public fun hashCode ()I + public fun iterator ()Ljava/util/Iterator; + public final fun name (I)Ljava/lang/String; + public final fun names ()Ljava/util/Set; + public final fun newBuilder ()Lokhttp3/Headers$Builder; + public static final fun of (Ljava/util/Map;)Lokhttp3/Headers; + public static final fun of ([Ljava/lang/String;)Lokhttp3/Headers; + public final fun size ()I + public final fun toMultimap ()Ljava/util/Map; + public fun toString ()Ljava/lang/String; + public final fun value (I)Ljava/lang/String; + public final fun values (Ljava/lang/String;)Ljava/util/List; +} + +public final class okhttp3/Headers$Builder { + public fun ()V + public final fun add (Ljava/lang/String;)Lokhttp3/Headers$Builder; + public final fun add (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Headers$Builder; + public final fun add (Ljava/lang/String;Ljava/time/Instant;)Lokhttp3/Headers$Builder; + public final fun add (Ljava/lang/String;Ljava/util/Date;)Lokhttp3/Headers$Builder; + public final fun addAll (Lokhttp3/Headers;)Lokhttp3/Headers$Builder; + public final fun addUnsafeNonAscii (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Headers$Builder; + public final fun build ()Lokhttp3/Headers; + public final fun get (Ljava/lang/String;)Ljava/lang/String; + public final fun removeAll (Ljava/lang/String;)Lokhttp3/Headers$Builder; + public final fun set (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Headers$Builder; + public final fun set (Ljava/lang/String;Ljava/time/Instant;)Lokhttp3/Headers$Builder; + public final fun set (Ljava/lang/String;Ljava/util/Date;)Lokhttp3/Headers$Builder; +} + +public final class okhttp3/Headers$Companion { + public final fun -deprecated_of (Ljava/util/Map;)Lokhttp3/Headers; + public final fun -deprecated_of ([Ljava/lang/String;)Lokhttp3/Headers; + public final fun of (Ljava/util/Map;)Lokhttp3/Headers; + public final fun of ([Ljava/lang/String;)Lokhttp3/Headers; +} + +public final class okhttp3/HttpUrl { + public static final field Companion Lokhttp3/HttpUrl$Companion; + public final fun -deprecated_encodedFragment ()Ljava/lang/String; + public final fun -deprecated_encodedPassword ()Ljava/lang/String; + public final fun -deprecated_encodedPath ()Ljava/lang/String; + public final fun -deprecated_encodedPathSegments ()Ljava/util/List; + public final fun -deprecated_encodedQuery ()Ljava/lang/String; + public final fun -deprecated_encodedUsername ()Ljava/lang/String; + public final fun -deprecated_fragment ()Ljava/lang/String; + public final fun -deprecated_host ()Ljava/lang/String; + public final fun -deprecated_password ()Ljava/lang/String; + public final fun -deprecated_pathSegments ()Ljava/util/List; + public final fun -deprecated_pathSize ()I + public final fun -deprecated_port ()I + public final fun -deprecated_query ()Ljava/lang/String; + public final fun -deprecated_queryParameterNames ()Ljava/util/Set; + public final fun -deprecated_querySize ()I + public final fun -deprecated_scheme ()Ljava/lang/String; + public final fun -deprecated_uri ()Ljava/net/URI; + public final fun -deprecated_url ()Ljava/net/URL; + public final fun -deprecated_username ()Ljava/lang/String; + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/util/List;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public static final fun defaultPort (Ljava/lang/String;)I + public final fun encodedFragment ()Ljava/lang/String; + public final fun encodedPassword ()Ljava/lang/String; + public final fun encodedPath ()Ljava/lang/String; + public final fun encodedPathSegments ()Ljava/util/List; + public final fun encodedQuery ()Ljava/lang/String; + public final fun encodedUsername ()Ljava/lang/String; + public fun equals (Ljava/lang/Object;)Z + public final fun fragment ()Ljava/lang/String; + public static final fun get (Ljava/lang/String;)Lokhttp3/HttpUrl; + public static final fun get (Ljava/net/URI;)Lokhttp3/HttpUrl; + public static final fun get (Ljava/net/URL;)Lokhttp3/HttpUrl; + public fun hashCode ()I + public final fun host ()Ljava/lang/String; + public final fun isHttps ()Z + public final fun newBuilder ()Lokhttp3/HttpUrl$Builder; + public final fun newBuilder (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public static final fun parse (Ljava/lang/String;)Lokhttp3/HttpUrl; + public final fun password ()Ljava/lang/String; + public final fun pathSegments ()Ljava/util/List; + public final fun pathSize ()I + public final fun port ()I + public final fun query ()Ljava/lang/String; + public final fun queryParameter (Ljava/lang/String;)Ljava/lang/String; + public final fun queryParameterName (I)Ljava/lang/String; + public final fun queryParameterNames ()Ljava/util/Set; + public final fun queryParameterValue (I)Ljava/lang/String; + public final fun queryParameterValues (Ljava/lang/String;)Ljava/util/List; + public final fun querySize ()I + public final fun redact ()Ljava/lang/String; + public final fun resolve (Ljava/lang/String;)Lokhttp3/HttpUrl; + public final fun scheme ()Ljava/lang/String; + public fun toString ()Ljava/lang/String; + public final fun topPrivateDomain ()Ljava/lang/String; + public final fun uri ()Ljava/net/URI; + public final fun url ()Ljava/net/URL; + public final fun username ()Ljava/lang/String; +} + +public final class okhttp3/HttpUrl$Builder { + public fun ()V + public final fun addEncodedPathSegment (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun addEncodedPathSegments (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun addEncodedQueryParameter (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun addPathSegment (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun addPathSegments (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun addQueryParameter (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun build ()Lokhttp3/HttpUrl; + public final fun encodedFragment (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun encodedPassword (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun encodedPath (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun encodedQuery (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun encodedUsername (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun fragment (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun host (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun password (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun port (I)Lokhttp3/HttpUrl$Builder; + public final fun query (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun removeAllEncodedQueryParameters (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun removeAllQueryParameters (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun removePathSegment (I)Lokhttp3/HttpUrl$Builder; + public final fun scheme (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun setEncodedPathSegment (ILjava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun setEncodedQueryParameter (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun setPathSegment (ILjava/lang/String;)Lokhttp3/HttpUrl$Builder; + public final fun setQueryParameter (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; + public fun toString ()Ljava/lang/String; + public final fun username (Ljava/lang/String;)Lokhttp3/HttpUrl$Builder; +} + +public final class okhttp3/HttpUrl$Companion { + public final fun -deprecated_get (Ljava/lang/String;)Lokhttp3/HttpUrl; + public final fun -deprecated_get (Ljava/net/URI;)Lokhttp3/HttpUrl; + public final fun -deprecated_get (Ljava/net/URL;)Lokhttp3/HttpUrl; + public final fun -deprecated_parse (Ljava/lang/String;)Lokhttp3/HttpUrl; + public final fun defaultPort (Ljava/lang/String;)I + public final fun get (Ljava/lang/String;)Lokhttp3/HttpUrl; + public final fun get (Ljava/net/URI;)Lokhttp3/HttpUrl; + public final fun get (Ljava/net/URL;)Lokhttp3/HttpUrl; + public final fun parse (Ljava/lang/String;)Lokhttp3/HttpUrl; +} + +public abstract interface class okhttp3/Interceptor { + public static final field Companion Lokhttp3/Interceptor$Companion; + public abstract fun intercept (Lokhttp3/Interceptor$Chain;)Lokhttp3/Response; +} + +public abstract interface class okhttp3/Interceptor$Chain { + public abstract fun call ()Lokhttp3/Call; + public abstract fun connectTimeoutMillis ()I + public abstract fun connection ()Lokhttp3/Connection; + public abstract fun proceed (Lokhttp3/Request;)Lokhttp3/Response; + public abstract fun readTimeoutMillis ()I + public abstract fun request ()Lokhttp3/Request; + public abstract fun withConnectTimeout (ILjava/util/concurrent/TimeUnit;)Lokhttp3/Interceptor$Chain; + public abstract fun withReadTimeout (ILjava/util/concurrent/TimeUnit;)Lokhttp3/Interceptor$Chain; + public abstract fun withWriteTimeout (ILjava/util/concurrent/TimeUnit;)Lokhttp3/Interceptor$Chain; + public abstract fun writeTimeoutMillis ()I +} + +public final class okhttp3/Interceptor$Companion { + public final fun invoke (Lkotlin/jvm/functions/Function1;)Lokhttp3/Interceptor; +} + +public final class okhttp3/MediaType { + public static final field Companion Lokhttp3/MediaType$Companion; + public final fun -deprecated_subtype ()Ljava/lang/String; + public final fun -deprecated_type ()Ljava/lang/String; + public final fun charset ()Ljava/nio/charset/Charset; + public final fun charset (Ljava/nio/charset/Charset;)Ljava/nio/charset/Charset; + public static synthetic fun charset$default (Lokhttp3/MediaType;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/nio/charset/Charset; + public fun equals (Ljava/lang/Object;)Z + public static final fun get (Ljava/lang/String;)Lokhttp3/MediaType; + public fun hashCode ()I + public final fun parameter (Ljava/lang/String;)Ljava/lang/String; + public static final fun parse (Ljava/lang/String;)Lokhttp3/MediaType; + public final fun subtype ()Ljava/lang/String; + public fun toString ()Ljava/lang/String; + public final fun type ()Ljava/lang/String; +} + +public final class okhttp3/MediaType$Companion { + public final fun -deprecated_get (Ljava/lang/String;)Lokhttp3/MediaType; + public final fun -deprecated_parse (Ljava/lang/String;)Lokhttp3/MediaType; + public final fun get (Ljava/lang/String;)Lokhttp3/MediaType; + public final fun parse (Ljava/lang/String;)Lokhttp3/MediaType; +} + +public final class okhttp3/MultipartBody : okhttp3/RequestBody { + public static final field ALTERNATIVE Lokhttp3/MediaType; + public static final field Companion Lokhttp3/MultipartBody$Companion; + public static final field DIGEST Lokhttp3/MediaType; + public static final field FORM Lokhttp3/MediaType; + public static final field MIXED Lokhttp3/MediaType; + public static final field PARALLEL Lokhttp3/MediaType; + public final fun -deprecated_boundary ()Ljava/lang/String; + public final fun -deprecated_parts ()Ljava/util/List; + public final fun -deprecated_size ()I + public final fun -deprecated_type ()Lokhttp3/MediaType; + public final fun boundary ()Ljava/lang/String; + public fun contentLength ()J + public fun contentType ()Lokhttp3/MediaType; + public fun isOneShot ()Z + public final fun part (I)Lokhttp3/MultipartBody$Part; + public final fun parts ()Ljava/util/List; + public final fun size ()I + public final fun type ()Lokhttp3/MediaType; + public fun writeTo (Lokio/BufferedSink;)V +} + +public final class okhttp3/MultipartBody$Builder { + public fun ()V + public fun (Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun addFormDataPart (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/MultipartBody$Builder; + public final fun addFormDataPart (Ljava/lang/String;Ljava/lang/String;Lokhttp3/RequestBody;)Lokhttp3/MultipartBody$Builder; + public final fun addPart (Lokhttp3/Headers;Lokhttp3/RequestBody;)Lokhttp3/MultipartBody$Builder; + public final fun addPart (Lokhttp3/MultipartBody$Part;)Lokhttp3/MultipartBody$Builder; + public final fun addPart (Lokhttp3/RequestBody;)Lokhttp3/MultipartBody$Builder; + public final fun build ()Lokhttp3/MultipartBody; + public final fun setType (Lokhttp3/MediaType;)Lokhttp3/MultipartBody$Builder; +} + +public final class okhttp3/MultipartBody$Companion { +} + +public final class okhttp3/MultipartBody$Part { + public static final field Companion Lokhttp3/MultipartBody$Part$Companion; + public final fun -deprecated_body ()Lokhttp3/RequestBody; + public final fun -deprecated_headers ()Lokhttp3/Headers; + public synthetic fun (Lokhttp3/Headers;Lokhttp3/RequestBody;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun body ()Lokhttp3/RequestBody; + public static final fun create (Lokhttp3/Headers;Lokhttp3/RequestBody;)Lokhttp3/MultipartBody$Part; + public static final fun create (Lokhttp3/RequestBody;)Lokhttp3/MultipartBody$Part; + public static final fun createFormData (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/MultipartBody$Part; + public static final fun createFormData (Ljava/lang/String;Ljava/lang/String;Lokhttp3/RequestBody;)Lokhttp3/MultipartBody$Part; + public final fun headers ()Lokhttp3/Headers; +} + +public final class okhttp3/MultipartBody$Part$Companion { + public final fun create (Lokhttp3/Headers;Lokhttp3/RequestBody;)Lokhttp3/MultipartBody$Part; + public final fun create (Lokhttp3/RequestBody;)Lokhttp3/MultipartBody$Part; + public final fun createFormData (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/MultipartBody$Part; + public final fun createFormData (Ljava/lang/String;Ljava/lang/String;Lokhttp3/RequestBody;)Lokhttp3/MultipartBody$Part; +} + +public final class okhttp3/MultipartReader : java/io/Closeable { + public fun (Lokhttp3/ResponseBody;)V + public fun (Lokio/BufferedSource;Ljava/lang/String;)V + public final fun boundary ()Ljava/lang/String; + public fun close ()V + public final fun nextPart ()Lokhttp3/MultipartReader$Part; +} + +public final class okhttp3/MultipartReader$Part : java/io/Closeable { + public fun (Lokhttp3/Headers;Lokio/BufferedSource;)V + public final fun body ()Lokio/BufferedSource; + public fun close ()V + public final fun headers ()Lokhttp3/Headers; +} + +public final class okhttp3/OkHttp { + public static final field INSTANCE Lokhttp3/OkHttp; + public static final field VERSION Ljava/lang/String; +} + +public class okhttp3/OkHttpClient : okhttp3/Call$Factory, okhttp3/WebSocket$Factory { + public static final field Companion Lokhttp3/OkHttpClient$Companion; + public final fun -deprecated_authenticator ()Lokhttp3/Authenticator; + public final fun -deprecated_cache ()Lokhttp3/Cache; + public final fun -deprecated_callTimeoutMillis ()I + public final fun -deprecated_certificatePinner ()Lokhttp3/CertificatePinner; + public final fun -deprecated_connectTimeoutMillis ()I + public final fun -deprecated_connectionPool ()Lokhttp3/ConnectionPool; + public final fun -deprecated_connectionSpecs ()Ljava/util/List; + public final fun -deprecated_cookieJar ()Lokhttp3/CookieJar; + public final fun -deprecated_dispatcher ()Lokhttp3/Dispatcher; + public final fun -deprecated_dns ()Lokhttp3/Dns; + public final fun -deprecated_eventListenerFactory ()Lokhttp3/EventListener$Factory; + public final fun -deprecated_followRedirects ()Z + public final fun -deprecated_followSslRedirects ()Z + public final fun -deprecated_hostnameVerifier ()Ljavax/net/ssl/HostnameVerifier; + public final fun -deprecated_interceptors ()Ljava/util/List; + public final fun -deprecated_networkInterceptors ()Ljava/util/List; + public final fun -deprecated_pingIntervalMillis ()I + public final fun -deprecated_protocols ()Ljava/util/List; + public final fun -deprecated_proxy ()Ljava/net/Proxy; + public final fun -deprecated_proxyAuthenticator ()Lokhttp3/Authenticator; + public final fun -deprecated_proxySelector ()Ljava/net/ProxySelector; + public final fun -deprecated_readTimeoutMillis ()I + public final fun -deprecated_retryOnConnectionFailure ()Z + public final fun -deprecated_socketFactory ()Ljavax/net/SocketFactory; + public final fun -deprecated_sslSocketFactory ()Ljavax/net/ssl/SSLSocketFactory; + public final fun -deprecated_writeTimeoutMillis ()I + public fun ()V + public final fun address (Lokhttp3/HttpUrl;)Lokhttp3/Address; + public final fun authenticator ()Lokhttp3/Authenticator; + public final fun cache ()Lokhttp3/Cache; + public final fun callTimeoutMillis ()I + public final fun certificateChainCleaner ()Lokhttp3/internal/tls/CertificateChainCleaner; + public final fun certificatePinner ()Lokhttp3/CertificatePinner; + public final fun connectTimeoutMillis ()I + public final fun connectionPool ()Lokhttp3/ConnectionPool; + public final fun connectionSpecs ()Ljava/util/List; + public final fun cookieJar ()Lokhttp3/CookieJar; + public final fun dispatcher ()Lokhttp3/Dispatcher; + public final fun dns ()Lokhttp3/Dns; + public final fun eventListenerFactory ()Lokhttp3/EventListener$Factory; + public final fun fastFallback ()Z + public final fun followRedirects ()Z + public final fun followSslRedirects ()Z + public final fun hostnameVerifier ()Ljavax/net/ssl/HostnameVerifier; + public final fun interceptors ()Ljava/util/List; + public final fun minWebSocketMessageToCompress ()J + public final fun networkInterceptors ()Ljava/util/List; + public fun newBuilder ()Lokhttp3/OkHttpClient$Builder; + public fun newCall (Lokhttp3/Request;)Lokhttp3/Call; + public fun newWebSocket (Lokhttp3/Request;Lokhttp3/WebSocketListener;)Lokhttp3/WebSocket; + public final fun pingIntervalMillis ()I + public final fun protocols ()Ljava/util/List; + public final fun proxy ()Ljava/net/Proxy; + public final fun proxyAuthenticator ()Lokhttp3/Authenticator; + public final fun proxySelector ()Ljava/net/ProxySelector; + public final fun readTimeoutMillis ()I + public final fun retryOnConnectionFailure ()Z + public final fun socketFactory ()Ljavax/net/SocketFactory; + public final fun sslSocketFactory ()Ljavax/net/ssl/SSLSocketFactory; + public final fun webSocketCloseTimeout ()I + public final fun writeTimeoutMillis ()I + public final fun x509TrustManager ()Ljavax/net/ssl/X509TrustManager; +} + +public final class okhttp3/OkHttpClient$Builder { + public final fun -addInterceptor (Lkotlin/jvm/functions/Function1;)Lokhttp3/OkHttpClient$Builder; + public final fun -addNetworkInterceptor (Lkotlin/jvm/functions/Function1;)Lokhttp3/OkHttpClient$Builder; + public fun ()V + public final fun addInterceptor (Lokhttp3/Interceptor;)Lokhttp3/OkHttpClient$Builder; + public final fun addNetworkInterceptor (Lokhttp3/Interceptor;)Lokhttp3/OkHttpClient$Builder; + public final fun authenticator (Lokhttp3/Authenticator;)Lokhttp3/OkHttpClient$Builder; + public final fun build ()Lokhttp3/OkHttpClient; + public final fun cache (Lokhttp3/Cache;)Lokhttp3/OkHttpClient$Builder; + public final fun callTimeout (JLjava/util/concurrent/TimeUnit;)Lokhttp3/OkHttpClient$Builder; + public final fun callTimeout (Ljava/time/Duration;)Lokhttp3/OkHttpClient$Builder; + public final fun callTimeout-LRDsOJo (J)Lokhttp3/OkHttpClient$Builder; + public final fun certificatePinner (Lokhttp3/CertificatePinner;)Lokhttp3/OkHttpClient$Builder; + public final fun connectTimeout (JLjava/util/concurrent/TimeUnit;)Lokhttp3/OkHttpClient$Builder; + public final fun connectTimeout (Ljava/time/Duration;)Lokhttp3/OkHttpClient$Builder; + public final fun connectTimeout-LRDsOJo (J)Lokhttp3/OkHttpClient$Builder; + public final fun connectionPool (Lokhttp3/ConnectionPool;)Lokhttp3/OkHttpClient$Builder; + public final fun connectionSpecs (Ljava/util/List;)Lokhttp3/OkHttpClient$Builder; + public final fun cookieJar (Lokhttp3/CookieJar;)Lokhttp3/OkHttpClient$Builder; + public final fun dispatcher (Lokhttp3/Dispatcher;)Lokhttp3/OkHttpClient$Builder; + public final fun dns (Lokhttp3/Dns;)Lokhttp3/OkHttpClient$Builder; + public final fun eventListener (Lokhttp3/EventListener;)Lokhttp3/OkHttpClient$Builder; + public final fun eventListenerFactory (Lokhttp3/EventListener$Factory;)Lokhttp3/OkHttpClient$Builder; + public final fun fastFallback (Z)Lokhttp3/OkHttpClient$Builder; + public final fun followRedirects (Z)Lokhttp3/OkHttpClient$Builder; + public final fun followSslRedirects (Z)Lokhttp3/OkHttpClient$Builder; + public final fun hostnameVerifier (Ljavax/net/ssl/HostnameVerifier;)Lokhttp3/OkHttpClient$Builder; + public final fun interceptors ()Ljava/util/List; + public final fun minWebSocketMessageToCompress (J)Lokhttp3/OkHttpClient$Builder; + public final fun networkInterceptors ()Ljava/util/List; + public final fun pingInterval (JLjava/util/concurrent/TimeUnit;)Lokhttp3/OkHttpClient$Builder; + public final fun pingInterval (Ljava/time/Duration;)Lokhttp3/OkHttpClient$Builder; + public final fun pingInterval-LRDsOJo (J)Lokhttp3/OkHttpClient$Builder; + public final fun protocols (Ljava/util/List;)Lokhttp3/OkHttpClient$Builder; + public final fun proxy (Ljava/net/Proxy;)Lokhttp3/OkHttpClient$Builder; + public final fun proxyAuthenticator (Lokhttp3/Authenticator;)Lokhttp3/OkHttpClient$Builder; + public final fun proxySelector (Ljava/net/ProxySelector;)Lokhttp3/OkHttpClient$Builder; + public final fun readTimeout (JLjava/util/concurrent/TimeUnit;)Lokhttp3/OkHttpClient$Builder; + public final fun readTimeout (Ljava/time/Duration;)Lokhttp3/OkHttpClient$Builder; + public final fun readTimeout-LRDsOJo (J)Lokhttp3/OkHttpClient$Builder; + public final fun retryOnConnectionFailure (Z)Lokhttp3/OkHttpClient$Builder; + public final fun socketFactory (Ljavax/net/SocketFactory;)Lokhttp3/OkHttpClient$Builder; + public final fun sslSocketFactory (Ljavax/net/ssl/SSLSocketFactory;)Lokhttp3/OkHttpClient$Builder; + public final fun sslSocketFactory (Ljavax/net/ssl/SSLSocketFactory;Ljavax/net/ssl/X509TrustManager;)Lokhttp3/OkHttpClient$Builder; + public final fun webSocketCloseTimeout (JLjava/util/concurrent/TimeUnit;)Lokhttp3/OkHttpClient$Builder; + public final fun webSocketCloseTimeout (Ljava/time/Duration;)Lokhttp3/OkHttpClient$Builder; + public final fun webSocketCloseTimeout-LRDsOJo (J)Lokhttp3/OkHttpClient$Builder; + public final fun writeTimeout (JLjava/util/concurrent/TimeUnit;)Lokhttp3/OkHttpClient$Builder; + public final fun writeTimeout (Ljava/time/Duration;)Lokhttp3/OkHttpClient$Builder; + public final fun writeTimeout-LRDsOJo (J)Lokhttp3/OkHttpClient$Builder; +} + +public final class okhttp3/OkHttpClient$Companion { +} + +public final class okhttp3/Protocol : java/lang/Enum { + public static final field Companion Lokhttp3/Protocol$Companion; + public static final field H2_PRIOR_KNOWLEDGE Lokhttp3/Protocol; + public static final field HTTP_1_0 Lokhttp3/Protocol; + public static final field HTTP_1_1 Lokhttp3/Protocol; + public static final field HTTP_2 Lokhttp3/Protocol; + public static final field HTTP_3 Lokhttp3/Protocol; + public static final field QUIC Lokhttp3/Protocol; + public static final field SPDY_3 Lokhttp3/Protocol; + public static final fun get (Ljava/lang/String;)Lokhttp3/Protocol; + public static fun getEntries ()Lkotlin/enums/EnumEntries; + public fun toString ()Ljava/lang/String; + public static fun valueOf (Ljava/lang/String;)Lokhttp3/Protocol; + public static fun values ()[Lokhttp3/Protocol; +} + +public final class okhttp3/Protocol$Companion { + public final fun get (Ljava/lang/String;)Lokhttp3/Protocol; +} + +public final class okhttp3/Request { + public final fun -deprecated_body ()Lokhttp3/RequestBody; + public final fun -deprecated_cacheControl ()Lokhttp3/CacheControl; + public final fun -deprecated_headers ()Lokhttp3/Headers; + public final fun -deprecated_method ()Ljava/lang/String; + public final fun -deprecated_url ()Lokhttp3/HttpUrl; + public fun (Lokhttp3/HttpUrl;Lokhttp3/Headers;Ljava/lang/String;Lokhttp3/RequestBody;)V + public synthetic fun (Lokhttp3/HttpUrl;Lokhttp3/Headers;Ljava/lang/String;Lokhttp3/RequestBody;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun body ()Lokhttp3/RequestBody; + public final fun cacheControl ()Lokhttp3/CacheControl; + public final fun cacheUrlOverride ()Lokhttp3/HttpUrl; + public final fun header (Ljava/lang/String;)Ljava/lang/String; + public final fun headers ()Lokhttp3/Headers; + public final fun headers (Ljava/lang/String;)Ljava/util/List; + public final fun isHttps ()Z + public final fun method ()Ljava/lang/String; + public final fun newBuilder ()Lokhttp3/Request$Builder; + public final fun tag ()Ljava/lang/Object; + public final fun tag (Ljava/lang/Class;)Ljava/lang/Object; + public final fun tag (Lkotlin/reflect/KClass;)Ljava/lang/Object; + public fun toString ()Ljava/lang/String; + public final fun url ()Lokhttp3/HttpUrl; +} + +public class okhttp3/Request$Builder { + public fun ()V + public fun addHeader (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Request$Builder; + public fun build ()Lokhttp3/Request; + public fun cacheControl (Lokhttp3/CacheControl;)Lokhttp3/Request$Builder; + public final fun cacheUrlOverride (Lokhttp3/HttpUrl;)Lokhttp3/Request$Builder; + public final fun delete ()Lokhttp3/Request$Builder; + public fun delete (Lokhttp3/RequestBody;)Lokhttp3/Request$Builder; + public static synthetic fun delete$default (Lokhttp3/Request$Builder;Lokhttp3/RequestBody;ILjava/lang/Object;)Lokhttp3/Request$Builder; + public fun get ()Lokhttp3/Request$Builder; + public fun head ()Lokhttp3/Request$Builder; + public fun header (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Request$Builder; + public fun headers (Lokhttp3/Headers;)Lokhttp3/Request$Builder; + public fun method (Ljava/lang/String;Lokhttp3/RequestBody;)Lokhttp3/Request$Builder; + public fun patch (Lokhttp3/RequestBody;)Lokhttp3/Request$Builder; + public fun post (Lokhttp3/RequestBody;)Lokhttp3/Request$Builder; + public fun put (Lokhttp3/RequestBody;)Lokhttp3/Request$Builder; + public fun removeHeader (Ljava/lang/String;)Lokhttp3/Request$Builder; + public fun tag (Ljava/lang/Class;Ljava/lang/Object;)Lokhttp3/Request$Builder; + public fun tag (Ljava/lang/Object;)Lokhttp3/Request$Builder; + public final fun tag (Lkotlin/reflect/KClass;Ljava/lang/Object;)Lokhttp3/Request$Builder; + public fun url (Ljava/lang/String;)Lokhttp3/Request$Builder; + public fun url (Ljava/net/URL;)Lokhttp3/Request$Builder; + public fun url (Lokhttp3/HttpUrl;)Lokhttp3/Request$Builder; +} + +public abstract class okhttp3/RequestBody { + public static final field Companion Lokhttp3/RequestBody$Companion; + public fun ()V + public fun contentLength ()J + public abstract fun contentType ()Lokhttp3/MediaType; + public static final fun create (Ljava/io/File;Lokhttp3/MediaType;)Lokhttp3/RequestBody; + public static final fun create (Ljava/io/FileDescriptor;Lokhttp3/MediaType;)Lokhttp3/RequestBody; + public static final fun create (Ljava/lang/String;Lokhttp3/MediaType;)Lokhttp3/RequestBody; + public static final fun create (Lokhttp3/MediaType;Ljava/io/File;)Lokhttp3/RequestBody; + public static final fun create (Lokhttp3/MediaType;Ljava/lang/String;)Lokhttp3/RequestBody; + public static final fun create (Lokhttp3/MediaType;Lokio/ByteString;)Lokhttp3/RequestBody; + public static final fun create (Lokhttp3/MediaType;[B)Lokhttp3/RequestBody; + public static final fun create (Lokhttp3/MediaType;[BI)Lokhttp3/RequestBody; + public static final fun create (Lokhttp3/MediaType;[BII)Lokhttp3/RequestBody; + public static final fun create (Lokio/ByteString;Lokhttp3/MediaType;)Lokhttp3/RequestBody; + public static final fun create (Lokio/Path;Lokio/FileSystem;Lokhttp3/MediaType;)Lokhttp3/RequestBody; + public static final fun create ([B)Lokhttp3/RequestBody; + public static final fun create ([BLokhttp3/MediaType;)Lokhttp3/RequestBody; + public static final fun create ([BLokhttp3/MediaType;I)Lokhttp3/RequestBody; + public static final fun create ([BLokhttp3/MediaType;II)Lokhttp3/RequestBody; + public static final fun gzip (Lokhttp3/RequestBody;)Lokhttp3/RequestBody; + public fun isDuplex ()Z + public fun isOneShot ()Z + public abstract fun writeTo (Lokio/BufferedSink;)V +} + +public final class okhttp3/RequestBody$Companion { + public final fun create (Ljava/io/File;Lokhttp3/MediaType;)Lokhttp3/RequestBody; + public final fun create (Ljava/io/FileDescriptor;Lokhttp3/MediaType;)Lokhttp3/RequestBody; + public final fun create (Ljava/lang/String;Lokhttp3/MediaType;)Lokhttp3/RequestBody; + public final fun create (Lokhttp3/MediaType;Ljava/io/File;)Lokhttp3/RequestBody; + public final fun create (Lokhttp3/MediaType;Ljava/lang/String;)Lokhttp3/RequestBody; + public final fun create (Lokhttp3/MediaType;Lokio/ByteString;)Lokhttp3/RequestBody; + public final fun create (Lokhttp3/MediaType;[B)Lokhttp3/RequestBody; + public final fun create (Lokhttp3/MediaType;[BI)Lokhttp3/RequestBody; + public final fun create (Lokhttp3/MediaType;[BII)Lokhttp3/RequestBody; + public final fun create (Lokio/ByteString;Lokhttp3/MediaType;)Lokhttp3/RequestBody; + public final fun create (Lokio/Path;Lokio/FileSystem;Lokhttp3/MediaType;)Lokhttp3/RequestBody; + public final fun create ([B)Lokhttp3/RequestBody; + public final fun create ([BLokhttp3/MediaType;)Lokhttp3/RequestBody; + public final fun create ([BLokhttp3/MediaType;I)Lokhttp3/RequestBody; + public final fun create ([BLokhttp3/MediaType;II)Lokhttp3/RequestBody; + public static synthetic fun create$default (Lokhttp3/RequestBody$Companion;Ljava/io/File;Lokhttp3/MediaType;ILjava/lang/Object;)Lokhttp3/RequestBody; + public static synthetic fun create$default (Lokhttp3/RequestBody$Companion;Ljava/io/FileDescriptor;Lokhttp3/MediaType;ILjava/lang/Object;)Lokhttp3/RequestBody; + public static synthetic fun create$default (Lokhttp3/RequestBody$Companion;Ljava/lang/String;Lokhttp3/MediaType;ILjava/lang/Object;)Lokhttp3/RequestBody; + public static synthetic fun create$default (Lokhttp3/RequestBody$Companion;Lokhttp3/MediaType;[BIIILjava/lang/Object;)Lokhttp3/RequestBody; + public static synthetic fun create$default (Lokhttp3/RequestBody$Companion;Lokio/ByteString;Lokhttp3/MediaType;ILjava/lang/Object;)Lokhttp3/RequestBody; + public static synthetic fun create$default (Lokhttp3/RequestBody$Companion;Lokio/Path;Lokio/FileSystem;Lokhttp3/MediaType;ILjava/lang/Object;)Lokhttp3/RequestBody; + public static synthetic fun create$default (Lokhttp3/RequestBody$Companion;[BLokhttp3/MediaType;IIILjava/lang/Object;)Lokhttp3/RequestBody; + public final fun gzip (Lokhttp3/RequestBody;)Lokhttp3/RequestBody; +} + +public final class okhttp3/Response : java/io/Closeable { + public final fun -deprecated_body ()Lokhttp3/ResponseBody; + public final fun -deprecated_cacheControl ()Lokhttp3/CacheControl; + public final fun -deprecated_cacheResponse ()Lokhttp3/Response; + public final fun -deprecated_code ()I + public final fun -deprecated_handshake ()Lokhttp3/Handshake; + public final fun -deprecated_headers ()Lokhttp3/Headers; + public final fun -deprecated_message ()Ljava/lang/String; + public final fun -deprecated_networkResponse ()Lokhttp3/Response; + public final fun -deprecated_priorResponse ()Lokhttp3/Response; + public final fun -deprecated_protocol ()Lokhttp3/Protocol; + public final fun -deprecated_receivedResponseAtMillis ()J + public final fun -deprecated_request ()Lokhttp3/Request; + public final fun -deprecated_sentRequestAtMillis ()J + public final fun body ()Lokhttp3/ResponseBody; + public final fun cacheControl ()Lokhttp3/CacheControl; + public final fun cacheResponse ()Lokhttp3/Response; + public final fun challenges ()Ljava/util/List; + public fun close ()V + public final fun code ()I + public final fun handshake ()Lokhttp3/Handshake; + public final fun header (Ljava/lang/String;)Ljava/lang/String; + public final fun header (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + public static synthetic fun header$default (Lokhttp3/Response;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/String; + public final fun headers ()Lokhttp3/Headers; + public final fun headers (Ljava/lang/String;)Ljava/util/List; + public final fun isRedirect ()Z + public final fun isSuccessful ()Z + public final fun message ()Ljava/lang/String; + public final fun networkResponse ()Lokhttp3/Response; + public final fun newBuilder ()Lokhttp3/Response$Builder; + public final fun peekBody (J)Lokhttp3/ResponseBody; + public final fun priorResponse ()Lokhttp3/Response; + public final fun protocol ()Lokhttp3/Protocol; + public final fun receivedResponseAtMillis ()J + public final fun request ()Lokhttp3/Request; + public final fun sentRequestAtMillis ()J + public fun toString ()Ljava/lang/String; + public final fun trailers ()Lokhttp3/Headers; +} + +public class okhttp3/Response$Builder { + public fun ()V + public fun addHeader (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Response$Builder; + public fun body (Lokhttp3/ResponseBody;)Lokhttp3/Response$Builder; + public fun build ()Lokhttp3/Response; + public fun cacheResponse (Lokhttp3/Response;)Lokhttp3/Response$Builder; + public fun code (I)Lokhttp3/Response$Builder; + public fun handshake (Lokhttp3/Handshake;)Lokhttp3/Response$Builder; + public fun header (Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Response$Builder; + public fun headers (Lokhttp3/Headers;)Lokhttp3/Response$Builder; + public fun message (Ljava/lang/String;)Lokhttp3/Response$Builder; + public fun networkResponse (Lokhttp3/Response;)Lokhttp3/Response$Builder; + public fun priorResponse (Lokhttp3/Response;)Lokhttp3/Response$Builder; + public fun protocol (Lokhttp3/Protocol;)Lokhttp3/Response$Builder; + public fun receivedResponseAtMillis (J)Lokhttp3/Response$Builder; + public fun removeHeader (Ljava/lang/String;)Lokhttp3/Response$Builder; + public fun request (Lokhttp3/Request;)Lokhttp3/Response$Builder; + public fun sentRequestAtMillis (J)Lokhttp3/Response$Builder; + public fun trailers (Lkotlin/jvm/functions/Function0;)Lokhttp3/Response$Builder; +} + +public abstract class okhttp3/ResponseBody : java/io/Closeable { + public static final field Companion Lokhttp3/ResponseBody$Companion; + public fun ()V + public final fun byteStream ()Ljava/io/InputStream; + public final fun byteString ()Lokio/ByteString; + public final fun bytes ()[B + public final fun charStream ()Ljava/io/Reader; + public fun close ()V + public abstract fun contentLength ()J + public abstract fun contentType ()Lokhttp3/MediaType; + public static final fun create (Ljava/lang/String;Lokhttp3/MediaType;)Lokhttp3/ResponseBody; + public static final fun create (Lokhttp3/MediaType;JLokio/BufferedSource;)Lokhttp3/ResponseBody; + public static final fun create (Lokhttp3/MediaType;Ljava/lang/String;)Lokhttp3/ResponseBody; + public static final fun create (Lokhttp3/MediaType;Lokio/ByteString;)Lokhttp3/ResponseBody; + public static final fun create (Lokhttp3/MediaType;[B)Lokhttp3/ResponseBody; + public static final fun create (Lokio/BufferedSource;Lokhttp3/MediaType;J)Lokhttp3/ResponseBody; + public static final fun create (Lokio/ByteString;Lokhttp3/MediaType;)Lokhttp3/ResponseBody; + public static final fun create ([BLokhttp3/MediaType;)Lokhttp3/ResponseBody; + public abstract fun source ()Lokio/BufferedSource; + public final fun string ()Ljava/lang/String; +} + +public final class okhttp3/ResponseBody$Companion { + public final fun create (Ljava/lang/String;Lokhttp3/MediaType;)Lokhttp3/ResponseBody; + public final fun create (Lokhttp3/MediaType;JLokio/BufferedSource;)Lokhttp3/ResponseBody; + public final fun create (Lokhttp3/MediaType;Ljava/lang/String;)Lokhttp3/ResponseBody; + public final fun create (Lokhttp3/MediaType;Lokio/ByteString;)Lokhttp3/ResponseBody; + public final fun create (Lokhttp3/MediaType;[B)Lokhttp3/ResponseBody; + public final fun create (Lokio/BufferedSource;Lokhttp3/MediaType;J)Lokhttp3/ResponseBody; + public final fun create (Lokio/ByteString;Lokhttp3/MediaType;)Lokhttp3/ResponseBody; + public final fun create ([BLokhttp3/MediaType;)Lokhttp3/ResponseBody; + public static synthetic fun create$default (Lokhttp3/ResponseBody$Companion;Ljava/lang/String;Lokhttp3/MediaType;ILjava/lang/Object;)Lokhttp3/ResponseBody; + public static synthetic fun create$default (Lokhttp3/ResponseBody$Companion;Lokio/BufferedSource;Lokhttp3/MediaType;JILjava/lang/Object;)Lokhttp3/ResponseBody; + public static synthetic fun create$default (Lokhttp3/ResponseBody$Companion;Lokio/ByteString;Lokhttp3/MediaType;ILjava/lang/Object;)Lokhttp3/ResponseBody; + public static synthetic fun create$default (Lokhttp3/ResponseBody$Companion;[BLokhttp3/MediaType;ILjava/lang/Object;)Lokhttp3/ResponseBody; +} + +public final class okhttp3/Route { + public final fun -deprecated_address ()Lokhttp3/Address; + public final fun -deprecated_proxy ()Ljava/net/Proxy; + public final fun -deprecated_socketAddress ()Ljava/net/InetSocketAddress; + public fun (Lokhttp3/Address;Ljava/net/Proxy;Ljava/net/InetSocketAddress;)V + public final fun address ()Lokhttp3/Address; + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I + public final fun proxy ()Ljava/net/Proxy; + public final fun requiresTunnel ()Z + public final fun socketAddress ()Ljava/net/InetSocketAddress; + public fun toString ()Ljava/lang/String; +} + +public final class okhttp3/TlsVersion : java/lang/Enum { + public static final field Companion Lokhttp3/TlsVersion$Companion; + public static final field SSL_3_0 Lokhttp3/TlsVersion; + public static final field TLS_1_0 Lokhttp3/TlsVersion; + public static final field TLS_1_1 Lokhttp3/TlsVersion; + public static final field TLS_1_2 Lokhttp3/TlsVersion; + public static final field TLS_1_3 Lokhttp3/TlsVersion; + public final fun -deprecated_javaName ()Ljava/lang/String; + public static final fun forJavaName (Ljava/lang/String;)Lokhttp3/TlsVersion; + public static fun getEntries ()Lkotlin/enums/EnumEntries; + public final fun javaName ()Ljava/lang/String; + public static fun valueOf (Ljava/lang/String;)Lokhttp3/TlsVersion; + public static fun values ()[Lokhttp3/TlsVersion; +} + +public final class okhttp3/TlsVersion$Companion { + public final fun forJavaName (Ljava/lang/String;)Lokhttp3/TlsVersion; +} + +public abstract interface class okhttp3/WebSocket { + public abstract fun cancel ()V + public abstract fun close (ILjava/lang/String;)Z + public abstract fun queueSize ()J + public abstract fun request ()Lokhttp3/Request; + public abstract fun send (Ljava/lang/String;)Z + public abstract fun send (Lokio/ByteString;)Z +} + +public abstract interface class okhttp3/WebSocket$Factory { + public abstract fun newWebSocket (Lokhttp3/Request;Lokhttp3/WebSocketListener;)Lokhttp3/WebSocket; +} + +public abstract class okhttp3/WebSocketListener { + public fun ()V + public fun onClosed (Lokhttp3/WebSocket;ILjava/lang/String;)V + public fun onClosing (Lokhttp3/WebSocket;ILjava/lang/String;)V + public fun onFailure (Lokhttp3/WebSocket;Ljava/lang/Throwable;Lokhttp3/Response;)V + public fun onMessage (Lokhttp3/WebSocket;Ljava/lang/String;)V + public fun onMessage (Lokhttp3/WebSocket;Lokio/ByteString;)V + public fun onOpen (Lokhttp3/WebSocket;Lokhttp3/Response;)V +} + +public final class okhttp3/android/AndroidAsyncDns : okhttp3/AsyncDns { + public static final field Companion Lokhttp3/android/AndroidAsyncDns$Companion; + public fun (Lokhttp3/AsyncDns$DnsClass;Landroid/net/Network;)V + public synthetic fun (Lokhttp3/AsyncDns$DnsClass;Landroid/net/Network;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun query (Ljava/lang/String;Lokhttp3/AsyncDns$Callback;)V +} + +public final class okhttp3/android/AndroidAsyncDns$Companion { + public final fun getIPv4 ()Lokhttp3/android/AndroidAsyncDns; + public final fun getIPv6 ()Lokhttp3/android/AndroidAsyncDns; +} + diff --git a/okhttp/api/okhttp.api b/okhttp/api/jvm/okhttp.api similarity index 99% rename from okhttp/api/okhttp.api rename to okhttp/api/jvm/okhttp.api index 6eb3024b6f21..fcc0709091a4 100644 --- a/okhttp/api/okhttp.api +++ b/okhttp/api/jvm/okhttp.api @@ -68,7 +68,7 @@ public final class okhttp3/Cache : java/io/Closeable, java/io/Flushable { public static final field Companion Lokhttp3/Cache$Companion; public final fun -deprecated_directory ()Ljava/io/File; public fun (Ljava/io/File;J)V - public fun (Lokio/Path;JLokio/FileSystem;)V + public fun (Lokio/FileSystem;Lokio/Path;J)V public fun close ()V public final fun delete ()V public final fun directory ()Ljava/io/File; @@ -130,11 +130,11 @@ public final class okhttp3/CacheControl$Builder { public final fun build ()Lokhttp3/CacheControl; public final fun immutable ()Lokhttp3/CacheControl$Builder; public final fun maxAge (ILjava/util/concurrent/TimeUnit;)Lokhttp3/CacheControl$Builder; - public final fun maxAge (ILkotlin/time/DurationUnit;)Lokhttp3/CacheControl$Builder; + public final fun maxAge-LRDsOJo (J)Lokhttp3/CacheControl$Builder; public final fun maxStale (ILjava/util/concurrent/TimeUnit;)Lokhttp3/CacheControl$Builder; - public final fun maxStale (ILkotlin/time/DurationUnit;)Lokhttp3/CacheControl$Builder; + public final fun maxStale-LRDsOJo (J)Lokhttp3/CacheControl$Builder; public final fun minFresh (ILjava/util/concurrent/TimeUnit;)Lokhttp3/CacheControl$Builder; - public final fun minFresh (ILkotlin/time/DurationUnit;)Lokhttp3/CacheControl$Builder; + public final fun minFresh-LRDsOJo (J)Lokhttp3/CacheControl$Builder; public final fun noCache ()Lokhttp3/CacheControl$Builder; public final fun noStore ()Lokhttp3/CacheControl$Builder; public final fun noTransform ()Lokhttp3/CacheControl$Builder; diff --git a/okhttp/build.gradle.kts b/okhttp/build.gradle.kts index 5c3f2fb4e8df..7a562870cf62 100644 --- a/okhttp/build.gradle.kts +++ b/okhttp/build.gradle.kts @@ -1,20 +1,36 @@ +@file:Suppress("UnstableApiUsage") + +import aQute.bnd.gradle.BundleTaskExtension import com.vanniktech.maven.publish.JavadocJar -import com.vanniktech.maven.publish.KotlinJvm +import com.vanniktech.maven.publish.KotlinMultiplatform +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension plugins { - kotlin("jvm") + kotlin("multiplatform") + id("com.android.library") kotlin("plugin.serialization") id("org.jetbrains.dokka") id("com.vanniktech.maven.publish.base") id("binary-compatibility-validator") + id("io.github.gmazzo.aar2jar") version "1.0.1" } -// Build & use okhttp3/internal/-InternalVersion.kt +val platform = System.getProperty("okhttp.platform", "jdk9") +val testJavaVersion = System.getProperty("test.java.version", "21").toInt() + val copyKotlinTemplates = tasks.register("copyKotlinTemplates") { - from("src/main/kotlinTemplates") - into("$buildDir/generated/sources/kotlinTemplates") - expand("projectVersion" to project.version) + val kotlinTemplatesOutput = layout.buildDirectory.dir("generated/sources/kotlinTemplates") + + from("src/commonJvmAndroid/kotlinTemplates") + into(kotlinTemplatesOutput) + filteringCharset = Charsets.UTF_8.toString() + + expand( + // Build & use okhttp3/internal/-InternalVersion.kt + "projectVersion" to project.version, + ) } // Build & use okhttp3/internal/idn/IdnaMappingTableInstance.kt @@ -22,131 +38,256 @@ val generateIdnaMappingTableConfiguration: Configuration by configurations.creat dependencies { generateIdnaMappingTableConfiguration(projects.okhttpIdnaMappingTable) } -val generateIdnaMappingTable by tasks.creating(JavaExec::class.java) { - outputs.dir("$buildDir/generated/sources/idnaMappingTable") +val generateIdnaMappingTable = tasks.register("generateIdnaMappingTable") { + val idnaOutput = layout.buildDirectory.dir("generated/sources/idnaMappingTable") + + outputs.dir(idnaOutput) mainClass.set("okhttp3.internal.idn.GenerateIdnaMappingTableCode") - args("$buildDir/generated/sources/idnaMappingTable") + args(idnaOutput.get()) classpath = generateIdnaMappingTableConfiguration } kotlin { + jvmToolchain(8) + + jvm { +// withJava() /* <- cannot be used when the Android Plugin is present */ + } + + androidTarget { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } + sourceSets { - getByName("main") { - kotlin.srcDir(copyKotlinTemplates.get().outputs) - kotlin.srcDir(generateIdnaMappingTable.outputs) + val commonJvmAndroid = create("commonJvmAndroid") { + dependsOn(commonMain.get()) + + kotlin.srcDir(copyKotlinTemplates.map { it.outputs }) + kotlin.srcDir(generateIdnaMappingTable.map { it.outputs }) + + dependencies { + api(libs.squareup.okio) + api(libs.kotlin.stdlib) + + compileOnly(libs.findbugs.jsr305) + compileOnly(libs.animalsniffer.annotations) + } + } + + commonTest { + dependencies { + implementation(projects.okhttpTestingSupport) + implementation(libs.assertk) + implementation(libs.kotlin.test.annotations) + implementation(libs.kotlin.test.common) + implementation(libs.kotlin.test.junit) + implementation(libs.junit) + implementation(libs.junit.jupiter.api) + implementation(libs.junit.jupiter.params) + } + } + + androidMain { + dependsOn(commonJvmAndroid) + dependencies { + compileOnly(libs.bouncycastle.bcprov) + compileOnly(libs.bouncycastle.bctls) + compileOnly(libs.conscrypt.openjdk) + implementation(libs.androidx.annotation) + implementation(libs.androidx.startup.runtime) + } + } + + jvmMain { + dependsOn(commonJvmAndroid) + + dependencies { + // These compileOnly dependencies must also be listed in the OSGi configuration above. + compileOnly(libs.conscrypt.openjdk) + compileOnly(libs.bouncycastle.bcprov) + compileOnly(libs.bouncycastle.bctls) + + // graal build support + compileOnly(libs.nativeImageSvm) + compileOnly(libs.openjsse) + } + } + + val jvmTest by getting { + dependencies { + implementation(projects.okhttpTestingSupport) + implementation(libs.assertk) + implementation(libs.kotlin.test.annotations) + implementation(libs.kotlin.test.common) + implementation(libs.kotlinx.serialization.core) + implementation(libs.kotlinx.serialization.json) + implementation(projects.okhttpJavaNetCookiejar) + implementation(projects.okhttpTls) + implementation(projects.okhttpUrlconnection) + implementation(projects.mockwebserver3) + implementation(projects.mockwebserver3Junit4) + implementation(projects.mockwebserver3Junit5) + implementation(projects.mockwebserver) + implementation(projects.loggingInterceptor) + implementation(projects.okhttpBrotli) + implementation(projects.okhttpDnsoverhttps) + implementation(projects.okhttpIdnaMappingTable) + implementation(projects.okhttpSse) + implementation(projects.okhttpCoroutines) + implementation(libs.kotlinx.coroutines.core) + implementation(libs.squareup.moshi) + implementation(libs.squareup.moshi.kotlin) + implementation(libs.squareup.okio.fakefilesystem) + implementation(libs.conscrypt.openjdk) + implementation(libs.junit) + implementation(libs.junit.jupiter.api) + implementation(libs.junit.jupiter.params) + implementation(libs.kotlin.test.junit) + implementation(libs.openjsse) + compileOnly(libs.findbugs.jsr305) + + implementation(libs.junit.jupiter.engine) + implementation(libs.junit.vintage.engine) + + if (platform == "conscrypt") { + implementation(rootProject.libs.conscrypt.openjdk) + } else if (platform == "openjsse") { + implementation(rootProject.libs.openjsse) + } + } + } + + val androidUnitTest by getting { + dependencies { + implementation(libs.assertk) + implementation(libs.kotlin.test.annotations) + implementation(libs.kotlin.test.common) + implementation(libs.androidx.junit) + + implementation(libs.junit.jupiter.engine) + implementation(libs.junit.vintage.engine) + + implementation(libs.robolectric) + } } } } -project.applyOsgi( - "Export-Package: okhttp3,okhttp3.internal.*;okhttpinternal=true;mandatory:=okhttpinternal", - "Import-Package: " + - "android.*;resolution:=optional," + - "com.oracle.svm.core.annotate;resolution:=optional," + - "com.oracle.svm.core.configure;resolution:=optional," + - "dalvik.system;resolution:=optional," + - "org.conscrypt;resolution:=optional," + - "org.bouncycastle.*;resolution:=optional," + - "org.openjsse.*;resolution:=optional," + - "org.graalvm.nativeimage;resolution:=optional," + - "org.graalvm.nativeimage.hosted;resolution:=optional," + - "sun.security.ssl;resolution:=optional,*", - "Automatic-Module-Name: okhttp3", - "Bundle-SymbolicName: com.squareup.okhttp3" -) - -normalization { - runtimeClasspath { - /* - - The below two ignored files are generated during test execution - by the test: okhttp/src/test/java/okhttp3/osgi/OsgiTest.java - - - The compressed index.xml file contains a timestamp property which - changes with every test execution, such that running the test - actually changes the test classpath itself. This means that it - can"t benefit from incremental build acceleration, because on every - execution it sees that the classpath has changed, and so to be - safe, it needs to re-run. - - - This is unfortunate, because actually it would be safe to declare - the task as up-to-date, because these two files, which are based on - the generated index.xml, are outputs, not inputs. We can be sure of - this because they are deleted in the @BeforeEach method of the - OsgiTest test class. - - - To enable the benefit of incremental builds, we can ask Gradle - to ignore these two files when considering whether the classpath - has changed. That is the purpose of this normalization block. - */ - ignore("okhttp3/osgi/workspace/cnf/repo/index.xml.gz") - ignore("okhttp3/osgi/workspace/cnf/repo/index.xml.gz.sha") +if (platform == "jdk8alpn") { + // Add alpn-boot on Java 8 so we can use HTTP/2 without a stable API. + val alpnBootVersion = alpnBootVersion() + if (alpnBootVersion != null) { + val alpnBootJar = configurations.detachedConfiguration( + dependencies.create("org.mortbay.jetty.alpn:alpn-boot:$alpnBootVersion") + ).singleFile + tasks.withType { + jvmArgs("-Xbootclasspath/p:${alpnBootJar}") + } } } -// Expose OSGi jars to the test environment. -val osgiTestDeploy: Configuration by configurations.creating +android { + compileSdk = 34 + + namespace = "okhttp.okhttp3" + + defaultConfig { + minSdk = 21 -val copyOsgiTestDeployment by tasks.creating(Copy::class.java) { - from(osgiTestDeploy) - into("$buildDir/resources/test/okhttp3/osgi/deployments") + consumerProguardFiles("okhttp3.pro") + } + + testOptions { + unitTests { + isIncludeAndroidResources = true + } + } + + sourceSets { + named("main") { + manifest.srcFile("src/androidMain/AndroidManifest.xml") + assets.srcDir("src/androidMain/assets") + } + } } -tasks.getByName("test") { - dependsOn(copyOsgiTestDeployment) + +// Hack to make BundleTaskExtension pass briefly +project.extensions + .getByType(JavaPluginExtension::class.java) + .sourceSets.create("main") + +// Call the convention when the task has finished, to modify the jar to contain OSGi metadata. +tasks.named("jvmJar").configure { + val bundleExtension = extensions.create( + BundleTaskExtension.NAME, + BundleTaskExtension::class.java, + this, + ).apply { + classpath(libs.kotlin.stdlib.osgi.map { it.artifacts }, tasks.named("jvmMainClasses").map { it.outputs }) + bnd( + "Export-Package: okhttp3,okhttp3.internal.*;okhttpinternal=true;mandatory:=okhttpinternal", + "Import-Package: " + + "com.oracle.svm.core.annotate;resolution:=optional," + + "com.oracle.svm.core.configure;resolution:=optional," + + "dalvik.system;resolution:=optional," + + "org.conscrypt;resolution:=optional," + + "org.bouncycastle.*;resolution:=optional," + + "org.openjsse.*;resolution:=optional," + + "org.graalvm.nativeimage;resolution:=optional," + + "org.graalvm.nativeimage.hosted;resolution:=optional," + + "sun.security.ssl;resolution:=optional,*", + "Automatic-Module-Name: okhttp3", + "Bundle-SymbolicName: com.squareup.okhttp3" + ) + } + + doLast { + bundleExtension.buildAction().execute(this) + } } +val checkstyleConfig: Configuration by configurations.named("checkstyleConfig") dependencies { - api(libs.squareup.okio) - api(libs.kotlin.stdlib) - - // These compileOnly dependencies must also be listed in the OSGi configuration above. - compileOnly(libs.robolectric.android) - compileOnly(libs.bouncycastle.bcprov) - compileOnly(libs.bouncycastle.bctls) - compileOnly(libs.conscrypt.openjdk) - compileOnly(libs.openjsse) - compileOnly(libs.findbugs.jsr305) - compileOnly(libs.animalsniffer.annotations) - - // graal build support - compileOnly(libs.nativeImageSvm) - - testCompileOnly(libs.bouncycastle.bctls) - testImplementation(projects.okhttpTestingSupport) - testImplementation(libs.assertk) - testImplementation(libs.kotlin.test.annotations) - testImplementation(libs.kotlin.test.common) - testImplementation(libs.kotlinx.serialization.core) - testImplementation(libs.kotlinx.serialization.json) - testImplementation(projects.okhttpJavaNetCookiejar) - testImplementation(projects.okhttpTls) - testImplementation(projects.okhttpUrlconnection) - testImplementation(projects.mockwebserver3) - testImplementation(projects.mockwebserver3Junit4) - testImplementation(projects.mockwebserver3Junit5) - testImplementation(projects.mockwebserver) - testImplementation(projects.loggingInterceptor) - testImplementation(projects.okhttpBrotli) - testImplementation(projects.okhttpDnsoverhttps) - testImplementation(projects.okhttpIdnaMappingTable) - testImplementation(projects.okhttpSse) - testImplementation(projects.okhttpCoroutines) - testImplementation(libs.kotlinx.coroutines.core) - testImplementation(libs.squareup.moshi) - testImplementation(libs.squareup.moshi.kotlin) - testImplementation(libs.squareup.okio.fakefilesystem) - testImplementation(libs.conscrypt.openjdk) - testImplementation(libs.junit) - testImplementation(libs.junit.jupiter.api) - testImplementation(libs.junit.jupiter.params) - testImplementation(libs.kotlin.test.junit) - testImplementation(libs.openjsse) - testImplementation(libs.aqute.resolve) - testCompileOnly(libs.findbugs.jsr305) - - osgiTestDeploy(libs.eclipseOsgi) - osgiTestDeploy(libs.kotlin.stdlib.osgi) + // Everything else requires Android API 21+. + "signature"(rootProject.libs.signature.android.apilevel21) { artifact { type = "signature" } } + + // OkHttp requires Java 8+. + "signature"(rootProject.libs.codehaus.signature.java18) { artifact { type = "signature" } } + + checkstyleConfig(rootProject.libs.checkStyle) { + isTransitive = false + } +} + +// Animal Sniffer confirms we generally don't use APIs not on Java 8. +configure { + annotation = "okhttp3.internal.SuppressSignatureCheck" } +configure { + config = resources.text.fromArchiveEntry(checkstyleConfig, "google_checks.xml") + toolVersion = rootProject.libs.versions.checkStyle.get() + // TODO switch out checkstyle to use something supporting KMP + sourceSets = listOf(project.sourceSets["main"]) +} + +afterEvaluate { + tasks.withType { + if (javaLauncher.get().metadata.languageVersion.asInt() < 9) { + // Work around robolectric requirements and limitations + // https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/factory/AndroidUnitTest.java;l=339 + allJvmArgs = allJvmArgs.filter { !it.startsWith("--add-opens") } + filter { + excludeTest("okhttp3.internal.publicsuffix.PublicSuffixDatabaseTest", null) + } + } + } +} + +apply(plugin = "io.github.usefulness.maven-sympathy") + mavenPublishing { - configure(KotlinJvm(javadocJar = JavadocJar.Empty())) + configure(KotlinMultiplatform(javadocJar = JavadocJar.Empty(), androidVariantsToPublish = listOf("release"))) } diff --git a/okhttp/src/main/resources/META-INF/proguard/okhttp3.pro b/okhttp/okhttp3.pro similarity index 67% rename from okhttp/src/main/resources/META-INF/proguard/okhttp3.pro rename to okhttp/okhttp3.pro index 74fc3168014a..06eb9cc36d90 100644 --- a/okhttp/src/main/resources/META-INF/proguard/okhttp3.pro +++ b/okhttp/okhttp3.pro @@ -1,14 +1,11 @@ # JSR 305 annotations are for embedding nullability information. -dontwarn javax.annotation.** -# A resource is loaded with a relative path so the package of this class must be preserved. --keeppackagenames okhttp3.internal.publicsuffix.* --adaptresourcefilenames okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz - # Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. -dontwarn org.codehaus.mojo.animal_sniffer.* # OkHttp platform used only on JVM and when Conscrypt and other security providers are available. +# May be used with robolectric or deliberate use of Bouncy Castle on Android -dontwarn okhttp3.internal.platform.** -dontwarn org.conscrypt.** -dontwarn org.bouncycastle.** diff --git a/okhttp/src/androidMain/AndroidManifest.xml b/okhttp/src/androidMain/AndroidManifest.xml new file mode 100644 index 000000000000..7454e18f58b6 --- /dev/null +++ b/okhttp/src/androidMain/AndroidManifest.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + diff --git a/okhttp/src/androidMain/assets/PublicSuffixDatabase.list b/okhttp/src/androidMain/assets/PublicSuffixDatabase.list new file mode 100644 index 000000000000..5e99c0e45106 Binary files /dev/null and b/okhttp/src/androidMain/assets/PublicSuffixDatabase.list differ diff --git a/okhttp-android/src/main/baseline-prof.txt b/okhttp/src/androidMain/baseline-prof.txt similarity index 100% rename from okhttp-android/src/main/baseline-prof.txt rename to okhttp/src/androidMain/baseline-prof.txt diff --git a/okhttp-android/src/main/kotlin/okhttp3/android/AndroidAsyncDns.kt b/okhttp/src/androidMain/kotlin/okhttp3/android/AndroidAsyncDns.kt similarity index 100% rename from okhttp-android/src/main/kotlin/okhttp3/android/AndroidAsyncDns.kt rename to okhttp/src/androidMain/kotlin/okhttp3/android/AndroidAsyncDns.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/Android10Platform.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/Android10Platform.kt similarity index 96% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/Android10Platform.kt rename to okhttp/src/androidMain/kotlin/okhttp3/internal/platform/Android10Platform.kt index ea31d548fcec..2ca1334c58ab 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/platform/Android10Platform.kt +++ b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/Android10Platform.kt @@ -16,6 +16,7 @@ package okhttp3.internal.platform import android.annotation.SuppressLint +import android.content.Context import android.os.Build import android.os.StrictMode import android.security.NetworkSecurityPolicy @@ -37,7 +38,9 @@ import okhttp3.internal.tls.TrustRootIndex /** Android 10+ (API 29+). */ @SuppressSignatureCheck -class Android10Platform : Platform() { +class Android10Platform : Platform(), ContextAwarePlatform { + override var applicationContext: Context? = null + private val socketAdapters = listOfNotNull( Android10SocketAdapter.buildIfSupported(), diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/AndroidPlatform.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/AndroidPlatform.kt similarity index 94% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/AndroidPlatform.kt rename to okhttp/src/androidMain/kotlin/okhttp3/internal/platform/AndroidPlatform.kt index 1d4e007530ba..0a43568c0496 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/platform/AndroidPlatform.kt +++ b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/AndroidPlatform.kt @@ -15,9 +15,11 @@ */ package okhttp3.internal.platform +import android.content.Context import android.os.Build import android.os.StrictMode import android.security.NetworkSecurityPolicy +import android.util.Log import java.io.IOException import java.lang.reflect.InvocationTargetException import java.lang.reflect.Method @@ -43,7 +45,9 @@ import okhttp3.internal.tls.TrustRootIndex /** Android 5 to 9 (API 21 to 28). */ @SuppressSignatureCheck -class AndroidPlatform : Platform() { +class AndroidPlatform : Platform(), ContextAwarePlatform { + override var applicationContext: Context? = null + private val socketAdapters = listOfNotNull( StandardAndroidSocketAdapter.buildIfSupported(), @@ -129,6 +133,18 @@ class AndroidPlatform : Platform() { return super.getHandshakeServerNames(sslSocket) } + override fun log( + message: String, + level: Int, + t: Throwable?, + ) { + if (level == WARN) { + Log.w(Tag, message, t) + } else { + Log.i(Tag, message, t) + } + } + /** * A trust manager for Android applications that customize the trust manager. * @@ -157,6 +173,8 @@ class AndroidPlatform : Platform() { } companion object { + val Tag = "OkHttp" + val isSupported: Boolean = when { !isAndroid -> false diff --git a/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/ContextAwarePlatform.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/ContextAwarePlatform.kt new file mode 100644 index 000000000000..05195310d505 --- /dev/null +++ b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/ContextAwarePlatform.kt @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2024 Block, 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.internal.platform + +import android.content.Context + +interface ContextAwarePlatform { + var applicationContext: Context? +} diff --git a/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/PlatformInitializer.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/PlatformInitializer.kt new file mode 100644 index 000000000000..87f64133c371 --- /dev/null +++ b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/PlatformInitializer.kt @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2024 Block, 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.internal.platform + +import android.content.Context +import androidx.startup.Initializer + +/** + * Androidx Startup initializer to ensure that the AndroidPlatform has access to the application context. + */ +class PlatformInitializer : Initializer { + override fun create(context: Context): Platform { + PlatformRegistry.applicationContext = context + + return Platform.get() + } + + override fun dependencies(): List>> = listOf() +} diff --git a/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/PlatformRegistry.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/PlatformRegistry.kt new file mode 100644 index 000000000000..17b4aad9267f --- /dev/null +++ b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/PlatformRegistry.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 Block, 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.internal.platform + +import android.content.Context +import okhttp3.internal.platform.android.AndroidLog + +actual object PlatformRegistry { + actual fun findPlatform(): Platform { + AndroidLog.enable() + return Android10Platform.buildIfSupported() ?: AndroidPlatform.buildIfSupported()!! + } + + actual val isAndroid: Boolean + get() = true + + var applicationContext: Context? + get() = (Platform.get() as? ContextAwarePlatform)?.applicationContext + set(value) { + (Platform.get() as? ContextAwarePlatform)?.applicationContext = value + } +} diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/android/Android10SocketAdapter.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/Android10SocketAdapter.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/android/Android10SocketAdapter.kt rename to okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/Android10SocketAdapter.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/android/AndroidCertificateChainCleaner.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/AndroidCertificateChainCleaner.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/android/AndroidCertificateChainCleaner.kt rename to okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/AndroidCertificateChainCleaner.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/android/AndroidLog.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/AndroidLog.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/android/AndroidLog.kt rename to okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/AndroidLog.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/android/AndroidSocketAdapter.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/AndroidSocketAdapter.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/android/AndroidSocketAdapter.kt rename to okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/AndroidSocketAdapter.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/android/BouncyCastleSocketAdapter.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/BouncyCastleSocketAdapter.kt similarity index 81% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/android/BouncyCastleSocketAdapter.kt rename to okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/BouncyCastleSocketAdapter.kt index a2a4ffdfb018..fb0bab1a40ac 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/platform/android/BouncyCastleSocketAdapter.kt +++ b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/BouncyCastleSocketAdapter.kt @@ -17,7 +17,6 @@ package okhttp3.internal.platform.android import javax.net.ssl.SSLSocket import okhttp3.Protocol -import okhttp3.internal.platform.BouncyCastlePlatform import okhttp3.internal.platform.Platform import org.bouncycastle.jsse.BCSSLSocket @@ -27,7 +26,7 @@ import org.bouncycastle.jsse.BCSSLSocket class BouncyCastleSocketAdapter : SocketAdapter { override fun matchesSocket(sslSocket: SSLSocket): Boolean = sslSocket is BCSSLSocket - override fun isSupported(): Boolean = BouncyCastlePlatform.isSupported + override fun isSupported(): Boolean = isSupported override fun getSelectedProtocol(sslSocket: SSLSocket): String? { val s = sslSocket as BCSSLSocket @@ -60,10 +59,20 @@ class BouncyCastleSocketAdapter : SocketAdapter { val factory = object : DeferredSocketAdapter.Factory { override fun matchesSocket(sslSocket: SSLSocket): Boolean { - return BouncyCastlePlatform.isSupported && sslSocket is BCSSLSocket + return isSupported && sslSocket is BCSSLSocket } override fun create(sslSocket: SSLSocket): SocketAdapter = BouncyCastleSocketAdapter() } + + val isSupported: Boolean = + try { + // Trigger an early exception over a fatal error, prefer a RuntimeException over Error. + Class.forName("org.bouncycastle.jsse.provider.BouncyCastleJsseProvider", false, javaClass.classLoader) + + true + } catch (_: ClassNotFoundException) { + false + } } } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/android/ConscryptSocketAdapter.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/ConscryptSocketAdapter.kt similarity index 64% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/android/ConscryptSocketAdapter.kt rename to okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/ConscryptSocketAdapter.kt index 00781ee19b05..f14b9f8b9bc9 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/platform/android/ConscryptSocketAdapter.kt +++ b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/ConscryptSocketAdapter.kt @@ -17,7 +17,6 @@ package okhttp3.internal.platform.android import javax.net.ssl.SSLSocket import okhttp3.Protocol -import okhttp3.internal.platform.ConscryptPlatform import okhttp3.internal.platform.Platform import org.conscrypt.Conscrypt @@ -28,7 +27,7 @@ import org.conscrypt.Conscrypt class ConscryptSocketAdapter : SocketAdapter { override fun matchesSocket(sslSocket: SSLSocket): Boolean = Conscrypt.isConscrypt(sslSocket) - override fun isSupported(): Boolean = ConscryptPlatform.isSupported + override fun isSupported(): Boolean = isSupported override fun getSelectedProtocol(sslSocket: SSLSocket): String? = when { @@ -56,10 +55,44 @@ class ConscryptSocketAdapter : SocketAdapter { val factory = object : DeferredSocketAdapter.Factory { override fun matchesSocket(sslSocket: SSLSocket): Boolean { - return ConscryptPlatform.isSupported && Conscrypt.isConscrypt(sslSocket) + return isSupported && Conscrypt.isConscrypt(sslSocket) } override fun create(sslSocket: SSLSocket): SocketAdapter = ConscryptSocketAdapter() } + + val isSupported: Boolean = + try { + // Trigger an early exception over a fatal error, prefer a RuntimeException over Error. + Class.forName("org.conscrypt.Conscrypt\$Version", false, javaClass.classLoader) + + when { + // Bump this version if we ever have a binary incompatibility + Conscrypt.isAvailable() && atLeastVersion(2, 1, 0) -> true + else -> false + } + } catch (e: NoClassDefFoundError) { + false + } catch (e: ClassNotFoundException) { + false + } + + fun atLeastVersion( + major: Int, + minor: Int = 0, + patch: Int = 0, + ): Boolean { + val conscryptVersion = Conscrypt.version() ?: return false + + if (conscryptVersion.major() != major) { + return conscryptVersion.major() > major + } + + if (conscryptVersion.minor() != minor) { + return conscryptVersion.minor() > minor + } + + return conscryptVersion.patch() >= patch + } } } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/android/DeferredSocketAdapter.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/DeferredSocketAdapter.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/android/DeferredSocketAdapter.kt rename to okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/DeferredSocketAdapter.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/android/SocketAdapter.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/SocketAdapter.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/android/SocketAdapter.kt rename to okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/SocketAdapter.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/android/StandardAndroidSocketAdapter.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/StandardAndroidSocketAdapter.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/android/StandardAndroidSocketAdapter.kt rename to okhttp/src/androidMain/kotlin/okhttp3/internal/platform/android/StandardAndroidSocketAdapter.kt diff --git a/okhttp/src/androidMain/kotlin/okhttp3/internal/publicsuffix/AssetPublicSuffixList.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/publicsuffix/AssetPublicSuffixList.kt new file mode 100644 index 000000000000..8fa98c914e16 --- /dev/null +++ b/okhttp/src/androidMain/kotlin/okhttp3/internal/publicsuffix/AssetPublicSuffixList.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 Block, 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.internal.publicsuffix + +import java.io.IOException +import okhttp3.internal.platform.PlatformRegistry +import okio.Source +import okio.source + +internal class AssetPublicSuffixList( + override val path: String = PUBLIC_SUFFIX_RESOURCE, +) : BasePublicSuffixList() { + override fun listSource(): Source { + val assets = + PlatformRegistry.applicationContext?.assets ?: throw IOException("Platform applicationContext not initialized") + + return assets.open(path).source() + } + + companion object { + val PUBLIC_SUFFIX_RESOURCE = "PublicSuffixDatabase.list" + } +} diff --git a/okhttp/src/androidMain/kotlin/okhttp3/internal/publicsuffix/PublicSuffixList.android.kt b/okhttp/src/androidMain/kotlin/okhttp3/internal/publicsuffix/PublicSuffixList.android.kt new file mode 100644 index 000000000000..4deaba74cdf6 --- /dev/null +++ b/okhttp/src/androidMain/kotlin/okhttp3/internal/publicsuffix/PublicSuffixList.android.kt @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 Block, 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.internal.publicsuffix + +internal actual val PublicSuffixList.Companion.Default: PublicSuffixList + get() = AssetPublicSuffixList() diff --git a/okhttp/src/androidUnitTest/kotlin/okhttp3/test/BaseJavaTest.android.kt b/okhttp/src/androidUnitTest/kotlin/okhttp3/test/BaseJavaTest.android.kt new file mode 100644 index 000000000000..72a3c78f7dd8 --- /dev/null +++ b/okhttp/src/androidUnitTest/kotlin/okhttp3/test/BaseJavaTest.android.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 Block, 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.test + +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import okhttp3.internal.platform.PlatformRegistry +import org.junit.Before +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +actual abstract class BaseJavaTest actual constructor() { + @Before + fun init() { + PlatformRegistry.applicationContext = ApplicationProvider.getApplicationContext() + } +} diff --git a/okhttp/src/main/kotlin/okhttp3/Address.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Address.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Address.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Address.kt diff --git a/okhttp/src/main/kotlin/okhttp3/AsyncDns.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/AsyncDns.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/AsyncDns.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/AsyncDns.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Authenticator.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Authenticator.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Authenticator.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Authenticator.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Cache.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Cache.kt similarity index 99% rename from okhttp/src/main/kotlin/okhttp3/Cache.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Cache.kt index e9cc322d36fd..69d79cd9394f 100644 --- a/okhttp/src/main/kotlin/okhttp3/Cache.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Cache.kt @@ -151,11 +151,11 @@ class Cache internal constructor( fileSystem: FileSystem, taskRunner: TaskRunner, ) : Closeable, Flushable { - @ExperimentalOkHttpApi + /** Create a cache of at most [maxSize] bytes in [directory]. */ constructor( + fileSystem: FileSystem, directory: Path, maxSize: Long, - fileSystem: FileSystem, ) : this( directory, maxSize, @@ -163,6 +163,13 @@ class Cache internal constructor( TaskRunner.INSTANCE, ) + /** Create a cache of at most [maxSize] bytes in [directory]. */ + constructor(directory: File, maxSize: Long) : this( + FileSystem.SYSTEM, + directory.toOkioPath(), + maxSize, + ) + internal val cache = DiskLruCache( fileSystem = fileSystem, @@ -183,13 +190,6 @@ class Cache internal constructor( val isClosed: Boolean get() = cache.isClosed() - /** Create a cache of at most [maxSize] bytes in [directory]. */ - constructor(directory: File, maxSize: Long) : this( - directory.toOkioPath(), - maxSize, - FileSystem.SYSTEM, - ) - internal fun get(request: Request): Response? { val key = key(request.url) val snapshot: DiskLruCache.Snapshot = @@ -389,7 +389,6 @@ class Cache internal constructor( get() = cache.directory.toFile() @get:JvmName("directoryPath") - @ExperimentalOkHttpApi val directoryPath: Path get() = cache.directory diff --git a/okhttp/src/main/kotlin/okhttp3/CacheControl.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/CacheControl.kt similarity index 91% rename from okhttp/src/main/kotlin/okhttp3/CacheControl.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/CacheControl.kt index 9f507bc3525f..652b3398b805 100644 --- a/okhttp/src/main/kotlin/okhttp3/CacheControl.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/CacheControl.kt @@ -16,15 +16,12 @@ package okhttp3 import java.util.concurrent.TimeUnit -import kotlin.time.DurationUnit +import kotlin.time.Duration import okhttp3.internal.commonBuild import okhttp3.internal.commonClampToInt import okhttp3.internal.commonForceCache import okhttp3.internal.commonForceNetwork import okhttp3.internal.commonImmutable -import okhttp3.internal.commonMaxAge -import okhttp3.internal.commonMaxStale -import okhttp3.internal.commonMinFresh import okhttp3.internal.commonNoCache import okhttp3.internal.commonNoStore import okhttp3.internal.commonNoTransform @@ -186,26 +183,29 @@ class CacheControl internal constructor( * Sets the maximum age of a cached response. If the cache response's age exceeds [maxAge], it * will not be used and a network request will be made. * - * @param maxAge a non-negative integer. This is stored and transmitted with [TimeUnit.SECONDS] + * @param maxAge a non-negative duration. This is stored and transmitted with [TimeUnit.SECONDS] * precision; finer precision will be lost. */ - @ExperimentalOkHttpApi - fun maxAge( - maxAge: Int, - timeUnit: DurationUnit, - ) = commonMaxAge(maxAge, timeUnit) + fun maxAge(maxAge: Duration) = + apply { + val maxAgeSeconds = maxAge.inWholeSeconds + require(maxAgeSeconds >= 0) { "maxAge < 0: $maxAgeSeconds" } + this.maxAgeSeconds = maxAgeSeconds.commonClampToInt() + } - @ExperimentalOkHttpApi - fun maxStale( - maxStale: Int, - timeUnit: DurationUnit, - ) = commonMaxStale(maxStale, timeUnit) + fun maxStale(maxStale: Duration) = + apply { + val maxStaleSeconds = maxStale.inWholeSeconds + require(maxStaleSeconds >= 0) { "maxStale < 0: $maxStaleSeconds" } + this.maxStaleSeconds = maxStaleSeconds.commonClampToInt() + } - @ExperimentalOkHttpApi - fun minFresh( - minFresh: Int, - timeUnit: DurationUnit, - ) = commonMinFresh(minFresh, timeUnit) + fun minFresh(minFresh: Duration) = + apply { + val minFreshSeconds = minFresh.inWholeSeconds + require(minFreshSeconds >= 0) { "minFresh < 0: $minFreshSeconds" } + this.minFreshSeconds = minFreshSeconds.commonClampToInt() + } /** * Sets the maximum age of a cached response. If the cache response's age exceeds [maxAge], it diff --git a/okhttp/src/main/kotlin/okhttp3/Call.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Call.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Call.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Call.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Callback.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Callback.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Callback.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Callback.kt diff --git a/okhttp/src/main/kotlin/okhttp3/CertificatePinner.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/CertificatePinner.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/CertificatePinner.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/CertificatePinner.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Challenge.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Challenge.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Challenge.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Challenge.kt diff --git a/okhttp/src/main/kotlin/okhttp3/CipherSuite.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/CipherSuite.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/CipherSuite.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/CipherSuite.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Connection.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Connection.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Connection.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Connection.kt diff --git a/okhttp/src/main/kotlin/okhttp3/ConnectionListener.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/ConnectionListener.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/ConnectionListener.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/ConnectionListener.kt diff --git a/okhttp/src/main/kotlin/okhttp3/ConnectionPool.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/ConnectionPool.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/ConnectionPool.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/ConnectionPool.kt diff --git a/okhttp/src/main/kotlin/okhttp3/ConnectionSpec.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/ConnectionSpec.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/ConnectionSpec.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/ConnectionSpec.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Cookie.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Cookie.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Cookie.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Cookie.kt diff --git a/okhttp/src/main/kotlin/okhttp3/CookieJar.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/CookieJar.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/CookieJar.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/CookieJar.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Credentials.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Credentials.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Credentials.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Credentials.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Dispatcher.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Dispatcher.kt similarity index 80% rename from okhttp/src/main/kotlin/okhttp3/Dispatcher.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Dispatcher.kt index e869053c1982..9e012a7907d5 100644 --- a/okhttp/src/main/kotlin/okhttp3/Dispatcher.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Dispatcher.kt @@ -22,7 +22,9 @@ import java.util.concurrent.ExecutorService import java.util.concurrent.SynchronousQueue import java.util.concurrent.ThreadPoolExecutor import java.util.concurrent.TimeUnit -import okhttp3.internal.assertThreadDoesntHoldLock +import java.util.concurrent.locks.ReentrantLock +import okhttp3.internal.assertNotHeld +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.connection.RealCall import okhttp3.internal.connection.RealCall.AsyncCall import okhttp3.internal.okHttpName @@ -36,6 +38,8 @@ import okhttp3.internal.threadFactory * concurrently. */ class Dispatcher() { + internal val lock: ReentrantLock = ReentrantLock() + /** * The maximum number of requests to execute concurrently. Above this requests queue in memory, * waiting for the running calls to complete. @@ -43,10 +47,11 @@ class Dispatcher() { * If more than [maxRequests] requests are in flight when this is invoked, those requests will * remain in flight. */ - @get:Synchronized var maxRequests = 64 + var maxRequests = 64 + get() = this.withLock { field } set(maxRequests) { require(maxRequests >= 1) { "max < 1: $maxRequests" } - synchronized(this) { + this.withLock { field = maxRequests } promoteAndExecute() @@ -62,10 +67,11 @@ class Dispatcher() { * * WebSocket connections to hosts **do not** count against this limit. */ - @get:Synchronized var maxRequestsPerHost = 5 + var maxRequestsPerHost = 5 + get() = this.withLock { field } set(maxRequestsPerHost) { require(maxRequestsPerHost >= 1) { "max < 1: $maxRequestsPerHost" } - synchronized(this) { + this.withLock { field = maxRequestsPerHost } promoteAndExecute() @@ -82,29 +88,31 @@ class Dispatcher() { * This means that if you are doing synchronous calls the network layer will not truly be idle * until every returned [Response] has been closed. */ - @set:Synchronized - @get:Synchronized var idleCallback: Runnable? = null + get() = this.withLock { field } + set(value) { + this.withLock { field = value } + } private var executorServiceOrNull: ExecutorService? = null - @get:Synchronized @get:JvmName("executorService") val executorService: ExecutorService - get() { - if (executorServiceOrNull == null) { - executorServiceOrNull = - ThreadPoolExecutor( - 0, - Int.MAX_VALUE, - 60, - TimeUnit.SECONDS, - SynchronousQueue(), - threadFactory("$okHttpName Dispatcher", false), - ) + get() = + this.withLock { + if (executorServiceOrNull == null) { + executorServiceOrNull = + ThreadPoolExecutor( + 0, + Int.MAX_VALUE, + 60, + TimeUnit.SECONDS, + SynchronousQueue(), + threadFactory("$okHttpName Dispatcher", false), + ) + } + return executorServiceOrNull!! } - return executorServiceOrNull!! - } /** Ready async calls in the order they'll be run. */ private val readyAsyncCalls = ArrayDeque() @@ -115,12 +123,12 @@ class Dispatcher() { /** Running synchronous calls. Includes canceled calls that haven't finished yet. */ private val runningSyncCalls = ArrayDeque() - constructor(executorService: ExecutorService) : this() { + constructor(executorService: ExecutorService?) : this() { this.executorServiceOrNull = executorService } internal fun enqueue(call: AsyncCall) { - synchronized(this) { + this.withLock { readyAsyncCalls.add(call) // Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to @@ -147,15 +155,17 @@ class Dispatcher() { * Cancel all calls currently enqueued or executing. Includes calls executed both * [synchronously][Call.execute] and [asynchronously][Call.enqueue]. */ - @Synchronized fun cancelAll() { - for (call in readyAsyncCalls) { - call.call.cancel() - } - for (call in runningAsyncCalls) { - call.call.cancel() - } - for (call in runningSyncCalls) { - call.cancel() + fun cancelAll() { + this.withLock { + for (call in readyAsyncCalls) { + call.call.cancel() + } + for (call in runningAsyncCalls) { + call.call.cancel() + } + for (call in runningSyncCalls) { + call.cancel() + } } } @@ -167,11 +177,11 @@ class Dispatcher() { * @return true if the dispatcher is currently running calls. */ private fun promoteAndExecute(): Boolean { - this.assertThreadDoesntHoldLock() + lock.assertNotHeld() val executableCalls = mutableListOf() val isRunning: Boolean - synchronized(this) { + this.withLock { val i = readyAsyncCalls.iterator() while (i.hasNext()) { val asyncCall = i.next() @@ -195,7 +205,7 @@ class Dispatcher() { val asyncCall = executableCalls[i] asyncCall.callsPerHost.decrementAndGet() - synchronized(this) { + this.withLock { runningAsyncCalls.remove(asyncCall) } @@ -213,9 +223,10 @@ class Dispatcher() { } /** Used by [Call.execute] to signal it is in-flight. */ - @Synchronized internal fun executed(call: RealCall) { - runningSyncCalls.add(call) - } + internal fun executed(call: RealCall) = + this.withLock { + runningSyncCalls.add(call) + } /** Used by [AsyncCall.run] to signal completion. */ internal fun finished(call: AsyncCall) { @@ -233,7 +244,7 @@ class Dispatcher() { call: T, ) { val idleCallback: Runnable? - synchronized(this) { + this.withLock { if (!calls.remove(call)) throw AssertionError("Call wasn't in-flight!") idleCallback = this.idleCallback } @@ -246,18 +257,20 @@ class Dispatcher() { } /** Returns a snapshot of the calls currently awaiting execution. */ - @Synchronized fun queuedCalls(): List { - return Collections.unmodifiableList(readyAsyncCalls.map { it.call }) - } + fun queuedCalls(): List = + this.withLock { + return Collections.unmodifiableList(readyAsyncCalls.map { it.call }) + } /** Returns a snapshot of the calls currently being executed. */ - @Synchronized fun runningCalls(): List { - return Collections.unmodifiableList(runningSyncCalls + runningAsyncCalls.map { it.call }) - } + fun runningCalls(): List = + this.withLock { + return Collections.unmodifiableList(runningSyncCalls + runningAsyncCalls.map { it.call }) + } - @Synchronized fun queuedCallsCount(): Int = readyAsyncCalls.size + fun queuedCallsCount(): Int = this.withLock { readyAsyncCalls.size } - @Synchronized fun runningCallsCount(): Int = runningAsyncCalls.size + runningSyncCalls.size + fun runningCallsCount(): Int = this.withLock { runningAsyncCalls.size + runningSyncCalls.size } @JvmName("-deprecated_executorService") @Deprecated( diff --git a/okhttp/src/main/kotlin/okhttp3/Dns.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Dns.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Dns.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Dns.kt diff --git a/okhttp/src/main/kotlin/okhttp3/EventListener.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/EventListener.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/EventListener.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/EventListener.kt diff --git a/okhttp/src/main/kotlin/okhttp3/ExperimentalOkHttpApi.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/ExperimentalOkHttpApi.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/ExperimentalOkHttpApi.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/ExperimentalOkHttpApi.kt diff --git a/okhttp/src/main/kotlin/okhttp3/FormBody.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/FormBody.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/FormBody.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/FormBody.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Handshake.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Handshake.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Handshake.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Handshake.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Headers.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Headers.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Headers.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Headers.kt diff --git a/okhttp/src/main/kotlin/okhttp3/HttpUrl.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/HttpUrl.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/HttpUrl.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/HttpUrl.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Interceptor.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Interceptor.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Interceptor.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Interceptor.kt diff --git a/okhttp/src/main/kotlin/okhttp3/MediaType.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/MediaType.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/MediaType.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/MediaType.kt diff --git a/okhttp/src/main/kotlin/okhttp3/MultipartBody.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/MultipartBody.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/MultipartBody.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/MultipartBody.kt diff --git a/okhttp/src/main/kotlin/okhttp3/MultipartReader.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/MultipartReader.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/MultipartReader.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/MultipartReader.kt diff --git a/okhttp/src/main/kotlin/okhttp3/OkHttp.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/OkHttp.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/OkHttp.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/OkHttp.kt diff --git a/okhttp/src/main/kotlin/okhttp3/OkHttpClient.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/OkHttpClient.kt similarity index 99% rename from okhttp/src/main/kotlin/okhttp3/OkHttpClient.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/OkHttpClient.kt index 7f499c765c73..4f480d4a334d 100644 --- a/okhttp/src/main/kotlin/okhttp3/OkHttpClient.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/OkHttpClient.kt @@ -15,7 +15,6 @@ */ package okhttp3 -import android.annotation.SuppressLint import java.net.Proxy import java.net.ProxySelector import java.net.Socket @@ -1113,7 +1112,6 @@ open class OkHttpClient internal constructor( * * The default value is 0 which imposes no timeout. */ - @SuppressLint("NewApi") @IgnoreJRERequirement fun callTimeout(duration: Duration) = apply { @@ -1156,7 +1154,6 @@ open class OkHttpClient internal constructor( * The connect timeout is applied when connecting a TCP socket to the target host. The default * value is 10 seconds. */ - @SuppressLint("NewApi") @IgnoreJRERequirement fun connectTimeout(duration: Duration) = apply { @@ -1202,7 +1199,6 @@ open class OkHttpClient internal constructor( * @see Socket.setSoTimeout * @see Source.timeout */ - @SuppressLint("NewApi") @IgnoreJRERequirement fun readTimeout(duration: Duration) = apply { @@ -1249,7 +1245,6 @@ open class OkHttpClient internal constructor( * * @see Sink.timeout */ - @SuppressLint("NewApi") @IgnoreJRERequirement fun writeTimeout(duration: Duration) = apply { @@ -1303,7 +1298,6 @@ open class OkHttpClient internal constructor( * * The default value of 0 disables client-initiated pings. */ - @SuppressLint("NewApi") @IgnoreJRERequirement fun pingInterval(duration: Duration) = apply { @@ -1351,7 +1345,6 @@ open class OkHttpClient internal constructor( * wait for a graceful shutdown. If the server doesn't respond the web socket will be canceled. * The default value is 60 seconds. */ - @SuppressLint("NewApi") @IgnoreJRERequirement fun webSocketCloseTimeout(duration: Duration) = apply { diff --git a/okhttp/src/main/kotlin/okhttp3/Protocol.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Protocol.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Protocol.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Protocol.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Request.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Request.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Request.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Request.kt diff --git a/okhttp/src/main/kotlin/okhttp3/RequestBody.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/RequestBody.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/RequestBody.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/RequestBody.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Response.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Response.kt similarity index 98% rename from okhttp/src/main/kotlin/okhttp3/Response.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Response.kt index 517c1047f987..6fd6fdf9567a 100644 --- a/okhttp/src/main/kotlin/okhttp3/Response.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Response.kt @@ -84,7 +84,7 @@ class Response internal constructor( * from [Call.execute]. Response bodies must be [closed][ResponseBody] and may * be consumed only once. * - * This always returns null on responses returned from [cacheResponse], [networkResponse], + * This always returns an unreadable [ResponseBody], which may implement [ResponseBody.contentType] and [ResponseBody.contentLength], on responses returned from [cacheResponse], [networkResponse], * and [priorResponse]. */ @get:JvmName("body") val body: ResponseBody, diff --git a/okhttp/src/main/kotlin/okhttp3/ResponseBody.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/ResponseBody.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/ResponseBody.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/ResponseBody.kt diff --git a/okhttp/src/main/kotlin/okhttp3/Route.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Route.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/Route.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/Route.kt diff --git a/okhttp/src/main/kotlin/okhttp3/TlsVersion.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/TlsVersion.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/TlsVersion.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/TlsVersion.kt diff --git a/okhttp/src/main/kotlin/okhttp3/WebSocket.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/WebSocket.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/WebSocket.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/WebSocket.kt diff --git a/okhttp/src/main/kotlin/okhttp3/WebSocketListener.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/WebSocketListener.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/WebSocketListener.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/WebSocketListener.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/-CacheControlCommon.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-CacheControlCommon.kt similarity index 88% rename from okhttp/src/main/kotlin/okhttp3/internal/-CacheControlCommon.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-CacheControlCommon.kt index d35103a34ff3..4b35218be2a2 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/-CacheControlCommon.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-CacheControlCommon.kt @@ -17,8 +17,7 @@ package okhttp3.internal -import kotlin.time.DurationUnit -import kotlin.time.toDuration +import kotlin.time.Duration.Companion.seconds import okhttp3.CacheControl import okhttp3.Headers @@ -47,33 +46,6 @@ internal fun CacheControl.commonToString(): String { return result } -internal fun CacheControl.Builder.commonMaxAge( - maxAge: Int, - timeUnit: DurationUnit, -) = apply { - require(maxAge >= 0) { "maxAge < 0: $maxAge" } - val maxAgeSecondsLong = maxAge.toDuration(timeUnit).inWholeSeconds - this.maxAgeSeconds = maxAgeSecondsLong.commonClampToInt() -} - -internal fun CacheControl.Builder.commonMaxStale( - maxStale: Int, - timeUnit: DurationUnit, -) = apply { - require(maxStale >= 0) { "maxStale < 0: $maxStale" } - val maxStaleSecondsLong = maxStale.toDuration(timeUnit).inWholeSeconds - this.maxStaleSeconds = maxStaleSecondsLong.commonClampToInt() -} - -internal fun CacheControl.Builder.commonMinFresh( - minFresh: Int, - timeUnit: DurationUnit, -) = apply { - require(minFresh >= 0) { "minFresh < 0: $minFresh" } - val minFreshSecondsLong = minFresh.toDuration(timeUnit).inWholeSeconds - this.minFreshSeconds = minFreshSecondsLong.commonClampToInt() -} - internal fun Long.commonClampToInt(): Int { return when { this > Int.MAX_VALUE -> Int.MAX_VALUE @@ -89,7 +61,7 @@ internal fun CacheControl.Companion.commonForceNetwork() = internal fun CacheControl.Companion.commonForceCache() = CacheControl.Builder() .onlyIfCached() - .maxStale(Int.MAX_VALUE, DurationUnit.SECONDS) + .maxStale(Int.MAX_VALUE.seconds) .build() internal fun CacheControl.Builder.commonBuild(): CacheControl { diff --git a/okhttp/src/main/kotlin/okhttp3/internal/-ChallengeCommon.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-ChallengeCommon.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/-ChallengeCommon.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-ChallengeCommon.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/-HeadersCommon.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-HeadersCommon.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/-HeadersCommon.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-HeadersCommon.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/-HostnamesCommon.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-HostnamesCommon.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/-HostnamesCommon.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-HostnamesCommon.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/-MediaTypeCommon.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-MediaTypeCommon.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/-MediaTypeCommon.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-MediaTypeCommon.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/-NormalizeJvm.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-NormalizeJvm.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/-NormalizeJvm.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-NormalizeJvm.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/-RequestBodyCommon.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-RequestBodyCommon.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/-RequestBodyCommon.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-RequestBodyCommon.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/-RequestCommon.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-RequestCommon.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/-RequestCommon.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-RequestCommon.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/-ResponseBodyCommon.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-ResponseBodyCommon.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/-ResponseBodyCommon.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-ResponseBodyCommon.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/-ResponseCommon.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-ResponseCommon.kt similarity index 96% rename from okhttp/src/main/kotlin/okhttp3/internal/-ResponseCommon.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-ResponseCommon.kt index 4f68f6403dd6..f75f4bf8738d 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/-ResponseCommon.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-ResponseCommon.kt @@ -17,7 +17,10 @@ package okhttp3.internal -import kotlin.jvm.JvmOverloads +import java.net.HttpURLConnection.HTTP_MOVED_PERM +import java.net.HttpURLConnection.HTTP_MOVED_TEMP +import java.net.HttpURLConnection.HTTP_MULT_CHOICE +import java.net.HttpURLConnection.HTTP_SEE_OTHER import okhttp3.CacheControl import okhttp3.Headers import okhttp3.MediaType @@ -26,11 +29,7 @@ import okhttp3.Request import okhttp3.Response import okhttp3.ResponseBody import okhttp3.ResponseBody.Companion.asResponseBody -import okhttp3.internal.http.HTTP_MOVED_PERM -import okhttp3.internal.http.HTTP_MOVED_TEMP -import okhttp3.internal.http.HTTP_MULT_CHOICE import okhttp3.internal.http.HTTP_PERM_REDIRECT -import okhttp3.internal.http.HTTP_SEE_OTHER import okhttp3.internal.http.HTTP_TEMP_REDIRECT import okio.Buffer import okio.IOException diff --git a/okhttp/src/main/kotlin/okhttp3/internal/-UtilCommon.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-UtilCommon.kt similarity index 99% rename from okhttp/src/main/kotlin/okhttp3/internal/-UtilCommon.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-UtilCommon.kt index 3db8d43a9c2a..16d1321b5afb 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/-UtilCommon.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-UtilCommon.kt @@ -55,12 +55,12 @@ internal val UNICODE_BOMS = "efbbbf".decodeHex(), // UTF-16BE. "feff".decodeHex(), + // UTF-32LE. + "fffe0000".decodeHex(), // UTF-16LE. "fffe".decodeHex(), // UTF-32BE. - "0000ffff".decodeHex(), - // UTF-32LE. - "ffff0000".decodeHex(), + "0000feff".decodeHex(), ) /** diff --git a/okhttp/src/main/kotlin/okhttp3/internal/-UtilJvm.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-UtilJvm.kt similarity index 98% rename from okhttp/src/main/kotlin/okhttp3/internal/-UtilJvm.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-UtilJvm.kt index 1f1c4f4e3a1f..71014a703f3f 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/-UtilJvm.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/-UtilJvm.kt @@ -94,14 +94,18 @@ internal fun format( return String.format(Locale.US, format, *args) } +/** + * will also strip BOM from the source + */ @Throws(IOException::class) internal fun BufferedSource.readBomAsCharset(default: Charset): Charset { return when (select(UNICODE_BOMS)) { + // a mapping from the index of encoding methods in UNICODE_BOMS to its corresponding encoding method 0 -> UTF_8 1 -> UTF_16BE - 2 -> UTF_16LE - 3 -> UTF_32BE - 4 -> UTF_32LE + 2 -> UTF_32LE + 3 -> UTF_16LE + 4 -> UTF_32BE -1 -> default else -> throw AssertionError() } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/NativeImageTestsAccessors.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/NativeImageTestsAccessors.kt similarity index 96% rename from okhttp/src/main/kotlin/okhttp3/internal/NativeImageTestsAccessors.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/NativeImageTestsAccessors.kt index cdf6fb62cfcf..db5f173887e4 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/NativeImageTestsAccessors.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/NativeImageTestsAccessors.kt @@ -29,7 +29,7 @@ internal fun buildCache( maxSize: Long, fileSystem: FileSystem, ): Cache { - return Cache(file, maxSize, fileSystem) + return Cache(fileSystem, file, maxSize) } internal var RealConnection.idleAtNsAccessor: Long diff --git a/okhttp/src/main/kotlin/okhttp3/internal/SuppressSignatureCheck.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/SuppressSignatureCheck.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/SuppressSignatureCheck.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/SuppressSignatureCheck.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticator.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticator.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticator.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticator.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/cache/CacheInterceptor.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache/CacheInterceptor.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/cache/CacheInterceptor.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache/CacheInterceptor.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/cache/CacheRequest.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache/CacheRequest.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/cache/CacheRequest.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache/CacheRequest.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/cache/CacheStrategy.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache/CacheStrategy.kt similarity index 96% rename from okhttp/src/main/kotlin/okhttp3/internal/cache/CacheStrategy.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache/CacheStrategy.kt index 7e447cc57dfb..0582fcb5028c 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/cache/CacheStrategy.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache/CacheStrategy.kt @@ -16,20 +16,20 @@ package okhttp3.internal.cache import java.net.HttpURLConnection.HTTP_BAD_METHOD +import java.net.HttpURLConnection.HTTP_GONE +import java.net.HttpURLConnection.HTTP_MOVED_PERM +import java.net.HttpURLConnection.HTTP_MOVED_TEMP +import java.net.HttpURLConnection.HTTP_MULT_CHOICE import java.net.HttpURLConnection.HTTP_NOT_AUTHORITATIVE +import java.net.HttpURLConnection.HTTP_NOT_FOUND +import java.net.HttpURLConnection.HTTP_NOT_IMPLEMENTED +import java.net.HttpURLConnection.HTTP_NO_CONTENT +import java.net.HttpURLConnection.HTTP_OK import java.net.HttpURLConnection.HTTP_REQ_TOO_LONG import java.util.Date import java.util.concurrent.TimeUnit.SECONDS import okhttp3.Request import okhttp3.Response -import okhttp3.internal.http.HTTP_GONE -import okhttp3.internal.http.HTTP_MOVED_PERM -import okhttp3.internal.http.HTTP_MOVED_TEMP -import okhttp3.internal.http.HTTP_MULT_CHOICE -import okhttp3.internal.http.HTTP_NOT_FOUND -import okhttp3.internal.http.HTTP_NOT_IMPLEMENTED -import okhttp3.internal.http.HTTP_NO_CONTENT -import okhttp3.internal.http.HTTP_OK import okhttp3.internal.http.HTTP_PERM_REDIRECT import okhttp3.internal.http.HTTP_TEMP_REDIRECT import okhttp3.internal.http.toHttpDateOrNull diff --git a/okhttp/src/main/kotlin/okhttp3/internal/cache/DiskLruCache.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache/DiskLruCache.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/cache/DiskLruCache.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache/DiskLruCache.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/cache/FaultHidingSink.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache/FaultHidingSink.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/cache/FaultHidingSink.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache/FaultHidingSink.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/cache2/FileOperator.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache2/FileOperator.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/cache2/FileOperator.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache2/FileOperator.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/cache2/Relay.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache2/Relay.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/cache2/Relay.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/cache2/Relay.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/concurrent/Task.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/concurrent/Task.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/concurrent/Task.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/concurrent/Task.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/concurrent/TaskLogger.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/concurrent/TaskLogger.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/concurrent/TaskLogger.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/concurrent/TaskLogger.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/concurrent/TaskQueue.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/concurrent/TaskQueue.kt similarity index 96% rename from okhttp/src/main/kotlin/okhttp3/internal/concurrent/TaskQueue.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/concurrent/TaskQueue.kt index 788fc0f44321..99d5b600b265 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/concurrent/TaskQueue.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/concurrent/TaskQueue.kt @@ -18,8 +18,8 @@ package okhttp3.internal.concurrent import java.util.concurrent.CountDownLatch import java.util.concurrent.RejectedExecutionException import java.util.concurrent.locks.ReentrantLock -import kotlin.concurrent.withLock import okhttp3.internal.assertNotHeld +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.okHttpName /** @@ -32,7 +32,7 @@ class TaskQueue internal constructor( internal val taskRunner: TaskRunner, internal val name: String, ) { - val lock: ReentrantLock = ReentrantLock() + internal val lock: ReentrantLock = ReentrantLock() internal var shutdown = false @@ -50,7 +50,7 @@ class TaskQueue internal constructor( * currently-executing task unless it is also scheduled for future execution. */ val scheduledTasks: List - get() = taskRunner.lock.withLock { futureTasks.toList() } + get() = taskRunner.withLock { futureTasks.toList() } /** * Schedules [task] for execution in [delayNanos]. A task may only have one future execution @@ -66,7 +66,7 @@ class TaskQueue internal constructor( task: Task, delayNanos: Long = 0L, ) { - taskRunner.lock.withLock { + taskRunner.withLock { if (shutdown) { if (task.cancelable) { taskRunner.logger.taskLog(task, this) { "schedule canceled (queue is shutdown)" } @@ -126,7 +126,7 @@ class TaskQueue internal constructor( /** Returns a latch that reaches 0 when the queue is next idle. */ fun idleLatch(): CountDownLatch { - taskRunner.lock.withLock { + taskRunner.withLock { // If the queue is already idle, that's easy. if (activeTask == null && futureTasks.isEmpty()) { return CountDownLatch(0) @@ -208,7 +208,7 @@ class TaskQueue internal constructor( fun cancelAll() { lock.assertNotHeld() - taskRunner.lock.withLock { + taskRunner.withLock { if (cancelAllAndDecide()) { taskRunner.kickCoordinator(this) } @@ -218,7 +218,7 @@ class TaskQueue internal constructor( fun shutdown() { lock.assertNotHeld() - taskRunner.lock.withLock { + taskRunner.withLock { shutdown = true if (cancelAllAndDecide()) { taskRunner.kickCoordinator(this) diff --git a/okhttp/src/main/kotlin/okhttp3/internal/concurrent/TaskRunner.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/concurrent/TaskRunner.kt similarity index 79% rename from okhttp/src/main/kotlin/okhttp3/internal/concurrent/TaskRunner.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/concurrent/TaskRunner.kt index 6acc7b24e774..01137cea4f4b 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/concurrent/TaskRunner.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/concurrent/TaskRunner.kt @@ -23,10 +23,11 @@ import java.util.concurrent.TimeUnit import java.util.concurrent.locks.Condition import java.util.concurrent.locks.ReentrantLock import java.util.logging.Logger -import kotlin.concurrent.withLock import okhttp3.internal.addIfAbsent import okhttp3.internal.assertHeld import okhttp3.internal.concurrent.TaskRunner.Companion.INSTANCE +import okhttp3.internal.connection.Locks.newLockCondition +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.okHttpName import okhttp3.internal.threadFactory @@ -45,13 +46,24 @@ class TaskRunner( val backend: Backend, internal val logger: Logger = TaskRunner.logger, ) { - val lock: ReentrantLock = ReentrantLock() - val condition: Condition = lock.newCondition() + internal val lock: ReentrantLock = ReentrantLock() + val condition: Condition = lock.newLockCondition() private var nextQueueName = 10000 private var coordinatorWaiting = false private var coordinatorWakeUpAt = 0L + /** + * When we need a new thread to run tasks, we call [Backend.execute]. A few microseconds later we + * expect a newly-started thread to call [Runnable.run]. We shouldn't request new threads until + * the already-requested ones are in service, otherwise we might create more threads than we need. + * + * We use [executeCallCount] and [runCallCount] to defend against starting more threads than we + * need. Both fields are guarded by [lock]. + */ + private var executeCallCount = 0 + private var runCallCount = 0 + /** Queues with tasks that are currently executing their [TaskQueue.activeTask]. */ private val busyQueues = mutableListOf() @@ -61,26 +73,36 @@ class TaskRunner( private val runnable: Runnable = object : Runnable { override fun run() { - while (true) { - val task = - this@TaskRunner.lock.withLock { + var task: Task = + withLock { + runCallCount++ + awaitTaskToRun() + } ?: return + + val currentThread = Thread.currentThread() + val oldName = currentThread.name + try { + while (true) { + currentThread.name = task.name + val delayNanos = + logger.logElapsed(task, task.queue!!) { + task.runOnce() + } + + // A task ran successfully. Update the execution state and take the next task. + task = withLock { + afterRun(task, delayNanos, true) awaitTaskToRun() } ?: return - - logger.logElapsed(task, task.queue!!) { - var completedNormally = false - try { - runTask(task) - completedNormally = true - } finally { - // If the task is crashing start another thread to service the queues. - if (!completedNormally) { - lock.withLock { - backend.execute(this@TaskRunner, this) - } - } - } } + } catch (thrown: Throwable) { + // A task failed. Update execution state and re-throw the exception. + withLock { + afterRun(task, -1L, false) + } + throw thrown + } finally { + currentThread.name = oldName } } } @@ -99,7 +121,7 @@ class TaskRunner( if (coordinatorWaiting) { backend.coordinatorNotify(this@TaskRunner) } else { - backend.execute(this@TaskRunner, runnable) + startAnotherThread() } } @@ -114,25 +136,10 @@ class TaskRunner( busyQueues.add(queue) } - private fun runTask(task: Task) { - val currentThread = Thread.currentThread() - val oldName = currentThread.name - currentThread.name = task.name - - var delayNanos = -1L - try { - delayNanos = task.runOnce() - } finally { - lock.withLock { - afterRun(task, delayNanos) - } - currentThread.name = oldName - } - } - private fun afterRun( task: Task, delayNanos: Long, + completedNormally: Boolean, ) { lock.assertHeld() @@ -150,6 +157,11 @@ class TaskRunner( if (queue.futureTasks.isNotEmpty()) { readyQueues.add(queue) + + // If the task crashed, start another thread to run the next task. + if (!completedNormally) { + startAnotherThread() + } } } @@ -157,7 +169,7 @@ class TaskRunner( * Returns an immediately-executable task for the calling thread to execute, sleeping as necessary * until one is ready. If there are no ready queues, or if other threads have everything under * control this will return null. If there is more than a single task ready to execute immediately - * this will launch another thread to handle that work. + * this will start another thread to handle that work. */ fun awaitTaskToRun(): Task? { lock.assertHeld() @@ -207,7 +219,7 @@ class TaskRunner( // Also start another thread if there's more work or scheduling to do. if (multipleReadyTasks || !coordinatorWaiting && readyQueues.isNotEmpty()) { - backend.execute(this@TaskRunner, runnable) + startAnotherThread() } return readyTask @@ -238,8 +250,17 @@ class TaskRunner( } } + /** Start another thread, unless a new thread is already scheduled to start. */ + private fun startAnotherThread() { + lock.assertHeld() + if (executeCallCount > runCallCount) return // A thread is still starting. + + executeCallCount++ + backend.execute(this@TaskRunner, runnable) + } + fun newQueue(): TaskQueue { - val name = lock.withLock { nextQueueName++ } + val name = this.withLock { nextQueueName++ } return TaskQueue(this, "Q$name") } @@ -248,7 +269,7 @@ class TaskRunner( * necessarily track queues that have no tasks scheduled. */ fun activeQueues(): List { - lock.withLock { + this.withLock { return busyQueues + readyQueues } } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/CallConnectionUser.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/CallConnectionUser.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/CallConnectionUser.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/CallConnectionUser.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/ConnectInterceptor.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ConnectInterceptor.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/ConnectInterceptor.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ConnectInterceptor.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/ConnectPlan.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ConnectPlan.kt similarity index 96% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/ConnectPlan.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ConnectPlan.kt index a5c31f9cf03b..a2815f5c1de3 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/connection/ConnectPlan.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ConnectPlan.kt @@ -35,6 +35,7 @@ import okhttp3.Request import okhttp3.Route import okhttp3.internal.closeQuietly import okhttp3.internal.concurrent.TaskRunner +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.connection.RoutePlanner.ConnectResult import okhttp3.internal.http.ExchangeCodec import okhttp3.internal.http1.Http1ExchangeCodec @@ -92,8 +93,8 @@ class ConnectPlan( internal var socket: Socket? = null private var handshake: Handshake? = null private var protocol: Protocol? = null - private var source: BufferedSource? = null - private var sink: BufferedSink? = null + private lateinit var source: BufferedSource + private lateinit var sink: BufferedSink private var connection: RealConnection? = null /** True if this connection is ready for use, including TCP, tunnels, and TLS. */ @@ -140,6 +141,14 @@ class ConnectPlan( success = true return ConnectResult(plan = this) } catch (e: IOException) { + // If we used the ProxySelector, and got a IOException during connect, report the failure. + if (route.address.proxy == null && route.proxy.type() != Proxy.Type.DIRECT) { + route.address.proxySelector.connectFailed( + route.address.url.toUri(), + route.proxy.address(), + e, + ) + } user.connectFailed(route, null, e) return ConnectResult(plan = this, throwable = e) } finally { @@ -151,7 +160,7 @@ class ConnectPlan( } override fun connectTlsEtc(): ConnectResult { - check(rawSocket != null) { "TCP not connected" } + val rawSocket = requireNotNull(rawSocket) { "TCP not connected" } check(!isReady) { "already connected" } val connectionSpecs = route.address.connectionSpecs @@ -175,7 +184,7 @@ class ConnectPlan( // that happens, then we will have buffered bytes that are needed by the SSLSocket! // This check is imperfect: it doesn't tell us whether a handshake will succeed, just // that it will almost certainly fail because the proxy has sent unexpected data. - if (source?.buffer?.exhausted() == false || sink?.buffer?.exhausted() == false) { + if (!source.buffer.exhausted() || !sink.buffer.exhausted()) { throw IOException("TLS tunnel buffered too many bytes!") } @@ -215,9 +224,9 @@ class ConnectPlan( connectionPool = connectionPool, route = route, rawSocket = rawSocket, - socket = socket, + socket = socket!!, handshake = handshake, - protocol = protocol, + protocol = protocol!!, source = source, sink = sink, pingIntervalMillis = pingIntervalMillis, @@ -246,7 +255,7 @@ class ConnectPlan( user.removePlanToCancel(this) if (!success) { socket?.closeQuietly() - rawSocket?.closeQuietly() + rawSocket.closeQuietly() } } } @@ -419,8 +428,6 @@ class ConnectPlan( val url = route.address.url val requestLine = "CONNECT ${url.toHostHeader(includeDefaultPort = true)} HTTP/1.1" while (true) { - val source = this.source!! - val sink = this.sink!! val tunnelCodec = Http1ExchangeCodec( // No client for CONNECT tunnels: @@ -503,7 +510,7 @@ class ConnectPlan( val pooled3 = routePlanner.planReusePooledConnection(this, routes) if (pooled3 != null) return pooled3.connection - synchronized(connection) { + connection.withLock { connectionPool.put(connection) user.acquireConnectionNoEvents(connection) } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/ConnectionUser.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ConnectionUser.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/ConnectionUser.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ConnectionUser.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/Exchange.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/Exchange.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/Exchange.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/Exchange.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/ExchangeFinder.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ExchangeFinder.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/ExchangeFinder.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ExchangeFinder.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/FailedPlan.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/FailedPlan.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/FailedPlan.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/FailedPlan.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/FastFallbackExchangeFinder.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/FastFallbackExchangeFinder.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/FastFallbackExchangeFinder.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/FastFallbackExchangeFinder.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/ForceConnectRoutePlanner.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ForceConnectRoutePlanner.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/ForceConnectRoutePlanner.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ForceConnectRoutePlanner.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/InetAddressOrder.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/InetAddressOrder.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/InetAddressOrder.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/InetAddressOrder.kt diff --git a/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/Locks.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/Locks.kt new file mode 100644 index 000000000000..9fc039419099 --- /dev/null +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/Locks.kt @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2024 Block, 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. + */ +@file:OptIn(ExperimentalContracts::class, ExperimentalContracts::class) + +package okhttp3.internal.connection + +import java.util.concurrent.locks.Condition +import java.util.concurrent.locks.ReentrantLock +import kotlin.concurrent.withLock +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract +import okhttp3.Dispatcher +import okhttp3.internal.concurrent.TaskQueue +import okhttp3.internal.concurrent.TaskRunner +import okhttp3.internal.http2.Http2Connection +import okhttp3.internal.http2.Http2Stream +import okhttp3.internal.http2.Http2Writer + +/** + * Centralisation of central locks according to docs/contribute/concurrency.md + */ +internal object Locks { + inline fun Dispatcher.withLock(action: () -> T): T { + contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } + return lock.runWithLock(action) + } + + inline fun RealConnection.withLock(action: () -> T): T { + contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } + return lock.runWithLock(action) + } + + inline fun RealCall.withLock(action: () -> T): T { + contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } + return lock.runWithLock(action) + } + + inline fun Http2Connection.withLock(action: () -> T): T { + contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } + return lock.runWithLock(action) + } + + inline fun Http2Stream.withLock(action: () -> T): T { + contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } + return lock.runWithLock(action) + } + + inline fun TaskRunner.withLock(action: () -> T): T { + contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } + return lock.runWithLock(action) + } + + inline fun TaskQueue.withLock(action: () -> T): T { + contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } + return lock.runWithLock(action) + } + + inline fun Http2Writer.withLock(action: () -> T): T { + // TODO can we assert we don't have the connection lock? + + contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } + return lock.runWithLock(action) + } + + /** + * A no cost (inlined) alias to [ReentrantLock#newCondition] for an OkHttp Lock. + * No function on its own but places a central place that all conditions go through to allow + * temporary debugging. + */ + internal fun ReentrantLock.newLockCondition(): Condition { + return this.newCondition() + } + + /** + * A no cost (inlined) alias to [ReentrantLock#withLock] for an OkHttp Lock. + * No function on its own but places a central place that all locks go through to allow + * temporary debugging. + */ + inline fun ReentrantLock.runWithLock(action: () -> T): T { + contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } + return withLock(action) + } +} diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/PoolConnectionUser.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/PoolConnectionUser.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/PoolConnectionUser.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/PoolConnectionUser.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/RealCall.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealCall.kt similarity index 96% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/RealCall.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealCall.kt index 2f7be64ba69e..1a83d90309af 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/connection/RealCall.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealCall.kt @@ -25,6 +25,7 @@ import java.util.concurrent.RejectedExecutionException import java.util.concurrent.TimeUnit.MILLISECONDS import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicInteger +import java.util.concurrent.locks.ReentrantLock import okhttp3.Call import okhttp3.Callback import okhttp3.EventListener @@ -32,10 +33,12 @@ import okhttp3.Interceptor import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response +import okhttp3.internal.assertHeld +import okhttp3.internal.assertNotHeld import okhttp3.internal.assertThreadDoesntHoldLock -import okhttp3.internal.assertThreadHoldsLock import okhttp3.internal.cache.CacheInterceptor import okhttp3.internal.closeQuietly +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.http.BridgeInterceptor import okhttp3.internal.http.CallServerInterceptor import okhttp3.internal.http.RealInterceptorChain @@ -60,6 +63,8 @@ class RealCall( val originalRequest: Request, val forWebSocket: Boolean, ) : Call, Cloneable { + internal val lock: ReentrantLock = ReentrantLock() + private val connectionPool: RealConnectionPool = client.connectionPool.delegate internal val eventListener: EventListener = client.eventListenerFactory.create(this) @@ -95,7 +100,7 @@ class RealCall( internal var interceptorScopedExchange: Exchange? = null private set - // These properties are guarded by this. They are typically only accessed by the thread executing + // These properties are guarded by [lock]. They are typically only accessed by the thread executing // the call, but they may be accessed by other threads for duplex requests. /** True if this call still has a request body open. */ @@ -231,7 +236,7 @@ class RealCall( ) { check(interceptorScopedExchange == null) - synchronized(this) { + this.withLock { check(!responseBodyOpen) { "cannot make a new request because the previous response is still open: " + "please call response.close()" @@ -265,7 +270,7 @@ class RealCall( /** Finds a new or pooled connection to carry a forthcoming request and response. */ internal fun initExchange(chain: RealInterceptorChain): Exchange { - synchronized(this) { + this.withLock { check(expectMoreExchanges) { "released" } check(!responseBodyOpen) check(!requestBodyOpen) @@ -277,7 +282,7 @@ class RealCall( val result = Exchange(this, eventListener, exchangeFinder, codec) this.interceptorScopedExchange = result this.exchange = result - synchronized(this) { + this.withLock { this.requestBodyOpen = true this.responseBodyOpen = true } @@ -287,7 +292,7 @@ class RealCall( } fun acquireConnectionNoEvents(connection: RealConnection) { - connection.assertThreadHoldsLock() + connection.lock.assertHeld() check(this.connection == null) this.connection = connection @@ -312,7 +317,7 @@ class RealCall( var bothStreamsDone = false var callDone = false - synchronized(this) { + this.withLock { if (requestDone && requestBodyOpen || responseDone && responseBodyOpen) { if (requestDone) requestBodyOpen = false if (responseDone) responseBodyOpen = false @@ -335,7 +340,7 @@ class RealCall( internal fun noMoreExchanges(e: IOException?): IOException? { var callDone = false - synchronized(this) { + this.withLock { if (expectMoreExchanges) { expectMoreExchanges = false callDone = !requestBodyOpen && !responseBodyOpen @@ -362,13 +367,13 @@ class RealCall( * additional context. Otherwise [e] is returned as-is. */ private fun callDone(e: E): E { - assertThreadDoesntHoldLock() + lock.assertNotHeld() val connection = this.connection if (connection != null) { - connection.assertThreadDoesntHoldLock() + connection.lock.assertNotHeld() val toClose: Socket? = - synchronized(connection) { + connection.withLock { // Sets this.connection to null. releaseConnectionNoEvents() } @@ -399,7 +404,7 @@ class RealCall( */ internal fun releaseConnectionNoEvents(): Socket? { val connection = this.connection!! - connection.assertThreadHoldsLock() + connection.lock.assertHeld() val calls = connection.calls val index = calls.indexOfFirst { it.get() == this@RealCall } @@ -443,7 +448,7 @@ class RealCall( * This is usually due to either an exception or a retry. */ internal fun exitNetworkInterceptorExchange(closeExchange: Boolean) { - synchronized(this) { + this.withLock { check(expectMoreExchanges) { "released" } } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/RealConnection.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealConnection.kt similarity index 84% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/RealConnection.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealConnection.kt index b19c52492a18..b2048715f906 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/connection/RealConnection.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealConnection.kt @@ -23,6 +23,7 @@ import java.net.Socket import java.net.SocketException import java.security.cert.X509Certificate import java.util.concurrent.TimeUnit.MILLISECONDS +import java.util.concurrent.locks.ReentrantLock import javax.net.ssl.SSLPeerUnverifiedException import javax.net.ssl.SSLSocket import okhttp3.Address @@ -33,10 +34,11 @@ import okhttp3.HttpUrl import okhttp3.OkHttpClient import okhttp3.Protocol import okhttp3.Route -import okhttp3.internal.assertThreadDoesntHoldLock -import okhttp3.internal.assertThreadHoldsLock +import okhttp3.internal.assertHeld +import okhttp3.internal.assertNotHeld import okhttp3.internal.closeQuietly import okhttp3.internal.concurrent.TaskRunner +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.http.ExchangeCodec import okhttp3.internal.http.RealInterceptorChain import okhttp3.internal.http1.Http1ExchangeCodec @@ -51,8 +53,13 @@ import okhttp3.internal.http2.StreamResetException import okhttp3.internal.isHealthy import okhttp3.internal.tls.OkHostnameVerifier import okhttp3.internal.ws.RealWebSocket +import okio.Buffer import okio.BufferedSink import okio.BufferedSource +import okio.Sink +import okio.Source +import okio.Timeout +import okio.buffer /** * A connection to a remote web server capable of carrying 1 or more concurrent streams. @@ -65,22 +72,24 @@ class RealConnection( val connectionPool: RealConnectionPool, override val route: Route, /** The low-level TCP socket. */ - private var rawSocket: Socket?, + private val rawSocket: Socket, /** * The application layer socket. Either an [SSLSocket] layered over [rawSocket], or [rawSocket] * itself if this connection does not use SSL. */ - private var socket: Socket?, - private var handshake: Handshake?, - private var protocol: Protocol?, - private var source: BufferedSource?, - private var sink: BufferedSink?, + private val socket: Socket, + private val handshake: Handshake?, + private val protocol: Protocol, + private val source: BufferedSource, + private val sink: BufferedSink, private val pingIntervalMillis: Int, internal val connectionListener: ConnectionListener, ) : Http2Connection.Listener(), Connection, ExchangeCodec.Carrier { private var http2Connection: Http2Connection? = null - // These properties are guarded by this. + internal val lock: ReentrantLock = ReentrantLock() + + // These properties are guarded by [lock]. /** * If true, no new exchanges can be created on this connection. It is necessary to set this to @@ -129,19 +138,23 @@ class RealConnection( /** Prevent further exchanges from being created on this connection. */ override fun noNewExchanges() { - synchronized(this) { + this.withLock { noNewExchanges = true } connectionListener.noNewExchanges(this) } /** Prevent this connection from being used for hosts other than the one in [route]. */ - @Synchronized internal fun noCoalescedConnections() { - noCoalescedConnections = true + internal fun noCoalescedConnections() { + this.withLock { + noCoalescedConnections = true + } } - @Synchronized internal fun incrementSuccessCount() { - successCount++ + internal fun incrementSuccessCount() { + this.withLock { + successCount++ + } } @Throws(IOException::class) @@ -154,9 +167,6 @@ class RealConnection( @Throws(IOException::class) private fun startHttp2() { - val socket = this.socket!! - val source = this.source!! - val sink = this.sink!! socket.soTimeout = 0 // HTTP/2 connection timeouts are set per-stream. val flowControlListener = connectionListener as? FlowControlListener ?: FlowControlListener.None val http2Connection = @@ -179,7 +189,7 @@ class RealConnection( address: Address, routes: List?, ): Boolean { - assertThreadHoldsLock() + lock.assertHeld() // If this connection is not accepting new exchanges, we're done. if (calls.size >= allocationLimit || noNewExchanges) return false @@ -232,7 +242,7 @@ class RealConnection( } private fun supportsUrl(url: HttpUrl): Boolean { - assertThreadHoldsLock() + lock.assertHeld() val routeUrl = route.address.url @@ -245,7 +255,7 @@ class RealConnection( } // We have a host mismatch. But if the certificate matches, we're still good. - return !noCoalescedConnections && handshake != null && certificateSupportHost(url, handshake!!) + return !noCoalescedConnections && handshake != null && certificateSupportHost(url, handshake) } private fun certificateSupportHost( @@ -263,9 +273,9 @@ class RealConnection( client: OkHttpClient, chain: RealInterceptorChain, ): ExchangeCodec { - val socket = this.socket!! - val source = this.source!! - val sink = this.sink!! + val socket = this.socket + val source = this.source + val sink = this.sink val http2Connection = this.http2Connection return if (http2Connection != null) { @@ -280,10 +290,6 @@ class RealConnection( @Throws(SocketException::class) internal fun newWebSocketStreams(exchange: Exchange): RealWebSocket.Streams { - val socket = this.socket!! - val source = this.source!! - val sink = this.sink!! - socket.soTimeout = 0 noNewExchanges() return object : RealWebSocket.Streams(true, source, sink) { @@ -301,20 +307,17 @@ class RealConnection( override fun cancel() { // Close the raw socket so we don't end up doing synchronous I/O. - rawSocket?.closeQuietly() + rawSocket.closeQuietly() } - override fun socket(): Socket = socket!! + override fun socket(): Socket = socket /** Returns true if this connection is ready to host new streams. */ fun isHealthy(doExtensiveChecks: Boolean): Boolean { - assertThreadDoesntHoldLock() + lock.assertNotHeld() val nowNs = System.nanoTime() - val rawSocket = this.rawSocket!! - val socket = this.socket!! - val source = this.source!! if (rawSocket.isClosed || socket.isClosed || socket.isInputShutdown || socket.isOutputShutdown ) { @@ -326,7 +329,7 @@ class RealConnection( return http2Connection.isHealthy(nowNs) } - val idleDurationNs = synchronized(this) { nowNs - idleAtNs } + val idleDurationNs = this.withLock { nowNs - idleAtNs } if (idleDurationNs >= IDLE_CONNECTION_HEALTHY_NS && doExtensiveChecks) { return socket.isHealthy(source) } @@ -341,19 +344,21 @@ class RealConnection( } /** When settings are received, adjust the allocation limit. */ - @Synchronized override fun onSettings( + override fun onSettings( connection: Http2Connection, settings: Settings, ) { - val oldLimit = allocationLimit - allocationLimit = settings.getMaxConcurrentStreams() - - if (allocationLimit < oldLimit) { - // We might need new connections to keep policies satisfied - connectionPool.scheduleConnectionOpener() - } else if (allocationLimit > oldLimit) { - // We might no longer need some connections - connectionPool.scheduleConnectionCloser() + this.withLock { + val oldLimit = allocationLimit + allocationLimit = settings.getMaxConcurrentStreams() + + if (allocationLimit < oldLimit) { + // We might need new connections to keep policies satisfied + connectionPool.scheduleOpener(route.address) + } else if (allocationLimit > oldLimit) { + // We might no longer need some connections + connectionPool.scheduleCloser() + } } } @@ -387,7 +392,7 @@ class RealConnection( e: IOException?, ) { var noNewExchangesEvent = false - synchronized(this) { + this.withLock { if (e is StreamResetException) { when { e.errorCode == ErrorCode.REFUSED_STREAM -> { @@ -432,7 +437,7 @@ class RealConnection( } } - override fun protocol(): Protocol = protocol!! + override fun protocol(): Protocol = protocol override fun toString(): String { return "Connection{${route.address.url.host}:${route.address.url.port}," + @@ -457,12 +462,38 @@ class RealConnection( taskRunner = taskRunner, connectionPool = connectionPool, route = route, - rawSocket = null, + rawSocket = Socket(), socket = socket, handshake = null, - protocol = null, - source = null, - sink = null, + protocol = Protocol.HTTP_2, + source = + object : Source { + override fun close() = Unit + + override fun read( + sink: Buffer, + byteCount: Long, + ): Long { + throw UnsupportedOperationException() + } + + override fun timeout(): Timeout = Timeout.NONE + }.buffer(), + sink = + object : Sink { + override fun close() = Unit + + override fun flush() = Unit + + override fun timeout(): Timeout = Timeout.NONE + + override fun write( + source: Buffer, + byteCount: Long, + ) { + throw UnsupportedOperationException() + } + }.buffer(), pingIntervalMillis = 0, ConnectionListener.NONE, ) diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/RealConnectionPool.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealConnectionPool.kt similarity index 61% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/RealConnectionPool.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealConnectionPool.kt index 9c57a44e3b89..f4bdfe69d23c 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/connection/RealConnectionPool.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealConnectionPool.kt @@ -20,18 +20,21 @@ import java.net.Socket import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.ThreadLocalRandom import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater import okhttp3.Address import okhttp3.ConnectionListener import okhttp3.ConnectionPool import okhttp3.Route -import okhttp3.internal.assertThreadHoldsLock +import okhttp3.internal.assertHeld import okhttp3.internal.closeQuietly import okhttp3.internal.concurrent.Task import okhttp3.internal.concurrent.TaskQueue import okhttp3.internal.concurrent.TaskRunner +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.connection.RealCall.CallReference import okhttp3.internal.okHttpName import okhttp3.internal.platform.Platform +import okio.IOException class RealConnectionPool( private val taskRunner: TaskRunner, @@ -47,21 +50,19 @@ class RealConnectionPool( ) { internal val keepAliveDurationNs: Long = timeUnit.toNanos(keepAliveDuration) - // guarded by [this] - private var policies: Map = mapOf() - private val user = PoolConnectionUser + @Volatile + private var addressStates: Map = mapOf() private val cleanupQueue: TaskQueue = taskRunner.newQueue() private val cleanupTask = object : Task("$okHttpName ConnectionPool connection closer") { - override fun runOnce(): Long = cleanup(System.nanoTime()) + override fun runOnce(): Long = closeConnections(System.nanoTime()) } - private fun MinimumConnectionState.schedule() { - val state = this + private fun AddressState.scheduleOpener() { queue.schedule( object : Task("$okHttpName ConnectionPool connection opener") { - override fun runOnce(): Long = ensureMinimumConnections(state) + override fun runOnce(): Long = openConnections(this@scheduleOpener) }, ) } @@ -80,7 +81,7 @@ class RealConnectionPool( fun idleConnectionCount(): Int { return connections.count { - synchronized(it) { it.calls.isEmpty() } + it.withLock { it.calls.isEmpty() } } } @@ -110,7 +111,7 @@ class RealConnectionPool( for (connection in connections) { // In the first synchronized block, acquire the connection if it can satisfy this call. val acquired = - synchronized(connection) { + connection.withLock { when { requireMultiplexed && !connection.isMultiplexed -> false !connection.isEligible(address, routes) -> false @@ -129,7 +130,7 @@ class RealConnectionPool( // the hook to close this connection if it's no longer in use. val noNewExchangesEvent: Boolean val toClose: Socket? = - synchronized(connection) { + connection.withLock { noNewExchangesEvent = !connection.noNewExchanges connection.noNewExchanges = true connectionUser.releaseConnectionNoEvents() @@ -145,11 +146,11 @@ class RealConnectionPool( } fun put(connection: RealConnection) { - connection.assertThreadHoldsLock() + connection.lock.assertHeld() connections.add(connection) // connection.queueEvent { connectionListener.connectEnd(connection) } - scheduleConnectionCloser() + scheduleCloser() } /** @@ -157,16 +158,16 @@ class RealConnectionPool( * removed from the pool and should be closed. */ fun connectionBecameIdle(connection: RealConnection): Boolean { - connection.assertThreadHoldsLock() + connection.lock.assertHeld() return if (connection.noNewExchanges || maxIdleConnections == 0) { connection.noNewExchanges = true connections.remove(connection) if (connections.isEmpty()) cleanupQueue.cancelAll() - scheduleConnectionOpener() + scheduleOpener(connection.route.address) true } else { - scheduleConnectionCloser() + scheduleCloser() false } } @@ -176,13 +177,13 @@ class RealConnectionPool( while (i.hasNext()) { val connection = i.next() val socketToClose = - synchronized(connection) { + connection.withLock { if (connection.calls.isEmpty()) { i.remove() connection.noNewExchanges = true - return@synchronized connection.socket() + return@withLock connection.socket() } else { - return@synchronized null + return@withLock null } } if (socketToClose != null) { @@ -192,7 +193,10 @@ class RealConnectionPool( } if (connections.isEmpty()) cleanupQueue.cancelAll() - scheduleConnectionOpener() + + for (policy in addressStates.values) { + policy.scheduleOpener() + } } /** @@ -202,74 +206,108 @@ class RealConnectionPool( * Returns the duration in nanoseconds to sleep until the next scheduled call to this method. * Returns -1 if no further cleanups are required. */ - fun cleanup(now: Long): Long { - var inUseConnectionCount = 0 - var idleConnectionCount = 0 - var longestIdleConnection: RealConnection? = null - var longestIdleDurationNs = Long.MIN_VALUE - var policyAffected: MinimumConnectionState? = null - policies - .forEach { it.value.unsatisfiedCountCleanupTask = it.value.policy.minimumConcurrentCalls } - - // Find either a connection to evict, or the time that the next eviction is due. + fun closeConnections(now: Long): Long { + // Compute the concurrent call capacity for each address. We won't close a connection if doing + // so would violate a policy, unless it's OLD. + val addressStates = this.addressStates + for (state in addressStates.values) { + state.concurrentCallCapacity = 0 + } for (connection in connections) { - synchronized(connection) { - val satisfiablePolicy = - policies.entries.firstOrNull { - it.value.unsatisfiedCountCleanupTask > 0 && connection.isEligible(it.key, null) - }?.value - val idleDurationNs = now - connection.idleAtNs + val addressState = addressStates[connection.route.address] ?: continue + connection.withLock { + addressState.concurrentCallCapacity += connection.allocationLimit + } + } + // Find the longest-idle connections in 2 categories: + // + // 1. OLD: Connections that have been idle for at least keepAliveDurationNs. We close these if + // we find them, regardless of what the address policies need. + // + // 2. EVICTABLE: Connections not required by any address policy. This matches connections that + // don't participate in any policy, plus connections whose policies won't be violated if the + // connection is closed. We only close these if the idle connection limit is exceeded. + // + // Also count the evictable connections to find out if we must close an EVICTABLE connection + // before its keepAliveDurationNs is reached. + var earliestOldIdleAtNs = (now - keepAliveDurationNs) + 1 + var earliestOldConnection: RealConnection? = null + var earliestEvictableIdleAtNs = Long.MAX_VALUE + var earliestEvictableConnection: RealConnection? = null + var inUseConnectionCount = 0 + var evictableConnectionCount = 0 + for (connection in connections) { + connection.withLock { + // If the connection is in use, keep searching. if (pruneAndGetAllocationCount(connection, now) > 0) { - // If the connection is in use, keep searching. - inUseConnectionCount++ - } else if (satisfiablePolicy != null && idleDurationNs < this.keepAliveDurationNs) { - // If the connection hasn't expired and helps satisfy a policy, keep searching. - satisfiablePolicy.unsatisfiedCountCleanupTask -= connection.allocationLimit inUseConnectionCount++ - } else { - idleConnectionCount++ - - // If the connection is ready to be evicted, we're done. - if (idleDurationNs > longestIdleDurationNs) { - longestIdleDurationNs = idleDurationNs - longestIdleConnection = connection - policyAffected = satisfiablePolicy - } else { - Unit + return@withLock + } + + val idleAtNs = connection.idleAtNs + + if (idleAtNs < earliestOldIdleAtNs) { + earliestOldIdleAtNs = idleAtNs + earliestOldConnection = connection + } + + if (isEvictable(addressStates, connection)) { + evictableConnectionCount++ + if (idleAtNs < earliestEvictableIdleAtNs) { + earliestEvictableIdleAtNs = idleAtNs + earliestEvictableConnection = connection } } } } + val toEvict: RealConnection? + val toEvictIdleAtNs: Long + when { + // We had at least one OLD connection. Close the oldest one. + earliestOldConnection != null -> { + toEvict = earliestOldConnection + toEvictIdleAtNs = earliestOldIdleAtNs + } + + // We have too many EVICTABLE connections. Close the oldest one. + evictableConnectionCount > maxIdleConnections -> { + toEvict = earliestEvictableConnection + toEvictIdleAtNs = earliestEvictableIdleAtNs + } + + else -> { + toEvict = null + toEvictIdleAtNs = -1L + } + } + when { - longestIdleDurationNs >= this.keepAliveDurationNs || - idleConnectionCount > this.maxIdleConnections -> { + toEvict != null -> { // We've chosen a connection to evict. Confirm it's still okay to be evicted, then close it. - val connection = longestIdleConnection!! - synchronized(connection) { - if (connection.calls.isNotEmpty()) return 0L // No longer idle. - if (connection.idleAtNs + longestIdleDurationNs != now) return 0L // No longer oldest. - connection.noNewExchanges = true - connections.remove(longestIdleConnection) + toEvict.withLock { + if (toEvict.calls.isNotEmpty()) return 0L // No longer idle. + if (toEvict.idleAtNs != toEvictIdleAtNs) return 0L // No longer oldest. + toEvict.noNewExchanges = true + connections.remove(toEvict) } - policyAffected?.schedule() - connection.socket().closeQuietly() - connectionListener.connectionClosed(connection) + addressStates[toEvict.route.address]?.scheduleOpener() + toEvict.socket().closeQuietly() + connectionListener.connectionClosed(toEvict) if (connections.isEmpty()) cleanupQueue.cancelAll() // Clean up again immediately. return 0L } - idleConnectionCount > 0 -> { + earliestEvictableConnection != null -> { // A connection will be ready to evict soon. - return keepAliveDurationNs - longestIdleDurationNs + return earliestEvictableIdleAtNs + keepAliveDurationNs - now } inUseConnectionCount > 0 -> { - // All connections are in use. It'll be at least the keep alive duration 'til we run - // again. + // All connections are in use. It'll be at least the keep alive duration 'til we run again. return keepAliveDurationNs } @@ -280,6 +318,16 @@ class RealConnectionPool( } } + /** Returns true if no address policies prevent [connection] from being evicted. */ + private fun isEvictable( + addressStates: Map, + connection: RealConnection, + ): Boolean { + val addressState = addressStates[connection.route.address] ?: return true + val capacityWithoutIt = addressState.concurrentCallCapacity - connection.allocationLimit + return capacityWithoutIt >= addressState.policy.minimumConcurrentCalls + } + /** * Prunes any leaked calls and then returns the number of remaining live calls on [connection]. * Calls are leaked if the connection is tracking them but the application code has abandoned @@ -289,7 +337,7 @@ class RealConnectionPool( connection: RealConnection, now: Long, ): Int { - connection.assertThreadHoldsLock() + connection.lock.assertHeld() val references = connection.calls var i = 0 @@ -328,27 +376,31 @@ class RealConnectionPool( address: Address, policy: ConnectionPool.AddressPolicy, ) { - val state = MinimumConnectionState(address, taskRunner.newQueue(), policy) - val oldPolicy: ConnectionPool.AddressPolicy? - synchronized(this) { - oldPolicy = policies[address]?.policy - policies = policies + (address to state) + val state = AddressState(address, taskRunner.newQueue(), policy) + val newConnectionsNeeded: Int + + while (true) { + val oldMap = this.addressStates + val newMap = oldMap + (address to state) + if (addressStatesUpdater.compareAndSet(this, oldMap, newMap)) { + val oldPolicyMinimumConcurrentCalls = oldMap[address]?.policy?.minimumConcurrentCalls ?: 0 + newConnectionsNeeded = policy.minimumConcurrentCalls - oldPolicyMinimumConcurrentCalls + break + } } - val newConnectionsNeeded = - policy.minimumConcurrentCalls - (oldPolicy?.minimumConcurrentCalls ?: 0) - if (newConnectionsNeeded > 0) { - state.schedule() - } else if (newConnectionsNeeded < 0) { - scheduleConnectionCloser() + when { + newConnectionsNeeded > 0 -> state.scheduleOpener() + newConnectionsNeeded < 0 -> scheduleCloser() } } - fun scheduleConnectionOpener() { - policies.values.forEach { it.schedule() } + /** Open connections to [address], if required by the address policy. */ + fun scheduleOpener(address: Address) { + addressStates[address]?.scheduleOpener() } - fun scheduleConnectionCloser() { + fun scheduleCloser() { cleanupQueue.schedule(cleanupTask) } @@ -357,35 +409,33 @@ class RealConnectionPool( * If there are already enough connections, we're done. * If not, we create one and then schedule the task to run again immediately. */ - private fun ensureMinimumConnections(state: MinimumConnectionState): Long { + private fun openConnections(state: AddressState): Long { // This policy does not require minimum connections, don't run again - if (state.policy.minimumConcurrentCalls < 1) return -1 - - var unsatisfiedCountMinTask = state.policy.minimumConcurrentCalls + if (state.policy.minimumConcurrentCalls == 0) return -1L + var concurrentCallCapacity = 0 for (connection in connections) { - synchronized(connection) { - if (connection.isEligible(state.address, null)) { - unsatisfiedCountMinTask -= connection.allocationLimit - } + if (state.address != connection.route.address) continue + connection.withLock { + concurrentCallCapacity += connection.allocationLimit } // The policy was satisfied by existing connections, don't run again - if (unsatisfiedCountMinTask < 1) return -1 + if (concurrentCallCapacity >= state.policy.minimumConcurrentCalls) return -1L } // If we got here then the policy was not satisfied -- open a connection! try { - val connection = exchangeFinderFactory(this, state.address, user).find() + val connection = exchangeFinderFactory(this, state.address, PoolConnectionUser).find() // RealRoutePlanner will add the connection to the pool itself, other RoutePlanners may not // TODO: make all RoutePlanners consistent in this behavior if (connection !in connections) { - synchronized(connection) { put(connection) } + connection.withLock { put(connection) } } - return 0 // run again immediately to create more connections if needed - } catch (ex: Exception) { + return 0L // run again immediately to create more connections if needed + } catch (e: IOException) { // No need to log, user.connectFailed() will already have been called. Just try again later. return state.policy.backoffDelayMillis.jitterBy(state.policy.backoffJitterMillis) * 1_000_000 } @@ -395,19 +445,26 @@ class RealConnectionPool( return this + ThreadLocalRandom.current().nextInt(amount * -1, amount) } - class MinimumConnectionState( + class AddressState( val address: Address, val queue: TaskQueue, var policy: ConnectionPool.AddressPolicy, ) { /** - * This field is only ever accessed by the cleanup task, and it tracks - * how many concurrent calls are already satisfied by existing connections. + * How many calls the pool can carry without opening new connections. This field must only be + * accessed by the connection closer task. */ - var unsatisfiedCountCleanupTask: Int = 0 + var concurrentCallCapacity: Int = 0 } companion object { fun get(connectionPool: ConnectionPool): RealConnectionPool = connectionPool.delegate + + private var addressStatesUpdater = + AtomicReferenceFieldUpdater.newUpdater( + RealConnectionPool::class.java, + Map::class.java, + "addressStates", + ) } } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/RealRoutePlanner.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealRoutePlanner.kt similarity index 99% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/RealRoutePlanner.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealRoutePlanner.kt index 3684a19da56c..e49564bcd722 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/connection/RealRoutePlanner.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealRoutePlanner.kt @@ -30,6 +30,7 @@ import okhttp3.internal.USER_AGENT import okhttp3.internal.canReuseConnectionFor import okhttp3.internal.closeQuietly import okhttp3.internal.concurrent.TaskRunner +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.connection.RoutePlanner.Plan import okhttp3.internal.platform.Platform import okhttp3.internal.toHostHeader @@ -94,7 +95,7 @@ class RealRoutePlanner( val healthy = candidate.isHealthy(connectionUser.doExtensiveHealthChecks()) var noNewExchangesEvent = false val toClose: Socket? = - synchronized(candidate) { + candidate.withLock { when { !healthy -> { noNewExchangesEvent = !candidate.noNewExchanges @@ -319,7 +320,7 @@ class RealRoutePlanner( * connections. */ private fun retryRoute(connection: RealConnection): Route? { - return synchronized(connection) { + return connection.withLock { when { connection.routeFailureCount != 0 -> null diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/RetryTlsHandshake.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RetryTlsHandshake.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/RetryTlsHandshake.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RetryTlsHandshake.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/ReusePlan.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ReusePlan.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/ReusePlan.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/ReusePlan.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/RouteDatabase.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RouteDatabase.kt similarity index 93% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/RouteDatabase.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RouteDatabase.kt index 920ab5920e77..fe9c91bbd901 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/connection/RouteDatabase.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RouteDatabase.kt @@ -18,7 +18,7 @@ package okhttp3.internal.connection import okhttp3.Route /** - * A blacklist of failed routes to avoid when creating a new connection to a target address. This is + * A denylist of failed routes to avoid when creating a new connection to a target address. This is * used so that OkHttp can learn from its mistakes: if there was a failure attempting to connect to * a specific IP address or proxy server, that failure is remembered and alternate routes are * preferred. diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/RoutePlanner.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RoutePlanner.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/RoutePlanner.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RoutePlanner.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/RouteSelector.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RouteSelector.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/RouteSelector.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RouteSelector.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/SequentialExchangeFinder.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/SequentialExchangeFinder.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/connection/SequentialExchangeFinder.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/SequentialExchangeFinder.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/BridgeInterceptor.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/BridgeInterceptor.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http/BridgeInterceptor.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/BridgeInterceptor.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/CallServerInterceptor.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/CallServerInterceptor.kt similarity index 98% rename from okhttp/src/main/kotlin/okhttp3/internal/http/CallServerInterceptor.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/CallServerInterceptor.kt index 9c7a60d49d15..324324f17a5e 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/http/CallServerInterceptor.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/CallServerInterceptor.kt @@ -105,7 +105,7 @@ class CallServerInterceptor(private val forWebSocket: Boolean) : Interceptor { .build() var code = response.code - if (shouldIgnoreAndWaitForRealResponse(code, exchange)) { + while (shouldIgnoreAndWaitForRealResponse(code, exchange)) { responseBuilder = exchange.readResponseHeaders(expectContinue = false)!! if (invokeStartEvent) { exchange.responseHeadersStart() diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/DateFormatting.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/DateFormatting.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http/DateFormatting.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/DateFormatting.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/ExchangeCodec.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/ExchangeCodec.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http/ExchangeCodec.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/ExchangeCodec.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/HttpHeaders.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/HttpHeaders.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http/HttpHeaders.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/HttpHeaders.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/HttpMethod.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/HttpMethod.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http/HttpMethod.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/HttpMethod.kt diff --git a/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/HttpStatusCodes.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/HttpStatusCodes.kt new file mode 100644 index 000000000000..d8a3fcce575d --- /dev/null +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/HttpStatusCodes.kt @@ -0,0 +1,51 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package okhttp3.internal.http + +// HTTP Status Codes not offered by HttpUrlConnection. +// +// https://datatracker.ietf.org/doc/html/rfc7231#page-47 +// +// From https://github.com/apache/httpcomponents-core/blob/master/httpcore5/src/main/java/org/apache/hc/core5/http/HttpStatus.java + +/** `100 Continue` (HTTP/1.1 - RFC 7231) */ +const val HTTP_CONTINUE = 100 + +/** `102 Processing` (WebDAV - RFC 2518) */ +const val HTTP_PROCESSING = 102 + +/** `103 Early Hints (Early Hints - RFC 8297)` */ +const val HTTP_EARLY_HINTS = 103 + +/** `307 Temporary Redirect` (HTTP/1.1 - RFC 7231) */ +const val HTTP_TEMP_REDIRECT = 307 + +/** `308 Permanent Redirect` (HTTP/1.1 - RFC 7538) */ +const val HTTP_PERM_REDIRECT = 308 + +/** `421 Misdirected Request` (HTTP/2 - RFC 7540) */ +const val HTTP_MISDIRECTED_REQUEST = 421 diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/RealInterceptorChain.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RealInterceptorChain.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http/RealInterceptorChain.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RealInterceptorChain.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/RealResponseBody.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RealResponseBody.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http/RealResponseBody.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RealResponseBody.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/RequestLine.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RequestLine.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http/RequestLine.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RequestLine.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/RetryAndFollowUpInterceptor.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RetryAndFollowUpInterceptor.kt similarity index 96% rename from okhttp/src/main/kotlin/okhttp3/internal/http/RetryAndFollowUpInterceptor.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RetryAndFollowUpInterceptor.kt index c7a3b4c5dea1..5dee0446f853 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/http/RetryAndFollowUpInterceptor.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RetryAndFollowUpInterceptor.kt @@ -18,6 +18,14 @@ package okhttp3.internal.http import java.io.FileNotFoundException import java.io.IOException import java.io.InterruptedIOException +import java.net.HttpURLConnection.HTTP_CLIENT_TIMEOUT +import java.net.HttpURLConnection.HTTP_MOVED_PERM +import java.net.HttpURLConnection.HTTP_MOVED_TEMP +import java.net.HttpURLConnection.HTTP_MULT_CHOICE +import java.net.HttpURLConnection.HTTP_PROXY_AUTH +import java.net.HttpURLConnection.HTTP_SEE_OTHER +import java.net.HttpURLConnection.HTTP_UNAUTHORIZED +import java.net.HttpURLConnection.HTTP_UNAVAILABLE import java.net.ProtocolException import java.net.Proxy import java.net.SocketTimeoutException diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/StatusLine.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/StatusLine.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http/StatusLine.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/StatusLine.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http1/HeadersReader.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http1/HeadersReader.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http1/HeadersReader.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http1/HeadersReader.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/ConnectionShutdownException.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/ConnectionShutdownException.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/ConnectionShutdownException.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/ConnectionShutdownException.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/ErrorCode.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/ErrorCode.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/ErrorCode.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/ErrorCode.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/FlowControlListener.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/FlowControlListener.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/FlowControlListener.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/FlowControlListener.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/Header.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Header.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/Header.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Header.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/Hpack.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Hpack.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/Hpack.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Hpack.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/Http2.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/Http2.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/Http2Connection.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Connection.kt similarity index 93% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/Http2Connection.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Connection.kt index 686568d3d0fd..eac412033736 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/http2/Http2Connection.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Connection.kt @@ -20,22 +20,24 @@ import java.io.IOException import java.io.InterruptedIOException import java.net.Socket import java.util.concurrent.TimeUnit +import java.util.concurrent.locks.Condition +import java.util.concurrent.locks.ReentrantLock import okhttp3.internal.EMPTY_BYTE_ARRAY import okhttp3.internal.EMPTY_HEADERS import okhttp3.internal.assertThreadDoesntHoldLock import okhttp3.internal.closeQuietly import okhttp3.internal.concurrent.TaskRunner +import okhttp3.internal.connection.Locks.newLockCondition +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.http2.ErrorCode.REFUSED_STREAM import okhttp3.internal.http2.Settings.Companion.DEFAULT_INITIAL_WINDOW_SIZE import okhttp3.internal.http2.flowcontrol.WindowCounter import okhttp3.internal.ignoreIoExceptions -import okhttp3.internal.notifyAll import okhttp3.internal.okHttpName import okhttp3.internal.peerName import okhttp3.internal.platform.Platform import okhttp3.internal.platform.Platform.Companion.INFO import okhttp3.internal.toHeaders -import okhttp3.internal.wait import okio.Buffer import okio.BufferedSink import okio.BufferedSource @@ -54,7 +56,10 @@ import okio.source */ @Suppress("NAME_SHADOWING") class Http2Connection internal constructor(builder: Builder) : Closeable { - // Internal state of this connection is guarded by 'this'. No blocking operations may be + internal val lock: ReentrantLock = ReentrantLock() + internal val condition: Condition = lock.newLockCondition() + + // Internal state of this connection is guarded by 'lock'. No blocking operations may be // performed while holding this lock! // // Socket writes are guarded by frameWriter. @@ -149,12 +154,12 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { val pingIntervalNanos = TimeUnit.MILLISECONDS.toNanos(builder.pingIntervalMillis.toLong()) writerQueue.schedule("$connectionName ping", pingIntervalNanos) { val failDueToMissingPong = - synchronized(this@Http2Connection) { + this.withLock { if (intervalPongsReceived < intervalPingsSent) { - return@synchronized true + return@withLock true } else { intervalPingsSent++ - return@synchronized false + return@withLock false } } if (failDueToMissingPong) { @@ -171,30 +176,31 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { /** * Returns the number of [open streams][Http2Stream.isOpen] on this connection. */ - @Synchronized - fun openStreamCount(): Int = streams.size + fun openStreamCount(): Int = this.withLock { streams.size } - @Synchronized - fun getStream(id: Int): Http2Stream? = streams[id] + fun getStream(id: Int): Http2Stream? = this.withLock { streams[id] } - @Synchronized internal fun removeStream(streamId: Int): Http2Stream? { - val stream = streams.remove(streamId) + this.withLock { + val stream = streams.remove(streamId) - // The removed stream may be blocked on a connection-wide window update. - notifyAll() + // The removed stream may be blocked on a connection-wide window update. + condition.signalAll() - return stream + return stream + } } - @Synchronized internal fun updateConnectionFlowControl(read: Long) { - readBytes.update(total = read) - val readBytesToAcknowledge = readBytes.unacknowledged - if (readBytesToAcknowledge >= okHttpSettings.initialWindowSize / 2) { - writeWindowUpdateLater(0, readBytesToAcknowledge) - readBytes.update(acknowledged = readBytesToAcknowledge) + internal fun updateConnectionFlowControl(read: Long) { + this.withLock { + readBytes.update(total = read) + val readBytesToAcknowledge = readBytes.unacknowledged + if (readBytesToAcknowledge >= okHttpSettings.initialWindowSize / 2) { + writeWindowUpdateLater(0, readBytesToAcknowledge) + readBytes.update(acknowledged = readBytesToAcknowledge) + } + flowControlListener.receivingConnectionWindowChanged(readBytes) } - flowControlListener.receivingConnectionWindowChanged(readBytes) } /** @@ -240,8 +246,8 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { val stream: Http2Stream val streamId: Int - synchronized(writer) { - synchronized(this) { + writer.withLock { + this.withLock { if (nextStreamId > Int.MAX_VALUE / 2) { shutdown(REFUSED_STREAM) } @@ -311,7 +317,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { var byteCount = byteCount while (byteCount > 0L) { var toWrite: Int - synchronized(this@Http2Connection) { + this.withLock { try { while (writeBytesTotal >= writeBytesMaximum) { // Before blocking, confirm that the stream we're writing is still open. It's possible @@ -319,7 +325,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { if (!streams.containsKey(streamId)) { throw IOException("stream closed") } - this@Http2Connection.wait() // Wait until we receive a WINDOW_UPDATE. + condition.await() // Wait until we receive a WINDOW_UPDATE. } } catch (e: InterruptedException) { Thread.currentThread().interrupt() // Retain interrupted status. @@ -392,7 +398,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { /** For testing: sends a ping to be awaited with [awaitPong]. */ @Throws(InterruptedException::class) fun writePing() { - synchronized(this) { + this.withLock { awaitPingsSent++ } @@ -401,11 +407,12 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { } /** For testing: awaits a pong. */ - @Synchronized @Throws(InterruptedException::class) fun awaitPong() { - while (awaitPongsReceived < awaitPingsSent) { - wait() + this.withLock { + while (awaitPongsReceived < awaitPingsSent) { + condition.await() + } } } @@ -421,9 +428,9 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { */ @Throws(IOException::class) fun shutdown(statusCode: ErrorCode) { - synchronized(writer) { + writer.withLock { val lastGoodStreamId: Int - synchronized(this) { + this.withLock { if (isShutdown) { return } @@ -456,7 +463,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { } var streamsToClose: Array? = null - synchronized(this) { + this.withLock { if (streams.isNotEmpty()) { streamsToClose = streams.values.toTypedArray() streams.clear() @@ -516,8 +523,8 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { /** Merges [settings] into this peer's settings and sends them to the remote peer. */ @Throws(IOException::class) fun setSettings(settings: Settings) { - synchronized(writer) { - synchronized(this) { + writer.withLock { + this.withLock { if (isShutdown) { throw ConnectionShutdownException() } @@ -527,14 +534,15 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { } } - @Synchronized fun isHealthy(nowNs: Long): Boolean { - if (isShutdown) return false + this.withLock { + if (isShutdown) return false - // A degraded pong is overdue. - if (degradedPongsReceived < degradedPingsSent && nowNs >= degradedPongDeadlineNs) return false + // A degraded pong is overdue. + if (degradedPongsReceived < degradedPingsSent && nowNs >= degradedPongDeadlineNs) return false - return true + return true + } } /** @@ -553,7 +561,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { * The deadline is currently hardcoded. We may make this configurable in the future! */ internal fun sendDegradedPingLater() { - synchronized(this) { + this.withLock { if (degradedPongsReceived < degradedPingsSent) return // Already awaiting a degraded pong. degradedPingsSent++ degradedPongDeadlineNs = System.nanoTime() + DEGRADED_PONG_TIMEOUT_NS @@ -682,7 +690,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { return } val stream: Http2Stream? - synchronized(this@Http2Connection) { + this@Http2Connection.withLock { stream = getStream(streamId) if (stream == null) { @@ -761,8 +769,8 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { var delta: Long var streamsToNotify: Array? var newPeerSettings: Settings - synchronized(writer) { - synchronized(this@Http2Connection) { + writer.withLock { + this@Http2Connection.withLock { val previousPeerSettings = peerSettings newPeerSettings = if (clearPrevious) { @@ -796,7 +804,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { } if (streamsToNotify != null) { for (stream in streamsToNotify!!) { - synchronized(stream) { + stream.withLock { stream.addBytesToWriteWindow(delta) } } @@ -813,7 +821,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { payload2: Int, ) { if (ack) { - synchronized(this@Http2Connection) { + this@Http2Connection.withLock { when (payload1) { INTERVAL_PING -> { intervalPongsReceived++ @@ -823,7 +831,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { } AWAIT_PING -> { awaitPongsReceived++ - this@Http2Connection.notifyAll() + condition.signalAll() } else -> { // Ignore an unexpected pong. @@ -849,7 +857,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { // Copy the streams first. We don't want to hold a lock when we call receiveRstStream(). val streamsCopy: Array - synchronized(this@Http2Connection) { + this@Http2Connection.withLock { streamsCopy = streams.values.toTypedArray() isShutdown = true } @@ -868,14 +876,14 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { windowSizeIncrement: Long, ) { if (streamId == 0) { - synchronized(this@Http2Connection) { + this@Http2Connection.withLock { writeBytesMaximum += windowSizeIncrement - this@Http2Connection.notifyAll() + condition.signalAll() } } else { val stream = getStream(streamId) if (stream != null) { - synchronized(stream) { + stream.withLock { stream.addBytesToWriteWindow(windowSizeIncrement) } } @@ -918,7 +926,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { streamId: Int, requestHeaders: List
, ) { - synchronized(this) { + this.withLock { if (streamId in currentPushRequests) { writeSynResetLater(streamId, ErrorCode.PROTOCOL_ERROR) return @@ -930,7 +938,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { ignoreIoExceptions { if (cancel) { writer.rstStream(streamId, ErrorCode.CANCEL) - synchronized(this@Http2Connection) { + this.withLock { currentPushRequests.remove(streamId) } } @@ -948,7 +956,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { ignoreIoExceptions { if (cancel) writer.rstStream(streamId, ErrorCode.CANCEL) if (cancel || inFinished) { - synchronized(this@Http2Connection) { + this.withLock { currentPushRequests.remove(streamId) } } @@ -975,7 +983,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { val cancel = pushObserver.onData(streamId, buffer, byteCount, inFinished) if (cancel) writer.rstStream(streamId, ErrorCode.CANCEL) if (cancel || inFinished) { - synchronized(this@Http2Connection) { + this.withLock { currentPushRequests.remove(streamId) } } @@ -989,7 +997,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable { ) { pushQueue.execute("$connectionName[$streamId] onReset") { pushObserver.onReset(streamId, errorCode) - synchronized(this@Http2Connection) { + this.withLock { currentPushRequests.remove(streamId) } } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/Http2ExchangeCodec.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2ExchangeCodec.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/Http2ExchangeCodec.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2ExchangeCodec.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/Http2Reader.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Reader.kt similarity index 99% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/Http2Reader.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Reader.kt index 38e7c685ba0a..cc8a4cc11486 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/http2/Http2Reader.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Reader.kt @@ -261,7 +261,7 @@ class Http2Reader( if (length % 6 != 0) throw IOException("TYPE_SETTINGS length % 6 != 0: $length") val settings = Settings() for (i in 0 until length step 6) { - var id = source.readShort() and 0xffff + val id = source.readShort() and 0xffff val value = source.readInt() when (id) { @@ -277,11 +277,11 @@ class Http2Reader( } // SETTINGS_MAX_CONCURRENT_STREAMS - 3 -> id = 4 // Renumbered in draft 10. + 3 -> { + } // SETTINGS_INITIAL_WINDOW_SIZE 4 -> { - id = 7 // Renumbered in draft 10. if (value < 0) { throw IOException("PROTOCOL_ERROR SETTINGS_INITIAL_WINDOW_SIZE > 2^31 - 1") } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/Http2Stream.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Stream.kt similarity index 88% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/Http2Stream.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Stream.kt index dd1fa1e49584..fcabc4d2ca5c 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/http2/Http2Stream.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Stream.kt @@ -20,13 +20,15 @@ import java.io.IOException import java.io.InterruptedIOException import java.net.SocketTimeoutException import java.util.ArrayDeque +import java.util.concurrent.locks.Condition +import java.util.concurrent.locks.ReentrantLock import okhttp3.Headers import okhttp3.internal.EMPTY_HEADERS -import okhttp3.internal.assertThreadDoesntHoldLock +import okhttp3.internal.assertNotHeld +import okhttp3.internal.connection.Locks.newLockCondition +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.http2.flowcontrol.WindowCounter -import okhttp3.internal.notifyAll import okhttp3.internal.toHeaderList -import okhttp3.internal.wait import okio.AsyncTimeout import okio.Buffer import okio.BufferedSource @@ -43,7 +45,10 @@ class Http2Stream internal constructor( inFinished: Boolean, headers: Headers?, ) { - // Internal state is guarded by this. No long-running or potentially blocking operations are + internal val lock: ReentrantLock = ReentrantLock() + val condition: Condition = lock.newLockCondition() + + // Internal state is guarded by [lock]. No long-running or potentially blocking operations are // performed while the lock is held. /** The bytes consumed and acknowledged by the stream. */ @@ -82,7 +87,8 @@ class Http2Stream internal constructor( * If there are multiple reasons to abnormally close this stream (such as both peers closing it * near-simultaneously) then this is the first reason known to this peer. */ - @get:Synchronized internal var errorCode: ErrorCode? = null + internal var errorCode: ErrorCode? = null + get() = this.withLock { field } /** The exception that explains [errorCode]. Null if no exception was provided. */ internal var errorException: IOException? = null @@ -106,17 +112,19 @@ class Http2Stream internal constructor( * not open. This is because input data is buffered. */ val isOpen: Boolean - @Synchronized get() { - if (errorCode != null) { - return false - } - if ((source.finished || source.closed) && - (sink.finished || sink.closed) && - hasResponseHeaders - ) { - return false + get() { + this.withLock { + if (errorCode != null) { + return false + } + if ((source.finished || source.closed) && + (sink.finished || sink.closed) && + hasResponseHeaders + ) { + return false + } + return true } - return true } /** Returns true if this stream was created by this peer. */ @@ -135,42 +143,44 @@ class Http2Stream internal constructor( * This is true after a `Expect-Continue` request, false for duplex requests, and false for * all other requests. */ - @Synchronized @Throws(IOException::class) fun takeHeaders(callerIsIdle: Boolean = false): Headers { - while (headersQueue.isEmpty() && errorCode == null) { - val doReadTimeout = callerIsIdle || doReadTimeout() - if (doReadTimeout) { - readTimeout.enter() - } - try { - waitForIo() - } finally { + this.withLock { + while (headersQueue.isEmpty() && errorCode == null) { + val doReadTimeout = callerIsIdle || doReadTimeout() if (doReadTimeout) { - readTimeout.exitAndThrowIfTimedOut() + readTimeout.enter() + } + try { + waitForIo() + } finally { + if (doReadTimeout) { + readTimeout.exitAndThrowIfTimedOut() + } } } + if (headersQueue.isNotEmpty()) { + return headersQueue.removeFirst() + } + throw errorException ?: StreamResetException(errorCode!!) } - if (headersQueue.isNotEmpty()) { - return headersQueue.removeFirst() - } - throw errorException ?: StreamResetException(errorCode!!) } /** * Returns the trailers. It is only safe to call this once the source stream has been completely * exhausted. */ - @Synchronized @Throws(IOException::class) fun trailers(): Headers { - if (source.finished && source.receiveBuffer.exhausted() && source.readBuffer.exhausted()) { - return source.trailers ?: EMPTY_HEADERS - } - if (errorCode != null) { - throw errorException ?: StreamResetException(errorCode!!) + this.withLock { + if (source.finished && source.receiveBuffer.exhausted() && source.readBuffer.exhausted()) { + return source.trailers ?: EMPTY_HEADERS + } + if (errorCode != null) { + throw errorException ?: StreamResetException(errorCode!!) + } + throw IllegalStateException("too early; can't read the trailers yet") } - throw IllegalStateException("too early; can't read the trailers yet") } /** @@ -187,21 +197,21 @@ class Http2Stream internal constructor( outFinished: Boolean, flushHeaders: Boolean, ) { - this@Http2Stream.assertThreadDoesntHoldLock() + lock.assertNotHeld() var flushHeaders = flushHeaders - synchronized(this) { + this.withLock { this.hasResponseHeaders = true if (outFinished) { this.sink.finished = true - this@Http2Stream.notifyAll() // Because doReadTimeout() may have changed. + condition.signalAll() // Because doReadTimeout() may have changed. } } // Only DATA frames are subject to flow-control. Transmit the HEADER frame if the connection // flow-control window is fully depleted. if (!flushHeaders) { - synchronized(connection) { + this.withLock { flushHeaders = (connection.writeBytesTotal >= connection.writeBytesMaximum) } } @@ -214,7 +224,7 @@ class Http2Stream internal constructor( } fun enqueueTrailers(trailers: Headers) { - synchronized(this) { + this.withLock { check(!sink.finished) { "already finished" } require(trailers.size != 0) { "trailers.size() == 0" } this.sink.trailers = trailers @@ -235,7 +245,7 @@ class Http2Stream internal constructor( * not yet been sent. */ fun getSink(): Sink { - synchronized(this) { + this.withLock { check(hasResponseHeaders || isLocallyInitiated) { "reply before requesting the sink" } @@ -273,15 +283,15 @@ class Http2Stream internal constructor( errorCode: ErrorCode, errorException: IOException?, ): Boolean { - this.assertThreadDoesntHoldLock() + lock.assertNotHeld() - synchronized(this) { + this.withLock { if (this.errorCode != null) { return false } this.errorCode = errorCode this.errorException = errorException - notifyAll() + condition.signalAll() if (source.finished && sink.finished) { return false } @@ -295,7 +305,7 @@ class Http2Stream internal constructor( source: BufferedSource, length: Int, ) { - this@Http2Stream.assertThreadDoesntHoldLock() + lock.assertNotHeld() this.source.receive(source, length.toLong()) } @@ -305,10 +315,10 @@ class Http2Stream internal constructor( headers: Headers, inFinished: Boolean, ) { - this@Http2Stream.assertThreadDoesntHoldLock() + lock.assertNotHeld() val open: Boolean - synchronized(this) { + this.withLock { if (!hasResponseHeaders || headers[Header.RESPONSE_STATUS_UTF8] != null || headers[Header.TARGET_METHOD_UTF8] != null @@ -322,17 +332,19 @@ class Http2Stream internal constructor( this.source.finished = true } open = isOpen - notifyAll() + condition.signalAll() } if (!open) { connection.removeStream(id) } } - @Synchronized fun receiveRstStream(errorCode: ErrorCode) { - if (this.errorCode == null) { - this.errorCode = errorCode - notifyAll() + fun receiveRstStream(errorCode: ErrorCode) { + this.withLock { + if (this.errorCode == null) { + this.errorCode = errorCode + condition.signalAll() + } } } @@ -389,7 +401,7 @@ class Http2Stream internal constructor( // 1. Decide what to do in a synchronized block. - synchronized(this@Http2Stream) { + this@Http2Stream.withLock { val doReadTimeout = doReadTimeout() if (doReadTimeout) { readTimeout.enter() @@ -452,7 +464,7 @@ class Http2Stream internal constructor( } private fun updateConnectionFlowControl(read: Long) { - this@Http2Stream.assertThreadDoesntHoldLock() + lock.assertNotHeld() connection.updateConnectionFlowControl(read) } @@ -466,14 +478,14 @@ class Http2Stream internal constructor( source: BufferedSource, byteCount: Long, ) { - this@Http2Stream.assertThreadDoesntHoldLock() + lock.assertNotHeld() var remainingByteCount = byteCount while (remainingByteCount > 0L) { val finished: Boolean val flowControlError: Boolean - synchronized(this@Http2Stream) { + this@Http2Stream.withLock { finished = this.finished flowControlError = remainingByteCount + readBuffer.size > maxByteCount } @@ -499,14 +511,14 @@ class Http2Stream internal constructor( // Move the received data to the read buffer to the reader can read it. If this source has // been closed since this read began we must discard the incoming data and tell the // connection we've done so. - synchronized(this@Http2Stream) { + this@Http2Stream.withLock { if (closed) { receiveBuffer.clear() } else { val wasEmpty = readBuffer.size == 0L readBuffer.writeAll(receiveBuffer) if (wasEmpty) { - this@Http2Stream.notifyAll() + condition.signalAll() } } } @@ -527,11 +539,11 @@ class Http2Stream internal constructor( @Throws(IOException::class) override fun close() { val bytesDiscarded: Long - synchronized(this@Http2Stream) { + this@Http2Stream.withLock { closed = true bytesDiscarded = readBuffer.size readBuffer.clear() - this@Http2Stream.notifyAll() // TODO(jwilson): Unnecessary? + condition.signalAll() // TODO(jwilson): Unnecessary? } if (bytesDiscarded > 0L) { updateConnectionFlowControl(bytesDiscarded) @@ -542,11 +554,11 @@ class Http2Stream internal constructor( @Throws(IOException::class) internal fun cancelStreamIfNecessary() { - this@Http2Stream.assertThreadDoesntHoldLock() + lock.assertNotHeld() val open: Boolean val cancel: Boolean - synchronized(this) { + this.withLock { cancel = !source.finished && source.closed && (sink.finished || sink.closed) open = isOpen } @@ -581,7 +593,7 @@ class Http2Stream internal constructor( source: Buffer, byteCount: Long, ) { - this@Http2Stream.assertThreadDoesntHoldLock() + lock.assertNotHeld() sendBuffer.write(source, byteCount) while (sendBuffer.size >= EMIT_BUFFER_SIZE) { @@ -597,7 +609,7 @@ class Http2Stream internal constructor( private fun emitFrame(outFinishedOnLastFrame: Boolean) { val toWrite: Long val outFinished: Boolean - synchronized(this@Http2Stream) { + this@Http2Stream.withLock { writeTimeout.enter() try { while (writeBytesTotal >= writeBytesMaximum && @@ -627,9 +639,9 @@ class Http2Stream internal constructor( @Throws(IOException::class) override fun flush() { - this@Http2Stream.assertThreadDoesntHoldLock() + lock.assertNotHeld() - synchronized(this@Http2Stream) { + this@Http2Stream.withLock { checkOutNotClosed() } // TODO(jwilson): flush the connection?! @@ -643,10 +655,10 @@ class Http2Stream internal constructor( @Throws(IOException::class) override fun close() { - this@Http2Stream.assertThreadDoesntHoldLock() + lock.assertNotHeld() val outFinished: Boolean - synchronized(this@Http2Stream) { + this@Http2Stream.withLock { if (closed) return outFinished = errorCode == null } @@ -675,9 +687,9 @@ class Http2Stream internal constructor( } } } - synchronized(this@Http2Stream) { + this@Http2Stream.withLock { closed = true - this@Http2Stream.notifyAll() // Because doReadTimeout() may have changed. + condition.signalAll() // Because doReadTimeout() may have changed. } connection.flush() cancelStreamIfNecessary() @@ -692,7 +704,7 @@ class Http2Stream internal constructor( fun addBytesToWriteWindow(delta: Long) { writeBytesMaximum += delta if (delta > 0L) { - this@Http2Stream.notifyAll() + condition.signalAll() } } @@ -712,7 +724,7 @@ class Http2Stream internal constructor( @Throws(InterruptedIOException::class) internal fun waitForIo() { try { - wait() + condition.await() } catch (_: InterruptedException) { Thread.currentThread().interrupt() // Retain interrupted status. throw InterruptedIOException() diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/Http2Writer.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Writer.kt similarity index 59% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/Http2Writer.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Writer.kt index ff72536e9b49..ca8de63c9598 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/http2/Http2Writer.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Writer.kt @@ -17,8 +17,10 @@ package okhttp3.internal.http2 import java.io.Closeable import java.io.IOException +import java.util.concurrent.locks.ReentrantLock import java.util.logging.Level.FINE import java.util.logging.Logger +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.format import okhttp3.internal.http2.Http2.CONNECTION_PREFACE import okhttp3.internal.http2.Http2.FLAG_ACK @@ -47,39 +49,43 @@ class Http2Writer( private val sink: BufferedSink, private val client: Boolean, ) : Closeable { + internal val lock: ReentrantLock = ReentrantLock() + private val hpackBuffer: Buffer = Buffer() private var maxFrameSize: Int = INITIAL_MAX_FRAME_SIZE private var closed: Boolean = false val hpackWriter: Hpack.Writer = Hpack.Writer(out = hpackBuffer) - @Synchronized @Throws(IOException::class) fun connectionPreface() { - if (closed) throw IOException("closed") - if (!client) return // Nothing to write; servers don't send connection headers! - if (logger.isLoggable(FINE)) { - logger.fine(format(">> CONNECTION ${CONNECTION_PREFACE.hex()}")) + this.withLock { + if (closed) throw IOException("closed") + if (!client) return // Nothing to write; servers don't send connection headers! + if (logger.isLoggable(FINE)) { + logger.fine(format(">> CONNECTION ${CONNECTION_PREFACE.hex()}")) + } + sink.write(CONNECTION_PREFACE) + sink.flush() } - sink.write(CONNECTION_PREFACE) - sink.flush() } /** Applies `peerSettings` and then sends a settings ACK. */ - @Synchronized @Throws(IOException::class) fun applyAndAckSettings(peerSettings: Settings) { - if (closed) throw IOException("closed") - this.maxFrameSize = peerSettings.getMaxFrameSize(maxFrameSize) - if (peerSettings.headerTableSize != -1) { - hpackWriter.resizeHeaderTable(peerSettings.headerTableSize) + this.withLock { + if (closed) throw IOException("closed") + this.maxFrameSize = peerSettings.getMaxFrameSize(maxFrameSize) + if (peerSettings.headerTableSize != -1) { + hpackWriter.resizeHeaderTable(peerSettings.headerTableSize) + } + frameHeader( + streamId = 0, + length = 0, + type = TYPE_SETTINGS, + flags = FLAG_ACK, + ) + sink.flush() } - frameHeader( - streamId = 0, - length = 0, - type = TYPE_SETTINGS, - flags = FLAG_ACK, - ) - sink.flush() } /** @@ -94,54 +100,57 @@ class Http2Writer( * @param promisedStreamId server-initiated stream ID. Must be an even number. * @param requestHeaders minimally includes `:method`, `:scheme`, `:authority`, and `:path`. */ - @Synchronized @Throws(IOException::class) fun pushPromise( streamId: Int, promisedStreamId: Int, requestHeaders: List
, ) { - if (closed) throw IOException("closed") - hpackWriter.writeHeaders(requestHeaders) + this.withLock { + if (closed) throw IOException("closed") + hpackWriter.writeHeaders(requestHeaders) - val byteCount = hpackBuffer.size - val length = minOf(maxFrameSize - 4L, byteCount).toInt() - frameHeader( - streamId = streamId, - length = length + 4, - type = TYPE_PUSH_PROMISE, - flags = if (byteCount == length.toLong()) FLAG_END_HEADERS else 0, - ) - sink.writeInt(promisedStreamId and 0x7fffffff) - sink.write(hpackBuffer, length.toLong()) + val byteCount = hpackBuffer.size + val length = minOf(maxFrameSize - 4L, byteCount).toInt() + frameHeader( + streamId = streamId, + length = length + 4, + type = TYPE_PUSH_PROMISE, + flags = if (byteCount == length.toLong()) FLAG_END_HEADERS else 0, + ) + sink.writeInt(promisedStreamId and 0x7fffffff) + sink.write(hpackBuffer, length.toLong()) - if (byteCount > length) writeContinuationFrames(streamId, byteCount - length) + if (byteCount > length) writeContinuationFrames(streamId, byteCount - length) + } } - @Synchronized @Throws(IOException::class) fun flush() { - if (closed) throw IOException("closed") - sink.flush() + this.withLock { + if (closed) throw IOException("closed") + sink.flush() + } } - @Synchronized @Throws(IOException::class) fun rstStream( streamId: Int, errorCode: ErrorCode, ) { - if (closed) throw IOException("closed") - require(errorCode.httpCode != -1) + this.withLock { + if (closed) throw IOException("closed") + require(errorCode.httpCode != -1) - frameHeader( - streamId = streamId, - length = 4, - type = TYPE_RST_STREAM, - flags = FLAG_NONE, - ) - sink.writeInt(errorCode.httpCode) - sink.flush() + frameHeader( + streamId = streamId, + length = 4, + type = TYPE_RST_STREAM, + flags = FLAG_NONE, + ) + sink.writeInt(errorCode.httpCode) + sink.flush() + } } /** The maximum size of bytes that may be sent in a single call to [data]. */ @@ -154,7 +163,6 @@ class Http2Writer( * @param source the buffer to draw bytes from. May be null if byteCount is 0. * @param byteCount must be between 0 and the minimum of `source.length` and [maxDataLength]. */ - @Synchronized @Throws(IOException::class) fun data( outFinished: Boolean, @@ -162,10 +170,12 @@ class Http2Writer( source: Buffer?, byteCount: Int, ) { - if (closed) throw IOException("closed") - var flags = FLAG_NONE - if (outFinished) flags = flags or FLAG_END_STREAM - dataFrame(streamId, flags, source, byteCount) + this.withLock { + if (closed) throw IOException("closed") + var flags = FLAG_NONE + if (outFinished) flags = flags or FLAG_END_STREAM + dataFrame(streamId, flags, source, byteCount) + } } @Throws(IOException::class) @@ -187,51 +197,47 @@ class Http2Writer( } /** Write okhttp's settings to the peer. */ - @Synchronized @Throws(IOException::class) fun settings(settings: Settings) { - if (closed) throw IOException("closed") - frameHeader( - streamId = 0, - length = settings.size() * 6, - type = TYPE_SETTINGS, - flags = FLAG_NONE, - ) - for (i in 0 until Settings.COUNT) { - if (!settings.isSet(i)) continue - val id = - when (i) { - 4 -> 3 // SETTINGS_MAX_CONCURRENT_STREAMS renumbered. - 7 -> 4 // SETTINGS_INITIAL_WINDOW_SIZE renumbered. - else -> i - } - sink.writeShort(id) - sink.writeInt(settings[i]) + this.withLock { + if (closed) throw IOException("closed") + frameHeader( + streamId = 0, + length = settings.size() * 6, + type = TYPE_SETTINGS, + flags = FLAG_NONE, + ) + for (i in 0 until Settings.COUNT) { + if (!settings.isSet(i)) continue + sink.writeShort(i) + sink.writeInt(settings[i]) + } + sink.flush() } - sink.flush() } /** * Send a connection-level ping to the peer. `ack` indicates this is a reply. The data in * `payload1` and `payload2` opaque binary, and there are no rules on the content. */ - @Synchronized @Throws(IOException::class) fun ping( ack: Boolean, payload1: Int, payload2: Int, ) { - if (closed) throw IOException("closed") - frameHeader( - streamId = 0, - length = 8, - type = TYPE_PING, - flags = if (ack) FLAG_ACK else FLAG_NONE, - ) - sink.writeInt(payload1) - sink.writeInt(payload2) - sink.flush() + this.withLock { + if (closed) throw IOException("closed") + frameHeader( + streamId = 0, + length = 8, + type = TYPE_PING, + flags = if (ack) FLAG_ACK else FLAG_NONE, + ) + sink.writeInt(payload1) + sink.writeInt(payload2) + sink.flush() + } } /** @@ -242,61 +248,63 @@ class Http2Writer( * @param errorCode reason for closing the connection. * @param debugData only valid for HTTP/2; opaque debug data to send. */ - @Synchronized @Throws(IOException::class) fun goAway( lastGoodStreamId: Int, errorCode: ErrorCode, debugData: ByteArray, ) { - if (closed) throw IOException("closed") - require(errorCode.httpCode != -1) { "errorCode.httpCode == -1" } - frameHeader( - streamId = 0, - length = 8 + debugData.size, - type = TYPE_GOAWAY, - flags = FLAG_NONE, - ) - sink.writeInt(lastGoodStreamId) - sink.writeInt(errorCode.httpCode) - if (debugData.isNotEmpty()) { - sink.write(debugData) + this.withLock { + if (closed) throw IOException("closed") + require(errorCode.httpCode != -1) { "errorCode.httpCode == -1" } + frameHeader( + streamId = 0, + length = 8 + debugData.size, + type = TYPE_GOAWAY, + flags = FLAG_NONE, + ) + sink.writeInt(lastGoodStreamId) + sink.writeInt(errorCode.httpCode) + if (debugData.isNotEmpty()) { + sink.write(debugData) + } + sink.flush() } - sink.flush() } /** * Inform peer that an additional `windowSizeIncrement` bytes can be sent on `streamId`, or the * connection if `streamId` is zero. */ - @Synchronized @Throws(IOException::class) fun windowUpdate( streamId: Int, windowSizeIncrement: Long, ) { - if (closed) throw IOException("closed") - require(windowSizeIncrement != 0L && windowSizeIncrement <= 0x7fffffffL) { - "windowSizeIncrement == 0 || windowSizeIncrement > 0x7fffffffL: $windowSizeIncrement" - } - if (logger.isLoggable(FINE)) { - logger.fine( - frameLogWindowUpdate( - inbound = false, - streamId = streamId, - length = 4, - windowSizeIncrement = windowSizeIncrement, - ), + this.withLock { + if (closed) throw IOException("closed") + require(windowSizeIncrement != 0L && windowSizeIncrement <= 0x7fffffffL) { + "windowSizeIncrement == 0 || windowSizeIncrement > 0x7fffffffL: $windowSizeIncrement" + } + if (logger.isLoggable(FINE)) { + logger.fine( + frameLogWindowUpdate( + inbound = false, + streamId = streamId, + length = 4, + windowSizeIncrement = windowSizeIncrement, + ), + ) + } + frameHeader( + streamId = streamId, + length = 4, + type = TYPE_WINDOW_UPDATE, + flags = FLAG_NONE, ) + sink.writeInt(windowSizeIncrement.toInt()) + sink.flush() } - frameHeader( - streamId = streamId, - length = 4, - type = TYPE_WINDOW_UPDATE, - flags = FLAG_NONE, - ) - sink.writeInt(windowSizeIncrement.toInt()) - sink.flush() } @Throws(IOException::class) @@ -317,11 +325,12 @@ class Http2Writer( sink.writeInt(streamId and 0x7fffffff) } - @Synchronized @Throws(IOException::class) override fun close() { - closed = true - sink.close() + this.withLock { + closed = true + sink.close() + } } @Throws(IOException::class) @@ -343,29 +352,30 @@ class Http2Writer( } } - @Synchronized @Throws(IOException::class) fun headers( outFinished: Boolean, streamId: Int, headerBlock: List
, ) { - if (closed) throw IOException("closed") - hpackWriter.writeHeaders(headerBlock) + this.withLock { + if (closed) throw IOException("closed") + hpackWriter.writeHeaders(headerBlock) - val byteCount = hpackBuffer.size - val length = minOf(maxFrameSize.toLong(), byteCount) - var flags = if (byteCount == length) FLAG_END_HEADERS else 0 - if (outFinished) flags = flags or FLAG_END_STREAM - frameHeader( - streamId = streamId, - length = length.toInt(), - type = TYPE_HEADERS, - flags = flags, - ) - sink.write(hpackBuffer, length) + val byteCount = hpackBuffer.size + val length = minOf(maxFrameSize.toLong(), byteCount) + var flags = if (byteCount == length) FLAG_END_HEADERS else 0 + if (outFinished) flags = flags or FLAG_END_STREAM + frameHeader( + streamId = streamId, + length = length.toInt(), + type = TYPE_HEADERS, + flags = flags, + ) + sink.write(hpackBuffer, length) - if (byteCount > length) writeContinuationFrames(streamId, byteCount - length) + if (byteCount > length) writeContinuationFrames(streamId, byteCount - length) + } } companion object { diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/Huffman.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Huffman.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/Huffman.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Huffman.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/PushObserver.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/PushObserver.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/PushObserver.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/PushObserver.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/Settings.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Settings.kt similarity index 97% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/Settings.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Settings.kt index ef704cdfde5d..a52bd3321037 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/http2/Settings.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Settings.kt @@ -116,7 +116,10 @@ class Settings { const val ENABLE_PUSH = 2 /** Sender's maximum number of concurrent streams. */ - const val MAX_CONCURRENT_STREAMS = 4 + const val MAX_CONCURRENT_STREAMS = 3 + + /** Window size in bytes. */ + const val INITIAL_WINDOW_SIZE = 4 /** HTTP/2: Size in bytes of the largest frame payload the sender will accept. */ const val MAX_FRAME_SIZE = 5 @@ -124,9 +127,6 @@ class Settings { /** HTTP/2: Advisory only. Size in bytes of the largest header list the sender will accept. */ const val MAX_HEADER_LIST_SIZE = 6 - /** Window size in bytes. */ - const val INITIAL_WINDOW_SIZE = 7 - /** Total number of settings. */ const val COUNT = 10 } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/StreamResetException.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/StreamResetException.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/StreamResetException.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/StreamResetException.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http2/flowcontrol/WindowCounter.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/flowcontrol/WindowCounter.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/http2/flowcontrol/WindowCounter.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/flowcontrol/WindowCounter.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/idn/IdnaMappingTable.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/idn/IdnaMappingTable.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/idn/IdnaMappingTable.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/idn/IdnaMappingTable.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/idn/Punycode.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/idn/Punycode.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/idn/Punycode.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/idn/Punycode.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/internal.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/internal.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/internal.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/internal.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/Platform.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/platform/Platform.kt similarity index 77% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/Platform.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/platform/Platform.kt index 4483de380150..71065ebc75b8 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/platform/Platform.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/platform/Platform.kt @@ -16,13 +16,11 @@ */ package okhttp3.internal.platform -import android.annotation.SuppressLint import java.io.IOException import java.net.InetSocketAddress import java.net.Socket import java.security.GeneralSecurityException import java.security.KeyStore -import java.security.Security import java.util.logging.Level import java.util.logging.Logger import javax.net.ssl.ExtendedSSLSession @@ -35,7 +33,6 @@ import javax.net.ssl.TrustManagerFactory import javax.net.ssl.X509TrustManager import okhttp3.OkHttpClient import okhttp3.Protocol -import okhttp3.internal.platform.android.AndroidLog import okhttp3.internal.readFieldOrNull import okhttp3.internal.tls.BasicCertificateChainCleaner import okhttp3.internal.tls.BasicTrustRootIndex @@ -129,11 +126,16 @@ open class Platform { open fun getSelectedProtocol(sslSocket: SSLSocket): String? = null /** For MockWebServer. This returns the inbound SNI names. */ - @SuppressLint("NewApi") @IgnoreJRERequirement // This function is overridden to require API >= 24. open fun getHandshakeServerNames(sslSocket: SSLSocket): List { val session = sslSocket.session as? ExtendedSSLSession ?: return listOf() - return session.requestedServerNames.mapNotNull { (it as? SNIHostName)?.asciiName } + return try { + session.requestedServerNames.mapNotNull { (it as? SNIHostName)?.asciiName } + } catch (uoe: UnsupportedOperationException) { + // UnsupportedOperationException – if the underlying provider does not implement the operation + // https://github.com/bcgit/bc-java/issues/1773 + listOf() + } } @Throws(IOException::class) @@ -214,83 +216,11 @@ open class Platform { fun alpnProtocolNames(protocols: List) = protocols.filter { it != Protocol.HTTP_1_0 }.map { it.toString() } - // This explicit check avoids activating in Android Studio with Android specific classes - // available when running plugins inside the IDE. val isAndroid: Boolean - get() = "Dalvik" == System.getProperty("java.vm.name") - - private val isConscryptPreferred: Boolean - get() { - val preferredProvider = Security.getProviders()[0].name - return "Conscrypt" == preferredProvider - } - - private val isOpenJSSEPreferred: Boolean - get() { - val preferredProvider = Security.getProviders()[0].name - return "OpenJSSE" == preferredProvider - } - - private val isBouncyCastlePreferred: Boolean - get() { - val preferredProvider = Security.getProviders()[0].name - return "BC" == preferredProvider - } + get() = PlatformRegistry.isAndroid /** Attempt to match the host runtime to a capable Platform implementation. */ - private fun findPlatform(): Platform = - if (isAndroid) { - findAndroidPlatform() - } else { - findJvmPlatform() - } - - private fun findAndroidPlatform(): Platform { - AndroidLog.enable() - return Android10Platform.buildIfSupported() ?: AndroidPlatform.buildIfSupported()!! - } - - private fun findJvmPlatform(): Platform { - if (isConscryptPreferred) { - val conscrypt = ConscryptPlatform.buildIfSupported() - - if (conscrypt != null) { - return conscrypt - } - } - - if (isBouncyCastlePreferred) { - val bc = BouncyCastlePlatform.buildIfSupported() - - if (bc != null) { - return bc - } - } - - if (isOpenJSSEPreferred) { - val openJSSE = OpenJSSEPlatform.buildIfSupported() - - if (openJSSE != null) { - return openJSSE - } - } - - // An Oracle JDK 9 like OpenJDK, or JDK 8 251+. - val jdk9 = Jdk9Platform.buildIfSupported() - - if (jdk9 != null) { - return jdk9 - } - - // An Oracle JDK 8 like OpenJDK, pre 251. - val jdkWithJettyBoot = Jdk8WithJettyBootPlatform.buildIfSupported() - - if (jdkWithJettyBoot != null) { - return jdkWithJettyBoot - } - - return Platform() - } + private fun findPlatform(): Platform = PlatformRegistry.findPlatform() /** * Returns the concatenation of 8-bit, length prefixed protocol names. diff --git a/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/platform/PlatformRegistry.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/platform/PlatformRegistry.kt new file mode 100644 index 000000000000..ce90f02f93dd --- /dev/null +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/platform/PlatformRegistry.kt @@ -0,0 +1,7 @@ +package okhttp3.internal.platform + +expect object PlatformRegistry { + fun findPlatform(): Platform + + val isAndroid: Boolean +} diff --git a/okhttp/src/main/kotlin/okhttp3/internal/proxy/NullProxySelector.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/proxy/NullProxySelector.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/proxy/NullProxySelector.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/proxy/NullProxySelector.kt diff --git a/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/publicsuffix/BasePublicSuffixList.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/publicsuffix/BasePublicSuffixList.kt new file mode 100644 index 000000000000..6410af966c64 --- /dev/null +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/publicsuffix/BasePublicSuffixList.kt @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2024 Block, 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.internal.publicsuffix + +import java.io.IOException +import java.io.InterruptedIOException +import java.util.concurrent.CountDownLatch +import java.util.concurrent.atomic.AtomicBoolean +import okhttp3.internal.platform.Platform +import okio.ByteString +import okio.Source +import okio.buffer + +internal abstract class BasePublicSuffixList : PublicSuffixList { + /** True after we've attempted to read the list for the first time. */ + private val listRead = AtomicBoolean(false) + + /** Used for concurrent threads reading the list for the first time. */ + private val readCompleteLatch = CountDownLatch(1) + + // The lists are held as a large array of UTF-8 bytes. This is to avoid allocating lots of strings + // that will likely never be used. Each rule is separated by '\n'. Please see the + // PublicSuffixListGenerator class for how these lists are generated. + // Guarded by this. + override lateinit var bytes: ByteString + override lateinit var exceptionBytes: ByteString + + @Throws(IOException::class) + private fun readTheList() { + var publicSuffixListBytes: ByteString? + var publicSuffixExceptionListBytes: ByteString? + + try { + listSource().buffer().use { bufferedSource -> + val totalBytes = bufferedSource.readInt() + publicSuffixListBytes = bufferedSource.readByteString(totalBytes.toLong()) + + val totalExceptionBytes = bufferedSource.readInt() + publicSuffixExceptionListBytes = bufferedSource.readByteString(totalExceptionBytes.toLong()) + } + + synchronized(this) { + this.bytes = publicSuffixListBytes!! + this.exceptionBytes = publicSuffixExceptionListBytes!! + } + } finally { + readCompleteLatch.countDown() + } + } + + abstract fun listSource(): Source + + override fun ensureLoaded() { + if (!listRead.get() && listRead.compareAndSet(false, true)) { + readTheListUninterruptibly() + } else { + try { + readCompleteLatch.await() + } catch (_: InterruptedException) { + Thread.currentThread().interrupt() // Retain interrupted status. + } + } + + check(::bytes.isInitialized) { + // May have failed with an IOException + "Unable to load $path resource." + } + } + + abstract val path: Any + + /** + * Reads the public suffix list treating the operation as uninterruptible. We always want to read + * the list otherwise we'll be left in a bad state. If the thread was interrupted prior to this + * operation, it will be re-interrupted after the list is read. + */ + private fun readTheListUninterruptibly() { + var interrupted = false + try { + while (true) { + try { + readTheList() + return + } catch (_: InterruptedIOException) { + Thread.interrupted() // Temporarily clear the interrupted state. + interrupted = true + } catch (e: IOException) { + Platform.get().log("Failed to read public suffix list", Platform.Companion.WARN, e) + return + } + } + } finally { + if (interrupted) { + Thread.currentThread().interrupt() // Retain interrupted status. + } + } + } +} diff --git a/okhttp/src/main/kotlin/okhttp3/internal/publicsuffix/PublicSuffixDatabase.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/publicsuffix/PublicSuffixDatabase.kt similarity index 65% rename from okhttp/src/main/kotlin/okhttp3/internal/publicsuffix/PublicSuffixDatabase.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/publicsuffix/PublicSuffixDatabase.kt index fef4fd01df79..fac470568d7a 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/publicsuffix/PublicSuffixDatabase.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/publicsuffix/PublicSuffixDatabase.kt @@ -15,18 +15,10 @@ */ package okhttp3.internal.publicsuffix -import java.io.IOException -import java.io.InterruptedIOException import java.net.IDN -import java.util.concurrent.CountDownLatch -import java.util.concurrent.atomic.AtomicBoolean import okhttp3.internal.and -import okhttp3.internal.platform.Platform -import okio.FileSystem -import okio.GzipSource -import okio.Path -import okio.Path.Companion.toPath -import okio.buffer +import okio.ByteString +import okio.ByteString.Companion.encodeUtf8 /** * A database of public suffixes provided by [publicsuffix.org][publicsuffix_org]. @@ -34,22 +26,8 @@ import okio.buffer * [publicsuffix_org]: https://publicsuffix.org/ */ class PublicSuffixDatabase internal constructor( - val path: Path = PUBLIC_SUFFIX_RESOURCE, - val fileSystem: FileSystem = FileSystem.RESOURCES, + private val publicSuffixList: PublicSuffixList, ) { - /** True after we've attempted to read the list for the first time. */ - private val listRead = AtomicBoolean(false) - - /** Used for concurrent threads reading the list for the first time. */ - private val readCompleteLatch = CountDownLatch(1) - - // The lists are held as a large array of UTF-8 bytes. This is to avoid allocating lots of strings - // that will likely never be used. Each rule is separated by '\n'. Please see the - // PublicSuffixListGenerator class for how these lists are generated. - // Guarded by this. - private lateinit var publicSuffixListBytes: ByteArray - private lateinit var publicSuffixExceptionListBytes: ByteArray - /** * Returns the effective top-level domain plus one (eTLD+1) by referencing the public suffix list. * Returns null if the domain is a public suffix or a private address. @@ -101,29 +79,16 @@ class PublicSuffixDatabase internal constructor( } private fun findMatchingRule(domainLabels: List): List { - if (!listRead.get() && listRead.compareAndSet(false, true)) { - readTheListUninterruptibly() - } else { - try { - readCompleteLatch.await() - } catch (_: InterruptedException) { - Thread.currentThread().interrupt() // Retain interrupted status. - } - } - - check(::publicSuffixListBytes.isInitialized) { - // May have failed with an IOException - "Unable to load $PUBLIC_SUFFIX_RESOURCE resource from the classpath." - } + publicSuffixList.ensureLoaded() // Break apart the domain into UTF-8 labels, i.e. foo.bar.com turns into [foo, bar, com]. - val domainLabelsUtf8Bytes = Array(domainLabels.size) { i -> domainLabels[i].toByteArray() } + val domainLabelsUtf8Bytes = Array(domainLabels.size) { i -> domainLabels[i].encodeUtf8() } // Start by looking for exact matches. We start at the leftmost label. For example, foo.bar.com // will look like: [foo, bar, com], [bar, com], [com]. The longest matching rule wins. var exactMatch: String? = null for (i in domainLabelsUtf8Bytes.indices) { - val rule = publicSuffixListBytes.binarySearch(domainLabelsUtf8Bytes, i) + val rule = publicSuffixList.bytes.binarySearch(domainLabelsUtf8Bytes, i) if (rule != null) { exactMatch = rule break @@ -140,7 +105,7 @@ class PublicSuffixDatabase internal constructor( val labelsWithWildcard = domainLabelsUtf8Bytes.clone() for (labelIndex in 0 until labelsWithWildcard.size - 1) { labelsWithWildcard[labelIndex] = WILDCARD_LABEL - val rule = publicSuffixListBytes.binarySearch(labelsWithWildcard, labelIndex) + val rule = publicSuffixList.bytes.binarySearch(labelsWithWildcard, labelIndex) if (rule != null) { wildcardMatch = rule break @@ -153,7 +118,7 @@ class PublicSuffixDatabase internal constructor( if (wildcardMatch != null) { for (labelIndex in 0 until domainLabelsUtf8Bytes.size - 1) { val rule = - publicSuffixExceptionListBytes.binarySearch( + publicSuffixList.exceptionBytes.binarySearch( domainLabelsUtf8Bytes, labelIndex, ) @@ -182,84 +147,20 @@ class PublicSuffixDatabase internal constructor( } } - /** - * Reads the public suffix list treating the operation as uninterruptible. We always want to read - * the list otherwise we'll be left in a bad state. If the thread was interrupted prior to this - * operation, it will be re-interrupted after the list is read. - */ - private fun readTheListUninterruptibly() { - var interrupted = false - try { - while (true) { - try { - readTheList() - return - } catch (_: InterruptedIOException) { - Thread.interrupted() // Temporarily clear the interrupted state. - interrupted = true - } catch (e: IOException) { - Platform.get().log("Failed to read public suffix list", Platform.WARN, e) - return - } - } - } finally { - if (interrupted) { - Thread.currentThread().interrupt() // Retain interrupted status. - } - } - } - - @Throws(IOException::class) - private fun readTheList() { - var publicSuffixListBytes: ByteArray? - var publicSuffixExceptionListBytes: ByteArray? - - try { - GzipSource(fileSystem.source(path)).buffer().use { bufferedSource -> - val totalBytes = bufferedSource.readInt() - publicSuffixListBytes = bufferedSource.readByteArray(totalBytes.toLong()) - - val totalExceptionBytes = bufferedSource.readInt() - publicSuffixExceptionListBytes = bufferedSource.readByteArray(totalExceptionBytes.toLong()) - } - - synchronized(this) { - this.publicSuffixListBytes = publicSuffixListBytes!! - this.publicSuffixExceptionListBytes = publicSuffixExceptionListBytes!! - } - } finally { - readCompleteLatch.countDown() - } - } - - /** Visible for testing. */ - fun setListBytes( - publicSuffixListBytes: ByteArray, - publicSuffixExceptionListBytes: ByteArray, - ) { - this.publicSuffixListBytes = publicSuffixListBytes - this.publicSuffixExceptionListBytes = publicSuffixExceptionListBytes - listRead.set(true) - readCompleteLatch.countDown() - } - companion object { - @JvmField - val PUBLIC_SUFFIX_RESOURCE = "/okhttp3/internal/publicsuffix/${PublicSuffixDatabase::class.java.simpleName}.gz".toPath() - - private val WILDCARD_LABEL = byteArrayOf('*'.code.toByte()) + private val WILDCARD_LABEL = ByteString.of('*'.code.toByte()) private val PREVAILING_RULE = listOf("*") private const val EXCEPTION_MARKER = '!' - private val instance = PublicSuffixDatabase() + private val instance = PublicSuffixDatabase(PublicSuffixList.Default) fun get(): PublicSuffixDatabase { return instance } - private fun ByteArray.binarySearch( - labels: Array, + private fun ByteString.binarySearch( + labels: Array, labelIndex: Int, ): String? { var low = 0 @@ -338,7 +239,7 @@ class PublicSuffixDatabase internal constructor( low = mid + end + 1 } else { // Found a match. - match = String(this, mid, publicSuffixLength) + match = this.substring(mid, mid + publicSuffixLength).string(Charsets.UTF_8) break } } diff --git a/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/publicsuffix/PublicSuffixList.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/publicsuffix/PublicSuffixList.kt new file mode 100644 index 000000000000..a3527add72cb --- /dev/null +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/publicsuffix/PublicSuffixList.kt @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2024 Block, 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.internal.publicsuffix + +import okio.ByteString + +/** + * Basic I/O for the PublicSuffixDatabase.gz. + */ +internal interface PublicSuffixList { + fun ensureLoaded() + + val bytes: ByteString + val exceptionBytes: ByteString + + companion object +} + +internal expect val PublicSuffixList.Companion.Default: PublicSuffixList diff --git a/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/publicsuffix/ResourcePublicSuffixList.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/publicsuffix/ResourcePublicSuffixList.kt new file mode 100644 index 000000000000..fcc4da38f276 --- /dev/null +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/publicsuffix/ResourcePublicSuffixList.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 Block, 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.internal.publicsuffix + +import okio.FileSystem +import okio.GzipSource +import okio.Path +import okio.Path.Companion.toPath +import okio.Source + +internal class ResourcePublicSuffixList( + override val path: Path = PUBLIC_SUFFIX_RESOURCE, + val fileSystem: FileSystem = FileSystem.Companion.RESOURCES, +) : BasePublicSuffixList() { + override fun listSource(): Source = GzipSource(fileSystem.source(path)) + + companion object { + @JvmField + val PUBLIC_SUFFIX_RESOURCE = + "okhttp3/internal/publicsuffix/${PublicSuffixDatabase::class.java.simpleName}.gz".toPath() + } +} diff --git a/okhttp/src/main/kotlin/okhttp3/internal/tls/BasicCertificateChainCleaner.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/tls/BasicCertificateChainCleaner.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/tls/BasicCertificateChainCleaner.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/tls/BasicCertificateChainCleaner.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/tls/BasicTrustRootIndex.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/tls/BasicTrustRootIndex.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/tls/BasicTrustRootIndex.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/tls/BasicTrustRootIndex.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/tls/CertificateChainCleaner.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/tls/CertificateChainCleaner.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/tls/CertificateChainCleaner.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/tls/CertificateChainCleaner.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/tls/OkHostnameVerifier.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/tls/OkHostnameVerifier.kt similarity index 98% rename from okhttp/src/main/kotlin/okhttp3/internal/tls/OkHostnameVerifier.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/tls/OkHostnameVerifier.kt index 706721b483e7..0c6263cef3bd 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/tls/OkHostnameVerifier.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/tls/OkHostnameVerifier.kt @@ -112,19 +112,18 @@ object OkHostnameVerifier : HostnameVerifier { ): Boolean { var hostname = hostname var pattern = pattern - // Basic sanity checks if (hostname.isNullOrEmpty() || hostname.startsWith(".") || hostname.endsWith("..") ) { - // Invalid domain name + // Invalid domain name. return false } if (pattern.isNullOrEmpty() || pattern.startsWith(".") || pattern.endsWith("..") ) { - // Invalid pattern/domain name + // Invalid pattern. return false } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/tls/TrustRootIndex.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/tls/TrustRootIndex.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/tls/TrustRootIndex.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/tls/TrustRootIndex.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/url/-Url.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/url/-Url.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/url/-Url.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/url/-Url.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/ws/MessageDeflater.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/MessageDeflater.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/ws/MessageDeflater.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/MessageDeflater.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/ws/MessageInflater.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/MessageInflater.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/ws/MessageInflater.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/MessageInflater.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/ws/RealWebSocket.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/RealWebSocket.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/ws/RealWebSocket.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/RealWebSocket.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/ws/WebSocketExtensions.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/WebSocketExtensions.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/ws/WebSocketExtensions.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/WebSocketExtensions.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/ws/WebSocketProtocol.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/WebSocketProtocol.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/ws/WebSocketProtocol.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/WebSocketProtocol.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/ws/WebSocketReader.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/WebSocketReader.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/ws/WebSocketReader.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/WebSocketReader.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/ws/WebSocketWriter.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/WebSocketWriter.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/ws/WebSocketWriter.kt rename to okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/WebSocketWriter.kt diff --git a/okhttp/src/main/kotlinTemplates/okhttp3/internal/-InternalVersion.kt b/okhttp/src/commonJvmAndroid/kotlinTemplates/okhttp3/internal/-InternalVersion.kt similarity index 100% rename from okhttp/src/main/kotlinTemplates/okhttp3/internal/-InternalVersion.kt rename to okhttp/src/commonJvmAndroid/kotlinTemplates/okhttp3/internal/-InternalVersion.kt diff --git a/okhttp/src/commonTest/kotlin/okhttp3/internal/publicsuffix/ConfiguredPublicSuffixDatabaseTest.kt b/okhttp/src/commonTest/kotlin/okhttp3/internal/publicsuffix/ConfiguredPublicSuffixDatabaseTest.kt new file mode 100644 index 000000000000..e677f18685d9 --- /dev/null +++ b/okhttp/src/commonTest/kotlin/okhttp3/internal/publicsuffix/ConfiguredPublicSuffixDatabaseTest.kt @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2017 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.internal.publicsuffix + +import assertk.assertThat +import assertk.assertions.isEqualTo +import assertk.assertions.isNull +import okio.Buffer +import org.junit.jupiter.api.Test + +class ConfiguredPublicSuffixDatabaseTest { + private val list = ConfiguredPublicSuffixList() + private val publicSuffixDatabase = PublicSuffixDatabase(list) + + @Test fun longestMatchWins() { + list.bytes = + Buffer() + .writeUtf8("com\n") + .writeUtf8("my.square.com\n") + .writeUtf8("square.com\n").readByteString() + + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("example.com")) + .isEqualTo("example.com") + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("foo.example.com")) + .isEqualTo("example.com") + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("foo.bar.square.com")) + .isEqualTo("bar.square.com") + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("foo.my.square.com")) + .isEqualTo("foo.my.square.com") + } + + @Test fun wildcardMatch() { + list.bytes = + Buffer() + .writeUtf8("*.square.com\n") + .writeUtf8("com\n") + .writeUtf8("example.com\n") + .readByteString() + + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("my.square.com")).isNull() + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("foo.my.square.com")) + .isEqualTo("foo.my.square.com") + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("bar.foo.my.square.com")) + .isEqualTo("foo.my.square.com") + } + + @Test fun boundarySearches() { + list.bytes = + Buffer() + .writeUtf8("bbb\n") + .writeUtf8("ddd\n") + .writeUtf8("fff\n") + .readByteString() + + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("aaa")).isNull() + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("ggg")).isNull() + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("ccc")).isNull() + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("eee")).isNull() + } + + @Test fun exceptionRule() { + list.bytes = + Buffer() + .writeUtf8("*.jp\n") + .writeUtf8("*.square.jp\n") + .writeUtf8("example.com\n") + .writeUtf8("square.com\n") + .readByteString() + list.exceptionBytes = + Buffer() + .writeUtf8("my.square.jp\n") + .readByteString() + + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("my.square.jp")) + .isEqualTo("my.square.jp") + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("foo.my.square.jp")) + .isEqualTo("my.square.jp") + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("my1.square.jp")).isNull() + } + + @Test fun noEffectiveTldPlusOne() { + list.bytes = + Buffer() + .writeUtf8("*.jp\n") + .writeUtf8("*.square.jp\n") + .writeUtf8("example.com\n") + .writeUtf8("square.com\n") + .readByteString() + list.exceptionBytes = + Buffer() + .writeUtf8("my.square.jp\n") + .readByteString() + + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("example.com")).isNull() + assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("foo.square.jp")).isNull() + } +} diff --git a/okhttp/src/commonTest/kotlin/okhttp3/internal/publicsuffix/ConfiguredPublicSuffixList.kt b/okhttp/src/commonTest/kotlin/okhttp3/internal/publicsuffix/ConfiguredPublicSuffixList.kt new file mode 100644 index 000000000000..610f19524092 --- /dev/null +++ b/okhttp/src/commonTest/kotlin/okhttp3/internal/publicsuffix/ConfiguredPublicSuffixList.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 Block, 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.internal.publicsuffix + +import okio.ByteString + +/** + * An implementation of I/O for PublicSuffixDatabase.gz by directly passing in ByteStrings. + */ +internal class ConfiguredPublicSuffixList : PublicSuffixList { + override fun ensureLoaded() { + } + + override var bytes: ByteString = ByteString.EMPTY + + override var exceptionBytes: ByteString = ByteString.EMPTY +} diff --git a/okhttp/src/test/java/okhttp3/internal/publicsuffix/PublicSuffixDatabaseTest.kt b/okhttp/src/commonTest/kotlin/okhttp3/internal/publicsuffix/PublicSuffixDatabaseTest.kt similarity index 69% rename from okhttp/src/test/java/okhttp3/internal/publicsuffix/PublicSuffixDatabaseTest.kt rename to okhttp/src/commonTest/kotlin/okhttp3/internal/publicsuffix/PublicSuffixDatabaseTest.kt index e264cb34e36c..6e7aa981451c 100644 --- a/okhttp/src/test/java/okhttp3/internal/publicsuffix/PublicSuffixDatabaseTest.kt +++ b/okhttp/src/commonTest/kotlin/okhttp3/internal/publicsuffix/PublicSuffixDatabaseTest.kt @@ -21,98 +21,27 @@ import assertk.assertions.isNull import assertk.assertions.isTrue import kotlin.test.assertEquals import kotlin.test.assertFailsWith +import okhttp3.internal.publicsuffix.ResourcePublicSuffixList.Companion.PUBLIC_SUFFIX_RESOURCE import okhttp3.internal.toCanonicalHost +import okhttp3.okHttpRoot +import okhttp3.test.BaseJavaTest import okio.Buffer import okio.FileSystem import okio.GzipSource import okio.Path.Companion.toPath import okio.buffer import okio.use -import org.junit.jupiter.api.Test +import org.junit.Test -class PublicSuffixDatabaseTest { - private val publicSuffixDatabase = PublicSuffixDatabase() +class PublicSuffixDatabaseTest : BaseJavaTest() { + private val publicSuffixDatabase = PublicSuffixDatabase.get() - @Test fun longestMatchWins() { - val buffer = - Buffer() - .writeUtf8("com\n") - .writeUtf8("my.square.com\n") - .writeUtf8("square.com\n") - publicSuffixDatabase.setListBytes(buffer.readByteArray(), byteArrayOf()) - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("example.com")) - .isEqualTo("example.com") - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("foo.example.com")) - .isEqualTo("example.com") - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("foo.bar.square.com")) - .isEqualTo("bar.square.com") - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("foo.my.square.com")) - .isEqualTo("foo.my.square.com") - } - - @Test fun wildcardMatch() { - val buffer = - Buffer() - .writeUtf8("*.square.com\n") - .writeUtf8("com\n") - .writeUtf8("example.com\n") - publicSuffixDatabase.setListBytes(buffer.readByteArray(), byteArrayOf()) - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("my.square.com")).isNull() - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("foo.my.square.com")) - .isEqualTo("foo.my.square.com") - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("bar.foo.my.square.com")) - .isEqualTo("foo.my.square.com") - } - - @Test fun boundarySearches() { - val buffer = - Buffer() - .writeUtf8("bbb\n") - .writeUtf8("ddd\n") - .writeUtf8("fff\n") - publicSuffixDatabase.setListBytes(buffer.readByteArray(), byteArrayOf()) - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("aaa")).isNull() - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("ggg")).isNull() - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("ccc")).isNull() - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("eee")).isNull() - } - - @Test fun exceptionRule() { - val exception = - Buffer() - .writeUtf8("my.square.jp\n") - val buffer = - Buffer() - .writeUtf8("*.jp\n") - .writeUtf8("*.square.jp\n") - .writeUtf8("example.com\n") - .writeUtf8("square.com\n") - publicSuffixDatabase.setListBytes(buffer.readByteArray(), exception.readByteArray()) - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("my.square.jp")) - .isEqualTo("my.square.jp") - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("foo.my.square.jp")) - .isEqualTo("my.square.jp") - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("my1.square.jp")).isNull() - } - - @Test fun noEffectiveTldPlusOne() { - val exception = - Buffer() - .writeUtf8("my.square.jp\n") - val buffer = - Buffer() - .writeUtf8("*.jp\n") - .writeUtf8("*.square.jp\n") - .writeUtf8("example.com\n") - .writeUtf8("square.com\n") - publicSuffixDatabase.setListBytes(buffer.readByteArray(), exception.readByteArray()) - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("example.com")).isNull() - assertThat(publicSuffixDatabase.getEffectiveTldPlusOne("foo.square.jp")).isNull() - } + val pathForTests = okHttpRoot / "okhttp/src/jvmMain/resources" / PUBLIC_SUFFIX_RESOURCE - @Test fun allPublicSuffixes() { + @Test + fun allPublicSuffixes() { val buffer = Buffer() - FileSystem.RESOURCES.source(PublicSuffixDatabase.PUBLIC_SUFFIX_RESOURCE).use { resource -> + FileSystem.SYSTEM.source(pathForTests).use { resource -> GzipSource(resource).buffer().use { source -> val length = source.readInt() buffer.write(source, length.toLong()) @@ -130,9 +59,10 @@ class PublicSuffixDatabaseTest { } } - @Test fun publicSuffixExceptions() { + @Test + fun publicSuffixExceptions() { val buffer = Buffer() - FileSystem.RESOURCES.source(PublicSuffixDatabase.PUBLIC_SUFFIX_RESOURCE).use { resource -> + FileSystem.SYSTEM.source(pathForTests).use { resource -> GzipSource(resource).buffer().use { source -> var length = source.readInt() source.skip(length.toLong()) @@ -150,7 +80,8 @@ class PublicSuffixDatabaseTest { } } - @Test fun threadIsInterruptedOnFirstRead() { + @Test + fun threadIsInterruptedOnFirstRead() { Thread.currentThread().interrupt() try { val result = publicSuffixDatabase.getEffectiveTldPlusOne("squareup.com") @@ -160,10 +91,13 @@ class PublicSuffixDatabaseTest { } } - @Test fun secondReadFailsSameAsFirst() { + @Test + fun secondReadFailsSameAsFirst() { val badPublicSuffixDatabase = PublicSuffixDatabase( - path = "/xxx.gz".toPath(), + ResourcePublicSuffixList( + path = "/xxx.gz".toPath(), + ), ) lateinit var firstFailure: Exception assertFailsWith { @@ -179,7 +113,8 @@ class PublicSuffixDatabaseTest { } /** These tests are provided by [publicsuffix.org](https://publicsuffix.org/list/). */ - @Test fun publicSuffixDotOrgTestCases() { + @Test + fun publicSuffixDotOrgTestCases() { // Any copyright is dedicated to the Public Domain. // https://creativecommons.org/publicdomain/zero/1.0/ diff --git a/okhttp/src/commonTest/kotlin/okhttp3/test/BaseJavaTest.kt b/okhttp/src/commonTest/kotlin/okhttp3/test/BaseJavaTest.kt new file mode 100644 index 000000000000..3a2375717271 --- /dev/null +++ b/okhttp/src/commonTest/kotlin/okhttp3/test/BaseJavaTest.kt @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2024 Block, 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.test + +expect abstract class BaseJavaTest() diff --git a/okhttp/src/main/kotlin/okhttp3/internal/graal/GraalSvm.kt b/okhttp/src/jvmMain/kotlin/okhttp3/internal/graal/GraalSvm.kt similarity index 86% rename from okhttp/src/main/kotlin/okhttp3/internal/graal/GraalSvm.kt rename to okhttp/src/jvmMain/kotlin/okhttp3/internal/graal/GraalSvm.kt index caad047228d7..0e3b58e02c06 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/graal/GraalSvm.kt +++ b/okhttp/src/jvmMain/kotlin/okhttp3/internal/graal/GraalSvm.kt @@ -18,8 +18,6 @@ package okhttp3.internal.graal import com.oracle.svm.core.annotate.Delete import com.oracle.svm.core.annotate.Substitute import com.oracle.svm.core.annotate.TargetClass -import okhttp3.internal.platform.Android10Platform -import okhttp3.internal.platform.AndroidPlatform import okhttp3.internal.platform.BouncyCastlePlatform import okhttp3.internal.platform.ConscryptPlatform import okhttp3.internal.platform.Jdk8WithJettyBootPlatform @@ -27,14 +25,6 @@ import okhttp3.internal.platform.Jdk9Platform import okhttp3.internal.platform.OpenJSSEPlatform import okhttp3.internal.platform.Platform -@TargetClass(AndroidPlatform::class) -@Delete -class TargetAndroidPlatform - -@TargetClass(Android10Platform::class) -@Delete -class TargetAndroid10Platform - @TargetClass(BouncyCastlePlatform::class) @Delete class TargetBouncyCastlePlatform diff --git a/okhttp/src/main/kotlin/okhttp3/internal/graal/OkHttpFeature.kt b/okhttp/src/jvmMain/kotlin/okhttp3/internal/graal/OkHttpFeature.kt similarity index 80% rename from okhttp/src/main/kotlin/okhttp3/internal/graal/OkHttpFeature.kt rename to okhttp/src/jvmMain/kotlin/okhttp3/internal/graal/OkHttpFeature.kt index 857ab26a2793..5845330584b2 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/graal/OkHttpFeature.kt +++ b/okhttp/src/jvmMain/kotlin/okhttp3/internal/graal/OkHttpFeature.kt @@ -18,7 +18,6 @@ package okhttp3.internal.graal import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement import org.graalvm.nativeimage.hosted.Feature -import org.graalvm.nativeimage.hosted.RuntimeResourceAccess /** * Automatic configuration of OkHttp for native images. @@ -27,10 +26,5 @@ import org.graalvm.nativeimage.hosted.RuntimeResourceAccess */ class OkHttpFeature : Feature { @IgnoreJRERequirement - override fun beforeAnalysis(access: Feature.BeforeAnalysisAccess?) { - RuntimeResourceAccess.addResource( - ClassLoader.getSystemClassLoader().getUnnamedModule(), - "okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz", - ) - } + override fun beforeAnalysis(access: Feature.BeforeAnalysisAccess?) = Unit } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/BouncyCastlePlatform.kt b/okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/BouncyCastlePlatform.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/BouncyCastlePlatform.kt rename to okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/BouncyCastlePlatform.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/ConscryptPlatform.kt b/okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/ConscryptPlatform.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/ConscryptPlatform.kt rename to okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/ConscryptPlatform.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/Jdk8WithJettyBootPlatform.kt b/okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/Jdk8WithJettyBootPlatform.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/Jdk8WithJettyBootPlatform.kt rename to okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/Jdk8WithJettyBootPlatform.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/Jdk9Platform.kt b/okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/Jdk9Platform.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/Jdk9Platform.kt rename to okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/Jdk9Platform.kt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/platform/OpenJSSEPlatform.kt b/okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/OpenJSSEPlatform.kt similarity index 100% rename from okhttp/src/main/kotlin/okhttp3/internal/platform/OpenJSSEPlatform.kt rename to okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/OpenJSSEPlatform.kt diff --git a/okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/PlatformRegistry.kt b/okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/PlatformRegistry.kt new file mode 100644 index 000000000000..721170b8a047 --- /dev/null +++ b/okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/PlatformRegistry.kt @@ -0,0 +1,68 @@ +package okhttp3.internal.platform + +import java.security.Security + +actual object PlatformRegistry { + private val isConscryptPreferred: Boolean + get() { + val preferredProvider = Security.getProviders()[0].name + return "Conscrypt" == preferredProvider + } + + private val isOpenJSSEPreferred: Boolean + get() { + val preferredProvider = Security.getProviders()[0].name + return "OpenJSSE" == preferredProvider + } + + private val isBouncyCastlePreferred: Boolean + get() { + val preferredProvider = Security.getProviders()[0].name + return "BC" == preferredProvider + } + + actual fun findPlatform(): Platform { + if (isConscryptPreferred) { + val conscrypt = ConscryptPlatform.buildIfSupported() + + if (conscrypt != null) { + return conscrypt + } + } + + if (isBouncyCastlePreferred) { + val bc = BouncyCastlePlatform.buildIfSupported() + + if (bc != null) { + return bc + } + } + + if (isOpenJSSEPreferred) { + val openJSSE = OpenJSSEPlatform.buildIfSupported() + + if (openJSSE != null) { + return openJSSE + } + } + + // An Oracle JDK 9 like OpenJDK, or JDK 8 251+. + val jdk9 = Jdk9Platform.buildIfSupported() + + if (jdk9 != null) { + return jdk9 + } + + // An Oracle JDK 8 like OpenJDK, pre 251. + val jdkWithJettyBoot = Jdk8WithJettyBootPlatform.buildIfSupported() + + if (jdkWithJettyBoot != null) { + return jdkWithJettyBoot + } + + return Platform() + } + + actual val isAndroid: Boolean + get() = false +} diff --git a/okhttp/src/jvmMain/kotlin/okhttp3/internal/publicsuffix/PublicSuffixList.jvm.kt b/okhttp/src/jvmMain/kotlin/okhttp3/internal/publicsuffix/PublicSuffixList.jvm.kt new file mode 100644 index 000000000000..7bafc89b6d35 --- /dev/null +++ b/okhttp/src/jvmMain/kotlin/okhttp3/internal/publicsuffix/PublicSuffixList.jvm.kt @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 Block, 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.internal.publicsuffix + +internal actual val PublicSuffixList.Companion.Default: PublicSuffixList + get() = ResourcePublicSuffixList() diff --git a/okhttp/src/jvmMain/resources/META-INF/native-image/okhttp/okhttp/native-image.properties b/okhttp/src/jvmMain/resources/META-INF/native-image/okhttp/okhttp/native-image.properties new file mode 100644 index 000000000000..75cbefcdc5c1 --- /dev/null +++ b/okhttp/src/jvmMain/resources/META-INF/native-image/okhttp/okhttp/native-image.properties @@ -0,0 +1 @@ +Args = -H:+AddAllCharsets --enable-http --enable-https --features=okhttp3.internal.graal.OkHttpFeature --report-unsupported-elements-at-runtime diff --git a/okhttp/src/main/resources/META-INF/native-image/okhttp/okhttp/reflect-config.json b/okhttp/src/jvmMain/resources/META-INF/native-image/okhttp/okhttp/reflect-config.json similarity index 100% rename from okhttp/src/main/resources/META-INF/native-image/okhttp/okhttp/reflect-config.json rename to okhttp/src/jvmMain/resources/META-INF/native-image/okhttp/okhttp/reflect-config.json diff --git a/okhttp/src/main/resources/META-INF/native-image/okhttp/okhttp/resource-config.json b/okhttp/src/jvmMain/resources/META-INF/native-image/okhttp/okhttp/resource-config.json similarity index 100% rename from okhttp/src/main/resources/META-INF/native-image/okhttp/okhttp/resource-config.json rename to okhttp/src/jvmMain/resources/META-INF/native-image/okhttp/okhttp/resource-config.json diff --git a/okhttp/src/jvmMain/resources/okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz b/okhttp/src/jvmMain/resources/okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz new file mode 100644 index 000000000000..9102bd414099 Binary files /dev/null and b/okhttp/src/jvmMain/resources/okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz differ diff --git a/okhttp/src/test/java/okhttp3/AddressTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/AddressTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/AddressTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/AddressTest.kt diff --git a/okhttp/src/test/java/okhttp3/AutobahnTester.kt b/okhttp/src/jvmTest/kotlin/okhttp3/AutobahnTester.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/AutobahnTester.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/AutobahnTester.kt diff --git a/okhttp/src/test/java/okhttp3/BouncyCastleTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/BouncyCastleTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/BouncyCastleTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/BouncyCastleTest.kt diff --git a/okhttp/src/test/java/okhttp3/CacheControlJvmTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CacheControlJvmTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/CacheControlJvmTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CacheControlJvmTest.kt diff --git a/okhttp/src/test/java/okhttp3/CacheControlTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CacheControlTest.kt similarity index 94% rename from okhttp/src/test/java/okhttp3/CacheControlTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CacheControlTest.kt index d7d3e904df0b..a0f04390bd53 100644 --- a/okhttp/src/test/java/okhttp3/CacheControlTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/CacheControlTest.kt @@ -20,7 +20,7 @@ import assertk.assertions.isEqualTo import assertk.assertions.isFalse import assertk.assertions.isTrue import kotlin.test.Test -import kotlin.time.DurationUnit +import kotlin.time.Duration.Companion.seconds class CacheControlTest { @Test @@ -48,9 +48,9 @@ class CacheControlTest { CacheControl.Builder() .noCache() .noStore() - .maxAge(1, DurationUnit.SECONDS) - .maxStale(2, DurationUnit.SECONDS) - .minFresh(3, DurationUnit.SECONDS) + .maxAge(1.seconds) + .maxStale(2.seconds) + .minFresh(3.seconds) .onlyIfCached() .noTransform() .immutable() diff --git a/okhttp/src/test/java/okhttp3/CacheCorruptionTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CacheCorruptionTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/CacheCorruptionTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CacheCorruptionTest.kt diff --git a/okhttp/src/test/java/okhttp3/CacheTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CacheTest.kt similarity index 99% rename from okhttp/src/test/java/okhttp3/CacheTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CacheTest.kt index 707f0fcebd95..1400aadaeb68 100644 --- a/okhttp/src/test/java/okhttp3/CacheTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/CacheTest.kt @@ -92,7 +92,7 @@ class CacheTest { platform.assumeNotOpenJSSE() server.protocolNegotiationEnabled = false fileSystem.emulateUnix() - cache = Cache("/cache/".toPath(), Long.MAX_VALUE, fileSystem) + cache = Cache(fileSystem, "/cache/".toPath(), Long.MAX_VALUE) client = clientTestRule.newClientBuilder() .cache(cache) @@ -2758,7 +2758,7 @@ CLEAN $urlKey ${entryMetadata.length} ${entryBody.length} writeFile(cache.directoryPath, "$urlKey.0", entryMetadata) writeFile(cache.directoryPath, "$urlKey.1", entryBody) writeFile(cache.directoryPath, "journal", journalBody) - cache = Cache(cache.directory.path.toPath(), Int.MAX_VALUE.toLong(), fileSystem) + cache = Cache(fileSystem, cache.directory.path.toPath(), Int.MAX_VALUE.toLong()) client = client.newBuilder() .cache(cache) @@ -2807,7 +2807,7 @@ CLEAN $urlKey ${entryMetadata.length} ${entryBody.length} writeFile(cache.directoryPath, "$urlKey.1", entryBody) writeFile(cache.directoryPath, "journal", journalBody) cache.close() - cache = Cache(cache.directory.path.toPath(), Int.MAX_VALUE.toLong(), fileSystem) + cache = Cache(fileSystem, cache.directory.path.toPath(), Int.MAX_VALUE.toLong()) client = client.newBuilder() .cache(cache) @@ -2860,7 +2860,7 @@ CLEAN $urlKey ${entryMetadata.length} ${entryBody.length} writeFile(cache.directoryPath, "$urlKey.1", entryBody) writeFile(cache.directoryPath, "journal", journalBody) cache.close() - cache = Cache(cache.directory.path.toPath(), Int.MAX_VALUE.toLong(), fileSystem) + cache = Cache(fileSystem, cache.directory.path.toPath(), Int.MAX_VALUE.toLong()) client = client.newBuilder() .cache(cache) @@ -2905,7 +2905,7 @@ CLEAN $urlKey ${entryMetadata.length} ${entryBody.length} writeFile(cache.directoryPath, "$urlKey.1", entryBody) writeFile(cache.directoryPath, "journal", journalBody) cache.close() - cache = Cache(cache.directory.path.toPath(), Int.MAX_VALUE.toLong(), fileSystem) + cache = Cache(fileSystem, cache.directory.path.toPath(), Int.MAX_VALUE.toLong()) client = client.newBuilder() .cache(cache) @@ -3496,7 +3496,7 @@ CLEAN $urlKey ${entryMetadata.length} ${entryBody.length} } } val path: Path = "/cache".toPath() - val c = Cache(path, 100000L, loggingFileSystem) + val c = Cache(loggingFileSystem, path, 100000L) assertThat(c.directoryPath).isEqualTo(path) c.size() assertThat(events).containsExactly( diff --git a/okhttp/src/test/java/okhttp3/CallHandshakeTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CallHandshakeTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/CallHandshakeTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CallHandshakeTest.kt diff --git a/okhttp/src/test/java/okhttp3/CallKotlinTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CallKotlinTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/CallKotlinTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CallKotlinTest.kt diff --git a/okhttp/src/test/java/okhttp3/CallTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CallTest.kt similarity index 98% rename from okhttp/src/test/java/okhttp3/CallTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CallTest.kt index 2d8827faee08..c483e5843194 100644 --- a/okhttp/src/test/java/okhttp3/CallTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/CallTest.kt @@ -15,11 +15,14 @@ */ package okhttp3 +import assertk.all import assertk.assertThat import assertk.assertions.contains import assertk.assertions.containsExactly import assertk.assertions.doesNotContain import assertk.assertions.hasMessage +import assertk.assertions.hasSize +import assertk.assertions.index import assertk.assertions.isCloseTo import assertk.assertions.isEmpty import assertk.assertions.isEqualTo @@ -30,6 +33,7 @@ import assertk.assertions.isNotNull import assertk.assertions.isNotSameAs import assertk.assertions.isNull import assertk.assertions.isTrue +import assertk.assertions.matches import assertk.assertions.startsWith import assertk.fail import java.io.FileNotFoundException @@ -146,9 +150,9 @@ open class CallTest { private val callback = RecordingCallback() private val cache = Cache( + fileSystem = LoggingFilesystem(fileSystem), directory = "/cache".toPath(), maxSize = Int.MAX_VALUE.toLong(), - fileSystem = LoggingFilesystem(fileSystem), ) @BeforeEach @@ -1017,6 +1021,12 @@ open class CallTest { executeSynchronously(request) .assertCode(200) .assertBody("success!") + + assertThat(proxySelector.failures) + .all { + hasSize(1) + index(0).matches(".* Connect timed out".toRegex(RegexOption.IGNORE_CASE)) + } } /** https://github.com/square/okhttp/issues/4875 */ @@ -2619,8 +2629,8 @@ open class CallTest { } @Test - fun httpWithExcessiveHeaders() { - val longLine = "HTTP/1.1 200 " + stringFill('O', 256 * 1024) + "K" + fun httpWithExcessiveStatusLine() { + val longLine = "HTTP/1.1 200 " + "O".repeat(256 * 1024) + "K" server.protocols = listOf(Protocol.HTTP_1_1) server.enqueue( MockResponse.Builder() @@ -2629,16 +2639,21 @@ open class CallTest { .build(), ) executeSynchronously("/") - .assertFailureMatches(".*unexpected end of stream on " + server.url("/").redact()) + .assertFailureMatches(".*unexpected end of stream on ${server.url("/").redact()}") } - private fun stringFill( - fillChar: Char, - length: Int, - ): String { - val value = CharArray(length) - Arrays.fill(value, fillChar) - return String(value) + @Test + fun httpWithExcessiveHeaders() { + server.protocols = listOf(Protocol.HTTP_1_1) + server.enqueue( + MockResponse.Builder() + .addHeader("Set-Cookie", "a=${"A".repeat(255 * 1024)}") + .addHeader("Set-Cookie", "b=${"B".repeat(1 * 1024)}") + .body("I'm not even supposed to be here today.") + .build(), + ) + executeSynchronously("/") + .assertFailureMatches(".*unexpected end of stream on ${server.url("/").redact()}") } @Test @@ -3234,6 +3249,33 @@ open class CallTest { assertThat(recordedRequest.body.readUtf8()).isEqualTo("abc") } + @Test + fun serverRespondsWithProcessingMultiple() { + server.enqueue( + MockResponse.Builder() + .apply { + repeat(10) { + addInformationalResponse( + MockResponse( + code = HTTP_PROCESSING, + ), + ) + } + } + .build(), + ) + val request = + Request( + url = server.url("/"), + body = "abc".toRequestBody("text/plain".toMediaType()), + ) + executeSynchronously(request) + .assertCode(200) + .assertSuccessful() + val recordedRequest = server.takeRequest() + assertThat(recordedRequest.body.readUtf8()).isEqualTo("abc") + } + @Test fun serverRespondsWithUnsolicited100Continue_HTTP2() { enableProtocol(Protocol.HTTP_2) diff --git a/okhttp/src/test/java/okhttp3/CertificateChainCleanerTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CertificateChainCleanerTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/CertificateChainCleanerTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CertificateChainCleanerTest.kt diff --git a/okhttp/src/test/java/okhttp3/CertificatePinnerKotlinTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CertificatePinnerKotlinTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/CertificatePinnerKotlinTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CertificatePinnerKotlinTest.kt diff --git a/okhttp/src/test/java/okhttp3/CertificatePinnerTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CertificatePinnerTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/CertificatePinnerTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CertificatePinnerTest.kt diff --git a/okhttp/src/test/java/okhttp3/ChannelSocketFactory.kt b/okhttp/src/jvmTest/kotlin/okhttp3/ChannelSocketFactory.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/ChannelSocketFactory.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/ChannelSocketFactory.kt diff --git a/okhttp/src/test/java/okhttp3/CipherSuiteTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CipherSuiteTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/CipherSuiteTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CipherSuiteTest.kt diff --git a/okhttp/src/test/java/okhttp3/CommonRequestBodyTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CommonRequestBodyTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/CommonRequestBodyTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CommonRequestBodyTest.kt diff --git a/okhttp/src/test/java/okhttp3/ConnectionCoalescingTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/ConnectionCoalescingTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/ConnectionCoalescingTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/ConnectionCoalescingTest.kt diff --git a/okhttp/src/test/java/okhttp3/ConnectionListenerTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/ConnectionListenerTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/ConnectionListenerTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/ConnectionListenerTest.kt diff --git a/okhttp/src/test/java/okhttp3/ConnectionReuseTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/ConnectionReuseTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/ConnectionReuseTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/ConnectionReuseTest.kt diff --git a/okhttp/src/test/java/okhttp3/ConnectionSpecTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/ConnectionSpecTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/ConnectionSpecTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/ConnectionSpecTest.kt diff --git a/okhttp/src/test/java/okhttp3/ConscryptTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/ConscryptTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/ConscryptTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/ConscryptTest.kt diff --git a/okhttp/src/test/java/okhttp3/CookieTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CookieTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/CookieTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CookieTest.kt diff --git a/okhttp/src/test/java/okhttp3/CookiesTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CookiesTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/CookiesTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CookiesTest.kt diff --git a/okhttp/src/test/java/okhttp3/CorrettoTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CorrettoTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/CorrettoTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/CorrettoTest.kt diff --git a/okhttp/src/test/java/okhttp3/DispatcherCleanupTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/DispatcherCleanupTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/DispatcherCleanupTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/DispatcherCleanupTest.kt diff --git a/okhttp/src/test/java/okhttp3/DispatcherTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/DispatcherTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/DispatcherTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/DispatcherTest.kt diff --git a/okhttp/src/test/java/okhttp3/DuplexTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/DuplexTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/DuplexTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/DuplexTest.kt diff --git a/okhttp/src/test/java/okhttp3/EventListenerTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/EventListenerTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/EventListenerTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/EventListenerTest.kt diff --git a/okhttp/src/test/java/okhttp3/FakeRoutePlanner.kt b/okhttp/src/jvmTest/kotlin/okhttp3/FakeRoutePlanner.kt similarity index 94% rename from okhttp/src/test/java/okhttp3/FakeRoutePlanner.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/FakeRoutePlanner.kt index e817d2e09480..56fe78b9e246 100644 --- a/okhttp/src/test/java/okhttp3/FakeRoutePlanner.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/FakeRoutePlanner.kt @@ -24,23 +24,17 @@ import okhttp3.internal.connection.RoutePlanner import okhttp3.internal.connection.RoutePlanner.ConnectResult class FakeRoutePlanner( - private val taskFaker: TaskFaker, + val factory: TestValueFactory = TestValueFactory(), + val taskFaker: TaskFaker = factory.taskFaker, ) : RoutePlanner, Closeable { - /** - * Note that we don't use the same [TaskFaker] for this factory. That way off-topic tasks like - * connection pool maintenance tasks don't add noise to route planning tests. - */ - private val factory = TestValueFactory() - - private val pool = factory.newConnectionPool() - + val pool = factory.newConnectionPool(routePlanner = this) val events = LinkedBlockingDeque() var canceled = false var autoGeneratePlans = false var defaultConnectionIdleAtNanos = Long.MAX_VALUE private var nextPlanId = 0 private var nextPlanIndex = 0 - private val plans = mutableListOf() + val plans = mutableListOf() override val deferredPlans = ArrayDeque() diff --git a/okhttp/src/test/java/okhttp3/FallbackTestClientSocketFactory.kt b/okhttp/src/jvmTest/kotlin/okhttp3/FallbackTestClientSocketFactory.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/FallbackTestClientSocketFactory.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/FallbackTestClientSocketFactory.kt diff --git a/okhttp/src/test/java/okhttp3/FastFallbackTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/FastFallbackTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/FastFallbackTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/FastFallbackTest.kt diff --git a/okhttp/src/test/java/okhttp3/FormBodyTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/FormBodyTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/FormBodyTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/FormBodyTest.kt diff --git a/okhttp/src/test/java/okhttp3/HandshakeTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/HandshakeTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/HandshakeTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/HandshakeTest.kt diff --git a/okhttp/src/test/java/okhttp3/HeadersChallengesTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/HeadersChallengesTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/HeadersChallengesTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/HeadersChallengesTest.kt diff --git a/okhttp/src/test/java/okhttp3/HeadersJvmTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/HeadersJvmTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/HeadersJvmTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/HeadersJvmTest.kt diff --git a/okhttp/src/test/java/okhttp3/HeadersKotlinTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/HeadersKotlinTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/HeadersKotlinTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/HeadersKotlinTest.kt diff --git a/okhttp/src/test/java/okhttp3/HeadersRequestTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/HeadersRequestTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/HeadersRequestTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/HeadersRequestTest.kt diff --git a/okhttp/src/test/java/okhttp3/HeadersTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/HeadersTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/HeadersTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/HeadersTest.kt diff --git a/okhttp/src/test/java/okhttp3/HttpUrlJvmTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/HttpUrlJvmTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/HttpUrlJvmTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/HttpUrlJvmTest.kt diff --git a/okhttp/src/test/java/okhttp3/HttpUrlTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/HttpUrlTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/HttpUrlTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/HttpUrlTest.kt diff --git a/okhttp/src/test/java/okhttp3/InsecureForHostTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/InsecureForHostTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/InsecureForHostTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/InsecureForHostTest.kt diff --git a/okhttp/src/test/java/okhttp3/InterceptorTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/InterceptorTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/InterceptorTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/InterceptorTest.kt diff --git a/okhttp/src/test/java/okhttp3/JSSETest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/JSSETest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/JSSETest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/JSSETest.kt diff --git a/okhttp/src/test/java/okhttp3/KotlinDeprecationErrorTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/KotlinDeprecationErrorTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/KotlinDeprecationErrorTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/KotlinDeprecationErrorTest.kt diff --git a/okhttp/src/test/java/okhttp3/KotlinSourceModernTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/KotlinSourceModernTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/KotlinSourceModernTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/KotlinSourceModernTest.kt diff --git a/okhttp/src/test/java/okhttp3/LoomTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/LoomTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/LoomTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/LoomTest.kt diff --git a/okhttp/src/test/java/okhttp3/MediaTypeGetTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/MediaTypeGetTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/MediaTypeGetTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/MediaTypeGetTest.kt diff --git a/okhttp/src/test/java/okhttp3/MediaTypeJvmTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/MediaTypeJvmTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/MediaTypeJvmTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/MediaTypeJvmTest.kt diff --git a/okhttp/src/test/java/okhttp3/MediaTypeTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/MediaTypeTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/MediaTypeTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/MediaTypeTest.kt diff --git a/okhttp/src/test/java/okhttp3/MultipartBodyTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/MultipartBodyTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/MultipartBodyTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/MultipartBodyTest.kt diff --git a/okhttp/src/test/java/okhttp3/MultipartReaderTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/MultipartReaderTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/MultipartReaderTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/MultipartReaderTest.kt diff --git a/okhttp/src/test/java/okhttp3/OkHttpClientTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/OkHttpClientTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/OkHttpClientTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/OkHttpClientTest.kt diff --git a/okhttp/src/test/java/okhttp3/OkHttpTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/OkHttpTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/OkHttpTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/OkHttpTest.kt diff --git a/okhttp/src/test/java/okhttp3/OpenJSSETest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/OpenJSSETest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/OpenJSSETest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/OpenJSSETest.kt diff --git a/okhttp/src/test/java/okhttp3/ProtocolTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/ProtocolTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/ProtocolTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/ProtocolTest.kt diff --git a/okhttp/src/test/java/okhttp3/PublicInternalApiTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/PublicInternalApiTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/PublicInternalApiTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/PublicInternalApiTest.kt diff --git a/okhttp/src/test/java/okhttp3/RecordedResponse.kt b/okhttp/src/jvmTest/kotlin/okhttp3/RecordedResponse.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/RecordedResponse.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/RecordedResponse.kt diff --git a/okhttp/src/test/java/okhttp3/RecordingCallback.kt b/okhttp/src/jvmTest/kotlin/okhttp3/RecordingCallback.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/RecordingCallback.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/RecordingCallback.kt diff --git a/okhttp/src/test/java/okhttp3/RecordingExecutor.kt b/okhttp/src/jvmTest/kotlin/okhttp3/RecordingExecutor.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/RecordingExecutor.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/RecordingExecutor.kt diff --git a/okhttp/src/test/java/okhttp3/RequestBodyTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/RequestBodyTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/RequestBodyTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/RequestBodyTest.kt diff --git a/okhttp/src/test/java/okhttp3/RequestCommonTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/RequestCommonTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/RequestCommonTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/RequestCommonTest.kt diff --git a/okhttp/src/test/java/okhttp3/RequestTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/RequestTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/RequestTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/RequestTest.kt diff --git a/okhttp/src/test/java/okhttp3/ResponseBodyJvmTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/ResponseBodyJvmTest.kt similarity index 97% rename from okhttp/src/test/java/okhttp3/ResponseBodyJvmTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/ResponseBodyJvmTest.kt index a7967e92f3f1..730a77bed562 100644 --- a/okhttp/src/test/java/okhttp3/ResponseBodyJvmTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/ResponseBodyJvmTest.kt @@ -62,7 +62,7 @@ class ResponseBodyJvmTest { @Test fun stringBomOverridesExplicitCharset() { - val body = body("0000ffff00000068000000650000006c0000006c0000006f", "utf-8") + val body = body("0000feff00000068000000650000006c0000006c0000006f", "utf-8") assertThat(body.string()).isEqualTo("hello") } @@ -86,13 +86,13 @@ class ResponseBodyJvmTest { @Test fun stringBomUtf32Be() { - val body = body("0000ffff00000068000000650000006c0000006c0000006f") + val body = body("0000feff00000068000000650000006c0000006c0000006f") assertThat(body.string()).isEqualTo("hello") } @Test fun stringBomUtf32Le() { - val body = body("ffff000068000000650000006c0000006c0000006f000000") + val body = body("fffe000068000000650000006c0000006c0000006f000000") assertThat(body.string()).isEqualTo("hello") } @@ -168,13 +168,13 @@ class ResponseBodyJvmTest { @Test fun readerBomUtf32Be() { - val body = body("0000ffff00000068000000650000006c0000006c0000006f") + val body = body("0000feff00000068000000650000006c0000006c0000006f") assertThat(exhaust(body.charStream())).isEqualTo("hello") } @Test fun readerBomUtf32Le() { - val body = body("ffff000068000000650000006c0000006c0000006f000000") + val body = body("fffe000068000000650000006c0000006c0000006f000000") assertThat(exhaust(body.charStream())).isEqualTo("hello") } diff --git a/okhttp/src/test/java/okhttp3/ResponseBodyTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/ResponseBodyTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/ResponseBodyTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/ResponseBodyTest.kt diff --git a/okhttp/src/test/java/okhttp3/ResponseCommonTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/ResponseCommonTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/ResponseCommonTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/ResponseCommonTest.kt diff --git a/okhttp/src/test/java/okhttp3/ResponseJvmTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/ResponseJvmTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/ResponseJvmTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/ResponseJvmTest.kt diff --git a/okhttp/src/test/java/okhttp3/RouteFailureTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/RouteFailureTest.kt similarity index 98% rename from okhttp/src/test/java/okhttp3/RouteFailureTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/RouteFailureTest.kt index 4ced615788da..c0884a454d02 100644 --- a/okhttp/src/test/java/okhttp3/RouteFailureTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/RouteFailureTest.kt @@ -316,7 +316,8 @@ class RouteFailureTest { fun proxyMoveTest(cleanShutdown: Boolean) { // Define a single Proxy at myproxy:8008 that will artificially move during the test val proxySelector = RecordingProxySelector() - proxySelector.proxies.add(Proxy(Proxy.Type.HTTP, InetSocketAddress("myproxy", 8008))) + val socketAddress = InetSocketAddress.createUnresolved("myproxy", 8008) + proxySelector.proxies.add(Proxy(Proxy.Type.HTTP, socketAddress)) // Define two host names for the DNS routing of fake proxy servers val proxyServer1 = InetAddress.getByAddress("proxyServer1", byteArrayOf(127, 0, 0, 2)) diff --git a/okhttp/src/test/java/okhttp3/ServerTruncatesRequestTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/ServerTruncatesRequestTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/ServerTruncatesRequestTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/ServerTruncatesRequestTest.kt diff --git a/okhttp/src/test/java/okhttp3/SessionReuseTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/SessionReuseTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/SessionReuseTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/SessionReuseTest.kt diff --git a/okhttp/src/test/java/okhttp3/SocketChannelTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/SocketChannelTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/SocketChannelTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/SocketChannelTest.kt diff --git a/okhttp/src/test/java/okhttp3/SocksProxy.kt b/okhttp/src/jvmTest/kotlin/okhttp3/SocksProxy.kt similarity index 99% rename from okhttp/src/test/java/okhttp3/SocksProxy.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/SocksProxy.kt index 6873a0a1c911..b83fa0000a34 100644 --- a/okhttp/src/test/java/okhttp3/SocksProxy.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/SocksProxy.kt @@ -30,9 +30,9 @@ import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicInteger import java.util.logging.Level import java.util.logging.Logger +import okhttp3.TestUtil.threadFactory import okhttp3.internal.and import okhttp3.internal.closeQuietly -import okhttp3.internal.threadFactory import okhttp3.internal.threadName import okio.Buffer import okio.BufferedSink @@ -47,7 +47,7 @@ import okio.use * See [RFC 1928](https://www.ietf.org/rfc/rfc1928.txt). */ class SocksProxy { - private val executor = Executors.newCachedThreadPool(threadFactory("SocksProxy", false)) + private val executor = Executors.newCachedThreadPool(threadFactory("SocksProxy")) private var serverSocket: ServerSocket? = null private val connectionCount = AtomicInteger() private val openSockets = Collections.newSetFromMap(ConcurrentHashMap()) diff --git a/okhttp/src/test/java/okhttp3/SocksProxyTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/SocksProxyTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/SocksProxyTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/SocksProxyTest.kt diff --git a/okhttp/src/test/java/okhttp3/TestLogHandler.kt b/okhttp/src/jvmTest/kotlin/okhttp3/TestLogHandler.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/TestLogHandler.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/TestLogHandler.kt diff --git a/okhttp/src/test/java/okhttp3/TestTls13Request.kt b/okhttp/src/jvmTest/kotlin/okhttp3/TestTls13Request.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/TestTls13Request.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/TestTls13Request.kt diff --git a/okhttp/src/test/java/okhttp3/URLConnectionTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/URLConnectionTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/URLConnectionTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/URLConnectionTest.kt diff --git a/okhttp/src/test/java/okhttp3/UrlComponentEncodingTester.kt b/okhttp/src/jvmTest/kotlin/okhttp3/UrlComponentEncodingTester.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/UrlComponentEncodingTester.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/UrlComponentEncodingTester.kt diff --git a/okhttp/src/test/java/okhttp3/UrlComponentEncodingTesterJvm.kt b/okhttp/src/jvmTest/kotlin/okhttp3/UrlComponentEncodingTesterJvm.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/UrlComponentEncodingTesterJvm.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/UrlComponentEncodingTesterJvm.kt diff --git a/okhttp/src/test/java/okhttp3/WebPlatformToAsciiData.kt b/okhttp/src/jvmTest/kotlin/okhttp3/WebPlatformToAsciiData.kt similarity index 93% rename from okhttp/src/test/java/okhttp3/WebPlatformToAsciiData.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/WebPlatformToAsciiData.kt index 474862b25444..1912ae0c7442 100644 --- a/okhttp/src/test/java/okhttp3/WebPlatformToAsciiData.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/WebPlatformToAsciiData.kt @@ -34,7 +34,7 @@ class WebPlatformToAsciiData { companion object { fun load(): List { - val path = okHttpRoot / "okhttp/src/test/resources/web-platform-test-toascii.json" + val path = okHttpRoot / "okhttp/src/jvmTest/resources/web-platform-test-toascii.json" return SYSTEM_FILE_SYSTEM.read(path) { Json.decodeFromString>(readUtf8()) } diff --git a/okhttp/src/test/java/okhttp3/WebPlatformToAsciiTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/WebPlatformToAsciiTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/WebPlatformToAsciiTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/WebPlatformToAsciiTest.kt diff --git a/okhttp/src/test/java/okhttp3/WebPlatformUrlTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/WebPlatformUrlTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/WebPlatformUrlTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/WebPlatformUrlTest.kt diff --git a/okhttp/src/test/java/okhttp3/WebPlatformUrlTestData.kt b/okhttp/src/jvmTest/kotlin/okhttp3/WebPlatformUrlTestData.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/WebPlatformUrlTestData.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/WebPlatformUrlTestData.kt diff --git a/okhttp/src/test/java/okhttp3/WholeOperationTimeoutTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/WholeOperationTimeoutTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/WholeOperationTimeoutTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/WholeOperationTimeoutTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/DoubleInetAddressDns.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/DoubleInetAddressDns.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/DoubleInetAddressDns.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/DoubleInetAddressDns.kt diff --git a/okhttp/src/test/java/okhttp3/internal/HostnamesTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/HostnamesTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/HostnamesTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/HostnamesTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/RecordingAuthenticator.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/RecordingAuthenticator.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/RecordingAuthenticator.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/RecordingAuthenticator.kt diff --git a/okhttp/src/test/java/okhttp3/internal/UtilTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/UtilTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/UtilTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/UtilTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/authenticator/JavaNetAuthenticatorTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticatorTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/authenticator/JavaNetAuthenticatorTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticatorTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/cache/DiskLruCacheTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/cache/DiskLruCacheTest.kt similarity index 99% rename from okhttp/src/test/java/okhttp3/internal/cache/DiskLruCacheTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/cache/DiskLruCacheTest.kt index 2a0d537b8129..284d2d9fe893 100644 --- a/okhttp/src/test/java/okhttp3/internal/cache/DiskLruCacheTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/cache/DiskLruCacheTest.kt @@ -840,7 +840,7 @@ class DiskLruCacheTest { } taskFaker.runNextTask() - // Sanity check that a rebuilt journal behaves normally. + // Check that a rebuilt journal behaves normally. assertValue("a", "a", "a") assertValue("b", "b", "b") } diff --git a/okhttp/src/test/java/okhttp3/internal/cache2/FileOperatorTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/cache2/FileOperatorTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/cache2/FileOperatorTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/cache2/FileOperatorTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/cache2/RelayTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/cache2/RelayTest.kt similarity index 98% rename from okhttp/src/test/java/okhttp3/internal/cache2/RelayTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/cache2/RelayTest.kt index 597b6c43832c..da28c0c117e2 100644 --- a/okhttp/src/test/java/okhttp3/internal/cache2/RelayTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/cache2/RelayTest.kt @@ -25,6 +25,7 @@ import java.io.IOException import java.util.concurrent.Callable import java.util.concurrent.Executors import kotlin.test.assertFailsWith +import okhttp3.TestUtil.threadFactory import okhttp3.internal.cache2.Relay.Companion.edit import okhttp3.internal.cache2.Relay.Companion.read import okio.Buffer @@ -44,7 +45,7 @@ import org.junit.jupiter.api.io.TempDir class RelayTest { @TempDir var tempDir: File? = null - private val executor = Executors.newCachedThreadPool() + private val executor = Executors.newCachedThreadPool(threadFactory("RelayTest")) private val metadata: ByteString = "great metadata!".encodeUtf8() private lateinit var file: File diff --git a/okhttp/src/test/java/okhttp3/internal/concurrent/TaskLoggerTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/concurrent/TaskLoggerTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/concurrent/TaskLoggerTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/concurrent/TaskLoggerTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/concurrent/TaskRunnerRealBackendTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/concurrent/TaskRunnerRealBackendTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/concurrent/TaskRunnerRealBackendTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/concurrent/TaskRunnerRealBackendTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/concurrent/TaskRunnerTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/concurrent/TaskRunnerTest.kt similarity index 87% rename from okhttp/src/test/java/okhttp3/internal/concurrent/TaskRunnerTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/concurrent/TaskRunnerTest.kt index 5f343b5632c7..8675eb99caed 100644 --- a/okhttp/src/test/java/okhttp3/internal/concurrent/TaskRunnerTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/concurrent/TaskRunnerTest.kt @@ -95,11 +95,11 @@ class TaskRunnerTest { assertThat(testLogHandler.takeAll()).containsExactly( "FINE: Q10000 scheduled after 100 µs: task", "FINE: Q10000 starting : task", - "FINE: Q10000 run again after 50 µs: task", "FINE: Q10000 finished run in 0 µs: task", + "FINE: Q10000 run again after 50 µs: task", "FINE: Q10000 starting : task", - "FINE: Q10000 run again after 150 µs: task", "FINE: Q10000 finished run in 0 µs: task", + "FINE: Q10000 run again after 150 µs: task", "FINE: Q10000 starting : task", "FINE: Q10000 finished run in 0 µs: task", ) @@ -137,8 +137,8 @@ class TaskRunnerTest { "FINE: Q10000 scheduled after 100 µs: task", "FINE: Q10000 starting : task", "FINE: Q10000 scheduled after 50 µs: task", - "FINE: Q10000 already scheduled : task", "FINE: Q10000 finished run in 0 µs: task", + "FINE: Q10000 already scheduled : task", "FINE: Q10000 starting : task", "FINE: Q10000 finished run in 0 µs: task", ) @@ -176,8 +176,8 @@ class TaskRunnerTest { "FINE: Q10000 scheduled after 100 µs: task", "FINE: Q10000 starting : task", "FINE: Q10000 scheduled after 200 µs: task", - "FINE: Q10000 run again after 50 µs: task", "FINE: Q10000 finished run in 0 µs: task", + "FINE: Q10000 run again after 50 µs: task", "FINE: Q10000 starting : task", "FINE: Q10000 finished run in 0 µs: task", ) @@ -306,8 +306,8 @@ class TaskRunnerTest { assertThat(testLogHandler.takeAll()).containsExactly( "FINE: Q10000 scheduled after 100 µs: task", "FINE: Q10000 starting : task", - "FINE: Q10000 run again after 50 µs: task", "FINE: Q10000 finished run in 0 µs: task", + "FINE: Q10000 run again after 50 µs: task", "FINE: Q10000 starting : task", "FINE: Q10000 finished run in 0 µs: task", ) @@ -680,6 +680,96 @@ class TaskRunnerTest { assertThat(idleLatch2).isSameAs(idleLatch1) } + @Test fun cancelAllWhenEmptyDoesNotStartWorkerThread() { + redQueue.execute("red task", 100.µs) { + error("expected to be canceled") + } + assertThat(taskFaker.executeCallCount).isEqualTo(1) + + blueQueue.execute("task", 100.µs) { + error("expected to be canceled") + } + assertThat(taskFaker.executeCallCount).isEqualTo(1) + + redQueue.cancelAll() + assertThat(taskFaker.executeCallCount).isEqualTo(1) + + blueQueue.cancelAll() + assertThat(taskFaker.executeCallCount).isEqualTo(1) + } + + @Test fun noMoreThanOneWorkerThreadWaitingToStartAtATime() { + // Enqueueing the red task starts a thread because the head of the queue changed. + redQueue.execute("red task") { + log += "red:starting@${taskFaker.nanoTime}" + taskFaker.sleep(100.µs) + log += "red:finishing@${taskFaker.nanoTime}" + } + assertThat(taskFaker.executeCallCount).isEqualTo(1) + + // Enqueueing the blue task doesn't start a thread because the red one is still starting. + blueQueue.execute("blue task") { + log += "blue:starting@${taskFaker.nanoTime}" + taskFaker.sleep(100.µs) + log += "blue:finishing@${taskFaker.nanoTime}" + } + assertThat(taskFaker.executeCallCount).isEqualTo(1) + + // Running the red task starts another thread, so the two can run in parallel. + taskFaker.runNextTask() + assertThat(log).containsExactly("red:starting@0") + assertThat(taskFaker.executeCallCount).isEqualTo(2) + + // Next the blue task starts. + taskFaker.runNextTask() + assertThat(log).containsExactly( + "red:starting@0", + "blue:starting@0", + ) + assertThat(taskFaker.executeCallCount).isEqualTo(2) + + // Advance time until the tasks complete. + taskFaker.advanceUntil(100.µs) + assertThat(log).containsExactly( + "red:starting@0", + "blue:starting@0", + "red:finishing@100000", + "blue:finishing@100000", + ) + taskFaker.assertNoMoreTasks() + assertThat(taskFaker.executeCallCount).isEqualTo(2) + } + + @Test fun onlyOneCoordinatorWaitingToStartFutureTasks() { + // Enqueueing the red task starts a coordinator thread. + redQueue.execute("red task", 100.µs) { + log += "red:run@${taskFaker.nanoTime}" + } + assertThat(taskFaker.executeCallCount).isEqualTo(1) + + // Enqueueing the blue task doesn't need a 2nd coordinator yet. + blueQueue.execute("blue task", 200.µs) { + log += "blue:run@${taskFaker.nanoTime}" + } + assertThat(taskFaker.executeCallCount).isEqualTo(1) + + // Nothing to do. + taskFaker.runTasks() + assertThat(log).isEmpty() + + // At 100.µs, the coordinator runs the red task and starts a thread for the new coordinator. + taskFaker.advanceUntil(100.µs) + assertThat(log).containsExactly("red:run@100000") + assertThat(taskFaker.executeCallCount).isEqualTo(2) + + // At 200.µs, the blue task runs. + taskFaker.advanceUntil(200.µs) + assertThat(log).containsExactly("red:run@100000", "blue:run@200000") + assertThat(taskFaker.executeCallCount).isEqualTo(2) + + taskFaker.assertNoMoreTasks() + } + private val Int.µs: Long get() = this * 1_000L } diff --git a/okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/ConnectionPoolTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/ConnectionPoolTest.kt new file mode 100644 index 000000000000..74718ae1acf8 --- /dev/null +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/ConnectionPoolTest.kt @@ -0,0 +1,357 @@ +/* + * 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.internal.connection + +import assertk.assertThat +import assertk.assertions.isEmpty +import assertk.assertions.isEqualTo +import assertk.assertions.isFalse +import assertk.assertions.isNotEmpty +import assertk.assertions.isTrue +import okhttp3.Address +import okhttp3.ConnectionPool +import okhttp3.FakeRoutePlanner +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.TestUtil.awaitGarbageCollection +import okhttp3.internal.concurrent.TaskRunner +import okhttp3.internal.concurrent.TaskRunner.RealBackend +import okhttp3.internal.connection.Locks.withLock +import okhttp3.internal.http2.Http2 +import okhttp3.internal.http2.Http2Connection +import okhttp3.internal.http2.Http2ConnectionTest +import okhttp3.internal.http2.MockHttp2Peer +import okhttp3.internal.http2.Settings +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +class ConnectionPoolTest { + private val routePlanner = FakeRoutePlanner() + private val factory = routePlanner.factory + private val taskFaker = routePlanner.taskFaker + private val peer = MockHttp2Peer() + + /** The fake task runner prevents the cleanup runnable from being started. */ + private val addressA = factory.newAddress("a") + private val routeA1 = factory.newRoute(addressA) + private val addressB = factory.newAddress("b") + private val routeB1 = factory.newRoute(addressB) + private val addressC = factory.newAddress("c") + private val routeC1 = factory.newRoute(addressC) + + @AfterEach fun tearDown() { + factory.close() + peer.close() + } + + @Test fun connectionsEvictedWhenIdleLongEnough() { + val pool = factory.newConnectionPool() + val c1 = factory.newConnection(pool, routeA1, 50L) + + // Running at time 50, the pool returns that nothing can be evicted until time 150. + assertThat(pool.closeConnections(50L)).isEqualTo(100L) + assertThat(pool.connectionCount()).isEqualTo(1) + assertThat(c1.socket().isClosed).isFalse() + + // Running at time 60, the pool returns that nothing can be evicted until time 150. + assertThat(pool.closeConnections(60L)).isEqualTo(90L) + assertThat(pool.connectionCount()).isEqualTo(1) + assertThat(c1.socket().isClosed).isFalse() + + // Running at time 149, the pool returns that nothing can be evicted until time 150. + assertThat(pool.closeConnections(149L)).isEqualTo(1L) + assertThat(pool.connectionCount()).isEqualTo(1) + assertThat(c1.socket().isClosed).isFalse() + + // Running at time 150, the pool evicts. + assertThat(pool.closeConnections(150L)).isEqualTo(0) + assertThat(pool.connectionCount()).isEqualTo(0) + assertThat(c1.socket().isClosed).isTrue() + + // Running again, the pool reports that no further runs are necessary. + assertThat(pool.closeConnections(150L)).isEqualTo(-1) + assertThat(pool.connectionCount()).isEqualTo(0) + assertThat(c1.socket().isClosed).isTrue() + } + + @Test fun inUseConnectionsNotEvicted() { + val pool = factory.newConnectionPool() + val poolApi = ConnectionPool(pool) + val c1 = factory.newConnection(pool, routeA1, 50L) + val client = + OkHttpClient.Builder() + .connectionPool(poolApi) + .build() + val call = client.newCall(Request(addressA.url)) as RealCall + call.enterNetworkInterceptorExchange(call.request(), true, factory.newChain(call)) + c1.withLock { call.acquireConnectionNoEvents(c1) } + + // Running at time 50, the pool returns that nothing can be evicted until time 150. + assertThat(pool.closeConnections(50L)).isEqualTo(100L) + assertThat(pool.connectionCount()).isEqualTo(1) + assertThat(c1.socket().isClosed).isFalse() + + // Running at time 60, the pool returns that nothing can be evicted until time 160. + assertThat(pool.closeConnections(60L)).isEqualTo(100L) + assertThat(pool.connectionCount()).isEqualTo(1) + assertThat(c1.socket().isClosed).isFalse() + + // Running at time 160, the pool returns that nothing can be evicted until time 260. + assertThat(pool.closeConnections(160L)).isEqualTo(100L) + assertThat(pool.connectionCount()).isEqualTo(1) + assertThat(c1.socket().isClosed).isFalse() + } + + @Test fun cleanupPrioritizesEarliestEviction() { + val pool = factory.newConnectionPool() + val c1 = factory.newConnection(pool, routeA1, 75L) + val c2 = factory.newConnection(pool, routeB1, 50L) + + // Running at time 75, the pool returns that nothing can be evicted until time 150. + assertThat(pool.closeConnections(75L)).isEqualTo(75L) + assertThat(pool.connectionCount()).isEqualTo(2) + + // Running at time 149, the pool returns that nothing can be evicted until time 150. + assertThat(pool.closeConnections(149L)).isEqualTo(1L) + assertThat(pool.connectionCount()).isEqualTo(2) + + // Running at time 150, the pool evicts c2. + assertThat(pool.closeConnections(150L)).isEqualTo(0L) + assertThat(pool.connectionCount()).isEqualTo(1) + assertThat(c1.socket().isClosed).isFalse() + assertThat(c2.socket().isClosed).isTrue() + + // Running at time 150, the pool returns that nothing can be evicted until time 175. + assertThat(pool.closeConnections(150L)).isEqualTo(25L) + assertThat(pool.connectionCount()).isEqualTo(1) + + // Running at time 175, the pool evicts c1. + assertThat(pool.closeConnections(175L)).isEqualTo(0L) + assertThat(pool.connectionCount()).isEqualTo(0) + assertThat(c1.socket().isClosed).isTrue() + assertThat(c2.socket().isClosed).isTrue() + } + + @Test fun oldestConnectionsEvictedIfIdleLimitExceeded() { + val pool = + factory.newConnectionPool( + maxIdleConnections = 2, + ) + val c1 = factory.newConnection(pool, routeA1, 50L) + val c2 = factory.newConnection(pool, routeB1, 75L) + + // With 2 connections, there's no need to evict until the connections time out. + assertThat(pool.closeConnections(100L)).isEqualTo(50L) + assertThat(pool.connectionCount()).isEqualTo(2) + assertThat(c1.socket().isClosed).isFalse() + assertThat(c2.socket().isClosed).isFalse() + + // Add a third connection + val c3 = factory.newConnection(pool, routeC1, 75L) + + // The third connection bounces the first. + assertThat(pool.closeConnections(100L)).isEqualTo(0L) + assertThat(pool.connectionCount()).isEqualTo(2) + assertThat(c1.socket().isClosed).isTrue() + assertThat(c2.socket().isClosed).isFalse() + assertThat(c3.socket().isClosed).isFalse() + } + + @Test fun leakedAllocation() { + val pool = factory.newConnectionPool() + val poolApi = ConnectionPool(pool) + val c1 = factory.newConnection(pool, routeA1, 0L) + allocateAndLeakAllocation(poolApi, c1) + awaitGarbageCollection() + assertThat(pool.closeConnections(100L)).isEqualTo(0L) + assertThat(c1.calls).isEmpty() + + // Can't allocate once a leak has been detected. + assertThat(c1.noNewExchanges).isTrue() + } + + @Test fun interruptStopsThread() { + val taskRunnerThreads = mutableListOf() + val taskRunner = + TaskRunner( + RealBackend { runnable -> + Thread(runnable, "interruptStopsThread TaskRunner") + .also { taskRunnerThreads += it } + }, + ) + + val pool = + factory.newConnectionPool( + taskRunner = taskRunner, + maxIdleConnections = 2, + ) + factory.newConnection(pool, routeA1) + assertThat(taskRunner.activeQueues()).isNotEmpty() + assertThat(taskRunnerThreads).isNotEmpty() + Thread.sleep(100) + for (t in taskRunnerThreads) { + t.interrupt() + } + Thread.sleep(100) + assertThat(taskRunner.activeQueues()).isEmpty() + } + + @Test fun connectionPreWarmingHttp1() { + taskFaker.advanceUntil(System.nanoTime()) + val expireTime = taskFaker.nanoTime + 1_000_000_000_000 + + routePlanner.autoGeneratePlans = true + routePlanner.defaultConnectionIdleAtNanos = expireTime + val address = routePlanner.address + val pool = routePlanner.pool + + // Connections are created as soon as a policy is set + setPolicy(pool, address, ConnectionPool.AddressPolicy(2)) + assertThat(pool.connectionCount()).isEqualTo(2) + + // Connections are replaced if they idle out or are evicted from the pool + evictAllConnections(pool) + assertThat(pool.connectionCount()).isEqualTo(2) + forceConnectionsToExpire(pool, expireTime) + assertThat(pool.connectionCount()).isEqualTo(2) + + // Excess connections aren't removed until they idle out, even if no longer needed + setPolicy(pool, address, ConnectionPool.AddressPolicy(1)) + assertThat(pool.connectionCount()).isEqualTo(2) + forceConnectionsToExpire(pool, expireTime) + assertThat(pool.connectionCount()).isEqualTo(1) + } + + @Disabled("https://github.com/square/okhttp/issues/8451") + @Test + fun connectionPreWarmingHttp2() { + taskFaker.advanceUntil(System.nanoTime()) + val expireSooner = taskFaker.nanoTime + 1_000_000_000_000 + val expireLater = taskFaker.nanoTime + 2_000_000_000_000 + + routePlanner.autoGeneratePlans = true + val address = routePlanner.address + val pool = routePlanner.pool + + // Add a connection to the pool that won't expire for a while + routePlanner.defaultConnectionIdleAtNanos = expireLater + setPolicy(pool, address, ConnectionPool.AddressPolicy(1)) + assertThat(pool.connectionCount()).isEqualTo(1) + + // All other connections created will expire sooner + routePlanner.defaultConnectionIdleAtNanos = expireSooner + + // Turn it into an http/2 connection that supports 5 concurrent streams + // which can satisfy a larger policy + val connection = routePlanner.plans.first().connection + val http2Connection = connectHttp2(peer, connection, 5) + setPolicy(pool, address, ConnectionPool.AddressPolicy(5)) + assertThat(pool.connectionCount()).isEqualTo(1) + + // Decrease the connection's max so that another connection is needed + updateMaxConcurrentStreams(http2Connection, 4) + assertThat(pool.connectionCount()).isEqualTo(2) + + // Increase the connection's max so that the new connection is no longer needed + updateMaxConcurrentStreams(http2Connection, 5) + forceConnectionsToExpire(pool, expireSooner) + assertThat(pool.connectionCount()).isEqualTo(1) + } + + private fun setPolicy( + pool: RealConnectionPool, + address: Address, + policy: ConnectionPool.AddressPolicy, + ) { + pool.setPolicy(address, policy) + taskFaker.runTasks() + } + + private fun evictAllConnections(pool: RealConnectionPool) { + pool.evictAll() + assertThat(pool.connectionCount()).isEqualTo(0) + taskFaker.runTasks() + } + + private fun forceConnectionsToExpire( + pool: RealConnectionPool, + expireTime: Long, + ) { + val idleTimeNanos = expireTime + pool.keepAliveDurationNs + repeat(pool.connectionCount()) { pool.closeConnections(idleTimeNanos) } + taskFaker.runTasks() + } + + private fun connectHttp2( + peer: MockHttp2Peer, + realConnection: RealConnection, + maxConcurrentStreams: Int, + ): Http2Connection { + // Write the mocking script. + val settings1 = Settings() + settings1[Settings.MAX_CONCURRENT_STREAMS] = maxConcurrentStreams + peer.sendFrame().settings(settings1) + peer.acceptFrame() // ACK + peer.sendFrame().ping(false, 2, 0) + peer.acceptFrame() // PING + peer.play() + + // Play it back. + val connection = + Http2Connection.Builder(true, TaskRunner.INSTANCE) + .socket(peer.openSocket()) + .pushObserver(Http2ConnectionTest.IGNORE) + .listener(realConnection) + .build() + connection.start(sendConnectionPreface = false) + + // verify the peer received the ACK + val ackFrame = peer.takeFrame() + assertThat(ackFrame.type).isEqualTo(Http2.TYPE_SETTINGS) + assertThat(ackFrame.streamId).isEqualTo(0) + assertThat(ackFrame.ack).isTrue() + + taskFaker.runTasks() + + return connection + } + + private fun updateMaxConcurrentStreams( + connection: Http2Connection, + amount: Int, + ) { + val settings = Settings() + settings[Settings.MAX_CONCURRENT_STREAMS] = amount + connection.readerRunnable.applyAndAckSettings(true, settings) + assertThat(connection.peerSettings[Settings.MAX_CONCURRENT_STREAMS]).isEqualTo(amount) + taskFaker.runTasks() + } + + /** Use a helper method so there's no hidden reference remaining on the stack. */ + private fun allocateAndLeakAllocation( + pool: ConnectionPool, + connection: RealConnection, + ) { + val client = + OkHttpClient.Builder() + .connectionPool(pool) + .build() + val call = client.newCall(Request(connection.route().address.url)) as RealCall + call.enterNetworkInterceptorExchange(call.request(), true, factory.newChain(call)) + connection.withLock { call.acquireConnectionNoEvents(connection) } + } +} diff --git a/okhttp/src/test/java/okhttp3/internal/connection/FastFallbackExchangeFinderTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/FastFallbackExchangeFinderTest.kt similarity index 98% rename from okhttp/src/test/java/okhttp3/internal/connection/FastFallbackExchangeFinderTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/FastFallbackExchangeFinderTest.kt index e6327295a4af..1d41ccd14b03 100644 --- a/okhttp/src/test/java/okhttp3/internal/connection/FastFallbackExchangeFinderTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/FastFallbackExchangeFinderTest.kt @@ -25,10 +25,8 @@ import kotlin.test.assertFailsWith import okhttp3.FakeRoutePlanner import okhttp3.FakeRoutePlanner.ConnectState.TLS_CONNECTED import okhttp3.internal.concurrent.TaskFaker -import okhttp3.testing.Flaky import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Test -import org.junitpioneer.jupiter.RetryingTest /** * Unit test for [FastFallbackExchangeFinder] implementation details. @@ -43,7 +41,12 @@ import org.junitpioneer.jupiter.RetryingTest internal class FastFallbackExchangeFinderTest { private val taskFaker = TaskFaker() private val taskRunner = taskFaker.taskRunner - private val routePlanner = FakeRoutePlanner(taskFaker) + + /** + * Note that we don't use the same [TaskFaker] for this factory. That way off-topic tasks like + * connection pool maintenance tasks don't add noise to route planning tests. + */ + private val routePlanner = FakeRoutePlanner(taskFaker = taskFaker) private val finder = FastFallbackExchangeFinder(routePlanner, taskRunner) @AfterEach @@ -790,8 +793,7 @@ internal class FastFallbackExchangeFinderTest { * * https://github.com/square/okhttp/issues/7152 */ - @RetryingTest(5) - @Flaky + @Test fun reusePlanAndNewConnectRace() { val plan0 = routePlanner.addPlan() plan0.tcpConnectDelayNanos = 250.ms @@ -814,12 +816,8 @@ internal class FastFallbackExchangeFinderTest { taskFaker.advanceUntil(250.ms) assertEvents( "take plan 1", - ) - - taskFaker.runTasks() - assertEvents( - "plan 0 TCP connected", "plan 0 cancel", + "plan 0 TCP connect canceled", ) } diff --git a/okhttp/src/test/java/okhttp3/internal/connection/InetAddressOrderTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/InetAddressOrderTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/connection/InetAddressOrderTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/InetAddressOrderTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/connection/RetryConnectionTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/RetryConnectionTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/connection/RetryConnectionTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/RetryConnectionTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/connection/RouteSelectorTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/RouteSelectorTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/connection/RouteSelectorTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/RouteSelectorTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/http/CancelTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http/CancelTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/http/CancelTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http/CancelTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/http/ExternalHttp2Example.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http/ExternalHttp2Example.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/http/ExternalHttp2Example.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http/ExternalHttp2Example.kt diff --git a/okhttp/src/test/java/okhttp3/internal/http/HttpDateTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http/HttpDateTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/http/HttpDateTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http/HttpDateTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/http/StatusLineTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http/StatusLineTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/http/StatusLineTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http/StatusLineTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/http/ThreadInterruptTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http/ThreadInterruptTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/http/ThreadInterruptTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http/ThreadInterruptTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/http2/BaseTestHandler.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/BaseTestHandler.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/http2/BaseTestHandler.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/BaseTestHandler.kt diff --git a/okhttp/src/test/java/okhttp3/internal/http2/FrameLogTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/FrameLogTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/http2/FrameLogTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/FrameLogTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/http2/HpackTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/HpackTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/http2/HpackTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/HpackTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/http2/Http2ConnectionTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/Http2ConnectionTest.kt similarity index 99% rename from okhttp/src/test/java/okhttp3/internal/http2/Http2ConnectionTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/Http2ConnectionTest.kt index faeb3f041104..923522e32503 100644 --- a/okhttp/src/test/java/okhttp3/internal/http2/Http2ConnectionTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/Http2ConnectionTest.kt @@ -38,6 +38,7 @@ import okhttp3.internal.EMPTY_BYTE_ARRAY import okhttp3.internal.EMPTY_HEADERS import okhttp3.internal.concurrent.TaskFaker import okhttp3.internal.concurrent.TaskRunner +import okhttp3.internal.connection.Locks.withLock import okhttp3.internal.notifyAll import okhttp3.internal.wait import okio.AsyncTimeout @@ -968,7 +969,7 @@ class Http2ConnectionTest { } } val connection = connect(peer, IGNORE, listener) - synchronized(connection) { + connection.withLock { assertThat(connection.peerSettings.getMaxConcurrentStreams()).isEqualTo(10) } maxConcurrentStreamsUpdated.await() @@ -997,7 +998,7 @@ class Http2ConnectionTest { val connection = connect(peer) assertThat(peer.takeFrame().type).isEqualTo(Http2.TYPE_SETTINGS) assertThat(peer.takeFrame().type).isEqualTo(Http2.TYPE_PING) - synchronized(connection) { + connection.withLock { assertThat(connection.peerSettings.headerTableSize).isEqualTo(10000) assertThat(connection.peerSettings.initialWindowSize).isEqualTo(40000) assertThat(connection.peerSettings.getMaxFrameSize(-1)).isEqualTo(50000) @@ -1024,7 +1025,7 @@ class Http2ConnectionTest { val settings2 = Settings() settings2[Settings.MAX_CONCURRENT_STREAMS] = 60000 connection.readerRunnable.applyAndAckSettings(true, settings2) - synchronized(connection) { + connection.withLock { assertThat(connection.peerSettings.headerTableSize).isEqualTo(-1) assertThat(connection.peerSettings.initialWindowSize) .isEqualTo(Settings.DEFAULT_INITIAL_WINDOW_SIZE) @@ -1393,7 +1394,7 @@ class Http2ConnectionTest { // Play it back. val connection = connect(peer) connection.newStream(headerEntries("a", "android"), false) - synchronized(connection) { + connection.withLock { if (!connection.isHealthy(System.nanoTime())) { throw ConnectionShutdownException() } diff --git a/okhttp/src/test/java/okhttp3/internal/http2/Http2Test.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/Http2Test.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/http2/Http2Test.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/Http2Test.kt diff --git a/okhttp/src/test/java/okhttp3/internal/http2/HttpOverHttp2Test.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/HttpOverHttp2Test.kt similarity index 99% rename from okhttp/src/test/java/okhttp3/internal/http2/HttpOverHttp2Test.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/HttpOverHttp2Test.kt index 4c1f4b795171..3edea2595db5 100644 --- a/okhttp/src/test/java/okhttp3/internal/http2/HttpOverHttp2Test.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/HttpOverHttp2Test.kt @@ -74,6 +74,7 @@ import okhttp3.SimpleProvider import okhttp3.TestLogHandler import okhttp3.TestUtil.assumeNotWindows import okhttp3.TestUtil.repeat +import okhttp3.TestUtil.threadFactory import okhttp3.internal.DoubleInetAddressDns import okhttp3.internal.EMPTY_REQUEST import okhttp3.internal.RecordingOkAuthenticator @@ -125,7 +126,7 @@ class HttpOverHttp2Test { private lateinit var protocol: Protocol private lateinit var client: OkHttpClient private val fileSystem: FakeFileSystem = FakeFileSystem() - private val cache: Cache = Cache("/tmp/cache".toPath(), Long.MAX_VALUE, fileSystem) + private val cache: Cache = Cache(fileSystem, "/tmp/cache".toPath(), Long.MAX_VALUE) private lateinit var scheme: String private fun configureClientTestRule(): OkHttpClientTestRule { @@ -509,7 +510,7 @@ class HttpOverHttp2Test { setUp(protocol, mockWebServer) server.enqueue(MockResponse(body = "A")) server.enqueue(MockResponse(body = "A")) - val executor = Executors.newCachedThreadPool() + val executor = Executors.newCachedThreadPool(threadFactory("HttpOverHttp2Test")) val countDownLatch = CountDownLatch(2) executor.execute(AsyncRequest("/r1", countDownLatch)) executor.execute(AsyncRequest("/r2", countDownLatch)) diff --git a/okhttp/src/test/java/okhttp3/internal/http2/HuffmanTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/HuffmanTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/http2/HuffmanTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/HuffmanTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/http2/MockHttp2Peer.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/MockHttp2Peer.kt similarity index 99% rename from okhttp/src/test/java/okhttp3/internal/http2/MockHttp2Peer.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/MockHttp2Peer.kt index aa7c8cbebd2c..0b65d9876b03 100644 --- a/okhttp/src/test/java/okhttp3/internal/http2/MockHttp2Peer.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/MockHttp2Peer.kt @@ -24,8 +24,8 @@ import java.util.concurrent.BlockingQueue import java.util.concurrent.Executors import java.util.concurrent.LinkedBlockingQueue import java.util.logging.Logger +import okhttp3.TestUtil.threadFactory import okhttp3.internal.closeQuietly -import okhttp3.internal.threadFactory import okio.Buffer import okio.BufferedSource import okio.ByteString @@ -41,7 +41,7 @@ class MockHttp2Peer : Closeable { private val outFrames: MutableList = ArrayList() private val inFrames: BlockingQueue = LinkedBlockingQueue() private var port = 0 - private val executor = Executors.newSingleThreadExecutor(threadFactory("MockHttp2Peer", false)) + private val executor = Executors.newSingleThreadExecutor(threadFactory("MockHttp2Peer")) private var serverSocket: ServerSocket? = null private var socket: Socket? = null diff --git a/okhttp/src/test/java/okhttp3/internal/http2/SettingsTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/SettingsTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/http2/SettingsTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/SettingsTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/idn/IdnaMappingTableTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/idn/IdnaMappingTableTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/idn/IdnaMappingTableTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/idn/IdnaMappingTableTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/idn/PunycodeTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/idn/PunycodeTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/idn/PunycodeTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/idn/PunycodeTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/io/FaultyFileSystem.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/io/FaultyFileSystem.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/io/FaultyFileSystem.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/io/FaultyFileSystem.kt diff --git a/okhttp/src/test/java/okhttp3/internal/platform/Jdk8WithJettyBootPlatformTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/platform/Jdk8WithJettyBootPlatformTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/platform/Jdk8WithJettyBootPlatformTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/platform/Jdk8WithJettyBootPlatformTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/platform/Jdk9PlatformTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/platform/Jdk9PlatformTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/platform/Jdk9PlatformTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/platform/Jdk9PlatformTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/platform/PlatformTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/platform/PlatformTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/platform/PlatformTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/platform/PlatformTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/publicsuffix/PublicSuffixListGenerator.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/publicsuffix/PublicSuffixListGenerator.kt similarity index 89% rename from okhttp/src/test/java/okhttp3/internal/publicsuffix/PublicSuffixListGenerator.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/publicsuffix/PublicSuffixListGenerator.kt index f83112e2918a..174dc49171e8 100644 --- a/okhttp/src/test/java/okhttp3/internal/publicsuffix/PublicSuffixListGenerator.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/publicsuffix/PublicSuffixListGenerator.kt @@ -13,17 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +@file:OptIn(ExperimentalCoroutinesApi::class) + package okhttp3.internal.publicsuffix import java.util.SortedSet import java.util.TreeSet import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.withContext import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.OkHttpClient import okhttp3.Request -import okhttp3.executeAsync -import okhttp3.internal.publicsuffix.PublicSuffixDatabase.Companion.PUBLIC_SUFFIX_RESOURCE +import okhttp3.coroutines.executeAsync +import okhttp3.internal.publicsuffix.ResourcePublicSuffixList.Companion.PUBLIC_SUFFIX_RESOURCE import okio.BufferedSink import okio.ByteString import okio.ByteString.Companion.encodeUtf8 @@ -49,15 +52,13 @@ class PublicSuffixListGenerator( val fileSystem: FileSystem = FileSystem.SYSTEM, val client: OkHttpClient = OkHttpClient(), ) { - private val resources = projectRoot / "okhttp/src/main/resources/okhttp3/internal/publicsuffix" - private val testResources = projectRoot / "okhttp/src/test/resources/okhttp3/internal/publicsuffix" - private val publicSuffixListDotDat = testResources / "public_suffix_list.dat" - private val outputFile = resources / PUBLIC_SUFFIX_RESOURCE + private val testResources = projectRoot / "okhttp/src/test/resources" + private val publicSuffixListDotDat = testResources / "okhttp3/internal/publicsuffix/public_suffix_list.dat" + private val outputFile = testResources / PUBLIC_SUFFIX_RESOURCE val request = Request("https://publicsuffix.org/list/public_suffix_list.dat".toHttpUrl()) suspend fun import() { - check(fileSystem.metadata(resources).isDirectory) check(fileSystem.metadata(testResources).isDirectory) updateLocalFile() @@ -167,5 +168,14 @@ A wildcard rule was added that wildcards the first level! We'll need to change t } suspend fun main() { - PublicSuffixListGenerator().import() + val publicSuffixListGenerator = PublicSuffixListGenerator() + + try { + publicSuffixListGenerator.import() + } finally { + publicSuffixListGenerator.client.run { + connectionPool.evictAll() + dispatcher.executorService.shutdownNow() + } + } } diff --git a/okhttp/src/test/java/okhttp3/internal/tls/CertificatePinnerChainValidationTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/tls/CertificatePinnerChainValidationTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/tls/CertificatePinnerChainValidationTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/tls/CertificatePinnerChainValidationTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/tls/ClientAuthTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/tls/ClientAuthTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/tls/ClientAuthTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/tls/ClientAuthTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/tls/HostnameVerifierTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/tls/HostnameVerifierTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/tls/HostnameVerifierTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/tls/HostnameVerifierTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/ws/MessageDeflaterInflaterTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/MessageDeflaterInflaterTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/ws/MessageDeflaterInflaterTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/MessageDeflaterInflaterTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/ws/RealWebSocketTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/RealWebSocketTest.kt similarity index 98% rename from okhttp/src/test/java/okhttp3/internal/ws/RealWebSocketTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/RealWebSocketTest.kt index 89b06aabe892..640a2230938d 100644 --- a/okhttp/src/test/java/okhttp3/internal/ws/RealWebSocketTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/RealWebSocketTest.kt @@ -70,6 +70,7 @@ class RealWebSocketTest { server.listener.assertExhausted() server.source.close() client.source.close() + taskFaker.runTasks() server.webSocket!!.tearDown() client.webSocket!!.tearDown() taskFaker.close() @@ -78,7 +79,6 @@ class RealWebSocketTest { @Test fun close() { client.webSocket!!.close(1000, "Hello!") - taskFaker.runTasks() // This will trigger a close response. assertThat(server.processNextFrame()).isFalse() server.listener.assertClosing(1000, "Hello!") @@ -132,7 +132,6 @@ class RealWebSocketTest { @Test fun serverCloseThenWritingPingSucceeds() { server.webSocket!!.close(1000, "Hello!") - taskFaker.runTasks() client.processNextFrame() client.listener.assertClosing(1000, "Hello!") assertThat(client.webSocket!!.pong("Pong?".encodeUtf8())).isTrue() @@ -141,7 +140,6 @@ class RealWebSocketTest { @Test fun clientCanWriteMessagesAfterServerClose() { server.webSocket!!.close(1000, "Hello!") - taskFaker.runTasks() client.processNextFrame() client.listener.assertClosing(1000, "Hello!") assertThat(client.webSocket!!.send("Hi!")).isTrue() @@ -152,11 +150,11 @@ class RealWebSocketTest { @Test fun serverCloseThenClientClose() { server.webSocket!!.close(1000, "Hello!") - taskFaker.runTasks() client.processNextFrame() client.listener.assertClosing(1000, "Hello!") assertThat(client.webSocket!!.close(1000, "Bye!")).isTrue() client.webSocket!!.finishReader() + taskFaker.runTasks() client.listener.assertClosed(1000, "Hello!") server.processNextFrame() server.listener.assertClosing(1000, "Bye!") @@ -171,7 +169,6 @@ class RealWebSocketTest { client.listener.assertClosing(1005, "") client.webSocket!!.finishReader() assertThat(client.webSocket!!.close(1000, "Bye!")).isTrue() - taskFaker.runTasks() server.processNextFrame() server.listener.assertClosing(1000, "Bye!") server.webSocket!!.finishReader() @@ -238,7 +235,6 @@ class RealWebSocketTest { @Test fun serverCloseClosesConnection() { server.webSocket!!.close(1000, "Hello!") - taskFaker.runTasks() client.processNextFrame() // Read server close, send client close, close connection. assertThat(client.closed).isFalse() client.listener.assertClosing(1000, "Hello!") @@ -256,7 +252,6 @@ class RealWebSocketTest { fun clientAndServerCloseClosesConnection() { // Send close from both sides at the same time. server.webSocket!!.close(1000, "Hello!") - taskFaker.runTasks() client.processNextFrame() // Read close, close connection close. assertThat(client.closed).isFalse() client.webSocket!!.close(1000, "Hi!") @@ -277,7 +272,6 @@ class RealWebSocketTest { fun serverCloseBreaksReadMessageLoop() { server.webSocket!!.send("Hello!") server.webSocket!!.close(1000, "Bye!") - taskFaker.runTasks() assertThat(client.processNextFrame()).isTrue() client.listener.assertTextMessage("Hello!") assertThat(client.processNextFrame()).isFalse() @@ -303,7 +297,6 @@ class RealWebSocketTest { @Test fun protocolErrorInCloseResponseClosesConnection() { client.webSocket!!.close(1000, "Hello") - taskFaker.runTasks() server.processNextFrame() // Not closed until close reply is received. assertThat(client.closed).isFalse() @@ -324,7 +317,6 @@ class RealWebSocketTest { @Test fun protocolErrorAfterCloseDoesNotSendClose() { client.webSocket!!.close(1000, "Hello!") - taskFaker.runTasks() server.processNextFrame() // Not closed until close reply is received. @@ -402,7 +394,6 @@ class RealWebSocketTest { // At 0ms the server sends 3 unexpected pongs. The client accepts 'em and ignores em. server.webSocket!!.pong("pong 1".encodeUtf8()) - taskFaker.runTasks() client.processNextFrame() server.webSocket!!.pong("pong 2".encodeUtf8()) client.processNextFrame() @@ -527,6 +518,7 @@ class RealWebSocketTest { } fun processNextFrame(): Boolean { + taskFaker.runTasks() return webSocket!!.processNextFrame() } diff --git a/okhttp/src/test/java/okhttp3/internal/ws/WebSocketExtensionsTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/WebSocketExtensionsTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/ws/WebSocketExtensionsTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/WebSocketExtensionsTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/ws/WebSocketHttpTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/WebSocketHttpTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/ws/WebSocketHttpTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/WebSocketHttpTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/ws/WebSocketReaderTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/WebSocketReaderTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/ws/WebSocketReaderTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/WebSocketReaderTest.kt diff --git a/okhttp/src/test/java/okhttp3/internal/ws/WebSocketRecorder.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/WebSocketRecorder.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/ws/WebSocketRecorder.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/WebSocketRecorder.kt diff --git a/okhttp/src/test/java/okhttp3/internal/ws/WebSocketWriterTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/WebSocketWriterTest.kt similarity index 100% rename from okhttp/src/test/java/okhttp3/internal/ws/WebSocketWriterTest.kt rename to okhttp/src/jvmTest/kotlin/okhttp3/internal/ws/WebSocketWriterTest.kt diff --git a/okhttp/src/jvmTest/kotlin/okhttp3/test/BaseJavaTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/test/BaseJavaTest.kt new file mode 100644 index 000000000000..c1640950596c --- /dev/null +++ b/okhttp/src/jvmTest/kotlin/okhttp3/test/BaseJavaTest.kt @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2024 Block, 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.test + +actual abstract class BaseJavaTest actual constructor() diff --git a/okhttp/src/main/resources/okhttp3/internal/publicsuffix/NOTICE b/okhttp/src/jvmTest/resources/okhttp3/internal/publicsuffix/NOTICE similarity index 100% rename from okhttp/src/main/resources/okhttp3/internal/publicsuffix/NOTICE rename to okhttp/src/jvmTest/resources/okhttp3/internal/publicsuffix/NOTICE diff --git a/okhttp/src/test/resources/okhttp3/internal/publicsuffix/public_suffix_list.dat b/okhttp/src/jvmTest/resources/okhttp3/internal/publicsuffix/public_suffix_list.dat similarity index 52% rename from okhttp/src/test/resources/okhttp3/internal/publicsuffix/public_suffix_list.dat rename to okhttp/src/jvmTest/resources/okhttp3/internal/publicsuffix/public_suffix_list.dat index fcdecb55e42a..03c37d19860b 100644 --- a/okhttp/src/test/resources/okhttp3/internal/publicsuffix/public_suffix_list.dat +++ b/okhttp/src/jvmTest/resources/okhttp3/internal/publicsuffix/public_suffix_list.dat @@ -5,6 +5,9 @@ // Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat, // rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported. +// VERSION: 2024-11-26_09-06-27_UTC +// COMMIT: bf32ba1ae6228a185ebf297d636f1c6541149c45 + // Instructions on pulling and using this list can be found at https://publicsuffix.org/list/. // ===BEGIN ICANN DOMAINS=== @@ -18,9 +21,9 @@ net.ac mil.ac org.ac -// ad : https://en.wikipedia.org/wiki/.ad +// ad : https://www.iana.org/domains/root/db/ad.html +// Confirmed by Amadeu Abril i Abril (CORE) 2024-11-17 ad -nom.ad // ae : https://tdra.gov.ae/en/aeda/ae-policies ae @@ -32,22 +35,30 @@ ac.ae gov.ae mil.ae -// aero : see https://www.information.aero/index.php?id=66 +// aero : https://information.aero/registration/policies/dmp aero +// 2LDs +airline.aero +airport.aero +// 2LDs (currently not accepting registration, seemingly never have) +// As of 2024-07, these are marked as reserved for potential 3LD +// registrations (clause 11 "allocated subdomains" in the 2006 TLD +// policy), but the relevant industry partners have not opened them up +// for registration. Current status can be determined from the TLD's +// policy document: 2LDs that are open for registration must list +// their policy in the TLD's policy. Any 2LD without such a policy is +// not open for registrations. accident-investigation.aero accident-prevention.aero aerobatic.aero aeroclub.aero aerodrome.aero agents.aero -aircraft.aero -airline.aero -airport.aero air-surveillance.aero -airtraffic.aero air-traffic-control.aero +aircraft.aero +airtraffic.aero ambulance.aero -amusement.aero association.aero author.aero ballooning.aero @@ -78,6 +89,7 @@ exchange.aero express.aero federation.aero flight.aero +freight.aero fuel.aero gliding.aero government.aero @@ -92,6 +104,7 @@ leasing.aero logistics.aero magazine.aero maintenance.aero +marketplace.aero media.aero microlight.aero modelling.aero @@ -114,6 +127,7 @@ show.aero skydiving.aero software.aero student.aero +taxi.aero trader.aero trading.aero trainer.aero @@ -121,13 +135,13 @@ union.aero workinggroup.aero works.aero -// af : http://www.nic.af/help.jsp +// af : https://www.nic.af/domain-price af -gov.af com.af -org.af -net.af edu.af +gov.af +net.af +org.af // ag : http://www.nic.ag/prices.htm ag @@ -161,17 +175,20 @@ commune.am net.am org.am -// ao : https://en.wikipedia.org/wiki/.ao +// ao : https://www.iana.org/domains/root/db/ao.html // http://www.dns.ao/REGISTR.DOC ao ed.ao +edu.ao +gov.ao gv.ao og.ao +org.ao co.ao pb.ao it.ao -// aq : https://en.wikipedia.org/wiki/.aq +// aq : https://www.iana.org/domains/root/db/aq.html aq // ar : https://nic.ar/es/nic-argentina/normativa @@ -191,24 +208,25 @@ org.ar senasa.ar tur.ar -// arpa : https://en.wikipedia.org/wiki/.arpa +// arpa : https://www.iana.org/domains/root/db/arpa.html // Confirmed by registry 2008-06-18 arpa e164.arpa +home.arpa in-addr.arpa ip6.arpa iris.arpa uri.arpa urn.arpa -// as : https://en.wikipedia.org/wiki/.as +// as : https://www.iana.org/domains/root/db/as.html as gov.as -// asia : https://en.wikipedia.org/wiki/.asia +// asia : https://www.iana.org/domains/root/db/asia.html asia -// at : https://en.wikipedia.org/wiki/.at +// at : https://www.iana.org/domains/root/db/at.html // Confirmed by registry 2008-06-17 at ac.at @@ -217,8 +235,9 @@ gv.at or.at sth.ac.at -// au : https://en.wikipedia.org/wiki/.au +// au : https://www.iana.org/domains/root/db/au.html // http://www.auda.org.au/ +// Confirmed by registry 2024-11-17 au // 2LDs com.au @@ -229,7 +248,6 @@ gov.au asn.au id.au // Historic 2LDs (closed to new registration, but sites still exist) -info.au conf.au oz.au // CGDNs - http://www.cgdn.org.au/ @@ -264,27 +282,28 @@ wa.gov.au // education.tas.edu.au - Removed at the request of the Department of Education Tasmania schools.nsw.edu.au -// aw : https://en.wikipedia.org/wiki/.aw +// aw : https://www.iana.org/domains/root/db/aw.html aw com.aw -// ax : https://en.wikipedia.org/wiki/.ax +// ax : https://www.iana.org/domains/root/db/ax.html ax -// az : https://en.wikipedia.org/wiki/.az +// az : https://www.iana.org/domains/root/db/az.html +// https://whois.az/?page_id=10 az +biz.az com.az -net.az -int.az -gov.az -org.az edu.az +gov.az info.az -pp.az +int.az mil.az name.az +net.az +org.az +pp.az pro.az -biz.az // ba : http://nic.ba/users_data/files/pravilnik_o_registraciji.pdf ba @@ -295,7 +314,7 @@ mil.ba net.ba org.ba -// bb : https://en.wikipedia.org/wiki/.bb +// bb : https://www.iana.org/domains/root/db/bb.html bb biz.bb co.bb @@ -308,19 +327,19 @@ org.bb store.bb tv.bb -// bd : https://en.wikipedia.org/wiki/.bd +// bd : https://www.iana.org/domains/root/db/bd.html *.bd -// be : https://en.wikipedia.org/wiki/.be +// be : https://www.iana.org/domains/root/db/be.html // Confirmed by registry 2008-06-08 be ac.be -// bf : https://en.wikipedia.org/wiki/.bf +// bf : https://www.iana.org/domains/root/db/bf.html bf gov.bf -// bg : https://en.wikipedia.org/wiki/.bg +// bg : https://www.iana.org/domains/root/db/bg.html // https://www.register.bg/user/static/rules/en/index.html bg a.bg @@ -360,7 +379,7 @@ z.bg 8.bg 9.bg -// bh : https://en.wikipedia.org/wiki/.bh +// bh : https://www.iana.org/domains/root/db/bh.html bh com.bh edu.bh @@ -368,7 +387,7 @@ net.bh org.bh gov.bh -// bi : https://en.wikipedia.org/wiki/.bi +// bi : https://www.iana.org/domains/root/db/bi.html // http://whois.nic.bi/ bi co.bi @@ -377,7 +396,7 @@ edu.bi or.bi org.bi -// biz : https://en.wikipedia.org/wiki/.biz +// biz : https://www.iana.org/domains/root/db/biz.html biz // bj : https://nic.bj/bj-suffixes.txt @@ -420,15 +439,16 @@ gov.bn net.bn org.bn -// bo : https://nic.bo/delegacion2015.php#h-1.10 +// bo : https://nic.bo +// Confirmed by registry 2024-11-19 bo com.bo edu.bo gob.bo int.bo -org.bo -net.bo mil.bo +net.bo +org.bo tv.bo web.bo // Social Domains @@ -454,9 +474,9 @@ natural.bo nombre.bo noticias.bo patria.bo +plurinacional.bo politica.bo profesional.bo -plurinacional.bo pueblo.bo revista.bo salud.bo @@ -484,6 +504,7 @@ ato.br b.br barueri.br belem.br +bet.br bhz.br bib.br bio.br @@ -571,6 +592,7 @@ joinville.br jor.br jus.br leg.br +leilao.br lel.br log.br londrina.br @@ -646,7 +668,7 @@ org.bs edu.bs gov.bs -// bt : https://en.wikipedia.org/wiki/.bt +// bt : https://www.iana.org/domains/root/db/bt.html bt com.bt edu.bt @@ -658,14 +680,14 @@ org.bt // Submitted by registry bv -// bw : https://en.wikipedia.org/wiki/.bw +// bw : https://www.iana.org/domains/root/db/bw.html // http://www.gobin.info/domainname/bw.doc // list of other 2nd level tlds ? bw co.bw org.bw -// by : https://en.wikipedia.org/wiki/.by +// by : https://www.iana.org/domains/root/db/by.html // http://tld.by/rules_2006_en.html // list of other 2nd level tlds ? by @@ -675,20 +697,20 @@ mil.by // second-level domain, but it's being used as one (see www.google.com.by and // www.yahoo.com.by, for example), so we list it here for safety's sake. com.by - // http://hoster.by/ of.by -// bz : https://en.wikipedia.org/wiki/.bz +// bz : https://www.iana.org/domains/root/db/bz.html // http://www.belizenic.bz/ bz +co.bz com.bz net.bz org.bz edu.bz gov.bz -// ca : https://en.wikipedia.org/wiki/.ca +// ca : https://www.iana.org/domains/root/db/ca.html ca // ca geographical names ab.ca @@ -709,27 +731,27 @@ yk.ca // see also: http://registry.gc.ca/en/SubdomainFAQ gc.ca -// cat : https://en.wikipedia.org/wiki/.cat +// cat : https://www.iana.org/domains/root/db/cat.html cat -// cc : https://en.wikipedia.org/wiki/.cc +// cc : https://www.iana.org/domains/root/db/cc.html cc -// cd : https://en.wikipedia.org/wiki/.cd +// cd : https://www.iana.org/domains/root/db/cd.html // see also: https://www.nic.cd/domain/insertDomain_2.jsp?act=1 cd gov.cd -// cf : https://en.wikipedia.org/wiki/.cf +// cf : https://www.iana.org/domains/root/db/cf.html cf -// cg : https://en.wikipedia.org/wiki/.cg +// cg : https://www.iana.org/domains/root/db/cg.html cg -// ch : https://en.wikipedia.org/wiki/.ch +// ch : https://www.iana.org/domains/root/db/ch.html ch -// ci : https://en.wikipedia.org/wiki/.ci +// ci : https://www.iana.org/domains/root/db/ci.html // http://www.nic.ci/index.php?page=charte ci org.ci @@ -744,11 +766,9 @@ go.ci asso.ci aéroport.ci int.ci -presse.ci -md.ci gouv.ci -// ck : https://en.wikipedia.org/wiki/.ck +// ck : https://www.iana.org/domains/root/db/ck.html *.ck !www.ck @@ -760,14 +780,14 @@ gob.cl gov.cl mil.cl -// cm : https://en.wikipedia.org/wiki/.cm plus bug 981927 +// cm : https://www.iana.org/domains/root/db/cm.html plus bug 981927 cm co.cm com.cm gov.cm net.cm -// cn : https://en.wikipedia.org/wiki/.cn +// cn : https://www.iana.org/domains/root/db/cn.html // Submitted by registry cn ac.cn @@ -816,27 +836,23 @@ hk.cn mo.cn tw.cn -// co : https://en.wikipedia.org/wiki/.co -// Submitted by registry +// co : https://www.iana.org/domains/root/db/co.html +// https://www.cointernet.com.co/registra +// https://www.cointernet.com.co/como-funciona-un-dominio-restringido +// Confirmed by registry 2024-11-18 co -arts.co com.co edu.co -firm.co gov.co -info.co -int.co mil.co net.co nom.co org.co -rec.co -web.co -// com : https://en.wikipedia.org/wiki/.com +// com : https://www.iana.org/domains/root/db/com.html com -// coop : https://en.wikipedia.org/wiki/.coop +// coop : https://www.iana.org/domains/root/db/coop.html coop // cr : http://www.nic.cr/niccr_publico/showRegistroDominiosScreen.do @@ -849,33 +865,38 @@ go.cr or.cr sa.cr -// cu : https://en.wikipedia.org/wiki/.cu +// cu : https://www.iana.org/domains/root/db/cu.html cu com.cu edu.cu -org.cu -net.cu -gov.cu +gob.cu inf.cu +nat.cu +net.cu +org.cu -// cv : https://en.wikipedia.org/wiki/.cv -// cv : http://www.dns.cv/tldcv_portal/do?com=DS;5446457100;111;+PAGE(4000018)+K-CAT-CODIGO(RDOM)+RCNT(100); <- registration rules +// cv : https://www.iana.org/domains/root/db/cv.html +// https://ola.cv/domain-extensions-under-cv/ +// Confirmed by registry 2024-11-26 cv com.cv edu.cv +id.cv int.cv +net.cv nome.cv org.cv +publ.cv -// cw : http://www.una.cw/cw_registry/ -// Confirmed by registry 2013-03-26 +// cw : https://www.uoc.cw/cw-registry +// Confirmed by registry 2024-11-19 cw com.cw edu.cw net.cw org.cw -// cx : https://en.wikipedia.org/wiki/.cx +// cx : https://www.iana.org/domains/root/db/cx.html // list of other 2nd level tlds ? cx gov.cx @@ -897,30 +918,33 @@ press.cy pro.cy tm.cy -// cz : https://en.wikipedia.org/wiki/.cz +// cz : https://www.iana.org/domains/root/db/cz.html cz -// de : https://en.wikipedia.org/wiki/.de +// de : https://www.iana.org/domains/root/db/de.html // Confirmed by registry (with technical // reservations) 2008-07-01 de -// dj : https://en.wikipedia.org/wiki/.dj +// dj : https://www.iana.org/domains/root/db/dj.html dj -// dk : https://en.wikipedia.org/wiki/.dk +// dk : https://www.iana.org/domains/root/db/dk.html // Confirmed by registry 2008-06-17 dk -// dm : https://en.wikipedia.org/wiki/.dm +// dm : https://www.iana.org/domains/root/db/dm.html +// https://nic.dm/policies/pdf/DMRulesandGuidelines2024v1.pdf +// Confirmed by registry 2024-11-19 dm +co.dm com.dm -net.dm -org.dm edu.dm gov.dm +net.dm +org.dm -// do : https://en.wikipedia.org/wiki/.do +// do : https://www.iana.org/domains/root/db/do.html do art.do com.do @@ -962,7 +986,7 @@ gov.ec gob.ec mil.ec -// edu : https://en.wikipedia.org/wiki/.edu +// edu : https://www.iana.org/domains/root/db/edu.html edu // ee : http://www.eenet.ee/EENet/dom_reeglid.html#lisa_B @@ -978,7 +1002,7 @@ aip.ee org.ee fie.ee -// eg : https://en.wikipedia.org/wiki/.eg +// eg : https://www.iana.org/domains/root/db/eg.html eg com.eg edu.eg @@ -990,7 +1014,7 @@ net.eg org.eg sci.eg -// er : https://en.wikipedia.org/wiki/.er +// er : https://www.iana.org/domains/root/db/er.html *.er // es : https://www.nic.es/site_ingles/ingles/dominios/index.html @@ -1001,7 +1025,7 @@ org.es gob.es edu.es -// et : https://en.wikipedia.org/wiki/.et +// et : https://www.iana.org/domains/root/db/et.html et com.et gov.et @@ -1012,16 +1036,15 @@ name.et info.et net.et -// eu : https://en.wikipedia.org/wiki/.eu +// eu : https://www.iana.org/domains/root/db/eu.html eu -// fi : https://en.wikipedia.org/wiki/.fi +// fi : https://www.iana.org/domains/root/db/fi.html fi -// aland.fi : https://en.wikipedia.org/wiki/.ax +// aland.fi : https://www.iana.org/domains/root/db/ax.html // This domain is being phased out in favor of .ax. As there are still many // domains under aland.fi, we still keep it on the list until aland.fi is // completely removed. -// TODO: Check for updates (expected to be phased out around Q1/2009) aland.fi // fj : http://domains.fj/ @@ -1038,21 +1061,20 @@ net.fj org.fj pro.fj -// fk : https://en.wikipedia.org/wiki/.fk +// fk : https://www.iana.org/domains/root/db/fk.html *.fk -// fm : https://en.wikipedia.org/wiki/.fm +// fm : https://www.iana.org/domains/root/db/fm.html com.fm edu.fm net.fm org.fm fm -// fo : https://en.wikipedia.org/wiki/.fo +// fo : https://www.iana.org/domains/root/db/fo.html fo -// fr : http://www.afnic.fr/ -// domaines descriptifs : https://www.afnic.fr/medias/documents/Cadre_legal/Afnic_Naming_Policy_12122016_VEN.pdf +// fr : https://www.afnic.fr/ https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf fr asso.fr com.fr @@ -1060,46 +1082,36 @@ gouv.fr nom.fr prd.fr tm.fr -// domaines sectoriels : https://www.afnic.fr/en/products-and-services/the-fr-tld/sector-based-fr-domains-4.html -aeroport.fr -avocat.fr +// Other SLDs now selfmanaged out of AFNIC range. Former "domaines sectoriels", still registration suffixes avoues.fr cci.fr -chambagri.fr -chirurgiens-dentistes.fr -experts-comptables.fr -geometre-expert.fr greta.fr huissier-justice.fr -medecin.fr -notaires.fr -pharmacien.fr -port.fr -veterinaire.fr -// ga : https://en.wikipedia.org/wiki/.ga +// ga : https://www.iana.org/domains/root/db/ga.html ga // gb : This registry is effectively dormant // Submitted by registry gb -// gd : https://en.wikipedia.org/wiki/.gd +// gd : https://www.iana.org/domains/root/db/gd.html edu.gd gov.gd gd -// ge : http://www.nic.net.ge/policy_en.pdf +// ge : https://nic.ge/en/administrator/the-ge-domain-regulations +// Confirmed by registry 2024-11-20 ge com.ge edu.ge gov.ge -org.ge -mil.ge net.ge +org.ge pvt.ge +school.ge -// gf : https://en.wikipedia.org/wiki/.gf +// gf : https://www.iana.org/domains/root/db/gf.html gf // gg : http://www.channelisles.net/register-domains/ @@ -1109,7 +1121,7 @@ co.gg net.gg org.gg -// gh : https://en.wikipedia.org/wiki/.gh +// gh : https://www.iana.org/domains/root/db/gh.html // see also: http://www.nic.gh/reg_now.php // Although domains directly at second level are not possible at the moment, // they have been possible for some time and may come back. @@ -1129,7 +1141,7 @@ mod.gi edu.gi org.gi -// gl : https://en.wikipedia.org/wiki/.gl +// gl : https://www.iana.org/domains/root/db/gl.html // http://nic.gl gl co.gl @@ -1151,7 +1163,7 @@ gov.gn org.gn net.gn -// gov : https://en.wikipedia.org/wiki/.gov +// gov : https://www.iana.org/domains/root/db/gov.html gov // gp : http://www.nic.gp/index.php?lang=en @@ -1163,7 +1175,7 @@ edu.gp org.gp asso.gp -// gq : https://en.wikipedia.org/wiki/.gq +// gq : https://www.iana.org/domains/root/db/gq.html gq // gr : https://grweb.ics.forth.gr/english/1617-B-2005.html @@ -1175,7 +1187,7 @@ net.gr org.gr gov.gr -// gs : https://en.wikipedia.org/wiki/.gs +// gs : https://www.iana.org/domains/root/db/gs.html gs // gt : https://www.gt/sitio/registration_policy.php?lang=en @@ -1201,11 +1213,11 @@ net.gu org.gu web.gu -// gw : https://en.wikipedia.org/wiki/.gw +// gw : https://www.iana.org/domains/root/db/gw.html // gw : https://nic.gw/regras/ gw -// gy : https://en.wikipedia.org/wiki/.gy +// gy : https://www.iana.org/domains/root/db/gy.html // http://registry.gy/ gy co.gy @@ -1240,7 +1252,7 @@ org.hk 組織.hk 組织.hk -// hm : https://en.wikipedia.org/wiki/.hm +// hm : https://www.iana.org/domains/root/db/hm.html hm // hn : http://www.nic.hn/politicas/ps02,,05.html @@ -1329,7 +1341,7 @@ ponpes.id sch.id web.id -// ie : https://en.wikipedia.org/wiki/.ie +// ie : https://www.iana.org/domains/root/db/ie.html ie gov.ie @@ -1369,7 +1381,7 @@ plc.co.im tt.im tv.im -// in : https://en.wikipedia.org/wiki/.in +// in : https://www.iana.org/domains/root/db/in.html // see also: https://registry.in/policies // Please note, that nic.in is not an official eTLD, but used by most // government institutions. @@ -1416,18 +1428,24 @@ uk.in up.in us.in -// info : https://en.wikipedia.org/wiki/.info +// info : https://www.iana.org/domains/root/db/info.html info -// int : https://en.wikipedia.org/wiki/.int +// int : https://www.iana.org/domains/root/db/int.html // Confirmed by registry 2008-06-18 int eu.int // io : http://www.nic.io/rules.htm -// list of other 2nd level tlds ? io +co.io com.io +edu.io +gov.io +mil.io +net.io +nom.io +org.io // iq : http://www.cmc.iq/english/iq/iqregister1.htm iq @@ -1455,16 +1473,10 @@ sch.ir ايران.ir // is : http://www.isnic.is/domain/rules.php -// Confirmed by registry 2008-12-06 +// Confirmed by registry 2024-11-17 is -net.is -com.is -edu.is -gov.is -org.is -int.is - -// it : https://en.wikipedia.org/wiki/.it + +// it : https://www.iana.org/domains/root/db/it.html it gov.it edu.it @@ -1887,21 +1899,28 @@ org.je // jm : http://www.com.jm/register.html *.jm -// jo : http://www.dns.jo/Registration_policy.aspx +// jo : https://www.dns.jo/JoFamily.aspx +// Confirmed by registry 2024-11-17 jo +agri.jo +ai.jo com.jo -org.jo -net.jo edu.jo -sch.jo +eng.jo +fm.jo gov.jo mil.jo -name.jo +net.jo +org.jo +per.jo +phd.jo +sch.jo +tv.jo -// jobs : https://en.wikipedia.org/wiki/.jobs +// jobs : https://www.iana.org/domains/root/db/jobs.html jobs -// jp : https://en.wikipedia.org/wiki/.jp +// jp : https://www.iana.org/domains/root/db/jp.html // http://jprs.co.jp/en/jpdomain.html // Submitted by registry jp @@ -2013,18 +2032,18 @@ yamanashi.jp // jp geographic type names // http://jprs.jp/doc/rule/saisoku-1.html *.kawasaki.jp -*.kitakyushu.jp -*.kobe.jp -*.nagoya.jp -*.sapporo.jp -*.sendai.jp -*.yokohama.jp !city.kawasaki.jp +*.kitakyushu.jp !city.kitakyushu.jp +*.kobe.jp !city.kobe.jp +*.nagoya.jp !city.nagoya.jp +*.sapporo.jp !city.sapporo.jp +*.sendai.jp !city.sendai.jp +*.yokohama.jp !city.yokohama.jp // 4th level registration aisai.aichi.jp @@ -3735,7 +3754,7 @@ gov.ki info.ki com.ki -// km : https://en.wikipedia.org/wiki/.km +// km : https://www.iana.org/domains/root/db/km.html // http://www.domaine.km/documents/charte.doc km org.km @@ -3748,7 +3767,7 @@ mil.km ass.km com.km // These are only mentioned as proposed suggestions at domaine.km, but -// https://en.wikipedia.org/wiki/.km says they're available for registration: +// https://www.iana.org/domains/root/db/km.html says they're available for registration: coop.km asso.km presse.km @@ -3758,7 +3777,7 @@ pharmaciens.km veterinaire.km gouv.km -// kn : https://en.wikipedia.org/wiki/.kn +// kn : https://www.iana.org/domains/root/db/kn.html // http://www.dot.kn/domainRules.html kn net.kn @@ -3775,7 +3794,7 @@ org.kp rep.kp tra.kp -// kr : https://en.wikipedia.org/wiki/.kr +// kr : https://www.iana.org/domains/root/db/kr.html // see also: http://domain.nida.or.kr/eng/registration.jsp kr ac.kr @@ -3828,7 +3847,7 @@ edu.ky net.ky org.ky -// kz : https://en.wikipedia.org/wiki/.kz +// kz : https://www.iana.org/domains/root/db/kz.html // see also: http://www.nic.kz/rules/index.jsp kz org.kz @@ -3838,7 +3857,7 @@ gov.kz mil.kz com.kz -// la : https://en.wikipedia.org/wiki/.la +// la : https://www.iana.org/domains/root/db/la.html // Submitted by registry la int.la @@ -3850,7 +3869,7 @@ per.la com.la org.la -// lb : https://en.wikipedia.org/wiki/.lb +// lb : https://www.iana.org/domains/root/db/lb.html // Submitted by registry lb com.lb @@ -3859,7 +3878,7 @@ gov.lb net.lb org.lb -// lc : https://en.wikipedia.org/wiki/.lc +// lc : https://www.iana.org/domains/root/db/lc.html // see also: http://www.nic.lc/rules.htm lc com.lc @@ -3869,7 +3888,7 @@ org.lc edu.lc gov.lc -// li : https://en.wikipedia.org/wiki/.li +// li : https://www.iana.org/domains/root/db/li.html li // lk : https://www.nic.lk/index.php/domain-registration/lk-domain-naming-structure @@ -3912,7 +3931,7 @@ net.ls org.ls sc.ls -// lt : https://en.wikipedia.org/wiki/.lt +// lt : https://www.iana.org/domains/root/db/lt.html lt // gov.lt : http://www.gov.lt/index_en.php gov.lt @@ -3944,7 +3963,7 @@ med.ly org.ly id.ly -// ma : https://en.wikipedia.org/wiki/.ma +// ma : https://www.iana.org/domains/root/db/ma.html // http://www.anrt.ma/fr/admin/download/upload/file_fr782.pdf ma co.ma @@ -3959,10 +3978,10 @@ mc tm.mc asso.mc -// md : https://en.wikipedia.org/wiki/.md +// md : https://www.iana.org/domains/root/db/md.html md -// me : https://en.wikipedia.org/wiki/.me +// me : https://www.iana.org/domains/root/db/me.html me co.me net.me @@ -3973,25 +3992,24 @@ gov.me its.me priv.me -// mg : http://nic.mg/nicmg/?page_id=39 +// mg : https://nic.mg mg -org.mg -nom.mg -gov.mg -prd.mg -tm.mg +co.mg +com.mg edu.mg +gov.mg mil.mg -com.mg -co.mg +nom.mg +org.mg +prd.mg -// mh : https://en.wikipedia.org/wiki/.mh +// mh : https://www.iana.org/domains/root/db/mh.html mh -// mil : https://en.wikipedia.org/wiki/.mil +// mil : https://www.iana.org/domains/root/db/mil.html mil -// mk : https://en.wikipedia.org/wiki/.mk +// mk : https://www.iana.org/domains/root/db/mk.html // see also: http://dns.marnet.net.mk/postapka.php mk com.mk @@ -4003,7 +4021,7 @@ inf.mk name.mk // ml : http://www.gobin.info/domainname/ml-template.doc -// see also: https://en.wikipedia.org/wiki/.ml +// see also: https://www.iana.org/domains/root/db/ml.html ml com.ml edu.ml @@ -4013,10 +4031,10 @@ net.ml org.ml presse.ml -// mm : https://en.wikipedia.org/wiki/.mm +// mm : https://www.iana.org/domains/root/db/mm.html *.mm -// mn : https://en.wikipedia.org/wiki/.mn +// mn : https://www.iana.org/domains/root/db/mn.html mn gov.mn edu.mn @@ -4030,17 +4048,17 @@ org.mo edu.mo gov.mo -// mobi : https://en.wikipedia.org/wiki/.mobi +// mobi : https://www.iana.org/domains/root/db/mobi.html mobi // mp : http://www.dot.mp/ // Confirmed by registry 2008-06-17 mp -// mq : https://en.wikipedia.org/wiki/.mq +// mq : https://www.iana.org/domains/root/db/mq.html mq -// mr : https://en.wikipedia.org/wiki/.mr +// mr : https://www.iana.org/domains/root/db/mr.html mr gov.mr @@ -4060,7 +4078,7 @@ edu.mt net.mt org.mt -// mu : https://en.wikipedia.org/wiki/.mu +// mu : https://www.iana.org/domains/root/db/mu.html mu com.mu net.mu @@ -4070,557 +4088,10 @@ ac.mu co.mu or.mu -// museum : http://about.museum/naming/ -// http://index.museum/ +// museum : https://welcome.museum/wp-content/uploads/2018/05/20180525-Registration-Policy-MUSEUM-EN_VF-2.pdf https://welcome.museum/buy-your-dot-museum-2/ museum -academy.museum -agriculture.museum -air.museum -airguard.museum -alabama.museum -alaska.museum -amber.museum -ambulance.museum -american.museum -americana.museum -americanantiques.museum -americanart.museum -amsterdam.museum -and.museum -annefrank.museum -anthro.museum -anthropology.museum -antiques.museum -aquarium.museum -arboretum.museum -archaeological.museum -archaeology.museum -architecture.museum -art.museum -artanddesign.museum -artcenter.museum -artdeco.museum -arteducation.museum -artgallery.museum -arts.museum -artsandcrafts.museum -asmatart.museum -assassination.museum -assisi.museum -association.museum -astronomy.museum -atlanta.museum -austin.museum -australia.museum -automotive.museum -aviation.museum -axis.museum -badajoz.museum -baghdad.museum -bahn.museum -bale.museum -baltimore.museum -barcelona.museum -baseball.museum -basel.museum -baths.museum -bauern.museum -beauxarts.museum -beeldengeluid.museum -bellevue.museum -bergbau.museum -berkeley.museum -berlin.museum -bern.museum -bible.museum -bilbao.museum -bill.museum -birdart.museum -birthplace.museum -bonn.museum -boston.museum -botanical.museum -botanicalgarden.museum -botanicgarden.museum -botany.museum -brandywinevalley.museum -brasil.museum -bristol.museum -british.museum -britishcolumbia.museum -broadcast.museum -brunel.museum -brussel.museum -brussels.museum -bruxelles.museum -building.museum -burghof.museum -bus.museum -bushey.museum -cadaques.museum -california.museum -cambridge.museum -can.museum -canada.museum -capebreton.museum -carrier.museum -cartoonart.museum -casadelamoneda.museum -castle.museum -castres.museum -celtic.museum -center.museum -chattanooga.museum -cheltenham.museum -chesapeakebay.museum -chicago.museum -children.museum -childrens.museum -childrensgarden.museum -chiropractic.museum -chocolate.museum -christiansburg.museum -cincinnati.museum -cinema.museum -circus.museum -civilisation.museum -civilization.museum -civilwar.museum -clinton.museum -clock.museum -coal.museum -coastaldefence.museum -cody.museum -coldwar.museum -collection.museum -colonialwilliamsburg.museum -coloradoplateau.museum -columbia.museum -columbus.museum -communication.museum -communications.museum -community.museum -computer.museum -computerhistory.museum -comunicações.museum -contemporary.museum -contemporaryart.museum -convent.museum -copenhagen.museum -corporation.museum -correios-e-telecomunicações.museum -corvette.museum -costume.museum -countryestate.museum -county.museum -crafts.museum -cranbrook.museum -creation.museum -cultural.museum -culturalcenter.museum -culture.museum -cyber.museum -cymru.museum -dali.museum -dallas.museum -database.museum -ddr.museum -decorativearts.museum -delaware.museum -delmenhorst.museum -denmark.museum -depot.museum -design.museum -detroit.museum -dinosaur.museum -discovery.museum -dolls.museum -donostia.museum -durham.museum -eastafrica.museum -eastcoast.museum -education.museum -educational.museum -egyptian.museum -eisenbahn.museum -elburg.museum -elvendrell.museum -embroidery.museum -encyclopedic.museum -england.museum -entomology.museum -environment.museum -environmentalconservation.museum -epilepsy.museum -essex.museum -estate.museum -ethnology.museum -exeter.museum -exhibition.museum -family.museum -farm.museum -farmequipment.museum -farmers.museum -farmstead.museum -field.museum -figueres.museum -filatelia.museum -film.museum -fineart.museum -finearts.museum -finland.museum -flanders.museum -florida.museum -force.museum -fortmissoula.museum -fortworth.museum -foundation.museum -francaise.museum -frankfurt.museum -franziskaner.museum -freemasonry.museum -freiburg.museum -fribourg.museum -frog.museum -fundacio.museum -furniture.museum -gallery.museum -garden.museum -gateway.museum -geelvinck.museum -gemological.museum -geology.museum -georgia.museum -giessen.museum -glas.museum -glass.museum -gorge.museum -grandrapids.museum -graz.museum -guernsey.museum -halloffame.museum -hamburg.museum -handson.museum -harvestcelebration.museum -hawaii.museum -health.museum -heimatunduhren.museum -hellas.museum -helsinki.museum -hembygdsforbund.museum -heritage.museum -histoire.museum -historical.museum -historicalsociety.museum -historichouses.museum -historisch.museum -historisches.museum -history.museum -historyofscience.museum -horology.museum -house.museum -humanities.museum -illustration.museum -imageandsound.museum -indian.museum -indiana.museum -indianapolis.museum -indianmarket.museum -intelligence.museum -interactive.museum -iraq.museum -iron.museum -isleofman.museum -jamison.museum -jefferson.museum -jerusalem.museum -jewelry.museum -jewish.museum -jewishart.museum -jfk.museum -journalism.museum -judaica.museum -judygarland.museum -juedisches.museum -juif.museum -karate.museum -karikatur.museum -kids.museum -koebenhavn.museum -koeln.museum -kunst.museum -kunstsammlung.museum -kunstunddesign.museum -labor.museum -labour.museum -lajolla.museum -lancashire.museum -landes.museum -lans.museum -läns.museum -larsson.museum -lewismiller.museum -lincoln.museum -linz.museum -living.museum -livinghistory.museum -localhistory.museum -london.museum -losangeles.museum -louvre.museum -loyalist.museum -lucerne.museum -luxembourg.museum -luzern.museum -mad.museum -madrid.museum -mallorca.museum -manchester.museum -mansion.museum -mansions.museum -manx.museum -marburg.museum -maritime.museum -maritimo.museum -maryland.museum -marylhurst.museum -media.museum -medical.museum -medizinhistorisches.museum -meeres.museum -memorial.museum -mesaverde.museum -michigan.museum -midatlantic.museum -military.museum -mill.museum -miners.museum -mining.museum -minnesota.museum -missile.museum -missoula.museum -modern.museum -moma.museum -money.museum -monmouth.museum -monticello.museum -montreal.museum -moscow.museum -motorcycle.museum -muenchen.museum -muenster.museum -mulhouse.museum -muncie.museum -museet.museum -museumcenter.museum -museumvereniging.museum -music.museum -national.museum -nationalfirearms.museum -nationalheritage.museum -nativeamerican.museum -naturalhistory.museum -naturalhistorymuseum.museum -naturalsciences.museum -nature.museum -naturhistorisches.museum -natuurwetenschappen.museum -naumburg.museum -naval.museum -nebraska.museum -neues.museum -newhampshire.museum -newjersey.museum -newmexico.museum -newport.museum -newspaper.museum -newyork.museum -niepce.museum -norfolk.museum -north.museum -nrw.museum -nyc.museum -nyny.museum -oceanographic.museum -oceanographique.museum -omaha.museum -online.museum -ontario.museum -openair.museum -oregon.museum -oregontrail.museum -otago.museum -oxford.museum -pacific.museum -paderborn.museum -palace.museum -paleo.museum -palmsprings.museum -panama.museum -paris.museum -pasadena.museum -pharmacy.museum -philadelphia.museum -philadelphiaarea.museum -philately.museum -phoenix.museum -photography.museum -pilots.museum -pittsburgh.museum -planetarium.museum -plantation.museum -plants.museum -plaza.museum -portal.museum -portland.museum -portlligat.museum -posts-and-telecommunications.museum -preservation.museum -presidio.museum -press.museum -project.museum -public.museum -pubol.museum -quebec.museum -railroad.museum -railway.museum -research.museum -resistance.museum -riodejaneiro.museum -rochester.museum -rockart.museum -roma.museum -russia.museum -saintlouis.museum -salem.museum -salvadordali.museum -salzburg.museum -sandiego.museum -sanfrancisco.museum -santabarbara.museum -santacruz.museum -santafe.museum -saskatchewan.museum -satx.museum -savannahga.museum -schlesisches.museum -schoenbrunn.museum -schokoladen.museum -school.museum -schweiz.museum -science.museum -scienceandhistory.museum -scienceandindustry.museum -sciencecenter.museum -sciencecenters.museum -science-fiction.museum -sciencehistory.museum -sciences.museum -sciencesnaturelles.museum -scotland.museum -seaport.museum -settlement.museum -settlers.museum -shell.museum -sherbrooke.museum -sibenik.museum -silk.museum -ski.museum -skole.museum -society.museum -sologne.museum -soundandvision.museum -southcarolina.museum -southwest.museum -space.museum -spy.museum -square.museum -stadt.museum -stalbans.museum -starnberg.museum -state.museum -stateofdelaware.museum -station.museum -steam.museum -steiermark.museum -stjohn.museum -stockholm.museum -stpetersburg.museum -stuttgart.museum -suisse.museum -surgeonshall.museum -surrey.museum -svizzera.museum -sweden.museum -sydney.museum -tank.museum -tcm.museum -technology.museum -telekommunikation.museum -television.museum -texas.museum -textile.museum -theater.museum -time.museum -timekeeping.museum -topology.museum -torino.museum -touch.museum -town.museum -transport.museum -tree.museum -trolley.museum -trust.museum -trustee.museum -uhren.museum -ulm.museum -undersea.museum -university.museum -usa.museum -usantiques.museum -usarts.museum -uscountryestate.museum -usculture.museum -usdecorativearts.museum -usgarden.museum -ushistory.museum -ushuaia.museum -uslivinghistory.museum -utah.museum -uvic.museum -valley.museum -vantaa.museum -versailles.museum -viking.museum -village.museum -virginia.museum -virtual.museum -virtuel.museum -vlaanderen.museum -volkenkunde.museum -wales.museum -wallonie.museum -war.museum -washingtondc.museum -watchandclock.museum -watch-and-clock.museum -western.museum -westfalen.museum -whaling.museum -wildlife.museum -williamsburg.museum -windmill.museum -workshop.museum -york.museum -yorkshire.museum -yosemite.museum -youth.museum -zoological.museum -zoology.museum -ירושלים.museum -иком.museum - -// mv : https://en.wikipedia.org/wiki/.mv + +// mv : https://www.iana.org/domains/root/db/mv.html // "mv" included because, contra Wikipedia, google.mv exists. mv aero.mv @@ -4648,7 +4119,6 @@ coop.mw edu.mw gov.mw int.mw -museum.mw net.mw org.mw @@ -4686,24 +4156,12 @@ net.mz org.mz // na : http://www.na-nic.com.na/ -// http://www.info.na/domain/ na -info.na -pro.na -name.na -school.na -or.na -dr.na -us.na -mx.na -ca.na -in.na -cc.na -tv.na -ws.na -mobi.na +alt.na co.na com.na +gov.na +net.na org.na // name : has 2nd-level tlds, but there's no list of them @@ -4714,13 +4172,13 @@ nc asso.nc nom.nc -// ne : https://en.wikipedia.org/wiki/.ne +// ne : https://www.iana.org/domains/root/db/ne.html ne -// net : https://en.wikipedia.org/wiki/.net +// net : https://www.iana.org/domains/root/db/net.html net -// nf : https://en.wikipedia.org/wiki/.nf +// nf : https://www.iana.org/domains/root/db/nf.html nf com.nf net.nf @@ -4763,7 +4221,7 @@ nom.ni org.ni web.ni -// nl : https://en.wikipedia.org/wiki/.nl +// nl : https://www.iana.org/domains/root/db/nl.html // https://www.sidn.nl/ // ccTLD for the Netherlands nl @@ -5549,10 +5007,10 @@ org.nr net.nr com.nr -// nu : https://en.wikipedia.org/wiki/.nu +// nu : https://www.iana.org/domains/root/db/nu.html nu -// nz : https://en.wikipedia.org/wiki/.nz +// nz : https://www.iana.org/domains/root/db/nz.html // Submitted by registry nz ac.nz @@ -5572,7 +5030,7 @@ org.nz parliament.nz school.nz -// om : https://en.wikipedia.org/wiki/.om +// om : https://www.iana.org/domains/root/db/om.html om co.om com.om @@ -5587,7 +5045,7 @@ pro.om // onion : https://tools.ietf.org/html/rfc7686 onion -// org : https://en.wikipedia.org/wiki/.org +// org : https://www.iana.org/domains/root/db/org.html org // pa : http://www.nic.pa/ @@ -5622,7 +5080,7 @@ com.pf org.pf edu.pf -// pg : https://en.wikipedia.org/wiki/.pg +// pg : https://www.iana.org/domains/root/db/pg.html *.pg // ph : http://www.domains.ph/FAQ2.asp @@ -5637,32 +5095,37 @@ ngo.ph mil.ph i.ph -// pk : http://pk5.pknic.net.pk/pk5/msgNamepk.PK +// pk : https://pknic.net.pk +// pk : http://pk5.pknic.net.pk/pk5/msgNamepk.PK + grandfathered old gon.pk +// Contact Email: staff@pknic.net.pk PKNIC .PK Registry + pk +ac.pk +biz.pk com.pk -net.pk edu.pk -org.pk fam.pk -biz.pk -web.pk -gov.pk +gkp.pk gob.pk +gog.pk gok.pk gon.pk gop.pk gos.pk -info.pk +gov.pk +net.pk +org.pk +web.pk -// pl http://www.dns.pl/english/index.html -// Submitted by registry +// pl : https://www.dns.pl/en/ +// Confirmed by registry 2024-11-18 pl com.pl net.pl org.pl -// pl functional domains (http://www.dns.pl/english/index.html) -aid.pl +// pl functional domains : https://www.dns.pl/en/list_of_functional_domain_names agro.pl +aid.pl atm.pl auto.pl biz.pl @@ -5671,8 +5134,8 @@ gmina.pl gsm.pl info.pl mail.pl -miasta.pl media.pl +miasta.pl mil.pl nieruchomosci.pl nom.pl @@ -5691,56 +5154,65 @@ tm.pl tourism.pl travel.pl turystyka.pl -// Government domains +// Government domains : https://www.dns.pl/informacje_o_rejestracji_domen_gov_pl +// In accordance with the .gov.pl Domain Name Regulations : https://www.dns.pl/regulamin_gov_pl gov.pl ap.gov.pl +griw.gov.pl ic.gov.pl is.gov.pl -us.gov.pl kmpsp.gov.pl +konsulat.gov.pl kppsp.gov.pl -kwpsp.gov.pl -psp.gov.pl -wskr.gov.pl kwp.gov.pl +kwpsp.gov.pl +mup.gov.pl mw.gov.pl -ug.gov.pl -um.gov.pl -umig.gov.pl -ugim.gov.pl -upow.gov.pl -uw.gov.pl -starostwo.gov.pl +oia.gov.pl +oirm.gov.pl +oke.gov.pl +oow.gov.pl +oschr.gov.pl +oum.gov.pl pa.gov.pl +pinb.gov.pl +piw.gov.pl po.gov.pl +pr.gov.pl +psp.gov.pl psse.gov.pl pup.gov.pl rzgw.gov.pl sa.gov.pl +sdn.gov.pl +sko.gov.pl so.gov.pl sr.gov.pl -wsa.gov.pl -sko.gov.pl +starostwo.gov.pl +ug.gov.pl +ugim.gov.pl +um.gov.pl +umig.gov.pl +upow.gov.pl +uppo.gov.pl +us.gov.pl +uw.gov.pl uzs.gov.pl +wif.gov.pl wiih.gov.pl winb.gov.pl -pinb.gov.pl wios.gov.pl witd.gov.pl -wzmiuw.gov.pl -piw.gov.pl wiw.gov.pl -griw.gov.pl -wif.gov.pl -oum.gov.pl -sdn.gov.pl -zp.gov.pl -uppo.gov.pl -mup.gov.pl +wkz.gov.pl +wsa.gov.pl +wskr.gov.pl +wsse.gov.pl wuoz.gov.pl -konsulat.gov.pl -oirm.gov.pl -// pl regional domains (http://www.dns.pl/english/index.html) +wzmiuw.gov.pl +zp.gov.pl +zpisdn.gov.pl +// pl regional domains : https://www.dns.pl/en/list_of_regional_domain_names augustow.pl babia-gora.pl bedzin.pl @@ -5767,11 +5239,11 @@ jaworzno.pl jelenia-gora.pl jgora.pl kalisz.pl -kazimierz-dolny.pl karpacz.pl kartuzy.pl kaszuby.pl katowice.pl +kazimierz-dolny.pl kepno.pl ketrzyn.pl klodzko.pl @@ -5814,8 +5286,8 @@ pisz.pl podhale.pl podlasie.pl polkowice.pl -pomorze.pl pomorskie.pl +pomorze.pl prochowice.pl pruszkow.pl przeworsk.pl @@ -5826,11 +5298,11 @@ rybnik.pl rzeszow.pl sanok.pl sejny.pl +skoczow.pl slask.pl slupsk.pl sosnowiec.pl stalowa-wola.pl -skoczow.pl starachowice.pl stargard.pl suwalki.pl @@ -5861,7 +5333,7 @@ zarow.pl zgora.pl zgorzelec.pl -// pm : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf +// pm : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf pm // pn : http://www.government.pn/PnRegistry/policies.htm @@ -5872,7 +5344,7 @@ org.pn edu.pn net.pn -// post : https://en.wikipedia.org/wiki/.post +// post : https://www.iana.org/domains/root/db/post.html post // pr : http://www.nic.pr/index.asp?f=1 @@ -5887,7 +5359,7 @@ pro.pr biz.pr info.pr name.pr -// these aren't mentioned on nic.pr, but on https://en.wikipedia.org/wiki/.pr +// these aren't mentioned on nic.pr, but on https://www.iana.org/domains/root/db/pr.html est.pr prof.pr ac.pr @@ -5906,7 +5378,7 @@ law.pro med.pro recht.pro -// ps : https://en.wikipedia.org/wiki/.ps +// ps : https://www.iana.org/domains/root/db/ps.html // http://www.nic.ps/registration/policy.html#reg ps edu.ps @@ -5928,10 +5400,9 @@ publ.pt com.pt nome.pt -// pw : https://en.wikipedia.org/wiki/.pw +// pw : https://www.iana.org/domains/root/db/pw.html pw co.pw -ne.pw or.pw ed.pw go.pw @@ -5959,11 +5430,12 @@ net.qa org.qa sch.qa -// re : http://www.afnic.re/obtenir/chartes/nommage-re/annexe-descriptifs +// re : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +// Confirmed by registry 2024-11-18 re +// Closed for registration on 2013-03-15 but domains are still maintained asso.re com.re -nom.re // ro : http://www.rotld.ro/ ro @@ -6042,7 +5514,7 @@ tv.sd gov.sd info.sd -// se : https://en.wikipedia.org/wiki/.se +// se : https://www.iana.org/domains/root/db/se.html // Submitted by registry se a.se @@ -6085,14 +5557,14 @@ x.se y.se z.se -// sg : http://www.nic.net.sg/page/registration-policies-procedures-and-guidelines +// sg : https://www.sgnic.sg/domain-registration/sg-categories-rules +// Confirmed by registry 2024-11-19 sg com.sg net.sg org.sg gov.sg edu.sg -per.sg // sh : http://nic.sh/rules.htm sh @@ -6102,15 +5574,14 @@ gov.sh org.sh mil.sh -// si : https://en.wikipedia.org/wiki/.si +// si : https://www.iana.org/domains/root/db/si.html si // sj : No registrations at this time. // Submitted by registry sj -// sk : https://en.wikipedia.org/wiki/.sk -// list of 2nd level domains ? +// sk : https://www.iana.org/domains/root/db/sk.html sk // sl : http://www.nic.sl @@ -6122,10 +5593,10 @@ edu.sl gov.sl org.sl -// sm : https://en.wikipedia.org/wiki/.sm +// sm : https://www.iana.org/domains/root/db/sm.html sm -// sn : https://en.wikipedia.org/wiki/.sn +// sn : https://www.iana.org/domains/root/db/sn.html sn art.sn com.sn @@ -6144,13 +5615,14 @@ me.so net.so org.so -// sr : https://en.wikipedia.org/wiki/.sr +// sr : https://www.iana.org/domains/root/db/sr.html sr // ss : https://registry.nic.ss/ // Submitted by registry ss biz.ss +co.ss com.ss edu.ss gov.ss @@ -6173,7 +5645,7 @@ principe.st saotome.st store.st -// su : https://en.wikipedia.org/wiki/.su +// su : https://www.iana.org/domains/root/db/su.html su // sv : http://www.svnet.org.sv/niveldos.pdf @@ -6184,12 +5656,12 @@ gob.sv org.sv red.sv -// sx : https://en.wikipedia.org/wiki/.sx +// sx : https://www.iana.org/domains/root/db/sx.html // Submitted by registry sx gov.sx -// sy : https://en.wikipedia.org/wiki/.sy +// sy : https://www.iana.org/domains/root/db/sy.html // see also: http://www.gobin.info/domainname/sy.doc sy edu.sy @@ -6199,31 +5671,31 @@ mil.sy com.sy org.sy -// sz : https://en.wikipedia.org/wiki/.sz +// sz : https://www.iana.org/domains/root/db/sz.html // http://www.sispa.org.sz/ sz co.sz ac.sz org.sz -// tc : https://en.wikipedia.org/wiki/.tc +// tc : https://www.iana.org/domains/root/db/tc.html tc -// td : https://en.wikipedia.org/wiki/.td +// td : https://www.iana.org/domains/root/db/td.html td -// tel: https://en.wikipedia.org/wiki/.tel +// tel: https://www.iana.org/domains/root/db/tel.html // http://www.telnic.org/ tel -// tf : https://en.wikipedia.org/wiki/.tf +// tf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf tf -// tg : https://en.wikipedia.org/wiki/.tg +// tg : https://www.iana.org/domains/root/db/tg.html // http://www.nic.tg/ tg -// th : https://en.wikipedia.org/wiki/.th +// th : https://www.iana.org/domains/root/db/th.html // Submitted by registry th ac.th @@ -6252,23 +5724,24 @@ org.tj test.tj web.tj -// tk : https://en.wikipedia.org/wiki/.tk +// tk : https://www.iana.org/domains/root/db/tk.html tk -// tl : https://en.wikipedia.org/wiki/.tl +// tl : https://www.iana.org/domains/root/db/tl.html tl gov.tl -// tm : http://www.nic.tm/local.html +// tm : https://www.nic.tm/local.html +// Confirmed by registry - 2024-11-19 tm -com.tm co.tm -org.tm -net.tm -nom.tm +com.tm +edu.tm gov.tm mil.tm -edu.tm +net.tm +nom.tm +org.tm // tn : http://www.registre.tn/fr/ // https://whois.ati.tn/ @@ -6287,7 +5760,7 @@ org.tn perso.tn tourism.tn -// to : https://en.wikipedia.org/wiki/.to +// to : https://www.iana.org/domains/root/db/to.html // Submitted by registry to com.to @@ -6327,32 +5800,27 @@ nc.tr // Used by government agencies of Northern Cyprus gov.nc.tr -// tt : http://www.nic.tt/ +// tt : https://www.nic.tt/ +// Confirmed by registry - 2024-11-19 tt +biz.tt co.tt com.tt -org.tt -net.tt -biz.tt +edu.tt +gov.tt info.tt -pro.tt -int.tt -coop.tt -jobs.tt -mobi.tt -travel.tt -museum.tt -aero.tt +mil.tt name.tt -gov.tt -edu.tt +net.tt +org.tt +pro.tt -// tv : https://en.wikipedia.org/wiki/.tv +// tv : https://www.iana.org/domains/root/db/tv.html // Not listing any 2LDs as reserved since none seem to exist in practice, // Wikipedia notwithstanding. tv -// tw : https://en.wikipedia.org/wiki/.tw +// tw : https://www.iana.org/domains/root/db/tw.html tw edu.tw gov.tw @@ -6424,6 +5892,7 @@ kiev.ua kirovograd.ua km.ua kr.ua +kropyvnytskyi.ua krym.ua ks.ua kv.ua @@ -6431,6 +5900,7 @@ kyiv.ua lg.ua lt.ua lugansk.ua +luhansk.ua lutsk.ua lv.ua lviv.ua @@ -6454,11 +5924,13 @@ te.ua ternopil.ua uz.ua uzhgorod.ua +uzhhorod.ua vinnica.ua vinnytsia.ua vn.ua volyn.ua yalta.ua +zakarpattia.ua zaporizhzhe.ua zaporizhzhia.ua zhitomir.ua @@ -6477,7 +5949,7 @@ ne.ug com.ug org.ug -// uk : https://en.wikipedia.org/wiki/.uk +// uk : https://www.iana.org/domains/root/db/uk.html // Submitted by registry uk ac.uk @@ -6492,7 +5964,7 @@ plc.uk police.uk *.sch.uk -// us : https://en.wikipedia.org/wiki/.us +// us : https://www.iana.org/domains/root/db/us.html us dni.us fed.us @@ -6570,7 +6042,6 @@ k12.ca.us k12.co.us k12.ct.us k12.dc.us -k12.de.us k12.fl.us k12.ga.us k12.gu.us @@ -6761,10 +6232,10 @@ com.uz net.uz org.uz -// va : https://en.wikipedia.org/wiki/.va +// va : https://www.iana.org/domains/root/db/va.html va -// vc : https://en.wikipedia.org/wiki/.vc +// vc : https://www.iana.org/domains/root/db/vc.html // Submitted by registry vc com.vc @@ -6798,7 +6269,7 @@ store.ve tec.ve web.ve -// vg : https://en.wikipedia.org/wiki/.vg +// vg : https://www.iana.org/domains/root/db/vg.html vg // vi : http://www.nic.vi/newdomainform.htm @@ -6812,22 +6283,91 @@ k12.vi net.vi org.vi -// vn : https://www.dot.vn/vnnic/vnnic/domainregistration.jsp +// vn : https://www.vnnic.vn/en/domain/cctld-vn +// https://vnnic.vn/sites/default/files/tailieu/vn.cctld.domains.txt vn +ac.vn +ai.vn +biz.vn com.vn -net.vn -org.vn edu.vn gov.vn -int.vn -ac.vn -biz.vn +health.vn +id.vn info.vn +int.vn +io.vn name.vn +net.vn +org.vn pro.vn -health.vn -// vu : https://en.wikipedia.org/wiki/.vu +// vn geographical names +angiang.vn +bacgiang.vn +backan.vn +baclieu.vn +bacninh.vn +baria-vungtau.vn +bentre.vn +binhdinh.vn +binhduong.vn +binhphuoc.vn +binhthuan.vn +camau.vn +cantho.vn +caobang.vn +daklak.vn +daknong.vn +danang.vn +dienbien.vn +dongnai.vn +dongthap.vn +gialai.vn +hagiang.vn +haiduong.vn +haiphong.vn +hanam.vn +hanoi.vn +hatinh.vn +haugiang.vn +hoabinh.vn +hungyen.vn +khanhhoa.vn +kiengiang.vn +kontum.vn +laichau.vn +lamdong.vn +langson.vn +laocai.vn +longan.vn +namdinh.vn +nghean.vn +ninhbinh.vn +ninhthuan.vn +phutho.vn +phuyen.vn +quangbinh.vn +quangnam.vn +quangngai.vn +quangninh.vn +quangtri.vn +soctrang.vn +sonla.vn +tayninh.vn +thaibinh.vn +thainguyen.vn +thanhhoa.vn +thanhphohochiminh.vn +thuathienhue.vn +tiengiang.vn +travinh.vn +tuyenquang.vn +vinhlong.vn +vinhphuc.vn +yenbai.vn + +// vu : https://www.iana.org/domains/root/db/vu.html // http://www.vunic.vu/ vu com.vu @@ -6835,10 +6375,10 @@ edu.vu net.vu org.vu -// wf : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf +// wf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf wf -// ws : https://en.wikipedia.org/wiki/.ws +// ws : https://www.iana.org/domains/root/db/ws.html // http://samoanic.ws/index.dhtml ws com.ws @@ -6847,7 +6387,7 @@ org.ws gov.ws edu.ws -// yt : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf +// yt : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf yt // IDN ccTLDs @@ -7186,3479 +6726,4515 @@ gov.zw mil.zw org.zw - // newGTLDs -// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2023-02-15T15:49:53Z +// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2024-10-31T15:17:42Z // This list is auto-generated, don't edit it manually. -// aaa : 2015-02-26 American Automobile Association, Inc. +// aaa : American Automobile Association, Inc. +// https://www.iana.org/domains/root/db/aaa.html aaa -// aarp : 2015-05-21 AARP +// aarp : AARP +// https://www.iana.org/domains/root/db/aarp.html aarp -// abarth : 2015-07-30 Fiat Chrysler Automobiles N.V. -abarth - -// abb : 2014-10-24 ABB Ltd +// abb : ABB Ltd +// https://www.iana.org/domains/root/db/abb.html abb -// abbott : 2014-07-24 Abbott Laboratories, Inc. +// abbott : Abbott Laboratories, Inc. +// https://www.iana.org/domains/root/db/abbott.html abbott -// abbvie : 2015-07-30 AbbVie Inc. +// abbvie : AbbVie Inc. +// https://www.iana.org/domains/root/db/abbvie.html abbvie -// abc : 2015-07-30 Disney Enterprises, Inc. +// abc : Disney Enterprises, Inc. +// https://www.iana.org/domains/root/db/abc.html abc -// able : 2015-06-25 Able Inc. +// able : Able Inc. +// https://www.iana.org/domains/root/db/able.html able -// abogado : 2014-04-24 Registry Services, LLC +// abogado : Registry Services, LLC +// https://www.iana.org/domains/root/db/abogado.html abogado -// abudhabi : 2015-07-30 Abu Dhabi Systems and Information Centre +// abudhabi : Abu Dhabi Systems and Information Centre +// https://www.iana.org/domains/root/db/abudhabi.html abudhabi -// academy : 2013-11-07 Binky Moon, LLC +// academy : Binky Moon, LLC +// https://www.iana.org/domains/root/db/academy.html academy -// accenture : 2014-08-15 Accenture plc +// accenture : Accenture plc +// https://www.iana.org/domains/root/db/accenture.html accenture -// accountant : 2014-11-20 dot Accountant Limited +// accountant : dot Accountant Limited +// https://www.iana.org/domains/root/db/accountant.html accountant -// accountants : 2014-03-20 Binky Moon, LLC +// accountants : Binky Moon, LLC +// https://www.iana.org/domains/root/db/accountants.html accountants -// aco : 2015-01-08 ACO Severin Ahlmann GmbH & Co. KG +// aco : ACO Severin Ahlmann GmbH & Co. KG +// https://www.iana.org/domains/root/db/aco.html aco -// actor : 2013-12-12 Dog Beach, LLC +// actor : Dog Beach, LLC +// https://www.iana.org/domains/root/db/actor.html actor -// ads : 2014-12-04 Charleston Road Registry Inc. +// ads : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/ads.html ads -// adult : 2014-10-16 ICM Registry AD LLC +// adult : ICM Registry AD LLC +// https://www.iana.org/domains/root/db/adult.html adult -// aeg : 2015-03-19 Aktiebolaget Electrolux +// aeg : Aktiebolaget Electrolux +// https://www.iana.org/domains/root/db/aeg.html aeg -// aetna : 2015-05-21 Aetna Life Insurance Company +// aetna : Aetna Life Insurance Company +// https://www.iana.org/domains/root/db/aetna.html aetna -// afl : 2014-10-02 Australian Football League +// afl : Australian Football League +// https://www.iana.org/domains/root/db/afl.html afl -// africa : 2014-03-24 ZA Central Registry NPC trading as Registry.Africa +// africa : ZA Central Registry NPC trading as Registry.Africa +// https://www.iana.org/domains/root/db/africa.html africa -// agakhan : 2015-04-23 Fondation Aga Khan (Aga Khan Foundation) +// agakhan : Fondation Aga Khan (Aga Khan Foundation) +// https://www.iana.org/domains/root/db/agakhan.html agakhan -// agency : 2013-11-14 Binky Moon, LLC +// agency : Binky Moon, LLC +// https://www.iana.org/domains/root/db/agency.html agency -// aig : 2014-12-18 American International Group, Inc. +// aig : American International Group, Inc. +// https://www.iana.org/domains/root/db/aig.html aig -// airbus : 2015-07-30 Airbus S.A.S. +// airbus : Airbus S.A.S. +// https://www.iana.org/domains/root/db/airbus.html airbus -// airforce : 2014-03-06 Dog Beach, LLC +// airforce : Dog Beach, LLC +// https://www.iana.org/domains/root/db/airforce.html airforce -// airtel : 2014-10-24 Bharti Airtel Limited +// airtel : Bharti Airtel Limited +// https://www.iana.org/domains/root/db/airtel.html airtel -// akdn : 2015-04-23 Fondation Aga Khan (Aga Khan Foundation) +// akdn : Fondation Aga Khan (Aga Khan Foundation) +// https://www.iana.org/domains/root/db/akdn.html akdn -// alfaromeo : 2015-07-31 Fiat Chrysler Automobiles N.V. -alfaromeo - -// alibaba : 2015-01-15 Alibaba Group Holding Limited +// alibaba : Alibaba Group Holding Limited +// https://www.iana.org/domains/root/db/alibaba.html alibaba -// alipay : 2015-01-15 Alibaba Group Holding Limited +// alipay : Alibaba Group Holding Limited +// https://www.iana.org/domains/root/db/alipay.html alipay -// allfinanz : 2014-07-03 Allfinanz Deutsche Vermögensberatung Aktiengesellschaft +// allfinanz : Allfinanz Deutsche Vermögensberatung Aktiengesellschaft +// https://www.iana.org/domains/root/db/allfinanz.html allfinanz -// allstate : 2015-07-31 Allstate Fire and Casualty Insurance Company +// allstate : Allstate Fire and Casualty Insurance Company +// https://www.iana.org/domains/root/db/allstate.html allstate -// ally : 2015-06-18 Ally Financial Inc. +// ally : Ally Financial Inc. +// https://www.iana.org/domains/root/db/ally.html ally -// alsace : 2014-07-02 Region Grand Est +// alsace : Region Grand Est +// https://www.iana.org/domains/root/db/alsace.html alsace -// alstom : 2015-07-30 ALSTOM +// alstom : ALSTOM +// https://www.iana.org/domains/root/db/alstom.html alstom -// amazon : 2019-12-19 Amazon Registry Services, Inc. +// amazon : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/amazon.html amazon -// americanexpress : 2015-07-31 American Express Travel Related Services Company, Inc. +// americanexpress : American Express Travel Related Services Company, Inc. +// https://www.iana.org/domains/root/db/americanexpress.html americanexpress -// americanfamily : 2015-07-23 AmFam, Inc. +// americanfamily : AmFam, Inc. +// https://www.iana.org/domains/root/db/americanfamily.html americanfamily -// amex : 2015-07-31 American Express Travel Related Services Company, Inc. +// amex : American Express Travel Related Services Company, Inc. +// https://www.iana.org/domains/root/db/amex.html amex -// amfam : 2015-07-23 AmFam, Inc. +// amfam : AmFam, Inc. +// https://www.iana.org/domains/root/db/amfam.html amfam -// amica : 2015-05-28 Amica Mutual Insurance Company +// amica : Amica Mutual Insurance Company +// https://www.iana.org/domains/root/db/amica.html amica -// amsterdam : 2014-07-24 Gemeente Amsterdam +// amsterdam : Gemeente Amsterdam +// https://www.iana.org/domains/root/db/amsterdam.html amsterdam -// analytics : 2014-12-18 Campus IP LLC +// analytics : Campus IP LLC +// https://www.iana.org/domains/root/db/analytics.html analytics -// android : 2014-08-07 Charleston Road Registry Inc. +// android : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/android.html android -// anquan : 2015-01-08 Beijing Qihu Keji Co., Ltd. +// anquan : Beijing Qihu Keji Co., Ltd. +// https://www.iana.org/domains/root/db/anquan.html anquan -// anz : 2015-07-31 Australia and New Zealand Banking Group Limited +// anz : Australia and New Zealand Banking Group Limited +// https://www.iana.org/domains/root/db/anz.html anz -// aol : 2015-09-17 Oath Inc. +// aol : Yahoo Inc. +// https://www.iana.org/domains/root/db/aol.html aol -// apartments : 2014-12-11 Binky Moon, LLC +// apartments : Binky Moon, LLC +// https://www.iana.org/domains/root/db/apartments.html apartments -// app : 2015-05-14 Charleston Road Registry Inc. +// app : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/app.html app -// apple : 2015-05-14 Apple Inc. +// apple : Apple Inc. +// https://www.iana.org/domains/root/db/apple.html apple -// aquarelle : 2014-07-24 Aquarelle.com +// aquarelle : Aquarelle.com +// https://www.iana.org/domains/root/db/aquarelle.html aquarelle -// arab : 2015-11-12 League of Arab States +// arab : League of Arab States +// https://www.iana.org/domains/root/db/arab.html arab -// aramco : 2014-11-20 Aramco Services Company +// aramco : Aramco Services Company +// https://www.iana.org/domains/root/db/aramco.html aramco -// archi : 2014-02-06 Identity Digital Limited +// archi : Identity Digital Limited +// https://www.iana.org/domains/root/db/archi.html archi -// army : 2014-03-06 Dog Beach, LLC +// army : Dog Beach, LLC +// https://www.iana.org/domains/root/db/army.html army -// art : 2016-03-24 UK Creative Ideas Limited +// art : UK Creative Ideas Limited +// https://www.iana.org/domains/root/db/art.html art -// arte : 2014-12-11 Association Relative à la Télévision Européenne G.E.I.E. +// arte : Association Relative à la Télévision Européenne G.E.I.E. +// https://www.iana.org/domains/root/db/arte.html arte -// asda : 2015-07-31 Wal-Mart Stores, Inc. +// asda : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/asda.html asda -// associates : 2014-03-06 Binky Moon, LLC +// associates : Binky Moon, LLC +// https://www.iana.org/domains/root/db/associates.html associates -// athleta : 2015-07-30 The Gap, Inc. +// athleta : The Gap, Inc. +// https://www.iana.org/domains/root/db/athleta.html athleta -// attorney : 2014-03-20 Dog Beach, LLC +// attorney : Dog Beach, LLC +// https://www.iana.org/domains/root/db/attorney.html attorney -// auction : 2014-03-20 Dog Beach, LLC +// auction : Dog Beach, LLC +// https://www.iana.org/domains/root/db/auction.html auction -// audi : 2015-05-21 AUDI Aktiengesellschaft +// audi : AUDI Aktiengesellschaft +// https://www.iana.org/domains/root/db/audi.html audi -// audible : 2015-06-25 Amazon Registry Services, Inc. +// audible : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/audible.html audible -// audio : 2014-03-20 XYZ.COM LLC +// audio : XYZ.COM LLC +// https://www.iana.org/domains/root/db/audio.html audio -// auspost : 2015-08-13 Australian Postal Corporation +// auspost : Australian Postal Corporation +// https://www.iana.org/domains/root/db/auspost.html auspost -// author : 2014-12-18 Amazon Registry Services, Inc. +// author : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/author.html author -// auto : 2014-11-13 XYZ.COM LLC +// auto : XYZ.COM LLC +// https://www.iana.org/domains/root/db/auto.html auto -// autos : 2014-01-09 XYZ.COM LLC +// autos : XYZ.COM LLC +// https://www.iana.org/domains/root/db/autos.html autos -// avianca : 2015-01-08 Avianca Inc. -avianca - -// aws : 2015-06-25 AWS Registry LLC +// aws : AWS Registry LLC +// https://www.iana.org/domains/root/db/aws.html aws -// axa : 2013-12-19 AXA Group Operations SAS +// axa : AXA Group Operations SAS +// https://www.iana.org/domains/root/db/axa.html axa -// azure : 2014-12-18 Microsoft Corporation +// azure : Microsoft Corporation +// https://www.iana.org/domains/root/db/azure.html azure -// baby : 2015-04-09 XYZ.COM LLC +// baby : XYZ.COM LLC +// https://www.iana.org/domains/root/db/baby.html baby -// baidu : 2015-01-08 Baidu, Inc. +// baidu : Baidu, Inc. +// https://www.iana.org/domains/root/db/baidu.html baidu -// banamex : 2015-07-30 Citigroup Inc. +// banamex : Citigroup Inc. +// https://www.iana.org/domains/root/db/banamex.html banamex -// bananarepublic : 2015-07-31 The Gap, Inc. -bananarepublic - -// band : 2014-06-12 Dog Beach, LLC +// band : Dog Beach, LLC +// https://www.iana.org/domains/root/db/band.html band -// bank : 2014-09-25 fTLD Registry Services LLC +// bank : fTLD Registry Services LLC +// https://www.iana.org/domains/root/db/bank.html bank -// bar : 2013-12-12 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable +// bar : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable +// https://www.iana.org/domains/root/db/bar.html bar -// barcelona : 2014-07-24 Municipi de Barcelona +// barcelona : Municipi de Barcelona +// https://www.iana.org/domains/root/db/barcelona.html barcelona -// barclaycard : 2014-11-20 Barclays Bank PLC +// barclaycard : Barclays Bank PLC +// https://www.iana.org/domains/root/db/barclaycard.html barclaycard -// barclays : 2014-11-20 Barclays Bank PLC +// barclays : Barclays Bank PLC +// https://www.iana.org/domains/root/db/barclays.html barclays -// barefoot : 2015-06-11 Gallo Vineyards, Inc. +// barefoot : Gallo Vineyards, Inc. +// https://www.iana.org/domains/root/db/barefoot.html barefoot -// bargains : 2013-11-14 Binky Moon, LLC +// bargains : Binky Moon, LLC +// https://www.iana.org/domains/root/db/bargains.html bargains -// baseball : 2015-10-29 MLB Advanced Media DH, LLC +// baseball : MLB Advanced Media DH, LLC +// https://www.iana.org/domains/root/db/baseball.html baseball -// basketball : 2015-08-20 Fédération Internationale de Basketball (FIBA) +// basketball : Fédération Internationale de Basketball (FIBA) +// https://www.iana.org/domains/root/db/basketball.html basketball -// bauhaus : 2014-04-17 Werkhaus GmbH +// bauhaus : Werkhaus GmbH +// https://www.iana.org/domains/root/db/bauhaus.html bauhaus -// bayern : 2014-01-23 Bayern Connect GmbH +// bayern : Bayern Connect GmbH +// https://www.iana.org/domains/root/db/bayern.html bayern -// bbc : 2014-12-18 British Broadcasting Corporation +// bbc : British Broadcasting Corporation +// https://www.iana.org/domains/root/db/bbc.html bbc -// bbt : 2015-07-23 BB&T Corporation +// bbt : BB&T Corporation +// https://www.iana.org/domains/root/db/bbt.html bbt -// bbva : 2014-10-02 BANCO BILBAO VIZCAYA ARGENTARIA, S.A. +// bbva : BANCO BILBAO VIZCAYA ARGENTARIA, S.A. +// https://www.iana.org/domains/root/db/bbva.html bbva -// bcg : 2015-04-02 The Boston Consulting Group, Inc. +// bcg : The Boston Consulting Group, Inc. +// https://www.iana.org/domains/root/db/bcg.html bcg -// bcn : 2014-07-24 Municipi de Barcelona +// bcn : Municipi de Barcelona +// https://www.iana.org/domains/root/db/bcn.html bcn -// beats : 2015-05-14 Beats Electronics, LLC +// beats : Beats Electronics, LLC +// https://www.iana.org/domains/root/db/beats.html beats -// beauty : 2015-12-03 XYZ.COM LLC +// beauty : XYZ.COM LLC +// https://www.iana.org/domains/root/db/beauty.html beauty -// beer : 2014-01-09 Registry Services, LLC +// beer : Registry Services, LLC +// https://www.iana.org/domains/root/db/beer.html beer -// bentley : 2014-12-18 Bentley Motors Limited +// bentley : Bentley Motors Limited +// https://www.iana.org/domains/root/db/bentley.html bentley -// berlin : 2013-10-31 dotBERLIN GmbH & Co. KG +// berlin : dotBERLIN GmbH & Co. KG +// https://www.iana.org/domains/root/db/berlin.html berlin -// best : 2013-12-19 BestTLD Pty Ltd +// best : BestTLD Pty Ltd +// https://www.iana.org/domains/root/db/best.html best -// bestbuy : 2015-07-31 BBY Solutions, Inc. +// bestbuy : BBY Solutions, Inc. +// https://www.iana.org/domains/root/db/bestbuy.html bestbuy -// bet : 2015-05-07 Identity Digital Limited +// bet : Identity Digital Limited +// https://www.iana.org/domains/root/db/bet.html bet -// bharti : 2014-01-09 Bharti Enterprises (Holding) Private Limited +// bharti : Bharti Enterprises (Holding) Private Limited +// https://www.iana.org/domains/root/db/bharti.html bharti -// bible : 2014-06-19 American Bible Society +// bible : American Bible Society +// https://www.iana.org/domains/root/db/bible.html bible -// bid : 2013-12-19 dot Bid Limited +// bid : dot Bid Limited +// https://www.iana.org/domains/root/db/bid.html bid -// bike : 2013-08-27 Binky Moon, LLC +// bike : Binky Moon, LLC +// https://www.iana.org/domains/root/db/bike.html bike -// bing : 2014-12-18 Microsoft Corporation +// bing : Microsoft Corporation +// https://www.iana.org/domains/root/db/bing.html bing -// bingo : 2014-12-04 Binky Moon, LLC +// bingo : Binky Moon, LLC +// https://www.iana.org/domains/root/db/bingo.html bingo -// bio : 2014-03-06 Identity Digital Limited +// bio : Identity Digital Limited +// https://www.iana.org/domains/root/db/bio.html bio -// black : 2014-01-16 Identity Digital Limited +// black : Identity Digital Limited +// https://www.iana.org/domains/root/db/black.html black -// blackfriday : 2014-01-16 Registry Services, LLC +// blackfriday : Registry Services, LLC +// https://www.iana.org/domains/root/db/blackfriday.html blackfriday -// blockbuster : 2015-07-30 Dish DBS Corporation +// blockbuster : Dish DBS Corporation +// https://www.iana.org/domains/root/db/blockbuster.html blockbuster -// blog : 2015-05-14 Knock Knock WHOIS There, LLC +// blog : Knock Knock WHOIS There, LLC +// https://www.iana.org/domains/root/db/blog.html blog -// bloomberg : 2014-07-17 Bloomberg IP Holdings LLC +// bloomberg : Bloomberg IP Holdings LLC +// https://www.iana.org/domains/root/db/bloomberg.html bloomberg -// blue : 2013-11-07 Identity Digital Limited +// blue : Identity Digital Limited +// https://www.iana.org/domains/root/db/blue.html blue -// bms : 2014-10-30 Bristol-Myers Squibb Company +// bms : Bristol-Myers Squibb Company +// https://www.iana.org/domains/root/db/bms.html bms -// bmw : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft +// bmw : Bayerische Motoren Werke Aktiengesellschaft +// https://www.iana.org/domains/root/db/bmw.html bmw -// bnpparibas : 2014-05-29 BNP Paribas +// bnpparibas : BNP Paribas +// https://www.iana.org/domains/root/db/bnpparibas.html bnpparibas -// boats : 2014-12-04 XYZ.COM LLC +// boats : XYZ.COM LLC +// https://www.iana.org/domains/root/db/boats.html boats -// boehringer : 2015-07-09 Boehringer Ingelheim International GmbH +// boehringer : Boehringer Ingelheim International GmbH +// https://www.iana.org/domains/root/db/boehringer.html boehringer -// bofa : 2015-07-31 Bank of America Corporation +// bofa : Bank of America Corporation +// https://www.iana.org/domains/root/db/bofa.html bofa -// bom : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br +// bom : Núcleo de Informação e Coordenação do Ponto BR - NIC.br +// https://www.iana.org/domains/root/db/bom.html bom -// bond : 2014-06-05 ShortDot SA +// bond : ShortDot SA +// https://www.iana.org/domains/root/db/bond.html bond -// boo : 2014-01-30 Charleston Road Registry Inc. +// boo : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/boo.html boo -// book : 2015-08-27 Amazon Registry Services, Inc. +// book : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/book.html book -// booking : 2015-07-16 Booking.com B.V. +// booking : Booking.com B.V. +// https://www.iana.org/domains/root/db/booking.html booking -// bosch : 2015-06-18 Robert Bosch GMBH +// bosch : Robert Bosch GMBH +// https://www.iana.org/domains/root/db/bosch.html bosch -// bostik : 2015-05-28 Bostik SA +// bostik : Bostik SA +// https://www.iana.org/domains/root/db/bostik.html bostik -// boston : 2015-12-10 Registry Services, LLC +// boston : Registry Services, LLC +// https://www.iana.org/domains/root/db/boston.html boston -// bot : 2014-12-18 Amazon Registry Services, Inc. +// bot : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/bot.html bot -// boutique : 2013-11-14 Binky Moon, LLC +// boutique : Binky Moon, LLC +// https://www.iana.org/domains/root/db/boutique.html boutique -// box : 2015-11-12 Intercap Registry Inc. +// box : Intercap Registry Inc. +// https://www.iana.org/domains/root/db/box.html box -// bradesco : 2014-12-18 Banco Bradesco S.A. +// bradesco : Banco Bradesco S.A. +// https://www.iana.org/domains/root/db/bradesco.html bradesco -// bridgestone : 2014-12-18 Bridgestone Corporation +// bridgestone : Bridgestone Corporation +// https://www.iana.org/domains/root/db/bridgestone.html bridgestone -// broadway : 2014-12-22 Celebrate Broadway, Inc. +// broadway : Celebrate Broadway, Inc. +// https://www.iana.org/domains/root/db/broadway.html broadway -// broker : 2014-12-11 Dog Beach, LLC +// broker : Dog Beach, LLC +// https://www.iana.org/domains/root/db/broker.html broker -// brother : 2015-01-29 Brother Industries, Ltd. +// brother : Brother Industries, Ltd. +// https://www.iana.org/domains/root/db/brother.html brother -// brussels : 2014-02-06 DNS.be vzw +// brussels : DNS.be vzw +// https://www.iana.org/domains/root/db/brussels.html brussels -// build : 2013-11-07 Plan Bee LLC +// build : Plan Bee LLC +// https://www.iana.org/domains/root/db/build.html build -// builders : 2013-11-07 Binky Moon, LLC +// builders : Binky Moon, LLC +// https://www.iana.org/domains/root/db/builders.html builders -// business : 2013-11-07 Binky Moon, LLC +// business : Binky Moon, LLC +// https://www.iana.org/domains/root/db/business.html business -// buy : 2014-12-18 Amazon Registry Services, Inc. +// buy : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/buy.html buy -// buzz : 2013-10-02 DOTSTRATEGY CO. +// buzz : DOTSTRATEGY CO. +// https://www.iana.org/domains/root/db/buzz.html buzz -// bzh : 2014-02-27 Association www.bzh +// bzh : Association www.bzh +// https://www.iana.org/domains/root/db/bzh.html bzh -// cab : 2013-10-24 Binky Moon, LLC +// cab : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cab.html cab -// cafe : 2015-02-11 Binky Moon, LLC +// cafe : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cafe.html cafe -// cal : 2014-07-24 Charleston Road Registry Inc. +// cal : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/cal.html cal -// call : 2014-12-18 Amazon Registry Services, Inc. +// call : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/call.html call -// calvinklein : 2015-07-30 PVH gTLD Holdings LLC +// calvinklein : PVH gTLD Holdings LLC +// https://www.iana.org/domains/root/db/calvinklein.html calvinklein -// cam : 2016-04-21 Cam Connecting SARL +// cam : Cam Connecting SARL +// https://www.iana.org/domains/root/db/cam.html cam -// camera : 2013-08-27 Binky Moon, LLC +// camera : Binky Moon, LLC +// https://www.iana.org/domains/root/db/camera.html camera -// camp : 2013-11-07 Binky Moon, LLC +// camp : Binky Moon, LLC +// https://www.iana.org/domains/root/db/camp.html camp -// canon : 2014-09-12 Canon Inc. +// canon : Canon Inc. +// https://www.iana.org/domains/root/db/canon.html canon -// capetown : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry +// capetown : ZA Central Registry NPC trading as ZA Central Registry +// https://www.iana.org/domains/root/db/capetown.html capetown -// capital : 2014-03-06 Binky Moon, LLC +// capital : Binky Moon, LLC +// https://www.iana.org/domains/root/db/capital.html capital -// capitalone : 2015-08-06 Capital One Financial Corporation +// capitalone : Capital One Financial Corporation +// https://www.iana.org/domains/root/db/capitalone.html capitalone -// car : 2015-01-22 XYZ.COM LLC +// car : XYZ.COM LLC +// https://www.iana.org/domains/root/db/car.html car -// caravan : 2013-12-12 Caravan International, Inc. +// caravan : Caravan International, Inc. +// https://www.iana.org/domains/root/db/caravan.html caravan -// cards : 2013-12-05 Binky Moon, LLC +// cards : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cards.html cards -// care : 2014-03-06 Binky Moon, LLC +// care : Binky Moon, LLC +// https://www.iana.org/domains/root/db/care.html care -// career : 2013-10-09 dotCareer LLC +// career : dotCareer LLC +// https://www.iana.org/domains/root/db/career.html career -// careers : 2013-10-02 Binky Moon, LLC +// careers : Binky Moon, LLC +// https://www.iana.org/domains/root/db/careers.html careers -// cars : 2014-11-13 XYZ.COM LLC +// cars : XYZ.COM LLC +// https://www.iana.org/domains/root/db/cars.html cars -// casa : 2013-11-21 Registry Services, LLC +// casa : Registry Services, LLC +// https://www.iana.org/domains/root/db/casa.html casa -// case : 2015-09-03 Digity, LLC +// case : Digity, LLC +// https://www.iana.org/domains/root/db/case.html case -// cash : 2014-03-06 Binky Moon, LLC +// cash : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cash.html cash -// casino : 2014-12-18 Binky Moon, LLC +// casino : Binky Moon, LLC +// https://www.iana.org/domains/root/db/casino.html casino -// catering : 2013-12-05 Binky Moon, LLC +// catering : Binky Moon, LLC +// https://www.iana.org/domains/root/db/catering.html catering -// catholic : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// catholic : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// https://www.iana.org/domains/root/db/catholic.html catholic -// cba : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA +// cba : COMMONWEALTH BANK OF AUSTRALIA +// https://www.iana.org/domains/root/db/cba.html cba -// cbn : 2014-08-22 The Christian Broadcasting Network, Inc. +// cbn : The Christian Broadcasting Network, Inc. +// https://www.iana.org/domains/root/db/cbn.html cbn -// cbre : 2015-07-02 CBRE, Inc. +// cbre : CBRE, Inc. +// https://www.iana.org/domains/root/db/cbre.html cbre -// cbs : 2015-08-06 CBS Domains Inc. -cbs - -// center : 2013-11-07 Binky Moon, LLC +// center : Binky Moon, LLC +// https://www.iana.org/domains/root/db/center.html center -// ceo : 2013-11-07 CEOTLD Pty Ltd +// ceo : XYZ.COM LLC +// https://www.iana.org/domains/root/db/ceo.html ceo -// cern : 2014-06-05 European Organization for Nuclear Research ("CERN") +// cern : European Organization for Nuclear Research ("CERN") +// https://www.iana.org/domains/root/db/cern.html cern -// cfa : 2014-08-28 CFA Institute +// cfa : CFA Institute +// https://www.iana.org/domains/root/db/cfa.html cfa -// cfd : 2014-12-11 ShortDot SA +// cfd : ShortDot SA +// https://www.iana.org/domains/root/db/cfd.html cfd -// chanel : 2015-04-09 Chanel International B.V. +// chanel : Chanel International B.V. +// https://www.iana.org/domains/root/db/chanel.html chanel -// channel : 2014-05-08 Charleston Road Registry Inc. +// channel : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/channel.html channel -// charity : 2018-04-11 Public Interest Registry +// charity : Public Interest Registry +// https://www.iana.org/domains/root/db/charity.html charity -// chase : 2015-04-30 JPMorgan Chase Bank, National Association +// chase : JPMorgan Chase Bank, National Association +// https://www.iana.org/domains/root/db/chase.html chase -// chat : 2014-12-04 Binky Moon, LLC +// chat : Binky Moon, LLC +// https://www.iana.org/domains/root/db/chat.html chat -// cheap : 2013-11-14 Binky Moon, LLC +// cheap : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cheap.html cheap -// chintai : 2015-06-11 CHINTAI Corporation +// chintai : CHINTAI Corporation +// https://www.iana.org/domains/root/db/chintai.html chintai -// christmas : 2013-11-21 XYZ.COM LLC +// christmas : XYZ.COM LLC +// https://www.iana.org/domains/root/db/christmas.html christmas -// chrome : 2014-07-24 Charleston Road Registry Inc. +// chrome : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/chrome.html chrome -// church : 2014-02-06 Binky Moon, LLC +// church : Binky Moon, LLC +// https://www.iana.org/domains/root/db/church.html church -// cipriani : 2015-02-19 Hotel Cipriani Srl +// cipriani : Hotel Cipriani Srl +// https://www.iana.org/domains/root/db/cipriani.html cipriani -// circle : 2014-12-18 Amazon Registry Services, Inc. +// circle : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/circle.html circle -// cisco : 2014-12-22 Cisco Technology, Inc. +// cisco : Cisco Technology, Inc. +// https://www.iana.org/domains/root/db/cisco.html cisco -// citadel : 2015-07-23 Citadel Domain LLC +// citadel : Citadel Domain LLC +// https://www.iana.org/domains/root/db/citadel.html citadel -// citi : 2015-07-30 Citigroup Inc. +// citi : Citigroup Inc. +// https://www.iana.org/domains/root/db/citi.html citi -// citic : 2014-01-09 CITIC Group Corporation +// citic : CITIC Group Corporation +// https://www.iana.org/domains/root/db/citic.html citic -// city : 2014-05-29 Binky Moon, LLC +// city : Binky Moon, LLC +// https://www.iana.org/domains/root/db/city.html city -// cityeats : 2014-12-11 Lifestyle Domain Holdings, Inc. -cityeats - -// claims : 2014-03-20 Binky Moon, LLC +// claims : Binky Moon, LLC +// https://www.iana.org/domains/root/db/claims.html claims -// cleaning : 2013-12-05 Binky Moon, LLC +// cleaning : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cleaning.html cleaning -// click : 2014-06-05 Internet Naming Company LLC +// click : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/click.html click -// clinic : 2014-03-20 Binky Moon, LLC +// clinic : Binky Moon, LLC +// https://www.iana.org/domains/root/db/clinic.html clinic -// clinique : 2015-10-01 The Estée Lauder Companies Inc. +// clinique : The Estée Lauder Companies Inc. +// https://www.iana.org/domains/root/db/clinique.html clinique -// clothing : 2013-08-27 Binky Moon, LLC +// clothing : Binky Moon, LLC +// https://www.iana.org/domains/root/db/clothing.html clothing -// cloud : 2015-04-16 Aruba PEC S.p.A. +// cloud : Aruba PEC S.p.A. +// https://www.iana.org/domains/root/db/cloud.html cloud -// club : 2013-11-08 Registry Services, LLC +// club : Registry Services, LLC +// https://www.iana.org/domains/root/db/club.html club -// clubmed : 2015-06-25 Club Méditerranée S.A. +// clubmed : Club Méditerranée S.A. +// https://www.iana.org/domains/root/db/clubmed.html clubmed -// coach : 2014-10-09 Binky Moon, LLC +// coach : Binky Moon, LLC +// https://www.iana.org/domains/root/db/coach.html coach -// codes : 2013-10-31 Binky Moon, LLC +// codes : Binky Moon, LLC +// https://www.iana.org/domains/root/db/codes.html codes -// coffee : 2013-10-17 Binky Moon, LLC +// coffee : Binky Moon, LLC +// https://www.iana.org/domains/root/db/coffee.html coffee -// college : 2014-01-16 XYZ.COM LLC +// college : XYZ.COM LLC +// https://www.iana.org/domains/root/db/college.html college -// cologne : 2014-02-05 dotKoeln GmbH +// cologne : dotKoeln GmbH +// https://www.iana.org/domains/root/db/cologne.html cologne -// comcast : 2015-07-23 Comcast IP Holdings I, LLC -comcast - -// commbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA +// commbank : COMMONWEALTH BANK OF AUSTRALIA +// https://www.iana.org/domains/root/db/commbank.html commbank -// community : 2013-12-05 Binky Moon, LLC +// community : Binky Moon, LLC +// https://www.iana.org/domains/root/db/community.html community -// company : 2013-11-07 Binky Moon, LLC +// company : Binky Moon, LLC +// https://www.iana.org/domains/root/db/company.html company -// compare : 2015-10-08 Registry Services, LLC +// compare : Registry Services, LLC +// https://www.iana.org/domains/root/db/compare.html compare -// computer : 2013-10-24 Binky Moon, LLC +// computer : Binky Moon, LLC +// https://www.iana.org/domains/root/db/computer.html computer -// comsec : 2015-01-08 VeriSign, Inc. +// comsec : VeriSign, Inc. +// https://www.iana.org/domains/root/db/comsec.html comsec -// condos : 2013-12-05 Binky Moon, LLC +// condos : Binky Moon, LLC +// https://www.iana.org/domains/root/db/condos.html condos -// construction : 2013-09-16 Binky Moon, LLC +// construction : Binky Moon, LLC +// https://www.iana.org/domains/root/db/construction.html construction -// consulting : 2013-12-05 Dog Beach, LLC +// consulting : Dog Beach, LLC +// https://www.iana.org/domains/root/db/consulting.html consulting -// contact : 2015-01-08 Dog Beach, LLC +// contact : Dog Beach, LLC +// https://www.iana.org/domains/root/db/contact.html contact -// contractors : 2013-09-10 Binky Moon, LLC +// contractors : Binky Moon, LLC +// https://www.iana.org/domains/root/db/contractors.html contractors -// cooking : 2013-11-21 Registry Services, LLC +// cooking : Registry Services, LLC +// https://www.iana.org/domains/root/db/cooking.html cooking -// cookingchannel : 2015-07-02 Lifestyle Domain Holdings, Inc. -cookingchannel - -// cool : 2013-11-14 Binky Moon, LLC +// cool : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cool.html cool -// corsica : 2014-09-25 Collectivité de Corse +// corsica : Collectivité de Corse +// https://www.iana.org/domains/root/db/corsica.html corsica -// country : 2013-12-19 Internet Naming Company LLC +// country : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/country.html country -// coupon : 2015-02-26 Amazon Registry Services, Inc. +// coupon : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/coupon.html coupon -// coupons : 2015-03-26 Binky Moon, LLC +// coupons : Binky Moon, LLC +// https://www.iana.org/domains/root/db/coupons.html coupons -// courses : 2014-12-04 Registry Services, LLC +// courses : Registry Services, LLC +// https://www.iana.org/domains/root/db/courses.html courses -// cpa : 2019-06-10 American Institute of Certified Public Accountants +// cpa : American Institute of Certified Public Accountants +// https://www.iana.org/domains/root/db/cpa.html cpa -// credit : 2014-03-20 Binky Moon, LLC +// credit : Binky Moon, LLC +// https://www.iana.org/domains/root/db/credit.html credit -// creditcard : 2014-03-20 Binky Moon, LLC +// creditcard : Binky Moon, LLC +// https://www.iana.org/domains/root/db/creditcard.html creditcard -// creditunion : 2015-01-22 DotCooperation LLC +// creditunion : DotCooperation LLC +// https://www.iana.org/domains/root/db/creditunion.html creditunion -// cricket : 2014-10-09 dot Cricket Limited +// cricket : dot Cricket Limited +// https://www.iana.org/domains/root/db/cricket.html cricket -// crown : 2014-10-24 Crown Equipment Corporation +// crown : Crown Equipment Corporation +// https://www.iana.org/domains/root/db/crown.html crown -// crs : 2014-04-03 Federated Co-operatives Limited +// crs : Federated Co-operatives Limited +// https://www.iana.org/domains/root/db/crs.html crs -// cruise : 2015-12-10 Viking River Cruises (Bermuda) Ltd. +// cruise : Viking River Cruises (Bermuda) Ltd. +// https://www.iana.org/domains/root/db/cruise.html cruise -// cruises : 2013-12-05 Binky Moon, LLC +// cruises : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cruises.html cruises -// cuisinella : 2014-04-03 SCHMIDT GROUPE S.A.S. +// cuisinella : SCHMIDT GROUPE S.A.S. +// https://www.iana.org/domains/root/db/cuisinella.html cuisinella -// cymru : 2014-05-08 Nominet UK +// cymru : Nominet UK +// https://www.iana.org/domains/root/db/cymru.html cymru -// cyou : 2015-01-22 ShortDot SA +// cyou : ShortDot SA +// https://www.iana.org/domains/root/db/cyou.html cyou -// dabur : 2014-02-06 Dabur India Limited -dabur - -// dad : 2014-01-23 Charleston Road Registry Inc. +// dad : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/dad.html dad -// dance : 2013-10-24 Dog Beach, LLC +// dance : Dog Beach, LLC +// https://www.iana.org/domains/root/db/dance.html dance -// data : 2016-06-02 Dish DBS Corporation +// data : Dish DBS Corporation +// https://www.iana.org/domains/root/db/data.html data -// date : 2014-11-20 dot Date Limited +// date : dot Date Limited +// https://www.iana.org/domains/root/db/date.html date -// dating : 2013-12-05 Binky Moon, LLC +// dating : Binky Moon, LLC +// https://www.iana.org/domains/root/db/dating.html dating -// datsun : 2014-03-27 NISSAN MOTOR CO., LTD. +// datsun : NISSAN MOTOR CO., LTD. +// https://www.iana.org/domains/root/db/datsun.html datsun -// day : 2014-01-30 Charleston Road Registry Inc. +// day : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/day.html day -// dclk : 2014-11-20 Charleston Road Registry Inc. +// dclk : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/dclk.html dclk -// dds : 2015-05-07 Registry Services, LLC +// dds : Registry Services, LLC +// https://www.iana.org/domains/root/db/dds.html dds -// deal : 2015-06-25 Amazon Registry Services, Inc. +// deal : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/deal.html deal -// dealer : 2014-12-22 Intercap Registry Inc. +// dealer : Intercap Registry Inc. +// https://www.iana.org/domains/root/db/dealer.html dealer -// deals : 2014-05-22 Binky Moon, LLC +// deals : Binky Moon, LLC +// https://www.iana.org/domains/root/db/deals.html deals -// degree : 2014-03-06 Dog Beach, LLC +// degree : Dog Beach, LLC +// https://www.iana.org/domains/root/db/degree.html degree -// delivery : 2014-09-11 Binky Moon, LLC +// delivery : Binky Moon, LLC +// https://www.iana.org/domains/root/db/delivery.html delivery -// dell : 2014-10-24 Dell Inc. +// dell : Dell Inc. +// https://www.iana.org/domains/root/db/dell.html dell -// deloitte : 2015-07-31 Deloitte Touche Tohmatsu +// deloitte : Deloitte Touche Tohmatsu +// https://www.iana.org/domains/root/db/deloitte.html deloitte -// delta : 2015-02-19 Delta Air Lines, Inc. +// delta : Delta Air Lines, Inc. +// https://www.iana.org/domains/root/db/delta.html delta -// democrat : 2013-10-24 Dog Beach, LLC +// democrat : Dog Beach, LLC +// https://www.iana.org/domains/root/db/democrat.html democrat -// dental : 2014-03-20 Binky Moon, LLC +// dental : Binky Moon, LLC +// https://www.iana.org/domains/root/db/dental.html dental -// dentist : 2014-03-20 Dog Beach, LLC +// dentist : Dog Beach, LLC +// https://www.iana.org/domains/root/db/dentist.html dentist -// desi : 2013-11-14 Desi Networks LLC +// desi +// https://www.iana.org/domains/root/db/desi.html desi -// design : 2014-11-07 Registry Services, LLC +// design : Registry Services, LLC +// https://www.iana.org/domains/root/db/design.html design -// dev : 2014-10-16 Charleston Road Registry Inc. +// dev : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/dev.html dev -// dhl : 2015-07-23 Deutsche Post AG +// dhl : Deutsche Post AG +// https://www.iana.org/domains/root/db/dhl.html dhl -// diamonds : 2013-09-22 Binky Moon, LLC +// diamonds : Binky Moon, LLC +// https://www.iana.org/domains/root/db/diamonds.html diamonds -// diet : 2014-06-26 XYZ.COM LLC +// diet : XYZ.COM LLC +// https://www.iana.org/domains/root/db/diet.html diet -// digital : 2014-03-06 Binky Moon, LLC +// digital : Binky Moon, LLC +// https://www.iana.org/domains/root/db/digital.html digital -// direct : 2014-04-10 Binky Moon, LLC +// direct : Binky Moon, LLC +// https://www.iana.org/domains/root/db/direct.html direct -// directory : 2013-09-20 Binky Moon, LLC +// directory : Binky Moon, LLC +// https://www.iana.org/domains/root/db/directory.html directory -// discount : 2014-03-06 Binky Moon, LLC +// discount : Binky Moon, LLC +// https://www.iana.org/domains/root/db/discount.html discount -// discover : 2015-07-23 Discover Financial Services +// discover : Discover Financial Services +// https://www.iana.org/domains/root/db/discover.html discover -// dish : 2015-07-30 Dish DBS Corporation +// dish : Dish DBS Corporation +// https://www.iana.org/domains/root/db/dish.html dish -// diy : 2015-11-05 Lifestyle Domain Holdings, Inc. +// diy : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/diy.html diy -// dnp : 2013-12-13 Dai Nippon Printing Co., Ltd. +// dnp : Dai Nippon Printing Co., Ltd. +// https://www.iana.org/domains/root/db/dnp.html dnp -// docs : 2014-10-16 Charleston Road Registry Inc. +// docs : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/docs.html docs -// doctor : 2016-06-02 Binky Moon, LLC +// doctor : Binky Moon, LLC +// https://www.iana.org/domains/root/db/doctor.html doctor -// dog : 2014-12-04 Binky Moon, LLC +// dog : Binky Moon, LLC +// https://www.iana.org/domains/root/db/dog.html dog -// domains : 2013-10-17 Binky Moon, LLC +// domains : Binky Moon, LLC +// https://www.iana.org/domains/root/db/domains.html domains -// dot : 2015-05-21 Dish DBS Corporation +// dot : Dish DBS Corporation +// https://www.iana.org/domains/root/db/dot.html dot -// download : 2014-11-20 dot Support Limited +// download : dot Support Limited +// https://www.iana.org/domains/root/db/download.html download -// drive : 2015-03-05 Charleston Road Registry Inc. +// drive : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/drive.html drive -// dtv : 2015-06-04 Dish DBS Corporation +// dtv : Dish DBS Corporation +// https://www.iana.org/domains/root/db/dtv.html dtv -// dubai : 2015-01-01 Dubai Smart Government Department +// dubai : Dubai Smart Government Department +// https://www.iana.org/domains/root/db/dubai.html dubai -// dunlop : 2015-07-02 The Goodyear Tire & Rubber Company +// dunlop : The Goodyear Tire & Rubber Company +// https://www.iana.org/domains/root/db/dunlop.html dunlop -// dupont : 2015-06-25 DuPont Specialty Products USA, LLC +// dupont : DuPont Specialty Products USA, LLC +// https://www.iana.org/domains/root/db/dupont.html dupont -// durban : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry +// durban : ZA Central Registry NPC trading as ZA Central Registry +// https://www.iana.org/domains/root/db/durban.html durban -// dvag : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG +// dvag : Deutsche Vermögensberatung Aktiengesellschaft DVAG +// https://www.iana.org/domains/root/db/dvag.html dvag -// dvr : 2016-05-26 DISH Technologies L.L.C. +// dvr : DISH Technologies L.L.C. +// https://www.iana.org/domains/root/db/dvr.html dvr -// earth : 2014-12-04 Interlink Systems Innovation Institute K.K. +// earth : Interlink Systems Innovation Institute K.K. +// https://www.iana.org/domains/root/db/earth.html earth -// eat : 2014-01-23 Charleston Road Registry Inc. +// eat : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/eat.html eat -// eco : 2016-07-08 Big Room Inc. +// eco : Big Room Inc. +// https://www.iana.org/domains/root/db/eco.html eco -// edeka : 2014-12-18 EDEKA Verband kaufmännischer Genossenschaften e.V. +// edeka : EDEKA Verband kaufmännischer Genossenschaften e.V. +// https://www.iana.org/domains/root/db/edeka.html edeka -// education : 2013-11-07 Binky Moon, LLC +// education : Binky Moon, LLC +// https://www.iana.org/domains/root/db/education.html education -// email : 2013-10-31 Binky Moon, LLC +// email : Binky Moon, LLC +// https://www.iana.org/domains/root/db/email.html email -// emerck : 2014-04-03 Merck KGaA +// emerck : Merck KGaA +// https://www.iana.org/domains/root/db/emerck.html emerck -// energy : 2014-09-11 Binky Moon, LLC +// energy : Binky Moon, LLC +// https://www.iana.org/domains/root/db/energy.html energy -// engineer : 2014-03-06 Dog Beach, LLC +// engineer : Dog Beach, LLC +// https://www.iana.org/domains/root/db/engineer.html engineer -// engineering : 2014-03-06 Binky Moon, LLC +// engineering : Binky Moon, LLC +// https://www.iana.org/domains/root/db/engineering.html engineering -// enterprises : 2013-09-20 Binky Moon, LLC +// enterprises : Binky Moon, LLC +// https://www.iana.org/domains/root/db/enterprises.html enterprises -// epson : 2014-12-04 Seiko Epson Corporation +// epson : Seiko Epson Corporation +// https://www.iana.org/domains/root/db/epson.html epson -// equipment : 2013-08-27 Binky Moon, LLC +// equipment : Binky Moon, LLC +// https://www.iana.org/domains/root/db/equipment.html equipment -// ericsson : 2015-07-09 Telefonaktiebolaget L M Ericsson +// ericsson : Telefonaktiebolaget L M Ericsson +// https://www.iana.org/domains/root/db/ericsson.html ericsson -// erni : 2014-04-03 ERNI Group Holding AG +// erni : ERNI Group Holding AG +// https://www.iana.org/domains/root/db/erni.html erni -// esq : 2014-05-08 Charleston Road Registry Inc. +// esq : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/esq.html esq -// estate : 2013-08-27 Binky Moon, LLC +// estate : Binky Moon, LLC +// https://www.iana.org/domains/root/db/estate.html estate -// etisalat : 2015-09-03 Emirates Telecommunications Corporation (trading as Etisalat) -etisalat - -// eurovision : 2014-04-24 European Broadcasting Union (EBU) +// eurovision : European Broadcasting Union (EBU) +// https://www.iana.org/domains/root/db/eurovision.html eurovision -// eus : 2013-12-12 Puntueus Fundazioa +// eus : Puntueus Fundazioa +// https://www.iana.org/domains/root/db/eus.html eus -// events : 2013-12-05 Binky Moon, LLC +// events : Binky Moon, LLC +// https://www.iana.org/domains/root/db/events.html events -// exchange : 2014-03-06 Binky Moon, LLC +// exchange : Binky Moon, LLC +// https://www.iana.org/domains/root/db/exchange.html exchange -// expert : 2013-11-21 Binky Moon, LLC +// expert : Binky Moon, LLC +// https://www.iana.org/domains/root/db/expert.html expert -// exposed : 2013-12-05 Binky Moon, LLC +// exposed : Binky Moon, LLC +// https://www.iana.org/domains/root/db/exposed.html exposed -// express : 2015-02-11 Binky Moon, LLC +// express : Binky Moon, LLC +// https://www.iana.org/domains/root/db/express.html express -// extraspace : 2015-05-14 Extra Space Storage LLC +// extraspace : Extra Space Storage LLC +// https://www.iana.org/domains/root/db/extraspace.html extraspace -// fage : 2014-12-18 Fage International S.A. +// fage : Fage International S.A. +// https://www.iana.org/domains/root/db/fage.html fage -// fail : 2014-03-06 Binky Moon, LLC +// fail : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fail.html fail -// fairwinds : 2014-11-13 FairWinds Partners, LLC +// fairwinds : FairWinds Partners, LLC +// https://www.iana.org/domains/root/db/fairwinds.html fairwinds -// faith : 2014-11-20 dot Faith Limited +// faith : dot Faith Limited +// https://www.iana.org/domains/root/db/faith.html faith -// family : 2015-04-02 Dog Beach, LLC +// family : Dog Beach, LLC +// https://www.iana.org/domains/root/db/family.html family -// fan : 2014-03-06 Dog Beach, LLC +// fan : Dog Beach, LLC +// https://www.iana.org/domains/root/db/fan.html fan -// fans : 2014-11-07 ZDNS International Limited +// fans : ZDNS International Limited +// https://www.iana.org/domains/root/db/fans.html fans -// farm : 2013-11-07 Binky Moon, LLC +// farm : Binky Moon, LLC +// https://www.iana.org/domains/root/db/farm.html farm -// farmers : 2015-07-09 Farmers Insurance Exchange +// farmers : Farmers Insurance Exchange +// https://www.iana.org/domains/root/db/farmers.html farmers -// fashion : 2014-07-03 Registry Services, LLC +// fashion : Registry Services, LLC +// https://www.iana.org/domains/root/db/fashion.html fashion -// fast : 2014-12-18 Amazon Registry Services, Inc. +// fast : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/fast.html fast -// fedex : 2015-08-06 Federal Express Corporation +// fedex : Federal Express Corporation +// https://www.iana.org/domains/root/db/fedex.html fedex -// feedback : 2013-12-19 Top Level Spectrum, Inc. +// feedback : Top Level Spectrum, Inc. +// https://www.iana.org/domains/root/db/feedback.html feedback -// ferrari : 2015-07-31 Fiat Chrysler Automobiles N.V. +// ferrari : Fiat Chrysler Automobiles N.V. +// https://www.iana.org/domains/root/db/ferrari.html ferrari -// ferrero : 2014-12-18 Ferrero Trading Lux S.A. +// ferrero : Ferrero Trading Lux S.A. +// https://www.iana.org/domains/root/db/ferrero.html ferrero -// fiat : 2015-07-31 Fiat Chrysler Automobiles N.V. -fiat - -// fidelity : 2015-07-30 Fidelity Brokerage Services LLC +// fidelity : Fidelity Brokerage Services LLC +// https://www.iana.org/domains/root/db/fidelity.html fidelity -// fido : 2015-08-06 Rogers Communications Canada Inc. +// fido : Rogers Communications Canada Inc. +// https://www.iana.org/domains/root/db/fido.html fido -// film : 2015-01-08 Motion Picture Domain Registry Pty Ltd +// film : Motion Picture Domain Registry Pty Ltd +// https://www.iana.org/domains/root/db/film.html film -// final : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br +// final : Núcleo de Informação e Coordenação do Ponto BR - NIC.br +// https://www.iana.org/domains/root/db/final.html final -// finance : 2014-03-20 Binky Moon, LLC +// finance : Binky Moon, LLC +// https://www.iana.org/domains/root/db/finance.html finance -// financial : 2014-03-06 Binky Moon, LLC +// financial : Binky Moon, LLC +// https://www.iana.org/domains/root/db/financial.html financial -// fire : 2015-06-25 Amazon Registry Services, Inc. +// fire : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/fire.html fire -// firestone : 2014-12-18 Bridgestone Licensing Services, Inc +// firestone : Bridgestone Licensing Services, Inc +// https://www.iana.org/domains/root/db/firestone.html firestone -// firmdale : 2014-03-27 Firmdale Holdings Limited +// firmdale : Firmdale Holdings Limited +// https://www.iana.org/domains/root/db/firmdale.html firmdale -// fish : 2013-12-12 Binky Moon, LLC +// fish : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fish.html fish -// fishing : 2013-11-21 Registry Services, LLC +// fishing : Registry Services, LLC +// https://www.iana.org/domains/root/db/fishing.html fishing -// fit : 2014-11-07 Registry Services, LLC +// fit : Registry Services, LLC +// https://www.iana.org/domains/root/db/fit.html fit -// fitness : 2014-03-06 Binky Moon, LLC +// fitness : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fitness.html fitness -// flickr : 2015-04-02 Flickr, Inc. +// flickr : Flickr, Inc. +// https://www.iana.org/domains/root/db/flickr.html flickr -// flights : 2013-12-05 Binky Moon, LLC +// flights : Binky Moon, LLC +// https://www.iana.org/domains/root/db/flights.html flights -// flir : 2015-07-23 FLIR Systems, Inc. +// flir : FLIR Systems, Inc. +// https://www.iana.org/domains/root/db/flir.html flir -// florist : 2013-11-07 Binky Moon, LLC +// florist : Binky Moon, LLC +// https://www.iana.org/domains/root/db/florist.html florist -// flowers : 2014-10-09 XYZ.COM LLC +// flowers : XYZ.COM LLC +// https://www.iana.org/domains/root/db/flowers.html flowers -// fly : 2014-05-08 Charleston Road Registry Inc. +// fly : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/fly.html fly -// foo : 2014-01-23 Charleston Road Registry Inc. +// foo : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/foo.html foo -// food : 2016-04-21 Lifestyle Domain Holdings, Inc. +// food : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/food.html food -// foodnetwork : 2015-07-02 Lifestyle Domain Holdings, Inc. -foodnetwork - -// football : 2014-12-18 Binky Moon, LLC +// football : Binky Moon, LLC +// https://www.iana.org/domains/root/db/football.html football -// ford : 2014-11-13 Ford Motor Company +// ford : Ford Motor Company +// https://www.iana.org/domains/root/db/ford.html ford -// forex : 2014-12-11 Dog Beach, LLC +// forex : Dog Beach, LLC +// https://www.iana.org/domains/root/db/forex.html forex -// forsale : 2014-05-22 Dog Beach, LLC +// forsale : Dog Beach, LLC +// https://www.iana.org/domains/root/db/forsale.html forsale -// forum : 2015-04-02 Fegistry, LLC +// forum : Waterford Limited +// https://www.iana.org/domains/root/db/forum.html forum -// foundation : 2013-12-05 Public Interest Registry +// foundation : Public Interest Registry +// https://www.iana.org/domains/root/db/foundation.html foundation -// fox : 2015-09-11 FOX Registry, LLC +// fox : FOX Registry, LLC +// https://www.iana.org/domains/root/db/fox.html fox -// free : 2015-12-10 Amazon Registry Services, Inc. +// free : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/free.html free -// fresenius : 2015-07-30 Fresenius Immobilien-Verwaltungs-GmbH +// fresenius : Fresenius Immobilien-Verwaltungs-GmbH +// https://www.iana.org/domains/root/db/fresenius.html fresenius -// frl : 2014-05-15 FRLregistry B.V. +// frl : FRLregistry B.V. +// https://www.iana.org/domains/root/db/frl.html frl -// frogans : 2013-12-19 OP3FT +// frogans : OP3FT +// https://www.iana.org/domains/root/db/frogans.html frogans -// frontdoor : 2015-07-02 Lifestyle Domain Holdings, Inc. -frontdoor - -// frontier : 2015-02-05 Frontier Communications Corporation +// frontier : Frontier Communications Corporation +// https://www.iana.org/domains/root/db/frontier.html frontier -// ftr : 2015-07-16 Frontier Communications Corporation +// ftr : Frontier Communications Corporation +// https://www.iana.org/domains/root/db/ftr.html ftr -// fujitsu : 2015-07-30 Fujitsu Limited +// fujitsu : Fujitsu Limited +// https://www.iana.org/domains/root/db/fujitsu.html fujitsu -// fun : 2016-01-14 Radix FZC +// fun : Radix Technologies Inc. +// https://www.iana.org/domains/root/db/fun.html fun -// fund : 2014-03-20 Binky Moon, LLC +// fund : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fund.html fund -// furniture : 2014-03-20 Binky Moon, LLC +// furniture : Binky Moon, LLC +// https://www.iana.org/domains/root/db/furniture.html furniture -// futbol : 2013-09-20 Dog Beach, LLC +// futbol : Dog Beach, LLC +// https://www.iana.org/domains/root/db/futbol.html futbol -// fyi : 2015-04-02 Binky Moon, LLC +// fyi : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fyi.html fyi -// gal : 2013-11-07 Asociación puntoGAL +// gal : Asociación puntoGAL +// https://www.iana.org/domains/root/db/gal.html gal -// gallery : 2013-09-13 Binky Moon, LLC +// gallery : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gallery.html gallery -// gallo : 2015-06-11 Gallo Vineyards, Inc. +// gallo : Gallo Vineyards, Inc. +// https://www.iana.org/domains/root/db/gallo.html gallo -// gallup : 2015-02-19 Gallup, Inc. +// gallup : Gallup, Inc. +// https://www.iana.org/domains/root/db/gallup.html gallup -// game : 2015-05-28 XYZ.COM LLC +// game : XYZ.COM LLC +// https://www.iana.org/domains/root/db/game.html game -// games : 2015-05-28 Dog Beach, LLC +// games : Dog Beach, LLC +// https://www.iana.org/domains/root/db/games.html games -// gap : 2015-07-31 The Gap, Inc. +// gap : The Gap, Inc. +// https://www.iana.org/domains/root/db/gap.html gap -// garden : 2014-06-26 Registry Services, LLC +// garden : Registry Services, LLC +// https://www.iana.org/domains/root/db/garden.html garden -// gay : 2019-05-23 Top Level Design, LLC +// gay : Registry Services, LLC +// https://www.iana.org/domains/root/db/gay.html gay -// gbiz : 2014-07-17 Charleston Road Registry Inc. +// gbiz : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/gbiz.html gbiz -// gdn : 2014-07-31 Joint Stock Company "Navigation-information systems" +// gdn : Joint Stock Company "Navigation-information systems" +// https://www.iana.org/domains/root/db/gdn.html gdn -// gea : 2014-12-04 GEA Group Aktiengesellschaft +// gea : GEA Group Aktiengesellschaft +// https://www.iana.org/domains/root/db/gea.html gea -// gent : 2014-01-23 Easyhost BV +// gent : Easyhost BV +// https://www.iana.org/domains/root/db/gent.html gent -// genting : 2015-03-12 Resorts World Inc Pte. Ltd. +// genting : Resorts World Inc Pte. Ltd. +// https://www.iana.org/domains/root/db/genting.html genting -// george : 2015-07-31 Wal-Mart Stores, Inc. +// george : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/george.html george -// ggee : 2014-01-09 GMO Internet, Inc. +// ggee : GMO Internet, Inc. +// https://www.iana.org/domains/root/db/ggee.html ggee -// gift : 2013-10-17 DotGift, LLC +// gift : DotGift, LLC +// https://www.iana.org/domains/root/db/gift.html gift -// gifts : 2014-07-03 Binky Moon, LLC +// gifts : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gifts.html gifts -// gives : 2014-03-06 Public Interest Registry +// gives : Public Interest Registry +// https://www.iana.org/domains/root/db/gives.html gives -// giving : 2014-11-13 Public Interest Registry +// giving : Public Interest Registry +// https://www.iana.org/domains/root/db/giving.html giving -// glass : 2013-11-07 Binky Moon, LLC +// glass : Binky Moon, LLC +// https://www.iana.org/domains/root/db/glass.html glass -// gle : 2014-07-24 Charleston Road Registry Inc. +// gle : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/gle.html gle -// global : 2014-04-17 Dot Global Domain Registry Limited +// global : Identity Digital Limited +// https://www.iana.org/domains/root/db/global.html global -// globo : 2013-12-19 Globo Comunicação e Participações S.A +// globo : Globo Comunicação e Participações S.A +// https://www.iana.org/domains/root/db/globo.html globo -// gmail : 2014-05-01 Charleston Road Registry Inc. +// gmail : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/gmail.html gmail -// gmbh : 2016-01-29 Binky Moon, LLC +// gmbh : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gmbh.html gmbh -// gmo : 2014-01-09 GMO Internet, Inc. +// gmo : GMO Internet, Inc. +// https://www.iana.org/domains/root/db/gmo.html gmo -// gmx : 2014-04-24 1&1 Mail & Media GmbH +// gmx : 1&1 Mail & Media GmbH +// https://www.iana.org/domains/root/db/gmx.html gmx -// godaddy : 2015-07-23 Go Daddy East, LLC +// godaddy : Go Daddy East, LLC +// https://www.iana.org/domains/root/db/godaddy.html godaddy -// gold : 2015-01-22 Binky Moon, LLC +// gold : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gold.html gold -// goldpoint : 2014-11-20 YODOBASHI CAMERA CO.,LTD. +// goldpoint : YODOBASHI CAMERA CO.,LTD. +// https://www.iana.org/domains/root/db/goldpoint.html goldpoint -// golf : 2014-12-18 Binky Moon, LLC +// golf : Binky Moon, LLC +// https://www.iana.org/domains/root/db/golf.html golf -// goo : 2014-12-18 NTT Resonant Inc. +// goo : NTT DOCOMO, INC. +// https://www.iana.org/domains/root/db/goo.html goo -// goodyear : 2015-07-02 The Goodyear Tire & Rubber Company +// goodyear : The Goodyear Tire & Rubber Company +// https://www.iana.org/domains/root/db/goodyear.html goodyear -// goog : 2014-11-20 Charleston Road Registry Inc. +// goog : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/goog.html goog -// google : 2014-07-24 Charleston Road Registry Inc. +// google : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/google.html google -// gop : 2014-01-16 Republican State Leadership Committee, Inc. +// gop : Republican State Leadership Committee, Inc. +// https://www.iana.org/domains/root/db/gop.html gop -// got : 2014-12-18 Amazon Registry Services, Inc. +// got : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/got.html got -// grainger : 2015-05-07 Grainger Registry Services, LLC +// grainger : Grainger Registry Services, LLC +// https://www.iana.org/domains/root/db/grainger.html grainger -// graphics : 2013-09-13 Binky Moon, LLC +// graphics : Binky Moon, LLC +// https://www.iana.org/domains/root/db/graphics.html graphics -// gratis : 2014-03-20 Binky Moon, LLC +// gratis : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gratis.html gratis -// green : 2014-05-08 Identity Digital Limited +// green : Identity Digital Limited +// https://www.iana.org/domains/root/db/green.html green -// gripe : 2014-03-06 Binky Moon, LLC +// gripe : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gripe.html gripe -// grocery : 2016-06-16 Wal-Mart Stores, Inc. +// grocery : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/grocery.html grocery -// group : 2014-08-15 Binky Moon, LLC +// group : Binky Moon, LLC +// https://www.iana.org/domains/root/db/group.html group -// guardian : 2015-07-30 The Guardian Life Insurance Company of America -guardian - -// gucci : 2014-11-13 Guccio Gucci S.p.a. +// gucci : Guccio Gucci S.p.a. +// https://www.iana.org/domains/root/db/gucci.html gucci -// guge : 2014-08-28 Charleston Road Registry Inc. +// guge : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/guge.html guge -// guide : 2013-09-13 Binky Moon, LLC +// guide : Binky Moon, LLC +// https://www.iana.org/domains/root/db/guide.html guide -// guitars : 2013-11-14 XYZ.COM LLC +// guitars : XYZ.COM LLC +// https://www.iana.org/domains/root/db/guitars.html guitars -// guru : 2013-08-27 Binky Moon, LLC +// guru : Binky Moon, LLC +// https://www.iana.org/domains/root/db/guru.html guru -// hair : 2015-12-03 XYZ.COM LLC +// hair : XYZ.COM LLC +// https://www.iana.org/domains/root/db/hair.html hair -// hamburg : 2014-02-20 Hamburg Top-Level-Domain GmbH +// hamburg : Hamburg Top-Level-Domain GmbH +// https://www.iana.org/domains/root/db/hamburg.html hamburg -// hangout : 2014-11-13 Charleston Road Registry Inc. +// hangout : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/hangout.html hangout -// haus : 2013-12-05 Dog Beach, LLC +// haus : Dog Beach, LLC +// https://www.iana.org/domains/root/db/haus.html haus -// hbo : 2015-07-30 HBO Registry Services, Inc. +// hbo : HBO Registry Services, Inc. +// https://www.iana.org/domains/root/db/hbo.html hbo -// hdfc : 2015-07-30 HOUSING DEVELOPMENT FINANCE CORPORATION LIMITED +// hdfc : HDFC BANK LIMITED +// https://www.iana.org/domains/root/db/hdfc.html hdfc -// hdfcbank : 2015-02-12 HDFC Bank Limited +// hdfcbank : HDFC BANK LIMITED +// https://www.iana.org/domains/root/db/hdfcbank.html hdfcbank -// health : 2015-02-11 DotHealth, LLC +// health : Registry Services, LLC +// https://www.iana.org/domains/root/db/health.html health -// healthcare : 2014-06-12 Binky Moon, LLC +// healthcare : Binky Moon, LLC +// https://www.iana.org/domains/root/db/healthcare.html healthcare -// help : 2014-06-26 Innovation service Limited +// help : Innovation service Limited +// https://www.iana.org/domains/root/db/help.html help -// helsinki : 2015-02-05 City of Helsinki +// helsinki : City of Helsinki +// https://www.iana.org/domains/root/db/helsinki.html helsinki -// here : 2014-02-06 Charleston Road Registry Inc. +// here : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/here.html here -// hermes : 2014-07-10 HERMES INTERNATIONAL +// hermes : HERMES INTERNATIONAL +// https://www.iana.org/domains/root/db/hermes.html hermes -// hgtv : 2015-07-02 Lifestyle Domain Holdings, Inc. -hgtv - -// hiphop : 2014-03-06 Dot Hip Hop, LLC +// hiphop : Dot Hip Hop, LLC +// https://www.iana.org/domains/root/db/hiphop.html hiphop -// hisamitsu : 2015-07-16 Hisamitsu Pharmaceutical Co.,Inc. +// hisamitsu : Hisamitsu Pharmaceutical Co.,Inc. +// https://www.iana.org/domains/root/db/hisamitsu.html hisamitsu -// hitachi : 2014-10-31 Hitachi, Ltd. +// hitachi : Hitachi, Ltd. +// https://www.iana.org/domains/root/db/hitachi.html hitachi -// hiv : 2014-03-13 Internet Naming Company LLC +// hiv : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/hiv.html hiv -// hkt : 2015-05-14 PCCW-HKT DataCom Services Limited +// hkt : PCCW-HKT DataCom Services Limited +// https://www.iana.org/domains/root/db/hkt.html hkt -// hockey : 2015-03-19 Binky Moon, LLC +// hockey : Binky Moon, LLC +// https://www.iana.org/domains/root/db/hockey.html hockey -// holdings : 2013-08-27 Binky Moon, LLC +// holdings : Binky Moon, LLC +// https://www.iana.org/domains/root/db/holdings.html holdings -// holiday : 2013-11-07 Binky Moon, LLC +// holiday : Binky Moon, LLC +// https://www.iana.org/domains/root/db/holiday.html holiday -// homedepot : 2015-04-02 Home Depot Product Authority, LLC +// homedepot : Home Depot Product Authority, LLC +// https://www.iana.org/domains/root/db/homedepot.html homedepot -// homegoods : 2015-07-16 The TJX Companies, Inc. +// homegoods : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/homegoods.html homegoods -// homes : 2014-01-09 XYZ.COM LLC +// homes : XYZ.COM LLC +// https://www.iana.org/domains/root/db/homes.html homes -// homesense : 2015-07-16 The TJX Companies, Inc. +// homesense : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/homesense.html homesense -// honda : 2014-12-18 Honda Motor Co., Ltd. +// honda : Honda Motor Co., Ltd. +// https://www.iana.org/domains/root/db/honda.html honda -// horse : 2013-11-21 Registry Services, LLC +// horse : Registry Services, LLC +// https://www.iana.org/domains/root/db/horse.html horse -// hospital : 2016-10-20 Binky Moon, LLC +// hospital : Binky Moon, LLC +// https://www.iana.org/domains/root/db/hospital.html hospital -// host : 2014-04-17 Radix FZC +// host : Radix Technologies Inc. +// https://www.iana.org/domains/root/db/host.html host -// hosting : 2014-05-29 XYZ.COM LLC +// hosting : XYZ.COM LLC +// https://www.iana.org/domains/root/db/hosting.html hosting -// hot : 2015-08-27 Amazon Registry Services, Inc. +// hot : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/hot.html hot -// hoteles : 2015-03-05 Travel Reservations SRL -hoteles - -// hotels : 2016-04-07 Booking.com B.V. +// hotels : Booking.com B.V. +// https://www.iana.org/domains/root/db/hotels.html hotels -// hotmail : 2014-12-18 Microsoft Corporation +// hotmail : Microsoft Corporation +// https://www.iana.org/domains/root/db/hotmail.html hotmail -// house : 2013-11-07 Binky Moon, LLC +// house : Binky Moon, LLC +// https://www.iana.org/domains/root/db/house.html house -// how : 2014-01-23 Charleston Road Registry Inc. +// how : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/how.html how -// hsbc : 2014-10-24 HSBC Global Services (UK) Limited +// hsbc : HSBC Global Services (UK) Limited +// https://www.iana.org/domains/root/db/hsbc.html hsbc -// hughes : 2015-07-30 Hughes Satellite Systems Corporation +// hughes : Hughes Satellite Systems Corporation +// https://www.iana.org/domains/root/db/hughes.html hughes -// hyatt : 2015-07-30 Hyatt GTLD, L.L.C. +// hyatt : Hyatt GTLD, L.L.C. +// https://www.iana.org/domains/root/db/hyatt.html hyatt -// hyundai : 2015-07-09 Hyundai Motor Company +// hyundai : Hyundai Motor Company +// https://www.iana.org/domains/root/db/hyundai.html hyundai -// ibm : 2014-07-31 International Business Machines Corporation +// ibm : International Business Machines Corporation +// https://www.iana.org/domains/root/db/ibm.html ibm -// icbc : 2015-02-19 Industrial and Commercial Bank of China Limited +// icbc : Industrial and Commercial Bank of China Limited +// https://www.iana.org/domains/root/db/icbc.html icbc -// ice : 2014-10-30 IntercontinentalExchange, Inc. +// ice : IntercontinentalExchange, Inc. +// https://www.iana.org/domains/root/db/ice.html ice -// icu : 2015-01-08 ShortDot SA +// icu : ShortDot SA +// https://www.iana.org/domains/root/db/icu.html icu -// ieee : 2015-07-23 IEEE Global LLC +// ieee : IEEE Global LLC +// https://www.iana.org/domains/root/db/ieee.html ieee -// ifm : 2014-01-30 ifm electronic gmbh +// ifm : ifm electronic gmbh +// https://www.iana.org/domains/root/db/ifm.html ifm -// ikano : 2015-07-09 Ikano S.A. +// ikano : Ikano S.A. +// https://www.iana.org/domains/root/db/ikano.html ikano -// imamat : 2015-08-06 Fondation Aga Khan (Aga Khan Foundation) +// imamat : Fondation Aga Khan (Aga Khan Foundation) +// https://www.iana.org/domains/root/db/imamat.html imamat -// imdb : 2015-06-25 Amazon Registry Services, Inc. +// imdb : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/imdb.html imdb -// immo : 2014-07-10 Binky Moon, LLC +// immo : Binky Moon, LLC +// https://www.iana.org/domains/root/db/immo.html immo -// immobilien : 2013-11-07 Dog Beach, LLC +// immobilien : Dog Beach, LLC +// https://www.iana.org/domains/root/db/immobilien.html immobilien -// inc : 2018-03-10 Intercap Registry Inc. +// inc : Intercap Registry Inc. +// https://www.iana.org/domains/root/db/inc.html inc -// industries : 2013-12-05 Binky Moon, LLC +// industries : Binky Moon, LLC +// https://www.iana.org/domains/root/db/industries.html industries -// infiniti : 2014-03-27 NISSAN MOTOR CO., LTD. +// infiniti : NISSAN MOTOR CO., LTD. +// https://www.iana.org/domains/root/db/infiniti.html infiniti -// ing : 2014-01-23 Charleston Road Registry Inc. +// ing : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/ing.html ing -// ink : 2013-12-05 Top Level Design, LLC +// ink : Registry Services, LLC +// https://www.iana.org/domains/root/db/ink.html ink -// institute : 2013-11-07 Binky Moon, LLC +// institute : Binky Moon, LLC +// https://www.iana.org/domains/root/db/institute.html institute -// insurance : 2015-02-19 fTLD Registry Services LLC +// insurance : fTLD Registry Services LLC +// https://www.iana.org/domains/root/db/insurance.html insurance -// insure : 2014-03-20 Binky Moon, LLC +// insure : Binky Moon, LLC +// https://www.iana.org/domains/root/db/insure.html insure -// international : 2013-11-07 Binky Moon, LLC +// international : Binky Moon, LLC +// https://www.iana.org/domains/root/db/international.html international -// intuit : 2015-07-30 Intuit Administrative Services, Inc. +// intuit : Intuit Administrative Services, Inc. +// https://www.iana.org/domains/root/db/intuit.html intuit -// investments : 2014-03-20 Binky Moon, LLC +// investments : Binky Moon, LLC +// https://www.iana.org/domains/root/db/investments.html investments -// ipiranga : 2014-08-28 Ipiranga Produtos de Petroleo S.A. +// ipiranga : Ipiranga Produtos de Petroleo S.A. +// https://www.iana.org/domains/root/db/ipiranga.html ipiranga -// irish : 2014-08-07 Binky Moon, LLC +// irish : Binky Moon, LLC +// https://www.iana.org/domains/root/db/irish.html irish -// ismaili : 2015-08-06 Fondation Aga Khan (Aga Khan Foundation) +// ismaili : Fondation Aga Khan (Aga Khan Foundation) +// https://www.iana.org/domains/root/db/ismaili.html ismaili -// ist : 2014-08-28 Istanbul Metropolitan Municipality +// ist : Istanbul Metropolitan Municipality +// https://www.iana.org/domains/root/db/ist.html ist -// istanbul : 2014-08-28 Istanbul Metropolitan Municipality +// istanbul : Istanbul Metropolitan Municipality +// https://www.iana.org/domains/root/db/istanbul.html istanbul -// itau : 2014-10-02 Itau Unibanco Holding S.A. +// itau : Itau Unibanco Holding S.A. +// https://www.iana.org/domains/root/db/itau.html itau -// itv : 2015-07-09 ITV Services Limited +// itv : ITV Services Limited +// https://www.iana.org/domains/root/db/itv.html itv -// jaguar : 2014-11-13 Jaguar Land Rover Ltd +// jaguar : Jaguar Land Rover Ltd +// https://www.iana.org/domains/root/db/jaguar.html jaguar -// java : 2014-06-19 Oracle Corporation +// java : Oracle Corporation +// https://www.iana.org/domains/root/db/java.html java -// jcb : 2014-11-20 JCB Co., Ltd. +// jcb : JCB Co., Ltd. +// https://www.iana.org/domains/root/db/jcb.html jcb -// jeep : 2015-07-30 FCA US LLC. +// jeep : FCA US LLC. +// https://www.iana.org/domains/root/db/jeep.html jeep -// jetzt : 2014-01-09 Binky Moon, LLC +// jetzt : Binky Moon, LLC +// https://www.iana.org/domains/root/db/jetzt.html jetzt -// jewelry : 2015-03-05 Binky Moon, LLC +// jewelry : Binky Moon, LLC +// https://www.iana.org/domains/root/db/jewelry.html jewelry -// jio : 2015-04-02 Reliance Industries Limited +// jio : Reliance Industries Limited +// https://www.iana.org/domains/root/db/jio.html jio -// jll : 2015-04-02 Jones Lang LaSalle Incorporated +// jll : Jones Lang LaSalle Incorporated +// https://www.iana.org/domains/root/db/jll.html jll -// jmp : 2015-03-26 Matrix IP LLC +// jmp : Matrix IP LLC +// https://www.iana.org/domains/root/db/jmp.html jmp -// jnj : 2015-06-18 Johnson & Johnson Services, Inc. +// jnj : Johnson & Johnson Services, Inc. +// https://www.iana.org/domains/root/db/jnj.html jnj -// joburg : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry +// joburg : ZA Central Registry NPC trading as ZA Central Registry +// https://www.iana.org/domains/root/db/joburg.html joburg -// jot : 2014-12-18 Amazon Registry Services, Inc. +// jot : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/jot.html jot -// joy : 2014-12-18 Amazon Registry Services, Inc. +// joy : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/joy.html joy -// jpmorgan : 2015-04-30 JPMorgan Chase Bank, National Association +// jpmorgan : JPMorgan Chase Bank, National Association +// https://www.iana.org/domains/root/db/jpmorgan.html jpmorgan -// jprs : 2014-09-18 Japan Registry Services Co., Ltd. +// jprs : Japan Registry Services Co., Ltd. +// https://www.iana.org/domains/root/db/jprs.html jprs -// juegos : 2014-03-20 Internet Naming Company LLC +// juegos : Dog Beach, LLC +// https://www.iana.org/domains/root/db/juegos.html juegos -// juniper : 2015-07-30 JUNIPER NETWORKS, INC. +// juniper : JUNIPER NETWORKS, INC. +// https://www.iana.org/domains/root/db/juniper.html juniper -// kaufen : 2013-11-07 Dog Beach, LLC +// kaufen : Dog Beach, LLC +// https://www.iana.org/domains/root/db/kaufen.html kaufen -// kddi : 2014-09-12 KDDI CORPORATION +// kddi : KDDI CORPORATION +// https://www.iana.org/domains/root/db/kddi.html kddi -// kerryhotels : 2015-04-30 Kerry Trading Co. Limited +// kerryhotels : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/kerryhotels.html kerryhotels -// kerrylogistics : 2015-04-09 Kerry Trading Co. Limited +// kerrylogistics : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/kerrylogistics.html kerrylogistics -// kerryproperties : 2015-04-09 Kerry Trading Co. Limited +// kerryproperties : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/kerryproperties.html kerryproperties -// kfh : 2014-12-04 Kuwait Finance House +// kfh : Kuwait Finance House +// https://www.iana.org/domains/root/db/kfh.html kfh -// kia : 2015-07-09 KIA MOTORS CORPORATION +// kia : KIA MOTORS CORPORATION +// https://www.iana.org/domains/root/db/kia.html kia -// kids : 2021-08-13 DotKids Foundation Limited +// kids : DotKids Foundation Limited +// https://www.iana.org/domains/root/db/kids.html kids -// kim : 2013-09-23 Identity Digital Limited +// kim : Identity Digital Limited +// https://www.iana.org/domains/root/db/kim.html kim -// kinder : 2014-11-07 Ferrero Trading Lux S.A. -kinder - -// kindle : 2015-06-25 Amazon Registry Services, Inc. +// kindle : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/kindle.html kindle -// kitchen : 2013-09-20 Binky Moon, LLC +// kitchen : Binky Moon, LLC +// https://www.iana.org/domains/root/db/kitchen.html kitchen -// kiwi : 2013-09-20 DOT KIWI LIMITED +// kiwi : DOT KIWI LIMITED +// https://www.iana.org/domains/root/db/kiwi.html kiwi -// koeln : 2014-01-09 dotKoeln GmbH +// koeln : dotKoeln GmbH +// https://www.iana.org/domains/root/db/koeln.html koeln -// komatsu : 2015-01-08 Komatsu Ltd. +// komatsu : Komatsu Ltd. +// https://www.iana.org/domains/root/db/komatsu.html komatsu -// kosher : 2015-08-20 Kosher Marketing Assets LLC +// kosher : Kosher Marketing Assets LLC +// https://www.iana.org/domains/root/db/kosher.html kosher -// kpmg : 2015-04-23 KPMG International Cooperative (KPMG International Genossenschaft) +// kpmg : KPMG International Cooperative (KPMG International Genossenschaft) +// https://www.iana.org/domains/root/db/kpmg.html kpmg -// kpn : 2015-01-08 Koninklijke KPN N.V. +// kpn : Koninklijke KPN N.V. +// https://www.iana.org/domains/root/db/kpn.html kpn -// krd : 2013-12-05 KRG Department of Information Technology +// krd : KRG Department of Information Technology +// https://www.iana.org/domains/root/db/krd.html krd -// kred : 2013-12-19 KredTLD Pty Ltd +// kred : KredTLD Pty Ltd +// https://www.iana.org/domains/root/db/kred.html kred -// kuokgroup : 2015-04-09 Kerry Trading Co. Limited +// kuokgroup : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/kuokgroup.html kuokgroup -// kyoto : 2014-11-07 Academic Institution: Kyoto Jyoho Gakuen +// kyoto : Academic Institution: Kyoto Jyoho Gakuen +// https://www.iana.org/domains/root/db/kyoto.html kyoto -// lacaixa : 2014-01-09 Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa” +// lacaixa : Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa” +// https://www.iana.org/domains/root/db/lacaixa.html lacaixa -// lamborghini : 2015-06-04 Automobili Lamborghini S.p.A. +// lamborghini : Automobili Lamborghini S.p.A. +// https://www.iana.org/domains/root/db/lamborghini.html lamborghini -// lamer : 2015-10-01 The Estée Lauder Companies Inc. +// lamer : The Estée Lauder Companies Inc. +// https://www.iana.org/domains/root/db/lamer.html lamer -// lancaster : 2015-02-12 LANCASTER +// lancaster : LANCASTER +// https://www.iana.org/domains/root/db/lancaster.html lancaster -// lancia : 2015-07-31 Fiat Chrysler Automobiles N.V. -lancia - -// land : 2013-09-10 Binky Moon, LLC +// land : Binky Moon, LLC +// https://www.iana.org/domains/root/db/land.html land -// landrover : 2014-11-13 Jaguar Land Rover Ltd +// landrover : Jaguar Land Rover Ltd +// https://www.iana.org/domains/root/db/landrover.html landrover -// lanxess : 2015-07-30 LANXESS Corporation +// lanxess : LANXESS Corporation +// https://www.iana.org/domains/root/db/lanxess.html lanxess -// lasalle : 2015-04-02 Jones Lang LaSalle Incorporated +// lasalle : Jones Lang LaSalle Incorporated +// https://www.iana.org/domains/root/db/lasalle.html lasalle -// lat : 2014-10-16 XYZ.COM LLC +// lat : XYZ.COM LLC +// https://www.iana.org/domains/root/db/lat.html lat -// latino : 2015-07-30 Dish DBS Corporation +// latino : Dish DBS Corporation +// https://www.iana.org/domains/root/db/latino.html latino -// latrobe : 2014-06-16 La Trobe University +// latrobe : La Trobe University +// https://www.iana.org/domains/root/db/latrobe.html latrobe -// law : 2015-01-22 Registry Services, LLC +// law : Registry Services, LLC +// https://www.iana.org/domains/root/db/law.html law -// lawyer : 2014-03-20 Dog Beach, LLC +// lawyer : Dog Beach, LLC +// https://www.iana.org/domains/root/db/lawyer.html lawyer -// lds : 2014-03-20 IRI Domain Management, LLC +// lds : IRI Domain Management, LLC +// https://www.iana.org/domains/root/db/lds.html lds -// lease : 2014-03-06 Binky Moon, LLC +// lease : Binky Moon, LLC +// https://www.iana.org/domains/root/db/lease.html lease -// leclerc : 2014-08-07 A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc +// leclerc : A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc +// https://www.iana.org/domains/root/db/leclerc.html leclerc -// lefrak : 2015-07-16 LeFrak Organization, Inc. +// lefrak : LeFrak Organization, Inc. +// https://www.iana.org/domains/root/db/lefrak.html lefrak -// legal : 2014-10-16 Binky Moon, LLC +// legal : Binky Moon, LLC +// https://www.iana.org/domains/root/db/legal.html legal -// lego : 2015-07-16 LEGO Juris A/S +// lego : LEGO Juris A/S +// https://www.iana.org/domains/root/db/lego.html lego -// lexus : 2015-04-23 TOYOTA MOTOR CORPORATION +// lexus : TOYOTA MOTOR CORPORATION +// https://www.iana.org/domains/root/db/lexus.html lexus -// lgbt : 2014-05-08 Identity Digital Limited +// lgbt : Identity Digital Limited +// https://www.iana.org/domains/root/db/lgbt.html lgbt -// lidl : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG +// lidl : Schwarz Domains und Services GmbH & Co. KG +// https://www.iana.org/domains/root/db/lidl.html lidl -// life : 2014-02-06 Binky Moon, LLC +// life : Binky Moon, LLC +// https://www.iana.org/domains/root/db/life.html life -// lifeinsurance : 2015-01-15 American Council of Life Insurers +// lifeinsurance : American Council of Life Insurers +// https://www.iana.org/domains/root/db/lifeinsurance.html lifeinsurance -// lifestyle : 2014-12-11 Lifestyle Domain Holdings, Inc. +// lifestyle : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/lifestyle.html lifestyle -// lighting : 2013-08-27 Binky Moon, LLC +// lighting : Binky Moon, LLC +// https://www.iana.org/domains/root/db/lighting.html lighting -// like : 2014-12-18 Amazon Registry Services, Inc. +// like : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/like.html like -// lilly : 2015-07-31 Eli Lilly and Company +// lilly : Eli Lilly and Company +// https://www.iana.org/domains/root/db/lilly.html lilly -// limited : 2014-03-06 Binky Moon, LLC +// limited : Binky Moon, LLC +// https://www.iana.org/domains/root/db/limited.html limited -// limo : 2013-10-17 Binky Moon, LLC +// limo : Binky Moon, LLC +// https://www.iana.org/domains/root/db/limo.html limo -// lincoln : 2014-11-13 Ford Motor Company +// lincoln : Ford Motor Company +// https://www.iana.org/domains/root/db/lincoln.html lincoln -// linde : 2014-12-04 Linde Aktiengesellschaft -linde - -// link : 2013-11-14 Nova Registry Ltd +// link : Nova Registry Ltd +// https://www.iana.org/domains/root/db/link.html link -// lipsy : 2015-06-25 Lipsy Ltd +// lipsy : Lipsy Ltd +// https://www.iana.org/domains/root/db/lipsy.html lipsy -// live : 2014-12-04 Dog Beach, LLC +// live : Dog Beach, LLC +// https://www.iana.org/domains/root/db/live.html live -// living : 2015-07-30 Lifestyle Domain Holdings, Inc. +// living : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/living.html living -// llc : 2017-12-14 Identity Digital Limited +// llc : Identity Digital Limited +// https://www.iana.org/domains/root/db/llc.html llc -// llp : 2019-08-26 Intercap Registry Inc. +// llp : Intercap Registry Inc. +// https://www.iana.org/domains/root/db/llp.html llp -// loan : 2014-11-20 dot Loan Limited +// loan : dot Loan Limited +// https://www.iana.org/domains/root/db/loan.html loan -// loans : 2014-03-20 Binky Moon, LLC +// loans : Binky Moon, LLC +// https://www.iana.org/domains/root/db/loans.html loans -// locker : 2015-06-04 Dish DBS Corporation +// locker : Orange Domains LLC +// https://www.iana.org/domains/root/db/locker.html locker -// locus : 2015-06-25 Locus Analytics LLC +// locus : Locus Analytics LLC +// https://www.iana.org/domains/root/db/locus.html locus -// lol : 2015-01-30 XYZ.COM LLC +// lol : XYZ.COM LLC +// https://www.iana.org/domains/root/db/lol.html lol -// london : 2013-11-14 Dot London Domains Limited +// london : Dot London Domains Limited +// https://www.iana.org/domains/root/db/london.html london -// lotte : 2014-11-07 Lotte Holdings Co., Ltd. +// lotte : Lotte Holdings Co., Ltd. +// https://www.iana.org/domains/root/db/lotte.html lotte -// lotto : 2014-04-10 Identity Digital Limited +// lotto : Identity Digital Limited +// https://www.iana.org/domains/root/db/lotto.html lotto -// love : 2014-12-22 Merchant Law Group LLP +// love : Waterford Limited +// https://www.iana.org/domains/root/db/love.html love -// lpl : 2015-07-30 LPL Holdings, Inc. +// lpl : LPL Holdings, Inc. +// https://www.iana.org/domains/root/db/lpl.html lpl -// lplfinancial : 2015-07-30 LPL Holdings, Inc. +// lplfinancial : LPL Holdings, Inc. +// https://www.iana.org/domains/root/db/lplfinancial.html lplfinancial -// ltd : 2014-09-25 Binky Moon, LLC +// ltd : Binky Moon, LLC +// https://www.iana.org/domains/root/db/ltd.html ltd -// ltda : 2014-04-17 InterNetX, Corp +// ltda : InterNetX, Corp +// https://www.iana.org/domains/root/db/ltda.html ltda -// lundbeck : 2015-08-06 H. Lundbeck A/S +// lundbeck : H. Lundbeck A/S +// https://www.iana.org/domains/root/db/lundbeck.html lundbeck -// luxe : 2014-01-09 Registry Services, LLC +// luxe : Registry Services, LLC +// https://www.iana.org/domains/root/db/luxe.html luxe -// luxury : 2013-10-17 Luxury Partners, LLC +// luxury : Luxury Partners, LLC +// https://www.iana.org/domains/root/db/luxury.html luxury -// macys : 2015-07-31 Macys, Inc. -macys - -// madrid : 2014-05-01 Comunidad de Madrid +// madrid : Comunidad de Madrid +// https://www.iana.org/domains/root/db/madrid.html madrid -// maif : 2014-10-02 Mutuelle Assurance Instituteur France (MAIF) +// maif : Mutuelle Assurance Instituteur France (MAIF) +// https://www.iana.org/domains/root/db/maif.html maif -// maison : 2013-12-05 Binky Moon, LLC +// maison : Binky Moon, LLC +// https://www.iana.org/domains/root/db/maison.html maison -// makeup : 2015-01-15 XYZ.COM LLC +// makeup : XYZ.COM LLC +// https://www.iana.org/domains/root/db/makeup.html makeup -// man : 2014-12-04 MAN SE +// man : MAN Truck & Bus SE +// https://www.iana.org/domains/root/db/man.html man -// management : 2013-11-07 Binky Moon, LLC +// management : Binky Moon, LLC +// https://www.iana.org/domains/root/db/management.html management -// mango : 2013-10-24 PUNTO FA S.L. +// mango : PUNTO FA S.L. +// https://www.iana.org/domains/root/db/mango.html mango -// map : 2016-06-09 Charleston Road Registry Inc. +// map : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/map.html map -// market : 2014-03-06 Dog Beach, LLC +// market : Dog Beach, LLC +// https://www.iana.org/domains/root/db/market.html market -// marketing : 2013-11-07 Binky Moon, LLC +// marketing : Binky Moon, LLC +// https://www.iana.org/domains/root/db/marketing.html marketing -// markets : 2014-12-11 Dog Beach, LLC +// markets : Dog Beach, LLC +// https://www.iana.org/domains/root/db/markets.html markets -// marriott : 2014-10-09 Marriott Worldwide Corporation +// marriott : Marriott Worldwide Corporation +// https://www.iana.org/domains/root/db/marriott.html marriott -// marshalls : 2015-07-16 The TJX Companies, Inc. +// marshalls : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/marshalls.html marshalls -// maserati : 2015-07-31 Fiat Chrysler Automobiles N.V. -maserati - -// mattel : 2015-08-06 Mattel Sites, Inc. +// mattel : Mattel Sites, Inc. +// https://www.iana.org/domains/root/db/mattel.html mattel -// mba : 2015-04-02 Binky Moon, LLC +// mba : Binky Moon, LLC +// https://www.iana.org/domains/root/db/mba.html mba -// mckinsey : 2015-07-31 McKinsey Holdings, Inc. +// mckinsey : McKinsey Holdings, Inc. +// https://www.iana.org/domains/root/db/mckinsey.html mckinsey -// med : 2015-08-06 Medistry LLC +// med : Medistry LLC +// https://www.iana.org/domains/root/db/med.html med -// media : 2014-03-06 Binky Moon, LLC +// media : Binky Moon, LLC +// https://www.iana.org/domains/root/db/media.html media -// meet : 2014-01-16 Charleston Road Registry Inc. +// meet : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/meet.html meet -// melbourne : 2014-05-29 The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation +// melbourne : The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation +// https://www.iana.org/domains/root/db/melbourne.html melbourne -// meme : 2014-01-30 Charleston Road Registry Inc. +// meme : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/meme.html meme -// memorial : 2014-10-16 Dog Beach, LLC +// memorial : Dog Beach, LLC +// https://www.iana.org/domains/root/db/memorial.html memorial -// men : 2015-02-26 Exclusive Registry Limited +// men : Exclusive Registry Limited +// https://www.iana.org/domains/root/db/men.html men -// menu : 2013-09-11 Dot Menu Registry, LLC +// menu : Dot Menu Registry, LLC +// https://www.iana.org/domains/root/db/menu.html menu -// merckmsd : 2016-07-14 MSD Registry Holdings, Inc. +// merck : Merck Registry Holdings, Inc. +// https://www.iana.org/domains/root/db/merck.html +merck + +// merckmsd : MSD Registry Holdings, Inc. +// https://www.iana.org/domains/root/db/merckmsd.html merckmsd -// miami : 2013-12-19 Registry Services, LLC +// miami : Registry Services, LLC +// https://www.iana.org/domains/root/db/miami.html miami -// microsoft : 2014-12-18 Microsoft Corporation +// microsoft : Microsoft Corporation +// https://www.iana.org/domains/root/db/microsoft.html microsoft -// mini : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft +// mini : Bayerische Motoren Werke Aktiengesellschaft +// https://www.iana.org/domains/root/db/mini.html mini -// mint : 2015-07-30 Intuit Administrative Services, Inc. +// mint : Intuit Administrative Services, Inc. +// https://www.iana.org/domains/root/db/mint.html mint -// mit : 2015-07-02 Massachusetts Institute of Technology +// mit : Massachusetts Institute of Technology +// https://www.iana.org/domains/root/db/mit.html mit -// mitsubishi : 2015-07-23 Mitsubishi Corporation +// mitsubishi : Mitsubishi Corporation +// https://www.iana.org/domains/root/db/mitsubishi.html mitsubishi -// mlb : 2015-05-21 MLB Advanced Media DH, LLC +// mlb : MLB Advanced Media DH, LLC +// https://www.iana.org/domains/root/db/mlb.html mlb -// mls : 2015-04-23 The Canadian Real Estate Association +// mls : The Canadian Real Estate Association +// https://www.iana.org/domains/root/db/mls.html mls -// mma : 2014-11-07 MMA IARD +// mma : MMA IARD +// https://www.iana.org/domains/root/db/mma.html mma -// mobile : 2016-06-02 Dish DBS Corporation +// mobile : Dish DBS Corporation +// https://www.iana.org/domains/root/db/mobile.html mobile -// moda : 2013-11-07 Dog Beach, LLC +// moda : Dog Beach, LLC +// https://www.iana.org/domains/root/db/moda.html moda -// moe : 2013-11-13 Interlink Systems Innovation Institute K.K. +// moe : Interlink Systems Innovation Institute K.K. +// https://www.iana.org/domains/root/db/moe.html moe -// moi : 2014-12-18 Amazon Registry Services, Inc. +// moi : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/moi.html moi -// mom : 2015-04-16 XYZ.COM LLC +// mom : XYZ.COM LLC +// https://www.iana.org/domains/root/db/mom.html mom -// monash : 2013-09-30 Monash University +// monash : Monash University +// https://www.iana.org/domains/root/db/monash.html monash -// money : 2014-10-16 Binky Moon, LLC +// money : Binky Moon, LLC +// https://www.iana.org/domains/root/db/money.html money -// monster : 2015-09-11 XYZ.COM LLC +// monster : XYZ.COM LLC +// https://www.iana.org/domains/root/db/monster.html monster -// mormon : 2013-12-05 IRI Domain Management, LLC +// mormon : IRI Domain Management, LLC +// https://www.iana.org/domains/root/db/mormon.html mormon -// mortgage : 2014-03-20 Dog Beach, LLC +// mortgage : Dog Beach, LLC +// https://www.iana.org/domains/root/db/mortgage.html mortgage -// moscow : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) +// moscow : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) +// https://www.iana.org/domains/root/db/moscow.html moscow -// moto : 2015-06-04 Motorola Trademark Holdings, LLC +// moto : Motorola Trademark Holdings, LLC +// https://www.iana.org/domains/root/db/moto.html moto -// motorcycles : 2014-01-09 XYZ.COM LLC +// motorcycles : XYZ.COM LLC +// https://www.iana.org/domains/root/db/motorcycles.html motorcycles -// mov : 2014-01-30 Charleston Road Registry Inc. +// mov : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/mov.html mov -// movie : 2015-02-05 Binky Moon, LLC +// movie : Binky Moon, LLC +// https://www.iana.org/domains/root/db/movie.html movie -// msd : 2015-07-23 MSD Registry Holdings, Inc. +// msd : MSD Registry Holdings, Inc. +// https://www.iana.org/domains/root/db/msd.html msd -// mtn : 2014-12-04 MTN Dubai Limited +// mtn : MTN Dubai Limited +// https://www.iana.org/domains/root/db/mtn.html mtn -// mtr : 2015-03-12 MTR Corporation Limited +// mtr : MTR Corporation Limited +// https://www.iana.org/domains/root/db/mtr.html mtr -// music : 2021-05-04 DotMusic Limited +// music : DotMusic Limited +// https://www.iana.org/domains/root/db/music.html music -// mutual : 2015-04-02 Northwestern Mutual MU TLD Registry, LLC -mutual - -// nab : 2015-08-20 National Australia Bank Limited +// nab : National Australia Bank Limited +// https://www.iana.org/domains/root/db/nab.html nab -// nagoya : 2013-10-24 GMO Registry, Inc. +// nagoya : GMO Registry, Inc. +// https://www.iana.org/domains/root/db/nagoya.html nagoya -// natura : 2015-03-12 NATURA COSMÉTICOS S.A. -natura - -// navy : 2014-03-06 Dog Beach, LLC +// navy : Dog Beach, LLC +// https://www.iana.org/domains/root/db/navy.html navy -// nba : 2015-07-31 NBA REGISTRY, LLC +// nba : NBA REGISTRY, LLC +// https://www.iana.org/domains/root/db/nba.html nba -// nec : 2015-01-08 NEC Corporation +// nec : NEC Corporation +// https://www.iana.org/domains/root/db/nec.html nec -// netbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA +// netbank : COMMONWEALTH BANK OF AUSTRALIA +// https://www.iana.org/domains/root/db/netbank.html netbank -// netflix : 2015-06-18 Netflix, Inc. +// netflix : Netflix, Inc. +// https://www.iana.org/domains/root/db/netflix.html netflix -// network : 2013-11-14 Binky Moon, LLC +// network : Binky Moon, LLC +// https://www.iana.org/domains/root/db/network.html network -// neustar : 2013-12-05 NeuStar, Inc. +// neustar : NeuStar, Inc. +// https://www.iana.org/domains/root/db/neustar.html neustar -// new : 2014-01-30 Charleston Road Registry Inc. +// new : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/new.html new -// news : 2014-12-18 Dog Beach, LLC +// news : Dog Beach, LLC +// https://www.iana.org/domains/root/db/news.html news -// next : 2015-06-18 Next plc +// next : Next plc +// https://www.iana.org/domains/root/db/next.html next -// nextdirect : 2015-06-18 Next plc +// nextdirect : Next plc +// https://www.iana.org/domains/root/db/nextdirect.html nextdirect -// nexus : 2014-07-24 Charleston Road Registry Inc. +// nexus : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/nexus.html nexus -// nfl : 2015-07-23 NFL Reg Ops LLC +// nfl : NFL Reg Ops LLC +// https://www.iana.org/domains/root/db/nfl.html nfl -// ngo : 2014-03-06 Public Interest Registry +// ngo : Public Interest Registry +// https://www.iana.org/domains/root/db/ngo.html ngo -// nhk : 2014-02-13 Japan Broadcasting Corporation (NHK) +// nhk : Japan Broadcasting Corporation (NHK) +// https://www.iana.org/domains/root/db/nhk.html nhk -// nico : 2014-12-04 DWANGO Co., Ltd. +// nico : DWANGO Co., Ltd. +// https://www.iana.org/domains/root/db/nico.html nico -// nike : 2015-07-23 NIKE, Inc. +// nike : NIKE, Inc. +// https://www.iana.org/domains/root/db/nike.html nike -// nikon : 2015-05-21 NIKON CORPORATION +// nikon : NIKON CORPORATION +// https://www.iana.org/domains/root/db/nikon.html nikon -// ninja : 2013-11-07 Dog Beach, LLC +// ninja : Dog Beach, LLC +// https://www.iana.org/domains/root/db/ninja.html ninja -// nissan : 2014-03-27 NISSAN MOTOR CO., LTD. +// nissan : NISSAN MOTOR CO., LTD. +// https://www.iana.org/domains/root/db/nissan.html nissan -// nissay : 2015-10-29 Nippon Life Insurance Company +// nissay : Nippon Life Insurance Company +// https://www.iana.org/domains/root/db/nissay.html nissay -// nokia : 2015-01-08 Nokia Corporation +// nokia : Nokia Corporation +// https://www.iana.org/domains/root/db/nokia.html nokia -// northwesternmutual : 2015-06-18 Northwestern Mutual Registry, LLC -northwesternmutual - -// norton : 2014-12-04 NortonLifeLock Inc. +// norton : Gen Digital Inc. +// https://www.iana.org/domains/root/db/norton.html norton -// now : 2015-06-25 Amazon Registry Services, Inc. +// now : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/now.html now -// nowruz : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. +// nowruz : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. +// https://www.iana.org/domains/root/db/nowruz.html nowruz -// nowtv : 2015-05-14 Starbucks (HK) Limited +// nowtv : Starbucks (HK) Limited +// https://www.iana.org/domains/root/db/nowtv.html nowtv -// nra : 2014-05-22 NRA Holdings Company, INC. +// nra : NRA Holdings Company, INC. +// https://www.iana.org/domains/root/db/nra.html nra -// nrw : 2013-11-21 Minds + Machines GmbH +// nrw : Minds + Machines GmbH +// https://www.iana.org/domains/root/db/nrw.html nrw -// ntt : 2014-10-31 NIPPON TELEGRAPH AND TELEPHONE CORPORATION +// ntt : NIPPON TELEGRAPH AND TELEPHONE CORPORATION +// https://www.iana.org/domains/root/db/ntt.html ntt -// nyc : 2014-01-23 The City of New York by and through the New York City Department of Information Technology & Telecommunications +// nyc : The City of New York by and through the New York City Department of Information Technology & Telecommunications +// https://www.iana.org/domains/root/db/nyc.html nyc -// obi : 2014-09-25 OBI Group Holding SE & Co. KGaA +// obi : OBI Group Holding SE & Co. KGaA +// https://www.iana.org/domains/root/db/obi.html obi -// observer : 2015-04-30 Dog Beach, LLC +// observer : Fegistry, LLC +// https://www.iana.org/domains/root/db/observer.html observer -// office : 2015-03-12 Microsoft Corporation +// office : Microsoft Corporation +// https://www.iana.org/domains/root/db/office.html office -// okinawa : 2013-12-05 BRregistry, Inc. +// okinawa : BRregistry, Inc. +// https://www.iana.org/domains/root/db/okinawa.html okinawa -// olayan : 2015-05-14 Crescent Holding GmbH +// olayan : Competrol (Luxembourg) Sarl +// https://www.iana.org/domains/root/db/olayan.html olayan -// olayangroup : 2015-05-14 Crescent Holding GmbH +// olayangroup : Competrol (Luxembourg) Sarl +// https://www.iana.org/domains/root/db/olayangroup.html olayangroup -// oldnavy : 2015-07-31 The Gap, Inc. -oldnavy - -// ollo : 2015-06-04 Dish DBS Corporation +// ollo : Dish DBS Corporation +// https://www.iana.org/domains/root/db/ollo.html ollo -// omega : 2015-01-08 The Swatch Group Ltd +// omega : The Swatch Group Ltd +// https://www.iana.org/domains/root/db/omega.html omega -// one : 2014-11-07 One.com A/S +// one : One.com A/S +// https://www.iana.org/domains/root/db/one.html one -// ong : 2014-03-06 Public Interest Registry +// ong : Public Interest Registry +// https://www.iana.org/domains/root/db/ong.html ong -// onl : 2013-09-16 iRegistry GmbH +// onl : iRegistry GmbH +// https://www.iana.org/domains/root/db/onl.html onl -// online : 2015-01-15 Radix FZC +// online : Radix Technologies Inc. +// https://www.iana.org/domains/root/db/online.html online -// ooo : 2014-01-09 INFIBEAM AVENUES LIMITED +// ooo : INFIBEAM AVENUES LIMITED +// https://www.iana.org/domains/root/db/ooo.html ooo -// open : 2015-07-31 American Express Travel Related Services Company, Inc. +// open : American Express Travel Related Services Company, Inc. +// https://www.iana.org/domains/root/db/open.html open -// oracle : 2014-06-19 Oracle Corporation +// oracle : Oracle Corporation +// https://www.iana.org/domains/root/db/oracle.html oracle -// orange : 2015-03-12 Orange Brand Services Limited +// orange : Orange Brand Services Limited +// https://www.iana.org/domains/root/db/orange.html orange -// organic : 2014-03-27 Identity Digital Limited +// organic : Identity Digital Limited +// https://www.iana.org/domains/root/db/organic.html organic -// origins : 2015-10-01 The Estée Lauder Companies Inc. +// origins : The Estée Lauder Companies Inc. +// https://www.iana.org/domains/root/db/origins.html origins -// osaka : 2014-09-04 Osaka Registry Co., Ltd. +// osaka : Osaka Registry Co., Ltd. +// https://www.iana.org/domains/root/db/osaka.html osaka -// otsuka : 2013-10-11 Otsuka Holdings Co., Ltd. +// otsuka : Otsuka Holdings Co., Ltd. +// https://www.iana.org/domains/root/db/otsuka.html otsuka -// ott : 2015-06-04 Dish DBS Corporation +// ott : Dish DBS Corporation +// https://www.iana.org/domains/root/db/ott.html ott -// ovh : 2014-01-16 MédiaBC +// ovh : MédiaBC +// https://www.iana.org/domains/root/db/ovh.html ovh -// page : 2014-12-04 Charleston Road Registry Inc. +// page : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/page.html page -// panasonic : 2015-07-30 Panasonic Corporation +// panasonic : Panasonic Holdings Corporation +// https://www.iana.org/domains/root/db/panasonic.html panasonic -// paris : 2014-01-30 City of Paris +// paris : City of Paris +// https://www.iana.org/domains/root/db/paris.html paris -// pars : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. +// pars : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. +// https://www.iana.org/domains/root/db/pars.html pars -// partners : 2013-12-05 Binky Moon, LLC +// partners : Binky Moon, LLC +// https://www.iana.org/domains/root/db/partners.html partners -// parts : 2013-12-05 Binky Moon, LLC +// parts : Binky Moon, LLC +// https://www.iana.org/domains/root/db/parts.html parts -// party : 2014-09-11 Blue Sky Registry Limited +// party : Blue Sky Registry Limited +// https://www.iana.org/domains/root/db/party.html party -// passagens : 2015-03-05 Travel Reservations SRL -passagens - -// pay : 2015-08-27 Amazon Registry Services, Inc. +// pay : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/pay.html pay -// pccw : 2015-05-14 PCCW Enterprises Limited +// pccw : PCCW Enterprises Limited +// https://www.iana.org/domains/root/db/pccw.html pccw -// pet : 2015-05-07 Identity Digital Limited +// pet : Identity Digital Limited +// https://www.iana.org/domains/root/db/pet.html pet -// pfizer : 2015-09-11 Pfizer Inc. +// pfizer : Pfizer Inc. +// https://www.iana.org/domains/root/db/pfizer.html pfizer -// pharmacy : 2014-06-19 National Association of Boards of Pharmacy +// pharmacy : National Association of Boards of Pharmacy +// https://www.iana.org/domains/root/db/pharmacy.html pharmacy -// phd : 2016-07-28 Charleston Road Registry Inc. +// phd : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/phd.html phd -// philips : 2014-11-07 Koninklijke Philips N.V. +// philips : Koninklijke Philips N.V. +// https://www.iana.org/domains/root/db/philips.html philips -// phone : 2016-06-02 Dish DBS Corporation +// phone : Dish DBS Corporation +// https://www.iana.org/domains/root/db/phone.html phone -// photo : 2013-11-14 Registry Services, LLC +// photo : Registry Services, LLC +// https://www.iana.org/domains/root/db/photo.html photo -// photography : 2013-09-20 Binky Moon, LLC +// photography : Binky Moon, LLC +// https://www.iana.org/domains/root/db/photography.html photography -// photos : 2013-10-17 Binky Moon, LLC +// photos : Binky Moon, LLC +// https://www.iana.org/domains/root/db/photos.html photos -// physio : 2014-05-01 PhysBiz Pty Ltd +// physio : PhysBiz Pty Ltd +// https://www.iana.org/domains/root/db/physio.html physio -// pics : 2013-11-14 XYZ.COM LLC +// pics : XYZ.COM LLC +// https://www.iana.org/domains/root/db/pics.html pics -// pictet : 2014-06-26 Pictet Europe S.A. +// pictet : Pictet Europe S.A. +// https://www.iana.org/domains/root/db/pictet.html pictet -// pictures : 2014-03-06 Binky Moon, LLC +// pictures : Binky Moon, LLC +// https://www.iana.org/domains/root/db/pictures.html pictures -// pid : 2015-01-08 Top Level Spectrum, Inc. +// pid : Top Level Spectrum, Inc. +// https://www.iana.org/domains/root/db/pid.html pid -// pin : 2014-12-18 Amazon Registry Services, Inc. +// pin : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/pin.html pin -// ping : 2015-06-11 Ping Registry Provider, Inc. +// ping : Ping Registry Provider, Inc. +// https://www.iana.org/domains/root/db/ping.html ping -// pink : 2013-10-01 Identity Digital Limited +// pink : Identity Digital Limited +// https://www.iana.org/domains/root/db/pink.html pink -// pioneer : 2015-07-16 Pioneer Corporation +// pioneer : Pioneer Corporation +// https://www.iana.org/domains/root/db/pioneer.html pioneer -// pizza : 2014-06-26 Binky Moon, LLC +// pizza : Binky Moon, LLC +// https://www.iana.org/domains/root/db/pizza.html pizza -// place : 2014-04-24 Binky Moon, LLC +// place : Binky Moon, LLC +// https://www.iana.org/domains/root/db/place.html place -// play : 2015-03-05 Charleston Road Registry Inc. +// play : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/play.html play -// playstation : 2015-07-02 Sony Interactive Entertainment Inc. +// playstation : Sony Interactive Entertainment Inc. +// https://www.iana.org/domains/root/db/playstation.html playstation -// plumbing : 2013-09-10 Binky Moon, LLC +// plumbing : Binky Moon, LLC +// https://www.iana.org/domains/root/db/plumbing.html plumbing -// plus : 2015-02-05 Binky Moon, LLC +// plus : Binky Moon, LLC +// https://www.iana.org/domains/root/db/plus.html plus -// pnc : 2015-07-02 PNC Domain Co., LLC +// pnc : PNC Domain Co., LLC +// https://www.iana.org/domains/root/db/pnc.html pnc -// pohl : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG +// pohl : Deutsche Vermögensberatung Aktiengesellschaft DVAG +// https://www.iana.org/domains/root/db/pohl.html pohl -// poker : 2014-07-03 Identity Digital Limited +// poker : Identity Digital Limited +// https://www.iana.org/domains/root/db/poker.html poker -// politie : 2015-08-20 Politie Nederland +// politie : Politie Nederland +// https://www.iana.org/domains/root/db/politie.html politie -// porn : 2014-10-16 ICM Registry PN LLC +// porn : ICM Registry PN LLC +// https://www.iana.org/domains/root/db/porn.html porn -// pramerica : 2015-07-30 Prudential Financial, Inc. +// pramerica : Prudential Financial, Inc. +// https://www.iana.org/domains/root/db/pramerica.html pramerica -// praxi : 2013-12-05 Praxi S.p.A. +// praxi : Praxi S.p.A. +// https://www.iana.org/domains/root/db/praxi.html praxi -// press : 2014-04-03 Radix FZC +// press : Radix Technologies Inc. +// https://www.iana.org/domains/root/db/press.html press -// prime : 2015-06-25 Amazon Registry Services, Inc. +// prime : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/prime.html prime -// prod : 2014-01-23 Charleston Road Registry Inc. +// prod : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/prod.html prod -// productions : 2013-12-05 Binky Moon, LLC +// productions : Binky Moon, LLC +// https://www.iana.org/domains/root/db/productions.html productions -// prof : 2014-07-24 Charleston Road Registry Inc. +// prof : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/prof.html prof -// progressive : 2015-07-23 Progressive Casualty Insurance Company +// progressive : Progressive Casualty Insurance Company +// https://www.iana.org/domains/root/db/progressive.html progressive -// promo : 2014-12-18 Identity Digital Limited +// promo : Identity Digital Limited +// https://www.iana.org/domains/root/db/promo.html promo -// properties : 2013-12-05 Binky Moon, LLC +// properties : Binky Moon, LLC +// https://www.iana.org/domains/root/db/properties.html properties -// property : 2014-05-22 Internet Naming Company LLC +// property : Digital Property Infrastructure Limited +// https://www.iana.org/domains/root/db/property.html property -// protection : 2015-04-23 XYZ.COM LLC +// protection : XYZ.COM LLC +// https://www.iana.org/domains/root/db/protection.html protection -// pru : 2015-07-30 Prudential Financial, Inc. +// pru : Prudential Financial, Inc. +// https://www.iana.org/domains/root/db/pru.html pru -// prudential : 2015-07-30 Prudential Financial, Inc. +// prudential : Prudential Financial, Inc. +// https://www.iana.org/domains/root/db/prudential.html prudential -// pub : 2013-12-12 Dog Beach, LLC +// pub : Dog Beach, LLC +// https://www.iana.org/domains/root/db/pub.html pub -// pwc : 2015-10-29 PricewaterhouseCoopers LLP +// pwc : PricewaterhouseCoopers LLP +// https://www.iana.org/domains/root/db/pwc.html pwc -// qpon : 2013-11-14 dotQPON LLC +// qpon : dotQPON LLC +// https://www.iana.org/domains/root/db/qpon.html qpon -// quebec : 2013-12-19 PointQuébec Inc +// quebec : PointQuébec Inc +// https://www.iana.org/domains/root/db/quebec.html quebec -// quest : 2015-03-26 XYZ.COM LLC +// quest : XYZ.COM LLC +// https://www.iana.org/domains/root/db/quest.html quest -// racing : 2014-12-04 Premier Registry Limited +// racing : Premier Registry Limited +// https://www.iana.org/domains/root/db/racing.html racing -// radio : 2016-07-21 European Broadcasting Union (EBU) +// radio : European Broadcasting Union (EBU) +// https://www.iana.org/domains/root/db/radio.html radio -// read : 2014-12-18 Amazon Registry Services, Inc. +// read : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/read.html read -// realestate : 2015-09-11 dotRealEstate LLC +// realestate : dotRealEstate LLC +// https://www.iana.org/domains/root/db/realestate.html realestate -// realtor : 2014-05-29 Real Estate Domains LLC +// realtor : Real Estate Domains LLC +// https://www.iana.org/domains/root/db/realtor.html realtor -// realty : 2015-03-19 Dog Beach, LLC +// realty : Waterford Limited +// https://www.iana.org/domains/root/db/realty.html realty -// recipes : 2013-10-17 Binky Moon, LLC +// recipes : Binky Moon, LLC +// https://www.iana.org/domains/root/db/recipes.html recipes -// red : 2013-11-07 Identity Digital Limited +// red : Identity Digital Limited +// https://www.iana.org/domains/root/db/red.html red -// redstone : 2014-10-31 Redstone Haute Couture Co., Ltd. +// redstone : Redstone Haute Couture Co., Ltd. +// https://www.iana.org/domains/root/db/redstone.html redstone -// redumbrella : 2015-03-26 Travelers TLD, LLC +// redumbrella : Travelers TLD, LLC +// https://www.iana.org/domains/root/db/redumbrella.html redumbrella -// rehab : 2014-03-06 Dog Beach, LLC +// rehab : Dog Beach, LLC +// https://www.iana.org/domains/root/db/rehab.html rehab -// reise : 2014-03-13 Binky Moon, LLC +// reise : Binky Moon, LLC +// https://www.iana.org/domains/root/db/reise.html reise -// reisen : 2014-03-06 Binky Moon, LLC +// reisen : Binky Moon, LLC +// https://www.iana.org/domains/root/db/reisen.html reisen -// reit : 2014-09-04 National Association of Real Estate Investment Trusts, Inc. +// reit : National Association of Real Estate Investment Trusts, Inc. +// https://www.iana.org/domains/root/db/reit.html reit -// reliance : 2015-04-02 Reliance Industries Limited +// reliance : Reliance Industries Limited +// https://www.iana.org/domains/root/db/reliance.html reliance -// ren : 2013-12-12 ZDNS International Limited +// ren : ZDNS International Limited +// https://www.iana.org/domains/root/db/ren.html ren -// rent : 2014-12-04 XYZ.COM LLC +// rent : XYZ.COM LLC +// https://www.iana.org/domains/root/db/rent.html rent -// rentals : 2013-12-05 Binky Moon, LLC +// rentals : Binky Moon, LLC +// https://www.iana.org/domains/root/db/rentals.html rentals -// repair : 2013-11-07 Binky Moon, LLC +// repair : Binky Moon, LLC +// https://www.iana.org/domains/root/db/repair.html repair -// report : 2013-12-05 Binky Moon, LLC +// report : Binky Moon, LLC +// https://www.iana.org/domains/root/db/report.html report -// republican : 2014-03-20 Dog Beach, LLC +// republican : Dog Beach, LLC +// https://www.iana.org/domains/root/db/republican.html republican -// rest : 2013-12-19 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable +// rest : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable +// https://www.iana.org/domains/root/db/rest.html rest -// restaurant : 2014-07-03 Binky Moon, LLC +// restaurant : Binky Moon, LLC +// https://www.iana.org/domains/root/db/restaurant.html restaurant -// review : 2014-11-20 dot Review Limited +// review : dot Review Limited +// https://www.iana.org/domains/root/db/review.html review -// reviews : 2013-09-13 Dog Beach, LLC +// reviews : Dog Beach, LLC +// https://www.iana.org/domains/root/db/reviews.html reviews -// rexroth : 2015-06-18 Robert Bosch GMBH +// rexroth : Robert Bosch GMBH +// https://www.iana.org/domains/root/db/rexroth.html rexroth -// rich : 2013-11-21 iRegistry GmbH +// rich : iRegistry GmbH +// https://www.iana.org/domains/root/db/rich.html rich -// richardli : 2015-05-14 Pacific Century Asset Management (HK) Limited +// richardli : Pacific Century Asset Management (HK) Limited +// https://www.iana.org/domains/root/db/richardli.html richardli -// ricoh : 2014-11-20 Ricoh Company, Ltd. +// ricoh : Ricoh Company, Ltd. +// https://www.iana.org/domains/root/db/ricoh.html ricoh -// ril : 2015-04-02 Reliance Industries Limited +// ril : Reliance Industries Limited +// https://www.iana.org/domains/root/db/ril.html ril -// rio : 2014-02-27 Empresa Municipal de Informática SA - IPLANRIO +// rio : Empresa Municipal de Informática SA - IPLANRIO +// https://www.iana.org/domains/root/db/rio.html rio -// rip : 2014-07-10 Dog Beach, LLC +// rip : Dog Beach, LLC +// https://www.iana.org/domains/root/db/rip.html rip -// rocher : 2014-12-18 Ferrero Trading Lux S.A. -rocher - -// rocks : 2013-11-14 Dog Beach, LLC +// rocks : Dog Beach, LLC +// https://www.iana.org/domains/root/db/rocks.html rocks -// rodeo : 2013-12-19 Registry Services, LLC +// rodeo : Registry Services, LLC +// https://www.iana.org/domains/root/db/rodeo.html rodeo -// rogers : 2015-08-06 Rogers Communications Canada Inc. +// rogers : Rogers Communications Canada Inc. +// https://www.iana.org/domains/root/db/rogers.html rogers -// room : 2014-12-18 Amazon Registry Services, Inc. +// room : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/room.html room -// rsvp : 2014-05-08 Charleston Road Registry Inc. +// rsvp : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/rsvp.html rsvp -// rugby : 2016-12-15 World Rugby Strategic Developments Limited +// rugby : World Rugby Strategic Developments Limited +// https://www.iana.org/domains/root/db/rugby.html rugby -// ruhr : 2013-10-02 dotSaarland GmbH +// ruhr : dotSaarland GmbH +// https://www.iana.org/domains/root/db/ruhr.html ruhr -// run : 2015-03-19 Binky Moon, LLC +// run : Binky Moon, LLC +// https://www.iana.org/domains/root/db/run.html run -// rwe : 2015-04-02 RWE AG +// rwe : RWE AG +// https://www.iana.org/domains/root/db/rwe.html rwe -// ryukyu : 2014-01-09 BRregistry, Inc. +// ryukyu : BRregistry, Inc. +// https://www.iana.org/domains/root/db/ryukyu.html ryukyu -// saarland : 2013-12-12 dotSaarland GmbH +// saarland : dotSaarland GmbH +// https://www.iana.org/domains/root/db/saarland.html saarland -// safe : 2014-12-18 Amazon Registry Services, Inc. +// safe : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/safe.html safe -// safety : 2015-01-08 Safety Registry Services, LLC. +// safety : Safety Registry Services, LLC. +// https://www.iana.org/domains/root/db/safety.html safety -// sakura : 2014-12-18 SAKURA Internet Inc. +// sakura : SAKURA Internet Inc. +// https://www.iana.org/domains/root/db/sakura.html sakura -// sale : 2014-10-16 Dog Beach, LLC +// sale : Dog Beach, LLC +// https://www.iana.org/domains/root/db/sale.html sale -// salon : 2014-12-11 Binky Moon, LLC +// salon : Binky Moon, LLC +// https://www.iana.org/domains/root/db/salon.html salon -// samsclub : 2015-07-31 Wal-Mart Stores, Inc. +// samsclub : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/samsclub.html samsclub -// samsung : 2014-04-03 SAMSUNG SDS CO., LTD +// samsung : SAMSUNG SDS CO., LTD +// https://www.iana.org/domains/root/db/samsung.html samsung -// sandvik : 2014-11-13 Sandvik AB +// sandvik : Sandvik AB +// https://www.iana.org/domains/root/db/sandvik.html sandvik -// sandvikcoromant : 2014-11-07 Sandvik AB +// sandvikcoromant : Sandvik AB +// https://www.iana.org/domains/root/db/sandvikcoromant.html sandvikcoromant -// sanofi : 2014-10-09 Sanofi +// sanofi : Sanofi +// https://www.iana.org/domains/root/db/sanofi.html sanofi -// sap : 2014-03-27 SAP AG +// sap : SAP AG +// https://www.iana.org/domains/root/db/sap.html sap -// sarl : 2014-07-03 Binky Moon, LLC +// sarl : Binky Moon, LLC +// https://www.iana.org/domains/root/db/sarl.html sarl -// sas : 2015-04-02 Research IP LLC +// sas : Research IP LLC +// https://www.iana.org/domains/root/db/sas.html sas -// save : 2015-06-25 Amazon Registry Services, Inc. +// save : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/save.html save -// saxo : 2014-10-31 Saxo Bank A/S +// saxo : Saxo Bank A/S +// https://www.iana.org/domains/root/db/saxo.html saxo -// sbi : 2015-03-12 STATE BANK OF INDIA +// sbi : STATE BANK OF INDIA +// https://www.iana.org/domains/root/db/sbi.html sbi -// sbs : 2014-11-07 ShortDot SA +// sbs : ShortDot SA +// https://www.iana.org/domains/root/db/sbs.html sbs -// sca : 2014-03-13 SVENSKA CELLULOSA AKTIEBOLAGET SCA (publ) -sca - -// scb : 2014-02-20 The Siam Commercial Bank Public Company Limited ("SCB") +// scb : The Siam Commercial Bank Public Company Limited ("SCB") +// https://www.iana.org/domains/root/db/scb.html scb -// schaeffler : 2015-08-06 Schaeffler Technologies AG & Co. KG +// schaeffler : Schaeffler Technologies AG & Co. KG +// https://www.iana.org/domains/root/db/schaeffler.html schaeffler -// schmidt : 2014-04-03 SCHMIDT GROUPE S.A.S. +// schmidt : SCHMIDT GROUPE S.A.S. +// https://www.iana.org/domains/root/db/schmidt.html schmidt -// scholarships : 2014-04-24 Scholarships.com, LLC +// scholarships : Scholarships.com, LLC +// https://www.iana.org/domains/root/db/scholarships.html scholarships -// school : 2014-12-18 Binky Moon, LLC +// school : Binky Moon, LLC +// https://www.iana.org/domains/root/db/school.html school -// schule : 2014-03-06 Binky Moon, LLC +// schule : Binky Moon, LLC +// https://www.iana.org/domains/root/db/schule.html schule -// schwarz : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG +// schwarz : Schwarz Domains und Services GmbH & Co. KG +// https://www.iana.org/domains/root/db/schwarz.html schwarz -// science : 2014-09-11 dot Science Limited +// science : dot Science Limited +// https://www.iana.org/domains/root/db/science.html science -// scot : 2014-01-23 Dot Scot Registry Limited +// scot : Dot Scot Registry Limited +// https://www.iana.org/domains/root/db/scot.html scot -// search : 2016-06-09 Charleston Road Registry Inc. +// search : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/search.html search -// seat : 2014-05-22 SEAT, S.A. (Sociedad Unipersonal) +// seat : SEAT, S.A. (Sociedad Unipersonal) +// https://www.iana.org/domains/root/db/seat.html seat -// secure : 2015-08-27 Amazon Registry Services, Inc. +// secure : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/secure.html secure -// security : 2015-05-14 XYZ.COM LLC +// security : XYZ.COM LLC +// https://www.iana.org/domains/root/db/security.html security -// seek : 2014-12-04 Seek Limited +// seek : Seek Limited +// https://www.iana.org/domains/root/db/seek.html seek -// select : 2015-10-08 Registry Services, LLC +// select : Registry Services, LLC +// https://www.iana.org/domains/root/db/select.html select -// sener : 2014-10-24 Sener Ingeniería y Sistemas, S.A. +// sener : Sener Ingeniería y Sistemas, S.A. +// https://www.iana.org/domains/root/db/sener.html sener -// services : 2014-02-27 Binky Moon, LLC +// services : Binky Moon, LLC +// https://www.iana.org/domains/root/db/services.html services -// seven : 2015-08-06 Seven West Media Ltd +// seven : Seven West Media Ltd +// https://www.iana.org/domains/root/db/seven.html seven -// sew : 2014-07-17 SEW-EURODRIVE GmbH & Co KG +// sew : SEW-EURODRIVE GmbH & Co KG +// https://www.iana.org/domains/root/db/sew.html sew -// sex : 2014-11-13 ICM Registry SX LLC +// sex : ICM Registry SX LLC +// https://www.iana.org/domains/root/db/sex.html sex -// sexy : 2013-09-11 Internet Naming Company LLC +// sexy : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/sexy.html sexy -// sfr : 2015-08-13 Societe Francaise du Radiotelephone - SFR +// sfr : Societe Francaise du Radiotelephone - SFR +// https://www.iana.org/domains/root/db/sfr.html sfr -// shangrila : 2015-09-03 Shangri‐La International Hotel Management Limited +// shangrila : Shangri‐La International Hotel Management Limited +// https://www.iana.org/domains/root/db/shangrila.html shangrila -// sharp : 2014-05-01 Sharp Corporation +// sharp : Sharp Corporation +// https://www.iana.org/domains/root/db/sharp.html sharp -// shaw : 2015-04-23 Shaw Cablesystems G.P. -shaw - -// shell : 2015-07-30 Shell Information Technology International Inc +// shell : Shell Information Technology International Inc +// https://www.iana.org/domains/root/db/shell.html shell -// shia : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. +// shia : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. +// https://www.iana.org/domains/root/db/shia.html shia -// shiksha : 2013-11-14 Identity Digital Limited +// shiksha : Identity Digital Limited +// https://www.iana.org/domains/root/db/shiksha.html shiksha -// shoes : 2013-10-02 Binky Moon, LLC +// shoes : Binky Moon, LLC +// https://www.iana.org/domains/root/db/shoes.html shoes -// shop : 2016-04-08 GMO Registry, Inc. +// shop : GMO Registry, Inc. +// https://www.iana.org/domains/root/db/shop.html shop -// shopping : 2016-03-31 Binky Moon, LLC +// shopping : Binky Moon, LLC +// https://www.iana.org/domains/root/db/shopping.html shopping -// shouji : 2015-01-08 Beijing Qihu Keji Co., Ltd. +// shouji : Beijing Qihu Keji Co., Ltd. +// https://www.iana.org/domains/root/db/shouji.html shouji -// show : 2015-03-05 Binky Moon, LLC +// show : Binky Moon, LLC +// https://www.iana.org/domains/root/db/show.html show -// showtime : 2015-08-06 CBS Domains Inc. -showtime - -// silk : 2015-06-25 Amazon Registry Services, Inc. +// silk : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/silk.html silk -// sina : 2015-03-12 Sina Corporation +// sina : Sina Corporation +// https://www.iana.org/domains/root/db/sina.html sina -// singles : 2013-08-27 Binky Moon, LLC +// singles : Binky Moon, LLC +// https://www.iana.org/domains/root/db/singles.html singles -// site : 2015-01-15 Radix FZC +// site : Radix Technologies Inc. +// https://www.iana.org/domains/root/db/site.html site -// ski : 2015-04-09 Identity Digital Limited +// ski : Identity Digital Limited +// https://www.iana.org/domains/root/db/ski.html ski -// skin : 2015-01-15 XYZ.COM LLC +// skin : XYZ.COM LLC +// https://www.iana.org/domains/root/db/skin.html skin -// sky : 2014-06-19 Sky International AG +// sky : Sky UK Limited +// https://www.iana.org/domains/root/db/sky.html sky -// skype : 2014-12-18 Microsoft Corporation +// skype : Microsoft Corporation +// https://www.iana.org/domains/root/db/skype.html skype -// sling : 2015-07-30 DISH Technologies L.L.C. +// sling : DISH Technologies L.L.C. +// https://www.iana.org/domains/root/db/sling.html sling -// smart : 2015-07-09 Smart Communications, Inc. (SMART) +// smart : Smart Communications, Inc. (SMART) +// https://www.iana.org/domains/root/db/smart.html smart -// smile : 2014-12-18 Amazon Registry Services, Inc. +// smile : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/smile.html smile -// sncf : 2015-02-19 Société Nationale SNCF +// sncf : Société Nationale SNCF +// https://www.iana.org/domains/root/db/sncf.html sncf -// soccer : 2015-03-26 Binky Moon, LLC +// soccer : Binky Moon, LLC +// https://www.iana.org/domains/root/db/soccer.html soccer -// social : 2013-11-07 Dog Beach, LLC +// social : Dog Beach, LLC +// https://www.iana.org/domains/root/db/social.html social -// softbank : 2015-07-02 SoftBank Group Corp. +// softbank : SoftBank Group Corp. +// https://www.iana.org/domains/root/db/softbank.html softbank -// software : 2014-03-20 Dog Beach, LLC +// software : Dog Beach, LLC +// https://www.iana.org/domains/root/db/software.html software -// sohu : 2013-12-19 Sohu.com Limited +// sohu : Sohu.com Limited +// https://www.iana.org/domains/root/db/sohu.html sohu -// solar : 2013-11-07 Binky Moon, LLC +// solar : Binky Moon, LLC +// https://www.iana.org/domains/root/db/solar.html solar -// solutions : 2013-11-07 Binky Moon, LLC +// solutions : Binky Moon, LLC +// https://www.iana.org/domains/root/db/solutions.html solutions -// song : 2015-02-26 Amazon Registry Services, Inc. +// song : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/song.html song -// sony : 2015-01-08 Sony Corporation +// sony : Sony Corporation +// https://www.iana.org/domains/root/db/sony.html sony -// soy : 2014-01-23 Charleston Road Registry Inc. +// soy : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/soy.html soy -// spa : 2019-09-19 Asia Spa and Wellness Promotion Council Limited +// spa : Asia Spa and Wellness Promotion Council Limited +// https://www.iana.org/domains/root/db/spa.html spa -// space : 2014-04-03 Radix FZC +// space : Radix Technologies Inc. +// https://www.iana.org/domains/root/db/space.html space -// sport : 2017-11-16 Global Association of International Sports Federations (GAISF) +// sport : SportAccord +// https://www.iana.org/domains/root/db/sport.html sport -// spot : 2015-02-26 Amazon Registry Services, Inc. +// spot : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/spot.html spot -// srl : 2015-05-07 InterNetX, Corp +// srl : InterNetX, Corp +// https://www.iana.org/domains/root/db/srl.html srl -// stada : 2014-11-13 STADA Arzneimittel AG +// stada : STADA Arzneimittel AG +// https://www.iana.org/domains/root/db/stada.html stada -// staples : 2015-07-30 Staples, Inc. +// staples : Staples, Inc. +// https://www.iana.org/domains/root/db/staples.html staples -// star : 2015-01-08 Star India Private Limited +// star : Star India Private Limited +// https://www.iana.org/domains/root/db/star.html star -// statebank : 2015-03-12 STATE BANK OF INDIA +// statebank : STATE BANK OF INDIA +// https://www.iana.org/domains/root/db/statebank.html statebank -// statefarm : 2015-07-30 State Farm Mutual Automobile Insurance Company +// statefarm : State Farm Mutual Automobile Insurance Company +// https://www.iana.org/domains/root/db/statefarm.html statefarm -// stc : 2014-10-09 Saudi Telecom Company +// stc : Saudi Telecom Company +// https://www.iana.org/domains/root/db/stc.html stc -// stcgroup : 2014-10-09 Saudi Telecom Company +// stcgroup : Saudi Telecom Company +// https://www.iana.org/domains/root/db/stcgroup.html stcgroup -// stockholm : 2014-12-18 Stockholms kommun +// stockholm : Stockholms kommun +// https://www.iana.org/domains/root/db/stockholm.html stockholm -// storage : 2014-12-22 XYZ.COM LLC +// storage : XYZ.COM LLC +// https://www.iana.org/domains/root/db/storage.html storage -// store : 2015-04-09 Radix FZC +// store : Radix Technologies Inc. +// https://www.iana.org/domains/root/db/store.html store -// stream : 2016-01-08 dot Stream Limited +// stream : dot Stream Limited +// https://www.iana.org/domains/root/db/stream.html stream -// studio : 2015-02-11 Dog Beach, LLC +// studio : Dog Beach, LLC +// https://www.iana.org/domains/root/db/studio.html studio -// study : 2014-12-11 Registry Services, LLC +// study : Registry Services, LLC +// https://www.iana.org/domains/root/db/study.html study -// style : 2014-12-04 Binky Moon, LLC +// style : Binky Moon, LLC +// https://www.iana.org/domains/root/db/style.html style -// sucks : 2014-12-22 Vox Populi Registry Ltd. +// sucks : Vox Populi Registry Ltd. +// https://www.iana.org/domains/root/db/sucks.html sucks -// supplies : 2013-12-19 Binky Moon, LLC +// supplies : Binky Moon, LLC +// https://www.iana.org/domains/root/db/supplies.html supplies -// supply : 2013-12-19 Binky Moon, LLC +// supply : Binky Moon, LLC +// https://www.iana.org/domains/root/db/supply.html supply -// support : 2013-10-24 Binky Moon, LLC +// support : Binky Moon, LLC +// https://www.iana.org/domains/root/db/support.html support -// surf : 2014-01-09 Registry Services, LLC +// surf : Registry Services, LLC +// https://www.iana.org/domains/root/db/surf.html surf -// surgery : 2014-03-20 Binky Moon, LLC +// surgery : Binky Moon, LLC +// https://www.iana.org/domains/root/db/surgery.html surgery -// suzuki : 2014-02-20 SUZUKI MOTOR CORPORATION +// suzuki : SUZUKI MOTOR CORPORATION +// https://www.iana.org/domains/root/db/suzuki.html suzuki -// swatch : 2015-01-08 The Swatch Group Ltd +// swatch : The Swatch Group Ltd +// https://www.iana.org/domains/root/db/swatch.html swatch -// swiss : 2014-10-16 Swiss Confederation +// swiss : Swiss Confederation +// https://www.iana.org/domains/root/db/swiss.html swiss -// sydney : 2014-09-18 State of New South Wales, Department of Premier and Cabinet +// sydney : State of New South Wales, Department of Premier and Cabinet +// https://www.iana.org/domains/root/db/sydney.html sydney -// systems : 2013-11-07 Binky Moon, LLC +// systems : Binky Moon, LLC +// https://www.iana.org/domains/root/db/systems.html systems -// tab : 2014-12-04 Tabcorp Holdings Limited +// tab : Tabcorp Holdings Limited +// https://www.iana.org/domains/root/db/tab.html tab -// taipei : 2014-07-10 Taipei City Government +// taipei : Taipei City Government +// https://www.iana.org/domains/root/db/taipei.html taipei -// talk : 2015-04-09 Amazon Registry Services, Inc. +// talk : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/talk.html talk -// taobao : 2015-01-15 Alibaba Group Holding Limited +// taobao : Alibaba Group Holding Limited +// https://www.iana.org/domains/root/db/taobao.html taobao -// target : 2015-07-31 Target Domain Holdings, LLC +// target : Target Domain Holdings, LLC +// https://www.iana.org/domains/root/db/target.html target -// tatamotors : 2015-03-12 Tata Motors Ltd +// tatamotors : Tata Motors Ltd +// https://www.iana.org/domains/root/db/tatamotors.html tatamotors -// tatar : 2014-04-24 Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic" +// tatar : Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic" +// https://www.iana.org/domains/root/db/tatar.html tatar -// tattoo : 2013-08-30 Top Level Design, LLC +// tattoo : Registry Services, LLC +// https://www.iana.org/domains/root/db/tattoo.html tattoo -// tax : 2014-03-20 Binky Moon, LLC +// tax : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tax.html tax -// taxi : 2015-03-19 Binky Moon, LLC +// taxi : Binky Moon, LLC +// https://www.iana.org/domains/root/db/taxi.html taxi -// tci : 2014-09-12 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. +// tci : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. +// https://www.iana.org/domains/root/db/tci.html tci -// tdk : 2015-06-11 TDK Corporation +// tdk : TDK Corporation +// https://www.iana.org/domains/root/db/tdk.html tdk -// team : 2015-03-05 Binky Moon, LLC +// team : Binky Moon, LLC +// https://www.iana.org/domains/root/db/team.html team -// tech : 2015-01-30 Radix FZC +// tech : Radix Technologies Inc. +// https://www.iana.org/domains/root/db/tech.html tech -// technology : 2013-09-13 Binky Moon, LLC +// technology : Binky Moon, LLC +// https://www.iana.org/domains/root/db/technology.html technology -// temasek : 2014-08-07 Temasek Holdings (Private) Limited +// temasek : Temasek Holdings (Private) Limited +// https://www.iana.org/domains/root/db/temasek.html temasek -// tennis : 2014-12-04 Binky Moon, LLC +// tennis : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tennis.html tennis -// teva : 2015-07-02 Teva Pharmaceutical Industries Limited +// teva : Teva Pharmaceutical Industries Limited +// https://www.iana.org/domains/root/db/teva.html teva -// thd : 2015-04-02 Home Depot Product Authority, LLC +// thd : Home Depot Product Authority, LLC +// https://www.iana.org/domains/root/db/thd.html thd -// theater : 2015-03-19 Binky Moon, LLC +// theater : Binky Moon, LLC +// https://www.iana.org/domains/root/db/theater.html theater -// theatre : 2015-05-07 XYZ.COM LLC +// theatre : XYZ.COM LLC +// https://www.iana.org/domains/root/db/theatre.html theatre -// tiaa : 2015-07-23 Teachers Insurance and Annuity Association of America +// tiaa : Teachers Insurance and Annuity Association of America +// https://www.iana.org/domains/root/db/tiaa.html tiaa -// tickets : 2015-02-05 XYZ.COM LLC +// tickets : XYZ.COM LLC +// https://www.iana.org/domains/root/db/tickets.html tickets -// tienda : 2013-11-14 Binky Moon, LLC +// tienda : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tienda.html tienda -// tiffany : 2015-01-30 Tiffany and Company -tiffany - -// tips : 2013-09-20 Binky Moon, LLC +// tips : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tips.html tips -// tires : 2014-11-07 Binky Moon, LLC +// tires : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tires.html tires -// tirol : 2014-04-24 punkt Tirol GmbH +// tirol : punkt Tirol GmbH +// https://www.iana.org/domains/root/db/tirol.html tirol -// tjmaxx : 2015-07-16 The TJX Companies, Inc. +// tjmaxx : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/tjmaxx.html tjmaxx -// tjx : 2015-07-16 The TJX Companies, Inc. +// tjx : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/tjx.html tjx -// tkmaxx : 2015-07-16 The TJX Companies, Inc. +// tkmaxx : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/tkmaxx.html tkmaxx -// tmall : 2015-01-15 Alibaba Group Holding Limited +// tmall : Alibaba Group Holding Limited +// https://www.iana.org/domains/root/db/tmall.html tmall -// today : 2013-09-20 Binky Moon, LLC +// today : Binky Moon, LLC +// https://www.iana.org/domains/root/db/today.html today -// tokyo : 2013-11-13 GMO Registry, Inc. +// tokyo : GMO Registry, Inc. +// https://www.iana.org/domains/root/db/tokyo.html tokyo -// tools : 2013-11-21 Binky Moon, LLC +// tools : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tools.html tools -// top : 2014-03-20 .TOP Registry +// top : .TOP Registry +// https://www.iana.org/domains/root/db/top.html top -// toray : 2014-12-18 Toray Industries, Inc. +// toray : Toray Industries, Inc. +// https://www.iana.org/domains/root/db/toray.html toray -// toshiba : 2014-04-10 TOSHIBA Corporation +// toshiba : TOSHIBA Corporation +// https://www.iana.org/domains/root/db/toshiba.html toshiba -// total : 2015-08-06 TotalEnergies SE +// total : TotalEnergies SE +// https://www.iana.org/domains/root/db/total.html total -// tours : 2015-01-22 Binky Moon, LLC +// tours : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tours.html tours -// town : 2014-03-06 Binky Moon, LLC +// town : Binky Moon, LLC +// https://www.iana.org/domains/root/db/town.html town -// toyota : 2015-04-23 TOYOTA MOTOR CORPORATION +// toyota : TOYOTA MOTOR CORPORATION +// https://www.iana.org/domains/root/db/toyota.html toyota -// toys : 2014-03-06 Binky Moon, LLC +// toys : Binky Moon, LLC +// https://www.iana.org/domains/root/db/toys.html toys -// trade : 2014-01-23 Elite Registry Limited +// trade : Elite Registry Limited +// https://www.iana.org/domains/root/db/trade.html trade -// trading : 2014-12-11 Dog Beach, LLC +// trading : Dog Beach, LLC +// https://www.iana.org/domains/root/db/trading.html trading -// training : 2013-11-07 Binky Moon, LLC +// training : Binky Moon, LLC +// https://www.iana.org/domains/root/db/training.html training -// travel : 2015-10-09 Dog Beach, LLC +// travel : Dog Beach, LLC +// https://www.iana.org/domains/root/db/travel.html travel -// travelchannel : 2015-07-02 Lifestyle Domain Holdings, Inc. -travelchannel - -// travelers : 2015-03-26 Travelers TLD, LLC +// travelers : Travelers TLD, LLC +// https://www.iana.org/domains/root/db/travelers.html travelers -// travelersinsurance : 2015-03-26 Travelers TLD, LLC +// travelersinsurance : Travelers TLD, LLC +// https://www.iana.org/domains/root/db/travelersinsurance.html travelersinsurance -// trust : 2014-10-16 Internet Naming Company LLC +// trust : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/trust.html trust -// trv : 2015-03-26 Travelers TLD, LLC +// trv : Travelers TLD, LLC +// https://www.iana.org/domains/root/db/trv.html trv -// tube : 2015-06-11 Latin American Telecom LLC +// tube : Latin American Telecom LLC +// https://www.iana.org/domains/root/db/tube.html tube -// tui : 2014-07-03 TUI AG +// tui : TUI AG +// https://www.iana.org/domains/root/db/tui.html tui -// tunes : 2015-02-26 Amazon Registry Services, Inc. +// tunes : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/tunes.html tunes -// tushu : 2014-12-18 Amazon Registry Services, Inc. +// tushu : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/tushu.html tushu -// tvs : 2015-02-19 T V SUNDRAM IYENGAR & SONS LIMITED +// tvs : T V SUNDRAM IYENGAR & SONS LIMITED +// https://www.iana.org/domains/root/db/tvs.html tvs -// ubank : 2015-08-20 National Australia Bank Limited +// ubank : National Australia Bank Limited +// https://www.iana.org/domains/root/db/ubank.html ubank -// ubs : 2014-12-11 UBS AG +// ubs : UBS AG +// https://www.iana.org/domains/root/db/ubs.html ubs -// unicom : 2015-10-15 China United Network Communications Corporation Limited +// unicom : China United Network Communications Corporation Limited +// https://www.iana.org/domains/root/db/unicom.html unicom -// university : 2014-03-06 Binky Moon, LLC +// university : Binky Moon, LLC +// https://www.iana.org/domains/root/db/university.html university -// uno : 2013-09-11 Radix FZC +// uno : Radix Technologies Inc. +// https://www.iana.org/domains/root/db/uno.html uno -// uol : 2014-05-01 UBN INTERNET LTDA. +// uol : UBN INTERNET LTDA. +// https://www.iana.org/domains/root/db/uol.html uol -// ups : 2015-06-25 UPS Market Driver, Inc. +// ups : UPS Market Driver, Inc. +// https://www.iana.org/domains/root/db/ups.html ups -// vacations : 2013-12-05 Binky Moon, LLC +// vacations : Binky Moon, LLC +// https://www.iana.org/domains/root/db/vacations.html vacations -// vana : 2014-12-11 Lifestyle Domain Holdings, Inc. +// vana : D3 Registry LLC +// https://www.iana.org/domains/root/db/vana.html vana -// vanguard : 2015-09-03 The Vanguard Group, Inc. +// vanguard : The Vanguard Group, Inc. +// https://www.iana.org/domains/root/db/vanguard.html vanguard -// vegas : 2014-01-16 Dot Vegas, Inc. +// vegas : Dot Vegas, Inc. +// https://www.iana.org/domains/root/db/vegas.html vegas -// ventures : 2013-08-27 Binky Moon, LLC +// ventures : Binky Moon, LLC +// https://www.iana.org/domains/root/db/ventures.html ventures -// verisign : 2015-08-13 VeriSign, Inc. +// verisign : VeriSign, Inc. +// https://www.iana.org/domains/root/db/verisign.html verisign -// versicherung : 2014-03-20 tldbox GmbH +// versicherung : tldbox GmbH +// https://www.iana.org/domains/root/db/versicherung.html versicherung -// vet : 2014-03-06 Dog Beach, LLC +// vet : Dog Beach, LLC +// https://www.iana.org/domains/root/db/vet.html vet -// viajes : 2013-10-17 Binky Moon, LLC +// viajes : Binky Moon, LLC +// https://www.iana.org/domains/root/db/viajes.html viajes -// video : 2014-10-16 Dog Beach, LLC +// video : Dog Beach, LLC +// https://www.iana.org/domains/root/db/video.html video -// vig : 2015-05-14 VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe +// vig : VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe +// https://www.iana.org/domains/root/db/vig.html vig -// viking : 2015-04-02 Viking River Cruises (Bermuda) Ltd. +// viking : Viking River Cruises (Bermuda) Ltd. +// https://www.iana.org/domains/root/db/viking.html viking -// villas : 2013-12-05 Binky Moon, LLC +// villas : Binky Moon, LLC +// https://www.iana.org/domains/root/db/villas.html villas -// vin : 2015-06-18 Binky Moon, LLC +// vin : Binky Moon, LLC +// https://www.iana.org/domains/root/db/vin.html vin -// vip : 2015-01-22 Registry Services, LLC +// vip : Registry Services, LLC +// https://www.iana.org/domains/root/db/vip.html vip -// virgin : 2014-09-25 Virgin Enterprises Limited +// virgin : Virgin Enterprises Limited +// https://www.iana.org/domains/root/db/virgin.html virgin -// visa : 2015-07-30 Visa Worldwide Pte. Limited +// visa : Visa Worldwide Pte. Limited +// https://www.iana.org/domains/root/db/visa.html visa -// vision : 2013-12-05 Binky Moon, LLC +// vision : Binky Moon, LLC +// https://www.iana.org/domains/root/db/vision.html vision -// viva : 2014-11-07 Saudi Telecom Company +// viva : Saudi Telecom Company +// https://www.iana.org/domains/root/db/viva.html viva -// vivo : 2015-07-31 Telefonica Brasil S.A. +// vivo : Telefonica Brasil S.A. +// https://www.iana.org/domains/root/db/vivo.html vivo -// vlaanderen : 2014-02-06 DNS.be vzw +// vlaanderen : DNS.be vzw +// https://www.iana.org/domains/root/db/vlaanderen.html vlaanderen -// vodka : 2013-12-19 Registry Services, LLC +// vodka : Registry Services, LLC +// https://www.iana.org/domains/root/db/vodka.html vodka -// volkswagen : 2015-05-14 Volkswagen Group of America Inc. -volkswagen - -// volvo : 2015-11-12 Volvo Holding Sverige Aktiebolag +// volvo : Volvo Holding Sverige Aktiebolag +// https://www.iana.org/domains/root/db/volvo.html volvo -// vote : 2013-11-21 Monolith Registry LLC +// vote : Monolith Registry LLC +// https://www.iana.org/domains/root/db/vote.html vote -// voting : 2013-11-13 Valuetainment Corp. +// voting : Valuetainment Corp. +// https://www.iana.org/domains/root/db/voting.html voting -// voto : 2013-11-21 Monolith Registry LLC +// voto : Monolith Registry LLC +// https://www.iana.org/domains/root/db/voto.html voto -// voyage : 2013-08-27 Binky Moon, LLC +// voyage : Binky Moon, LLC +// https://www.iana.org/domains/root/db/voyage.html voyage -// vuelos : 2015-03-05 Travel Reservations SRL -vuelos - -// wales : 2014-05-08 Nominet UK +// wales : Nominet UK +// https://www.iana.org/domains/root/db/wales.html wales -// walmart : 2015-07-31 Wal-Mart Stores, Inc. +// walmart : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/walmart.html walmart -// walter : 2014-11-13 Sandvik AB +// walter : Sandvik AB +// https://www.iana.org/domains/root/db/walter.html walter -// wang : 2013-10-24 Zodiac Wang Limited +// wang : Zodiac Wang Limited +// https://www.iana.org/domains/root/db/wang.html wang -// wanggou : 2014-12-18 Amazon Registry Services, Inc. +// wanggou : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/wanggou.html wanggou -// watch : 2013-11-14 Binky Moon, LLC +// watch : Binky Moon, LLC +// https://www.iana.org/domains/root/db/watch.html watch -// watches : 2014-12-22 Identity Digital Limited +// watches : Identity Digital Limited +// https://www.iana.org/domains/root/db/watches.html watches -// weather : 2015-01-08 International Business Machines Corporation +// weather : International Business Machines Corporation +// https://www.iana.org/domains/root/db/weather.html weather -// weatherchannel : 2015-03-12 International Business Machines Corporation +// weatherchannel : International Business Machines Corporation +// https://www.iana.org/domains/root/db/weatherchannel.html weatherchannel -// webcam : 2014-01-23 dot Webcam Limited +// webcam : dot Webcam Limited +// https://www.iana.org/domains/root/db/webcam.html webcam -// weber : 2015-06-04 Saint-Gobain Weber SA +// weber : Saint-Gobain Weber SA +// https://www.iana.org/domains/root/db/weber.html weber -// website : 2014-04-03 Radix FZC +// website : Radix Technologies Inc. +// https://www.iana.org/domains/root/db/website.html website -// wedding : 2014-04-24 Registry Services, LLC +// wed +// https://www.iana.org/domains/root/db/wed.html +wed + +// wedding : Registry Services, LLC +// https://www.iana.org/domains/root/db/wedding.html wedding -// weibo : 2015-03-05 Sina Corporation +// weibo : Sina Corporation +// https://www.iana.org/domains/root/db/weibo.html weibo -// weir : 2015-01-29 Weir Group IP Limited +// weir : Weir Group IP Limited +// https://www.iana.org/domains/root/db/weir.html weir -// whoswho : 2014-02-20 Who's Who Registry +// whoswho : Who's Who Registry +// https://www.iana.org/domains/root/db/whoswho.html whoswho -// wien : 2013-10-28 punkt.wien GmbH +// wien : punkt.wien GmbH +// https://www.iana.org/domains/root/db/wien.html wien -// wiki : 2013-11-07 Top Level Design, LLC +// wiki : Registry Services, LLC +// https://www.iana.org/domains/root/db/wiki.html wiki -// williamhill : 2014-03-13 William Hill Organization Limited +// williamhill : William Hill Organization Limited +// https://www.iana.org/domains/root/db/williamhill.html williamhill -// win : 2014-11-20 First Registry Limited +// win : First Registry Limited +// https://www.iana.org/domains/root/db/win.html win -// windows : 2014-12-18 Microsoft Corporation +// windows : Microsoft Corporation +// https://www.iana.org/domains/root/db/windows.html windows -// wine : 2015-06-18 Binky Moon, LLC +// wine : Binky Moon, LLC +// https://www.iana.org/domains/root/db/wine.html wine -// winners : 2015-07-16 The TJX Companies, Inc. +// winners : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/winners.html winners -// wme : 2014-02-13 William Morris Endeavor Entertainment, LLC +// wme : William Morris Endeavor Entertainment, LLC +// https://www.iana.org/domains/root/db/wme.html wme -// wolterskluwer : 2015-08-06 Wolters Kluwer N.V. +// wolterskluwer : Wolters Kluwer N.V. +// https://www.iana.org/domains/root/db/wolterskluwer.html wolterskluwer -// woodside : 2015-07-09 Woodside Petroleum Limited +// woodside : Woodside Petroleum Limited +// https://www.iana.org/domains/root/db/woodside.html woodside -// work : 2013-12-19 Registry Services, LLC +// work : Registry Services, LLC +// https://www.iana.org/domains/root/db/work.html work -// works : 2013-11-14 Binky Moon, LLC +// works : Binky Moon, LLC +// https://www.iana.org/domains/root/db/works.html works -// world : 2014-06-12 Binky Moon, LLC +// world : Binky Moon, LLC +// https://www.iana.org/domains/root/db/world.html world -// wow : 2015-10-08 Amazon Registry Services, Inc. +// wow : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/wow.html wow -// wtc : 2013-12-19 World Trade Centers Association, Inc. +// wtc : World Trade Centers Association, Inc. +// https://www.iana.org/domains/root/db/wtc.html wtc -// wtf : 2014-03-06 Binky Moon, LLC +// wtf : Binky Moon, LLC +// https://www.iana.org/domains/root/db/wtf.html wtf -// xbox : 2014-12-18 Microsoft Corporation +// xbox : Microsoft Corporation +// https://www.iana.org/domains/root/db/xbox.html xbox -// xerox : 2014-10-24 Xerox DNHC LLC +// xerox : Xerox DNHC LLC +// https://www.iana.org/domains/root/db/xerox.html xerox -// xfinity : 2015-07-09 Comcast IP Holdings I, LLC -xfinity - -// xihuan : 2015-01-08 Beijing Qihu Keji Co., Ltd. +// xihuan : Beijing Qihu Keji Co., Ltd. +// https://www.iana.org/domains/root/db/xihuan.html xihuan -// xin : 2014-12-11 Elegant Leader Limited +// xin : Elegant Leader Limited +// https://www.iana.org/domains/root/db/xin.html xin -// xn--11b4c3d : 2015-01-15 VeriSign Sarl +// xn--11b4c3d : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--11b4c3d.html कॉम -// xn--1ck2e1b : 2015-02-26 Amazon Registry Services, Inc. +// xn--1ck2e1b : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--1ck2e1b.html セール -// xn--1qqw23a : 2014-01-09 Guangzhou YU Wei Information Technology Co., Ltd. +// xn--1qqw23a : Guangzhou YU Wei Information Technology Co., Ltd. +// https://www.iana.org/domains/root/db/xn--1qqw23a.html 佛山 -// xn--30rr7y : 2014-06-12 Excellent First Limited +// xn--30rr7y : Excellent First Limited +// https://www.iana.org/domains/root/db/xn--30rr7y.html 慈善 -// xn--3bst00m : 2013-09-13 Eagle Horizon Limited +// xn--3bst00m : Eagle Horizon Limited +// https://www.iana.org/domains/root/db/xn--3bst00m.html 集团 -// xn--3ds443g : 2013-09-08 TLD REGISTRY LIMITED OY +// xn--3ds443g : TLD REGISTRY LIMITED OY +// https://www.iana.org/domains/root/db/xn--3ds443g.html 在线 -// xn--3pxu8k : 2015-01-15 VeriSign Sarl +// xn--3pxu8k : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--3pxu8k.html 点看 -// xn--42c2d9a : 2015-01-15 VeriSign Sarl +// xn--42c2d9a : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--42c2d9a.html คอม -// xn--45q11c : 2013-11-21 Zodiac Gemini Ltd +// xn--45q11c : Zodiac Gemini Ltd +// https://www.iana.org/domains/root/db/xn--45q11c.html 八卦 -// xn--4gbrim : 2013-10-04 Helium TLDs Ltd +// xn--4gbrim : Helium TLDs Ltd +// https://www.iana.org/domains/root/db/xn--4gbrim.html موقع -// xn--55qw42g : 2013-11-08 China Organizational Name Administration Center +// xn--55qw42g : China Organizational Name Administration Center +// https://www.iana.org/domains/root/db/xn--55qw42g.html 公益 -// xn--55qx5d : 2013-11-14 China Internet Network Information Center (CNNIC) +// xn--55qx5d : China Internet Network Information Center (CNNIC) +// https://www.iana.org/domains/root/db/xn--55qx5d.html 公司 -// xn--5su34j936bgsg : 2015-09-03 Shangri‐La International Hotel Management Limited +// xn--5su34j936bgsg : Shangri‐La International Hotel Management Limited +// https://www.iana.org/domains/root/db/xn--5su34j936bgsg.html 香格里拉 -// xn--5tzm5g : 2014-12-22 Global Website TLD Asia Limited +// xn--5tzm5g : Global Website TLD Asia Limited +// https://www.iana.org/domains/root/db/xn--5tzm5g.html 网站 -// xn--6frz82g : 2013-09-23 Identity Digital Limited +// xn--6frz82g : Identity Digital Limited +// https://www.iana.org/domains/root/db/xn--6frz82g.html 移动 -// xn--6qq986b3xl : 2013-09-13 Tycoon Treasure Limited +// xn--6qq986b3xl : Tycoon Treasure Limited +// https://www.iana.org/domains/root/db/xn--6qq986b3xl.html 我爱你 -// xn--80adxhks : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) +// xn--80adxhks : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) +// https://www.iana.org/domains/root/db/xn--80adxhks.html москва -// xn--80aqecdr1a : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// xn--80aqecdr1a : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// https://www.iana.org/domains/root/db/xn--80aqecdr1a.html католик -// xn--80asehdb : 2013-07-14 CORE Association +// xn--80asehdb : CORE Association +// https://www.iana.org/domains/root/db/xn--80asehdb.html онлайн -// xn--80aswg : 2013-07-14 CORE Association +// xn--80aswg : CORE Association +// https://www.iana.org/domains/root/db/xn--80aswg.html сайт -// xn--8y0a063a : 2015-03-26 China United Network Communications Corporation Limited +// xn--8y0a063a : China United Network Communications Corporation Limited +// https://www.iana.org/domains/root/db/xn--8y0a063a.html 联通 -// xn--9dbq2a : 2015-01-15 VeriSign Sarl +// xn--9dbq2a : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--9dbq2a.html קום -// xn--9et52u : 2014-06-12 RISE VICTORY LIMITED +// xn--9et52u : RISE VICTORY LIMITED +// https://www.iana.org/domains/root/db/xn--9et52u.html 时尚 -// xn--9krt00a : 2015-03-12 Sina Corporation +// xn--9krt00a : Sina Corporation +// https://www.iana.org/domains/root/db/xn--9krt00a.html 微博 -// xn--b4w605ferd : 2014-08-07 Temasek Holdings (Private) Limited +// xn--b4w605ferd : Temasek Holdings (Private) Limited +// https://www.iana.org/domains/root/db/xn--b4w605ferd.html 淡马锡 -// xn--bck1b9a5dre4c : 2015-02-26 Amazon Registry Services, Inc. +// xn--bck1b9a5dre4c : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--bck1b9a5dre4c.html ファッション -// xn--c1avg : 2013-11-14 Public Interest Registry +// xn--c1avg : Public Interest Registry +// https://www.iana.org/domains/root/db/xn--c1avg.html орг -// xn--c2br7g : 2015-01-15 VeriSign Sarl +// xn--c2br7g : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--c2br7g.html नेट -// xn--cck2b3b : 2015-02-26 Amazon Registry Services, Inc. +// xn--cck2b3b : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--cck2b3b.html ストア -// xn--cckwcxetd : 2019-12-19 Amazon Registry Services, Inc. +// xn--cckwcxetd : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--cckwcxetd.html アマゾン -// xn--cg4bki : 2013-09-27 SAMSUNG SDS CO., LTD +// xn--cg4bki : SAMSUNG SDS CO., LTD +// https://www.iana.org/domains/root/db/xn--cg4bki.html 삼성 -// xn--czr694b : 2014-01-16 Internet DotTrademark Organisation Limited +// xn--czr694b : Internet DotTrademark Organisation Limited +// https://www.iana.org/domains/root/db/xn--czr694b.html 商标 -// xn--czrs0t : 2013-12-19 Binky Moon, LLC +// xn--czrs0t : Binky Moon, LLC +// https://www.iana.org/domains/root/db/xn--czrs0t.html 商店 -// xn--czru2d : 2013-11-21 Zodiac Aquarius Limited +// xn--czru2d : Zodiac Aquarius Limited +// https://www.iana.org/domains/root/db/xn--czru2d.html 商城 -// xn--d1acj3b : 2013-11-20 The Foundation for Network Initiatives “The Smart Internet” +// xn--d1acj3b : The Foundation for Network Initiatives “The Smart Internet” +// https://www.iana.org/domains/root/db/xn--d1acj3b.html дети -// xn--eckvdtc9d : 2014-12-18 Amazon Registry Services, Inc. +// xn--eckvdtc9d : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--eckvdtc9d.html ポイント -// xn--efvy88h : 2014-08-22 Guangzhou YU Wei Information Technology Co., Ltd. +// xn--efvy88h : Guangzhou YU Wei Information Technology Co., Ltd. +// https://www.iana.org/domains/root/db/xn--efvy88h.html 新闻 -// xn--fct429k : 2015-04-09 Amazon Registry Services, Inc. +// xn--fct429k : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--fct429k.html 家電 -// xn--fhbei : 2015-01-15 VeriSign Sarl +// xn--fhbei : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--fhbei.html كوم -// xn--fiq228c5hs : 2013-09-08 TLD REGISTRY LIMITED OY +// xn--fiq228c5hs : TLD REGISTRY LIMITED OY +// https://www.iana.org/domains/root/db/xn--fiq228c5hs.html 中文网 -// xn--fiq64b : 2013-10-14 CITIC Group Corporation +// xn--fiq64b : CITIC Group Corporation +// https://www.iana.org/domains/root/db/xn--fiq64b.html 中信 -// xn--fjq720a : 2014-05-22 Binky Moon, LLC +// xn--fjq720a : Binky Moon, LLC +// https://www.iana.org/domains/root/db/xn--fjq720a.html 娱乐 -// xn--flw351e : 2014-07-31 Charleston Road Registry Inc. +// xn--flw351e : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/xn--flw351e.html 谷歌 -// xn--fzys8d69uvgm : 2015-05-14 PCCW Enterprises Limited +// xn--fzys8d69uvgm : PCCW Enterprises Limited +// https://www.iana.org/domains/root/db/xn--fzys8d69uvgm.html 電訊盈科 -// xn--g2xx48c : 2015-01-30 Nawang Heli(Xiamen) Network Service Co., LTD. +// xn--g2xx48c : Nawang Heli(Xiamen) Network Service Co., LTD. +// https://www.iana.org/domains/root/db/xn--g2xx48c.html 购物 -// xn--gckr3f0f : 2015-02-26 Amazon Registry Services, Inc. +// xn--gckr3f0f : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--gckr3f0f.html クラウド -// xn--gk3at1e : 2015-10-08 Amazon Registry Services, Inc. +// xn--gk3at1e : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--gk3at1e.html 通販 -// xn--hxt814e : 2014-05-15 Zodiac Taurus Limited +// xn--hxt814e : Zodiac Taurus Limited +// https://www.iana.org/domains/root/db/xn--hxt814e.html 网店 -// xn--i1b6b1a6a2e : 2013-11-14 Public Interest Registry +// xn--i1b6b1a6a2e : Public Interest Registry +// https://www.iana.org/domains/root/db/xn--i1b6b1a6a2e.html संगठन -// xn--imr513n : 2014-12-11 Internet DotTrademark Organisation Limited +// xn--imr513n : Internet DotTrademark Organisation Limited +// https://www.iana.org/domains/root/db/xn--imr513n.html 餐厅 -// xn--io0a7i : 2013-11-14 China Internet Network Information Center (CNNIC) +// xn--io0a7i : China Internet Network Information Center (CNNIC) +// https://www.iana.org/domains/root/db/xn--io0a7i.html 网络 -// xn--j1aef : 2015-01-15 VeriSign Sarl +// xn--j1aef : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--j1aef.html ком -// xn--jlq480n2rg : 2019-12-19 Amazon Registry Services, Inc. +// xn--jlq480n2rg : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--jlq480n2rg.html 亚马逊 -// xn--jvr189m : 2015-02-26 Amazon Registry Services, Inc. +// xn--jvr189m : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--jvr189m.html 食品 -// xn--kcrx77d1x4a : 2014-11-07 Koninklijke Philips N.V. +// xn--kcrx77d1x4a : Koninklijke Philips N.V. +// https://www.iana.org/domains/root/db/xn--kcrx77d1x4a.html 飞利浦 -// xn--kput3i : 2014-02-13 Beijing RITT-Net Technology Development Co., Ltd +// xn--kput3i : Beijing RITT-Net Technology Development Co., Ltd +// https://www.iana.org/domains/root/db/xn--kput3i.html 手机 -// xn--mgba3a3ejt : 2014-11-20 Aramco Services Company +// xn--mgba3a3ejt : Aramco Services Company +// https://www.iana.org/domains/root/db/xn--mgba3a3ejt.html ارامكو -// xn--mgba7c0bbn0a : 2015-05-14 Crescent Holding GmbH +// xn--mgba7c0bbn0a : Competrol (Luxembourg) Sarl +// https://www.iana.org/domains/root/db/xn--mgba7c0bbn0a.html العليان -// xn--mgbaakc7dvf : 2015-09-03 Emirates Telecommunications Corporation (trading as Etisalat) -اتصالات - -// xn--mgbab2bd : 2013-10-31 CORE Association +// xn--mgbab2bd : CORE Association +// https://www.iana.org/domains/root/db/xn--mgbab2bd.html بازار -// xn--mgbca7dzdo : 2015-07-30 Abu Dhabi Systems and Information Centre +// xn--mgbca7dzdo : Abu Dhabi Systems and Information Centre +// https://www.iana.org/domains/root/db/xn--mgbca7dzdo.html ابوظبي -// xn--mgbi4ecexp : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// xn--mgbi4ecexp : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// https://www.iana.org/domains/root/db/xn--mgbi4ecexp.html كاثوليك -// xn--mgbt3dhd : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. +// xn--mgbt3dhd : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. +// https://www.iana.org/domains/root/db/xn--mgbt3dhd.html همراه -// xn--mk1bu44c : 2015-01-15 VeriSign Sarl +// xn--mk1bu44c : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--mk1bu44c.html 닷컴 -// xn--mxtq1m : 2014-03-06 Net-Chinese Co., Ltd. +// xn--mxtq1m : Net-Chinese Co., Ltd. +// https://www.iana.org/domains/root/db/xn--mxtq1m.html 政府 -// xn--ngbc5azd : 2013-07-13 International Domain Registry Pty. Ltd. +// xn--ngbc5azd : International Domain Registry Pty. Ltd. +// https://www.iana.org/domains/root/db/xn--ngbc5azd.html شبكة -// xn--ngbe9e0a : 2014-12-04 Kuwait Finance House +// xn--ngbe9e0a : Kuwait Finance House +// https://www.iana.org/domains/root/db/xn--ngbe9e0a.html بيتك -// xn--ngbrx : 2015-11-12 League of Arab States +// xn--ngbrx : League of Arab States +// https://www.iana.org/domains/root/db/xn--ngbrx.html عرب -// xn--nqv7f : 2013-11-14 Public Interest Registry +// xn--nqv7f : Public Interest Registry +// https://www.iana.org/domains/root/db/xn--nqv7f.html 机构 -// xn--nqv7fs00ema : 2013-11-14 Public Interest Registry +// xn--nqv7fs00ema : Public Interest Registry +// https://www.iana.org/domains/root/db/xn--nqv7fs00ema.html 组织机构 -// xn--nyqy26a : 2014-11-07 Stable Tone Limited +// xn--nyqy26a : Stable Tone Limited +// https://www.iana.org/domains/root/db/xn--nyqy26a.html 健康 -// xn--otu796d : 2017-08-06 Jiang Yu Liang Cai Technology Company Limited +// xn--otu796d : Jiang Yu Liang Cai Technology Company Limited +// https://www.iana.org/domains/root/db/xn--otu796d.html 招聘 -// xn--p1acf : 2013-12-12 Rusnames Limited +// xn--p1acf : Rusnames Limited +// https://www.iana.org/domains/root/db/xn--p1acf.html рус -// xn--pssy2u : 2015-01-15 VeriSign Sarl +// xn--pssy2u : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--pssy2u.html 大拿 -// xn--q9jyb4c : 2013-09-17 Charleston Road Registry Inc. +// xn--q9jyb4c : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/xn--q9jyb4c.html みんな -// xn--qcka1pmc : 2014-07-31 Charleston Road Registry Inc. +// xn--qcka1pmc : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/xn--qcka1pmc.html グーグル -// xn--rhqv96g : 2013-09-11 Stable Tone Limited +// xn--rhqv96g : Stable Tone Limited +// https://www.iana.org/domains/root/db/xn--rhqv96g.html 世界 -// xn--rovu88b : 2015-02-26 Amazon Registry Services, Inc. +// xn--rovu88b : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--rovu88b.html 書籍 -// xn--ses554g : 2014-01-16 KNET Co., Ltd. +// xn--ses554g : KNET Co., Ltd. +// https://www.iana.org/domains/root/db/xn--ses554g.html 网址 -// xn--t60b56a : 2015-01-15 VeriSign Sarl +// xn--t60b56a : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--t60b56a.html 닷넷 -// xn--tckwe : 2015-01-15 VeriSign Sarl +// xn--tckwe : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--tckwe.html コム -// xn--tiq49xqyj : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// xn--tiq49xqyj : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// https://www.iana.org/domains/root/db/xn--tiq49xqyj.html 天主教 -// xn--unup4y : 2013-07-14 Binky Moon, LLC +// xn--unup4y : Binky Moon, LLC +// https://www.iana.org/domains/root/db/xn--unup4y.html 游戏 -// xn--vermgensberater-ctb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG +// xn--vermgensberater-ctb : Deutsche Vermögensberatung Aktiengesellschaft DVAG +// https://www.iana.org/domains/root/db/xn--vermgensberater-ctb.html vermögensberater -// xn--vermgensberatung-pwb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG +// xn--vermgensberatung-pwb : Deutsche Vermögensberatung Aktiengesellschaft DVAG +// https://www.iana.org/domains/root/db/xn--vermgensberatung-pwb.html vermögensberatung -// xn--vhquv : 2013-08-27 Binky Moon, LLC +// xn--vhquv : Binky Moon, LLC +// https://www.iana.org/domains/root/db/xn--vhquv.html 企业 -// xn--vuq861b : 2014-10-16 Beijing Tele-info Network Technology Co., Ltd. +// xn--vuq861b : Beijing Tele-info Technology Co., Ltd. +// https://www.iana.org/domains/root/db/xn--vuq861b.html 信息 -// xn--w4r85el8fhu5dnra : 2015-04-30 Kerry Trading Co. Limited +// xn--w4r85el8fhu5dnra : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/xn--w4r85el8fhu5dnra.html 嘉里大酒店 -// xn--w4rs40l : 2015-07-30 Kerry Trading Co. Limited +// xn--w4rs40l : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/xn--w4rs40l.html 嘉里 -// xn--xhq521b : 2013-11-14 Guangzhou YU Wei Information Technology Co., Ltd. +// xn--xhq521b : Guangzhou YU Wei Information Technology Co., Ltd. +// https://www.iana.org/domains/root/db/xn--xhq521b.html 广东 -// xn--zfr164b : 2013-11-08 China Organizational Name Administration Center +// xn--zfr164b : China Organizational Name Administration Center +// https://www.iana.org/domains/root/db/xn--zfr164b.html 政务 -// xyz : 2013-12-05 XYZ.COM LLC +// xyz : XYZ.COM LLC +// https://www.iana.org/domains/root/db/xyz.html xyz -// yachts : 2014-01-09 XYZ.COM LLC +// yachts : XYZ.COM LLC +// https://www.iana.org/domains/root/db/yachts.html yachts -// yahoo : 2015-04-02 Oath Inc. +// yahoo : Yahoo Inc. +// https://www.iana.org/domains/root/db/yahoo.html yahoo -// yamaxun : 2014-12-18 Amazon Registry Services, Inc. +// yamaxun : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/yamaxun.html yamaxun -// yandex : 2014-04-10 Yandex Europe B.V. +// yandex : Yandex Europe B.V. +// https://www.iana.org/domains/root/db/yandex.html yandex -// yodobashi : 2014-11-20 YODOBASHI CAMERA CO.,LTD. +// yodobashi : YODOBASHI CAMERA CO.,LTD. +// https://www.iana.org/domains/root/db/yodobashi.html yodobashi -// yoga : 2014-05-29 Registry Services, LLC +// yoga : Registry Services, LLC +// https://www.iana.org/domains/root/db/yoga.html yoga -// yokohama : 2013-12-12 GMO Registry, Inc. +// yokohama : GMO Registry, Inc. +// https://www.iana.org/domains/root/db/yokohama.html yokohama -// you : 2015-04-09 Amazon Registry Services, Inc. +// you : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/you.html you -// youtube : 2014-05-01 Charleston Road Registry Inc. +// youtube : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/youtube.html youtube -// yun : 2015-01-08 Beijing Qihu Keji Co., Ltd. +// yun : Beijing Qihu Keji Co., Ltd. +// https://www.iana.org/domains/root/db/yun.html yun -// zappos : 2015-06-25 Amazon Registry Services, Inc. +// zappos : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/zappos.html zappos -// zara : 2014-11-07 Industria de Diseño Textil, S.A. (INDITEX, S.A.) +// zara : Industria de Diseño Textil, S.A. (INDITEX, S.A.) +// https://www.iana.org/domains/root/db/zara.html zara -// zero : 2014-12-18 Amazon Registry Services, Inc. +// zero : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/zero.html zero -// zip : 2014-05-08 Charleston Road Registry Inc. +// zip : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/zip.html zip -// zone : 2013-11-14 Binky Moon, LLC +// zone : Binky Moon, LLC +// https://www.iana.org/domains/root/db/zone.html zone -// zuerich : 2014-11-07 Kanton Zürich (Canton of Zurich) +// zuerich : Kanton Zürich (Canton of Zurich) +// https://www.iana.org/domains/root/db/zuerich.html zuerich - // ===END ICANN DOMAINS=== + // ===BEGIN PRIVATE DOMAINS=== + // (Note: these are in alphabetical order by company name) +// .KRD : http://nic.krd/data/krd/Registration%20Policy.pdf +co.krd +edu.krd + +// .pl domains (grandfathered) +art.pl +gliwice.pl +krakow.pl +poznan.pl +wroc.pl +zakopane.pl + +// .US +// Submitted by Ed Moore +lib.de.us + +// 12CHARS: https://12chars.com +// Submitted by Kenny Niehage +12chars.dev +12chars.it +12chars.pro + // 1GB LLC : https://www.1gb.ua/ // Submitted by 1GB LLC cc.ua inf.ua ltd.ua -// 611coin : https://611project.org/ +// 611 blockchain domain name system : https://611project.net/ 611.to -// Aaron Marais' Gitlab pages: https://lab.aaronleem.co.za -// Submitted by Aaron Marais -graphox.us +// A2 Hosting +// Submitted by Tyler Hall +a2hosted.com +cpserver.com -// accesso Technology Group, plc. : https://accesso.com/ -// Submitted by accesso Team -*.devcdnaccesso.com +// AAA workspace : https://aaa.vodka +// Submitted by Kirill Rezraf +aaa.vodka // Acorn Labs : https://acorn.io // Submitted by Craig Jellick @@ -10668,12 +11244,18 @@ graphox.us // Submitted by Ofer Kalaora activetrail.biz +// Adaptable.io : https://adaptable.io +// Submitted by Mark Terrel +adaptable.app + // Adobe : https://www.adobe.com/ // Submitted by Ian Boston and Lars Trieloff adobeaemcloud.com *.dev.adobeaemcloud.com +aem.live hlx.live adobeaemcloud.net +aem.page hlx.page hlx3.page @@ -10682,8 +11264,12 @@ hlx3.page adobeio-static.net adobeioruntime.net -// Agnat sp. z o.o. : https://domena.pl -// Submitted by Przemyslaw Plewa +// Africa.com Web Solutions Ltd : https://registry.africa.com +// Submitted by Gavin Brown +africa.com + +// Agnat sp. z o.o. : https://domena.pl +// Submitted by Przemyslaw Plewa beep.pl // Airkit : https://www.airkit.com/ @@ -10743,60 +11329,454 @@ myamaze.net // Submitted by AWS Security // Subsections of Amazon/subsidiaries will appear until "concludes" tag +// Amazon API Gateway +// Submitted by AWS Security +// Reference: 6a4f5a95-8c7d-4077-a7af-9cf1abec0a53 +execute-api.cn-north-1.amazonaws.com.cn +execute-api.cn-northwest-1.amazonaws.com.cn +execute-api.af-south-1.amazonaws.com +execute-api.ap-east-1.amazonaws.com +execute-api.ap-northeast-1.amazonaws.com +execute-api.ap-northeast-2.amazonaws.com +execute-api.ap-northeast-3.amazonaws.com +execute-api.ap-south-1.amazonaws.com +execute-api.ap-south-2.amazonaws.com +execute-api.ap-southeast-1.amazonaws.com +execute-api.ap-southeast-2.amazonaws.com +execute-api.ap-southeast-3.amazonaws.com +execute-api.ap-southeast-4.amazonaws.com +execute-api.ap-southeast-5.amazonaws.com +execute-api.ca-central-1.amazonaws.com +execute-api.ca-west-1.amazonaws.com +execute-api.eu-central-1.amazonaws.com +execute-api.eu-central-2.amazonaws.com +execute-api.eu-north-1.amazonaws.com +execute-api.eu-south-1.amazonaws.com +execute-api.eu-south-2.amazonaws.com +execute-api.eu-west-1.amazonaws.com +execute-api.eu-west-2.amazonaws.com +execute-api.eu-west-3.amazonaws.com +execute-api.il-central-1.amazonaws.com +execute-api.me-central-1.amazonaws.com +execute-api.me-south-1.amazonaws.com +execute-api.sa-east-1.amazonaws.com +execute-api.us-east-1.amazonaws.com +execute-api.us-east-2.amazonaws.com +execute-api.us-gov-east-1.amazonaws.com +execute-api.us-gov-west-1.amazonaws.com +execute-api.us-west-1.amazonaws.com +execute-api.us-west-2.amazonaws.com + // Amazon CloudFront // Submitted by Donavan Miller // Reference: 54144616-fd49-4435-8535-19c6a601bdb3 cloudfront.net +// Amazon Cognito +// Submitted by AWS Security +// Reference: cb38c251-c93d-4cda-81ec-e72c4f0fdb72 +auth.af-south-1.amazoncognito.com +auth.ap-east-1.amazoncognito.com +auth.ap-northeast-1.amazoncognito.com +auth.ap-northeast-2.amazoncognito.com +auth.ap-northeast-3.amazoncognito.com +auth.ap-south-1.amazoncognito.com +auth.ap-south-2.amazoncognito.com +auth.ap-southeast-1.amazoncognito.com +auth.ap-southeast-2.amazoncognito.com +auth.ap-southeast-3.amazoncognito.com +auth.ap-southeast-4.amazoncognito.com +auth.ca-central-1.amazoncognito.com +auth.ca-west-1.amazoncognito.com +auth.eu-central-1.amazoncognito.com +auth.eu-central-2.amazoncognito.com +auth.eu-north-1.amazoncognito.com +auth.eu-south-1.amazoncognito.com +auth.eu-south-2.amazoncognito.com +auth.eu-west-1.amazoncognito.com +auth.eu-west-2.amazoncognito.com +auth.eu-west-3.amazoncognito.com +auth.il-central-1.amazoncognito.com +auth.me-central-1.amazoncognito.com +auth.me-south-1.amazoncognito.com +auth.sa-east-1.amazoncognito.com +auth.us-east-1.amazoncognito.com +auth-fips.us-east-1.amazoncognito.com +auth.us-east-2.amazoncognito.com +auth-fips.us-east-2.amazoncognito.com +auth-fips.us-gov-west-1.amazoncognito.com +auth.us-west-1.amazoncognito.com +auth-fips.us-west-1.amazoncognito.com +auth.us-west-2.amazoncognito.com +auth-fips.us-west-2.amazoncognito.com + // Amazon EC2 // Submitted by Luke Wells // Reference: 4c38fa71-58ac-4768-99e5-689c1767e537 +*.compute.amazonaws.com.cn *.compute.amazonaws.com *.compute-1.amazonaws.com -*.compute.amazonaws.com.cn us-east-1.amazonaws.com +// Amazon EMR +// Submitted by AWS Security +// Reference: 82f43f9f-bbb8-400e-8349-854f5a62f20d +emrappui-prod.cn-north-1.amazonaws.com.cn +emrnotebooks-prod.cn-north-1.amazonaws.com.cn +emrstudio-prod.cn-north-1.amazonaws.com.cn +emrappui-prod.cn-northwest-1.amazonaws.com.cn +emrnotebooks-prod.cn-northwest-1.amazonaws.com.cn +emrstudio-prod.cn-northwest-1.amazonaws.com.cn +emrappui-prod.af-south-1.amazonaws.com +emrnotebooks-prod.af-south-1.amazonaws.com +emrstudio-prod.af-south-1.amazonaws.com +emrappui-prod.ap-east-1.amazonaws.com +emrnotebooks-prod.ap-east-1.amazonaws.com +emrstudio-prod.ap-east-1.amazonaws.com +emrappui-prod.ap-northeast-1.amazonaws.com +emrnotebooks-prod.ap-northeast-1.amazonaws.com +emrstudio-prod.ap-northeast-1.amazonaws.com +emrappui-prod.ap-northeast-2.amazonaws.com +emrnotebooks-prod.ap-northeast-2.amazonaws.com +emrstudio-prod.ap-northeast-2.amazonaws.com +emrappui-prod.ap-northeast-3.amazonaws.com +emrnotebooks-prod.ap-northeast-3.amazonaws.com +emrstudio-prod.ap-northeast-3.amazonaws.com +emrappui-prod.ap-south-1.amazonaws.com +emrnotebooks-prod.ap-south-1.amazonaws.com +emrstudio-prod.ap-south-1.amazonaws.com +emrappui-prod.ap-south-2.amazonaws.com +emrnotebooks-prod.ap-south-2.amazonaws.com +emrstudio-prod.ap-south-2.amazonaws.com +emrappui-prod.ap-southeast-1.amazonaws.com +emrnotebooks-prod.ap-southeast-1.amazonaws.com +emrstudio-prod.ap-southeast-1.amazonaws.com +emrappui-prod.ap-southeast-2.amazonaws.com +emrnotebooks-prod.ap-southeast-2.amazonaws.com +emrstudio-prod.ap-southeast-2.amazonaws.com +emrappui-prod.ap-southeast-3.amazonaws.com +emrnotebooks-prod.ap-southeast-3.amazonaws.com +emrstudio-prod.ap-southeast-3.amazonaws.com +emrappui-prod.ap-southeast-4.amazonaws.com +emrnotebooks-prod.ap-southeast-4.amazonaws.com +emrstudio-prod.ap-southeast-4.amazonaws.com +emrappui-prod.ca-central-1.amazonaws.com +emrnotebooks-prod.ca-central-1.amazonaws.com +emrstudio-prod.ca-central-1.amazonaws.com +emrappui-prod.ca-west-1.amazonaws.com +emrnotebooks-prod.ca-west-1.amazonaws.com +emrstudio-prod.ca-west-1.amazonaws.com +emrappui-prod.eu-central-1.amazonaws.com +emrnotebooks-prod.eu-central-1.amazonaws.com +emrstudio-prod.eu-central-1.amazonaws.com +emrappui-prod.eu-central-2.amazonaws.com +emrnotebooks-prod.eu-central-2.amazonaws.com +emrstudio-prod.eu-central-2.amazonaws.com +emrappui-prod.eu-north-1.amazonaws.com +emrnotebooks-prod.eu-north-1.amazonaws.com +emrstudio-prod.eu-north-1.amazonaws.com +emrappui-prod.eu-south-1.amazonaws.com +emrnotebooks-prod.eu-south-1.amazonaws.com +emrstudio-prod.eu-south-1.amazonaws.com +emrappui-prod.eu-south-2.amazonaws.com +emrnotebooks-prod.eu-south-2.amazonaws.com +emrstudio-prod.eu-south-2.amazonaws.com +emrappui-prod.eu-west-1.amazonaws.com +emrnotebooks-prod.eu-west-1.amazonaws.com +emrstudio-prod.eu-west-1.amazonaws.com +emrappui-prod.eu-west-2.amazonaws.com +emrnotebooks-prod.eu-west-2.amazonaws.com +emrstudio-prod.eu-west-2.amazonaws.com +emrappui-prod.eu-west-3.amazonaws.com +emrnotebooks-prod.eu-west-3.amazonaws.com +emrstudio-prod.eu-west-3.amazonaws.com +emrappui-prod.il-central-1.amazonaws.com +emrnotebooks-prod.il-central-1.amazonaws.com +emrstudio-prod.il-central-1.amazonaws.com +emrappui-prod.me-central-1.amazonaws.com +emrnotebooks-prod.me-central-1.amazonaws.com +emrstudio-prod.me-central-1.amazonaws.com +emrappui-prod.me-south-1.amazonaws.com +emrnotebooks-prod.me-south-1.amazonaws.com +emrstudio-prod.me-south-1.amazonaws.com +emrappui-prod.sa-east-1.amazonaws.com +emrnotebooks-prod.sa-east-1.amazonaws.com +emrstudio-prod.sa-east-1.amazonaws.com +emrappui-prod.us-east-1.amazonaws.com +emrnotebooks-prod.us-east-1.amazonaws.com +emrstudio-prod.us-east-1.amazonaws.com +emrappui-prod.us-east-2.amazonaws.com +emrnotebooks-prod.us-east-2.amazonaws.com +emrstudio-prod.us-east-2.amazonaws.com +emrappui-prod.us-gov-east-1.amazonaws.com +emrnotebooks-prod.us-gov-east-1.amazonaws.com +emrstudio-prod.us-gov-east-1.amazonaws.com +emrappui-prod.us-gov-west-1.amazonaws.com +emrnotebooks-prod.us-gov-west-1.amazonaws.com +emrstudio-prod.us-gov-west-1.amazonaws.com +emrappui-prod.us-west-1.amazonaws.com +emrnotebooks-prod.us-west-1.amazonaws.com +emrstudio-prod.us-west-1.amazonaws.com +emrappui-prod.us-west-2.amazonaws.com +emrnotebooks-prod.us-west-2.amazonaws.com +emrstudio-prod.us-west-2.amazonaws.com + +// Amazon Managed Workflows for Apache Airflow +// Submitted by AWS Security +// Reference: f5ea5d0a-ec6a-4f23-ac1c-553fbff13f5c +*.cn-north-1.airflow.amazonaws.com.cn +*.cn-northwest-1.airflow.amazonaws.com.cn +*.af-south-1.airflow.amazonaws.com +*.ap-east-1.airflow.amazonaws.com +*.ap-northeast-1.airflow.amazonaws.com +*.ap-northeast-2.airflow.amazonaws.com +*.ap-northeast-3.airflow.amazonaws.com +*.ap-south-1.airflow.amazonaws.com +*.ap-south-2.airflow.amazonaws.com +*.ap-southeast-1.airflow.amazonaws.com +*.ap-southeast-2.airflow.amazonaws.com +*.ap-southeast-3.airflow.amazonaws.com +*.ap-southeast-4.airflow.amazonaws.com +*.ca-central-1.airflow.amazonaws.com +*.ca-west-1.airflow.amazonaws.com +*.eu-central-1.airflow.amazonaws.com +*.eu-central-2.airflow.amazonaws.com +*.eu-north-1.airflow.amazonaws.com +*.eu-south-1.airflow.amazonaws.com +*.eu-south-2.airflow.amazonaws.com +*.eu-west-1.airflow.amazonaws.com +*.eu-west-2.airflow.amazonaws.com +*.eu-west-3.airflow.amazonaws.com +*.il-central-1.airflow.amazonaws.com +*.me-central-1.airflow.amazonaws.com +*.me-south-1.airflow.amazonaws.com +*.sa-east-1.airflow.amazonaws.com +*.us-east-1.airflow.amazonaws.com +*.us-east-2.airflow.amazonaws.com +*.us-west-1.airflow.amazonaws.com +*.us-west-2.airflow.amazonaws.com + // Amazon S3 -// Submitted by Luke Wells -// Reference: d068bd97-f0a9-4838-a6d8-954b622ef4ae +// Submitted by AWS Security +// Reference: ada5c9df-55e1-4195-a1ce-732d6c81e357 +s3.dualstack.cn-north-1.amazonaws.com.cn +s3-accesspoint.dualstack.cn-north-1.amazonaws.com.cn +s3-website.dualstack.cn-north-1.amazonaws.com.cn s3.cn-north-1.amazonaws.com.cn +s3-accesspoint.cn-north-1.amazonaws.com.cn +s3-deprecated.cn-north-1.amazonaws.com.cn +s3-object-lambda.cn-north-1.amazonaws.com.cn +s3-website.cn-north-1.amazonaws.com.cn +s3.dualstack.cn-northwest-1.amazonaws.com.cn +s3-accesspoint.dualstack.cn-northwest-1.amazonaws.com.cn +s3.cn-northwest-1.amazonaws.com.cn +s3-accesspoint.cn-northwest-1.amazonaws.com.cn +s3-object-lambda.cn-northwest-1.amazonaws.com.cn +s3-website.cn-northwest-1.amazonaws.com.cn +s3.dualstack.af-south-1.amazonaws.com +s3-accesspoint.dualstack.af-south-1.amazonaws.com +s3-website.dualstack.af-south-1.amazonaws.com +s3.af-south-1.amazonaws.com +s3-accesspoint.af-south-1.amazonaws.com +s3-object-lambda.af-south-1.amazonaws.com +s3-website.af-south-1.amazonaws.com +s3.dualstack.ap-east-1.amazonaws.com +s3-accesspoint.dualstack.ap-east-1.amazonaws.com +s3.ap-east-1.amazonaws.com +s3-accesspoint.ap-east-1.amazonaws.com +s3-object-lambda.ap-east-1.amazonaws.com +s3-website.ap-east-1.amazonaws.com s3.dualstack.ap-northeast-1.amazonaws.com +s3-accesspoint.dualstack.ap-northeast-1.amazonaws.com +s3-website.dualstack.ap-northeast-1.amazonaws.com +s3.ap-northeast-1.amazonaws.com +s3-accesspoint.ap-northeast-1.amazonaws.com +s3-object-lambda.ap-northeast-1.amazonaws.com +s3-website.ap-northeast-1.amazonaws.com s3.dualstack.ap-northeast-2.amazonaws.com +s3-accesspoint.dualstack.ap-northeast-2.amazonaws.com +s3-website.dualstack.ap-northeast-2.amazonaws.com s3.ap-northeast-2.amazonaws.com +s3-accesspoint.ap-northeast-2.amazonaws.com +s3-object-lambda.ap-northeast-2.amazonaws.com s3-website.ap-northeast-2.amazonaws.com +s3.dualstack.ap-northeast-3.amazonaws.com +s3-accesspoint.dualstack.ap-northeast-3.amazonaws.com +s3-website.dualstack.ap-northeast-3.amazonaws.com +s3.ap-northeast-3.amazonaws.com +s3-accesspoint.ap-northeast-3.amazonaws.com +s3-object-lambda.ap-northeast-3.amazonaws.com +s3-website.ap-northeast-3.amazonaws.com s3.dualstack.ap-south-1.amazonaws.com +s3-accesspoint.dualstack.ap-south-1.amazonaws.com +s3-website.dualstack.ap-south-1.amazonaws.com s3.ap-south-1.amazonaws.com +s3-accesspoint.ap-south-1.amazonaws.com +s3-object-lambda.ap-south-1.amazonaws.com s3-website.ap-south-1.amazonaws.com +s3.dualstack.ap-south-2.amazonaws.com +s3-accesspoint.dualstack.ap-south-2.amazonaws.com +s3-website.dualstack.ap-south-2.amazonaws.com +s3.ap-south-2.amazonaws.com +s3-accesspoint.ap-south-2.amazonaws.com +s3-object-lambda.ap-south-2.amazonaws.com +s3-website.ap-south-2.amazonaws.com s3.dualstack.ap-southeast-1.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-1.amazonaws.com +s3-website.dualstack.ap-southeast-1.amazonaws.com +s3.ap-southeast-1.amazonaws.com +s3-accesspoint.ap-southeast-1.amazonaws.com +s3-object-lambda.ap-southeast-1.amazonaws.com +s3-website.ap-southeast-1.amazonaws.com s3.dualstack.ap-southeast-2.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-2.amazonaws.com +s3-website.dualstack.ap-southeast-2.amazonaws.com +s3.ap-southeast-2.amazonaws.com +s3-accesspoint.ap-southeast-2.amazonaws.com +s3-object-lambda.ap-southeast-2.amazonaws.com +s3-website.ap-southeast-2.amazonaws.com +s3.dualstack.ap-southeast-3.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-3.amazonaws.com +s3-website.dualstack.ap-southeast-3.amazonaws.com +s3.ap-southeast-3.amazonaws.com +s3-accesspoint.ap-southeast-3.amazonaws.com +s3-object-lambda.ap-southeast-3.amazonaws.com +s3-website.ap-southeast-3.amazonaws.com +s3.dualstack.ap-southeast-4.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-4.amazonaws.com +s3-website.dualstack.ap-southeast-4.amazonaws.com +s3.ap-southeast-4.amazonaws.com +s3-accesspoint.ap-southeast-4.amazonaws.com +s3-object-lambda.ap-southeast-4.amazonaws.com +s3-website.ap-southeast-4.amazonaws.com +s3.dualstack.ap-southeast-5.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-5.amazonaws.com +s3-website.dualstack.ap-southeast-5.amazonaws.com +s3.ap-southeast-5.amazonaws.com +s3-accesspoint.ap-southeast-5.amazonaws.com +s3-deprecated.ap-southeast-5.amazonaws.com +s3-object-lambda.ap-southeast-5.amazonaws.com +s3-website.ap-southeast-5.amazonaws.com s3.dualstack.ca-central-1.amazonaws.com +s3-accesspoint.dualstack.ca-central-1.amazonaws.com +s3-accesspoint-fips.dualstack.ca-central-1.amazonaws.com +s3-fips.dualstack.ca-central-1.amazonaws.com +s3-website.dualstack.ca-central-1.amazonaws.com s3.ca-central-1.amazonaws.com +s3-accesspoint.ca-central-1.amazonaws.com +s3-accesspoint-fips.ca-central-1.amazonaws.com +s3-fips.ca-central-1.amazonaws.com +s3-object-lambda.ca-central-1.amazonaws.com s3-website.ca-central-1.amazonaws.com +s3.dualstack.ca-west-1.amazonaws.com +s3-accesspoint.dualstack.ca-west-1.amazonaws.com +s3-accesspoint-fips.dualstack.ca-west-1.amazonaws.com +s3-fips.dualstack.ca-west-1.amazonaws.com +s3-website.dualstack.ca-west-1.amazonaws.com +s3.ca-west-1.amazonaws.com +s3-accesspoint.ca-west-1.amazonaws.com +s3-accesspoint-fips.ca-west-1.amazonaws.com +s3-fips.ca-west-1.amazonaws.com +s3-object-lambda.ca-west-1.amazonaws.com +s3-website.ca-west-1.amazonaws.com s3.dualstack.eu-central-1.amazonaws.com +s3-accesspoint.dualstack.eu-central-1.amazonaws.com +s3-website.dualstack.eu-central-1.amazonaws.com s3.eu-central-1.amazonaws.com +s3-accesspoint.eu-central-1.amazonaws.com +s3-object-lambda.eu-central-1.amazonaws.com s3-website.eu-central-1.amazonaws.com +s3.dualstack.eu-central-2.amazonaws.com +s3-accesspoint.dualstack.eu-central-2.amazonaws.com +s3-website.dualstack.eu-central-2.amazonaws.com +s3.eu-central-2.amazonaws.com +s3-accesspoint.eu-central-2.amazonaws.com +s3-object-lambda.eu-central-2.amazonaws.com +s3-website.eu-central-2.amazonaws.com +s3.dualstack.eu-north-1.amazonaws.com +s3-accesspoint.dualstack.eu-north-1.amazonaws.com +s3.eu-north-1.amazonaws.com +s3-accesspoint.eu-north-1.amazonaws.com +s3-object-lambda.eu-north-1.amazonaws.com +s3-website.eu-north-1.amazonaws.com +s3.dualstack.eu-south-1.amazonaws.com +s3-accesspoint.dualstack.eu-south-1.amazonaws.com +s3-website.dualstack.eu-south-1.amazonaws.com +s3.eu-south-1.amazonaws.com +s3-accesspoint.eu-south-1.amazonaws.com +s3-object-lambda.eu-south-1.amazonaws.com +s3-website.eu-south-1.amazonaws.com +s3.dualstack.eu-south-2.amazonaws.com +s3-accesspoint.dualstack.eu-south-2.amazonaws.com +s3-website.dualstack.eu-south-2.amazonaws.com +s3.eu-south-2.amazonaws.com +s3-accesspoint.eu-south-2.amazonaws.com +s3-object-lambda.eu-south-2.amazonaws.com +s3-website.eu-south-2.amazonaws.com s3.dualstack.eu-west-1.amazonaws.com +s3-accesspoint.dualstack.eu-west-1.amazonaws.com +s3-website.dualstack.eu-west-1.amazonaws.com +s3.eu-west-1.amazonaws.com +s3-accesspoint.eu-west-1.amazonaws.com +s3-deprecated.eu-west-1.amazonaws.com +s3-object-lambda.eu-west-1.amazonaws.com +s3-website.eu-west-1.amazonaws.com s3.dualstack.eu-west-2.amazonaws.com +s3-accesspoint.dualstack.eu-west-2.amazonaws.com s3.eu-west-2.amazonaws.com +s3-accesspoint.eu-west-2.amazonaws.com +s3-object-lambda.eu-west-2.amazonaws.com s3-website.eu-west-2.amazonaws.com s3.dualstack.eu-west-3.amazonaws.com +s3-accesspoint.dualstack.eu-west-3.amazonaws.com +s3-website.dualstack.eu-west-3.amazonaws.com s3.eu-west-3.amazonaws.com +s3-accesspoint.eu-west-3.amazonaws.com +s3-object-lambda.eu-west-3.amazonaws.com s3-website.eu-west-3.amazonaws.com +s3.dualstack.il-central-1.amazonaws.com +s3-accesspoint.dualstack.il-central-1.amazonaws.com +s3-website.dualstack.il-central-1.amazonaws.com +s3.il-central-1.amazonaws.com +s3-accesspoint.il-central-1.amazonaws.com +s3-object-lambda.il-central-1.amazonaws.com +s3-website.il-central-1.amazonaws.com +s3.dualstack.me-central-1.amazonaws.com +s3-accesspoint.dualstack.me-central-1.amazonaws.com +s3-website.dualstack.me-central-1.amazonaws.com +s3.me-central-1.amazonaws.com +s3-accesspoint.me-central-1.amazonaws.com +s3-object-lambda.me-central-1.amazonaws.com +s3-website.me-central-1.amazonaws.com +s3.dualstack.me-south-1.amazonaws.com +s3-accesspoint.dualstack.me-south-1.amazonaws.com +s3.me-south-1.amazonaws.com +s3-accesspoint.me-south-1.amazonaws.com +s3-object-lambda.me-south-1.amazonaws.com +s3-website.me-south-1.amazonaws.com s3.amazonaws.com +s3-1.amazonaws.com +s3-ap-east-1.amazonaws.com s3-ap-northeast-1.amazonaws.com s3-ap-northeast-2.amazonaws.com +s3-ap-northeast-3.amazonaws.com s3-ap-south-1.amazonaws.com s3-ap-southeast-1.amazonaws.com s3-ap-southeast-2.amazonaws.com s3-ca-central-1.amazonaws.com s3-eu-central-1.amazonaws.com +s3-eu-north-1.amazonaws.com s3-eu-west-1.amazonaws.com s3-eu-west-2.amazonaws.com s3-eu-west-3.amazonaws.com s3-external-1.amazonaws.com +s3-fips-us-gov-east-1.amazonaws.com s3-fips-us-gov-west-1.amazonaws.com +mrap.accesspoint.s3-global.amazonaws.com +s3-me-south-1.amazonaws.com s3-sa-east-1.amazonaws.com s3-us-east-2.amazonaws.com +s3-us-gov-east-1.amazonaws.com s3-us-gov-west-1.amazonaws.com s3-us-west-1.amazonaws.com s3-us-west-2.amazonaws.com @@ -10806,80 +11786,311 @@ s3-website-ap-southeast-2.amazonaws.com s3-website-eu-west-1.amazonaws.com s3-website-sa-east-1.amazonaws.com s3-website-us-east-1.amazonaws.com +s3-website-us-gov-west-1.amazonaws.com s3-website-us-west-1.amazonaws.com s3-website-us-west-2.amazonaws.com s3.dualstack.sa-east-1.amazonaws.com +s3-accesspoint.dualstack.sa-east-1.amazonaws.com +s3-website.dualstack.sa-east-1.amazonaws.com +s3.sa-east-1.amazonaws.com +s3-accesspoint.sa-east-1.amazonaws.com +s3-object-lambda.sa-east-1.amazonaws.com +s3-website.sa-east-1.amazonaws.com s3.dualstack.us-east-1.amazonaws.com +s3-accesspoint.dualstack.us-east-1.amazonaws.com +s3-accesspoint-fips.dualstack.us-east-1.amazonaws.com +s3-fips.dualstack.us-east-1.amazonaws.com +s3-website.dualstack.us-east-1.amazonaws.com +s3.us-east-1.amazonaws.com +s3-accesspoint.us-east-1.amazonaws.com +s3-accesspoint-fips.us-east-1.amazonaws.com +s3-deprecated.us-east-1.amazonaws.com +s3-fips.us-east-1.amazonaws.com +s3-object-lambda.us-east-1.amazonaws.com +s3-website.us-east-1.amazonaws.com s3.dualstack.us-east-2.amazonaws.com +s3-accesspoint.dualstack.us-east-2.amazonaws.com +s3-accesspoint-fips.dualstack.us-east-2.amazonaws.com +s3-fips.dualstack.us-east-2.amazonaws.com +s3-website.dualstack.us-east-2.amazonaws.com s3.us-east-2.amazonaws.com +s3-accesspoint.us-east-2.amazonaws.com +s3-accesspoint-fips.us-east-2.amazonaws.com +s3-deprecated.us-east-2.amazonaws.com +s3-fips.us-east-2.amazonaws.com +s3-object-lambda.us-east-2.amazonaws.com s3-website.us-east-2.amazonaws.com +s3.dualstack.us-gov-east-1.amazonaws.com +s3-accesspoint.dualstack.us-gov-east-1.amazonaws.com +s3-accesspoint-fips.dualstack.us-gov-east-1.amazonaws.com +s3-fips.dualstack.us-gov-east-1.amazonaws.com +s3.us-gov-east-1.amazonaws.com +s3-accesspoint.us-gov-east-1.amazonaws.com +s3-accesspoint-fips.us-gov-east-1.amazonaws.com +s3-fips.us-gov-east-1.amazonaws.com +s3-object-lambda.us-gov-east-1.amazonaws.com +s3-website.us-gov-east-1.amazonaws.com +s3.dualstack.us-gov-west-1.amazonaws.com +s3-accesspoint.dualstack.us-gov-west-1.amazonaws.com +s3-accesspoint-fips.dualstack.us-gov-west-1.amazonaws.com +s3-fips.dualstack.us-gov-west-1.amazonaws.com +s3.us-gov-west-1.amazonaws.com +s3-accesspoint.us-gov-west-1.amazonaws.com +s3-accesspoint-fips.us-gov-west-1.amazonaws.com +s3-fips.us-gov-west-1.amazonaws.com +s3-object-lambda.us-gov-west-1.amazonaws.com +s3-website.us-gov-west-1.amazonaws.com +s3.dualstack.us-west-1.amazonaws.com +s3-accesspoint.dualstack.us-west-1.amazonaws.com +s3-accesspoint-fips.dualstack.us-west-1.amazonaws.com +s3-fips.dualstack.us-west-1.amazonaws.com +s3-website.dualstack.us-west-1.amazonaws.com +s3.us-west-1.amazonaws.com +s3-accesspoint.us-west-1.amazonaws.com +s3-accesspoint-fips.us-west-1.amazonaws.com +s3-fips.us-west-1.amazonaws.com +s3-object-lambda.us-west-1.amazonaws.com +s3-website.us-west-1.amazonaws.com +s3.dualstack.us-west-2.amazonaws.com +s3-accesspoint.dualstack.us-west-2.amazonaws.com +s3-accesspoint-fips.dualstack.us-west-2.amazonaws.com +s3-fips.dualstack.us-west-2.amazonaws.com +s3-website.dualstack.us-west-2.amazonaws.com +s3.us-west-2.amazonaws.com +s3-accesspoint.us-west-2.amazonaws.com +s3-accesspoint-fips.us-west-2.amazonaws.com +s3-deprecated.us-west-2.amazonaws.com +s3-fips.us-west-2.amazonaws.com +s3-object-lambda.us-west-2.amazonaws.com +s3-website.us-west-2.amazonaws.com + +// Amazon SageMaker Ground Truth +// Submitted by AWS Security +// Reference: 98dbfde4-7802-48c3-8751-b60f204e0d9c +labeling.ap-northeast-1.sagemaker.aws +labeling.ap-northeast-2.sagemaker.aws +labeling.ap-south-1.sagemaker.aws +labeling.ap-southeast-1.sagemaker.aws +labeling.ap-southeast-2.sagemaker.aws +labeling.ca-central-1.sagemaker.aws +labeling.eu-central-1.sagemaker.aws +labeling.eu-west-1.sagemaker.aws +labeling.eu-west-2.sagemaker.aws +labeling.us-east-1.sagemaker.aws +labeling.us-east-2.sagemaker.aws +labeling.us-west-2.sagemaker.aws + +// Amazon SageMaker Notebook Instances +// Submitted by AWS Security +// Reference: b5ea56df-669e-43cc-9537-14aa172f5dfc +notebook.af-south-1.sagemaker.aws +notebook.ap-east-1.sagemaker.aws +notebook.ap-northeast-1.sagemaker.aws +notebook.ap-northeast-2.sagemaker.aws +notebook.ap-northeast-3.sagemaker.aws +notebook.ap-south-1.sagemaker.aws +notebook.ap-south-2.sagemaker.aws +notebook.ap-southeast-1.sagemaker.aws +notebook.ap-southeast-2.sagemaker.aws +notebook.ap-southeast-3.sagemaker.aws +notebook.ap-southeast-4.sagemaker.aws +notebook.ca-central-1.sagemaker.aws +notebook-fips.ca-central-1.sagemaker.aws +notebook.ca-west-1.sagemaker.aws +notebook-fips.ca-west-1.sagemaker.aws +notebook.eu-central-1.sagemaker.aws +notebook.eu-central-2.sagemaker.aws +notebook.eu-north-1.sagemaker.aws +notebook.eu-south-1.sagemaker.aws +notebook.eu-south-2.sagemaker.aws +notebook.eu-west-1.sagemaker.aws +notebook.eu-west-2.sagemaker.aws +notebook.eu-west-3.sagemaker.aws +notebook.il-central-1.sagemaker.aws +notebook.me-central-1.sagemaker.aws +notebook.me-south-1.sagemaker.aws +notebook.sa-east-1.sagemaker.aws +notebook.us-east-1.sagemaker.aws +notebook-fips.us-east-1.sagemaker.aws +notebook.us-east-2.sagemaker.aws +notebook-fips.us-east-2.sagemaker.aws +notebook.us-gov-east-1.sagemaker.aws +notebook-fips.us-gov-east-1.sagemaker.aws +notebook.us-gov-west-1.sagemaker.aws +notebook-fips.us-gov-west-1.sagemaker.aws +notebook.us-west-1.sagemaker.aws +notebook-fips.us-west-1.sagemaker.aws +notebook.us-west-2.sagemaker.aws +notebook-fips.us-west-2.sagemaker.aws +notebook.cn-north-1.sagemaker.com.cn +notebook.cn-northwest-1.sagemaker.com.cn + +// Amazon SageMaker Studio +// Submitted by AWS Security +// Reference: 69c723d9-6e1a-4bff-a203-48eecd203183 +studio.af-south-1.sagemaker.aws +studio.ap-east-1.sagemaker.aws +studio.ap-northeast-1.sagemaker.aws +studio.ap-northeast-2.sagemaker.aws +studio.ap-northeast-3.sagemaker.aws +studio.ap-south-1.sagemaker.aws +studio.ap-southeast-1.sagemaker.aws +studio.ap-southeast-2.sagemaker.aws +studio.ap-southeast-3.sagemaker.aws +studio.ca-central-1.sagemaker.aws +studio.eu-central-1.sagemaker.aws +studio.eu-north-1.sagemaker.aws +studio.eu-south-1.sagemaker.aws +studio.eu-south-2.sagemaker.aws +studio.eu-west-1.sagemaker.aws +studio.eu-west-2.sagemaker.aws +studio.eu-west-3.sagemaker.aws +studio.il-central-1.sagemaker.aws +studio.me-central-1.sagemaker.aws +studio.me-south-1.sagemaker.aws +studio.sa-east-1.sagemaker.aws +studio.us-east-1.sagemaker.aws +studio.us-east-2.sagemaker.aws +studio.us-gov-east-1.sagemaker.aws +studio-fips.us-gov-east-1.sagemaker.aws +studio.us-gov-west-1.sagemaker.aws +studio-fips.us-gov-west-1.sagemaker.aws +studio.us-west-1.sagemaker.aws +studio.us-west-2.sagemaker.aws +studio.cn-north-1.sagemaker.com.cn +studio.cn-northwest-1.sagemaker.com.cn + +// Amazon SageMaker with MLflow +// Submited by: AWS Security +// Reference: c19f92b3-a82a-452d-8189-831b572eea7e +*.experiments.sagemaker.aws + +// Analytics on AWS +// Submitted by AWS Security +// Reference: 955f9f40-a495-4e73-ae85-67b77ac9cadd +analytics-gateway.ap-northeast-1.amazonaws.com +analytics-gateway.ap-northeast-2.amazonaws.com +analytics-gateway.ap-south-1.amazonaws.com +analytics-gateway.ap-southeast-1.amazonaws.com +analytics-gateway.ap-southeast-2.amazonaws.com +analytics-gateway.eu-central-1.amazonaws.com +analytics-gateway.eu-west-1.amazonaws.com +analytics-gateway.us-east-1.amazonaws.com +analytics-gateway.us-east-2.amazonaws.com +analytics-gateway.us-west-2.amazonaws.com + +// AWS Amplify +// Submitted by AWS Security +// Reference: c35bed18-6f4f-424f-9298-5756f2f7d72b +amplifyapp.com + +// AWS App Runner +// Submitted by AWS Security +// Reference: 6828c008-ba5d-442f-ade5-48da4e7c2316 +*.awsapprunner.com // AWS Cloud9 // Submitted by: AWS Security -// Reference: 2b6dfa9a-3a7f-4367-b2e7-0321e77c0d59 +// Reference: 30717f72-4007-4f0f-8ed4-864c6f2efec9 +webview-assets.aws-cloud9.af-south-1.amazonaws.com vfs.cloud9.af-south-1.amazonaws.com webview-assets.cloud9.af-south-1.amazonaws.com +webview-assets.aws-cloud9.ap-east-1.amazonaws.com vfs.cloud9.ap-east-1.amazonaws.com webview-assets.cloud9.ap-east-1.amazonaws.com +webview-assets.aws-cloud9.ap-northeast-1.amazonaws.com vfs.cloud9.ap-northeast-1.amazonaws.com webview-assets.cloud9.ap-northeast-1.amazonaws.com +webview-assets.aws-cloud9.ap-northeast-2.amazonaws.com vfs.cloud9.ap-northeast-2.amazonaws.com webview-assets.cloud9.ap-northeast-2.amazonaws.com +webview-assets.aws-cloud9.ap-northeast-3.amazonaws.com vfs.cloud9.ap-northeast-3.amazonaws.com webview-assets.cloud9.ap-northeast-3.amazonaws.com +webview-assets.aws-cloud9.ap-south-1.amazonaws.com vfs.cloud9.ap-south-1.amazonaws.com webview-assets.cloud9.ap-south-1.amazonaws.com +webview-assets.aws-cloud9.ap-southeast-1.amazonaws.com vfs.cloud9.ap-southeast-1.amazonaws.com webview-assets.cloud9.ap-southeast-1.amazonaws.com +webview-assets.aws-cloud9.ap-southeast-2.amazonaws.com vfs.cloud9.ap-southeast-2.amazonaws.com webview-assets.cloud9.ap-southeast-2.amazonaws.com +webview-assets.aws-cloud9.ca-central-1.amazonaws.com vfs.cloud9.ca-central-1.amazonaws.com webview-assets.cloud9.ca-central-1.amazonaws.com +webview-assets.aws-cloud9.eu-central-1.amazonaws.com vfs.cloud9.eu-central-1.amazonaws.com webview-assets.cloud9.eu-central-1.amazonaws.com +webview-assets.aws-cloud9.eu-north-1.amazonaws.com vfs.cloud9.eu-north-1.amazonaws.com webview-assets.cloud9.eu-north-1.amazonaws.com +webview-assets.aws-cloud9.eu-south-1.amazonaws.com vfs.cloud9.eu-south-1.amazonaws.com webview-assets.cloud9.eu-south-1.amazonaws.com +webview-assets.aws-cloud9.eu-west-1.amazonaws.com vfs.cloud9.eu-west-1.amazonaws.com webview-assets.cloud9.eu-west-1.amazonaws.com +webview-assets.aws-cloud9.eu-west-2.amazonaws.com vfs.cloud9.eu-west-2.amazonaws.com webview-assets.cloud9.eu-west-2.amazonaws.com +webview-assets.aws-cloud9.eu-west-3.amazonaws.com vfs.cloud9.eu-west-3.amazonaws.com webview-assets.cloud9.eu-west-3.amazonaws.com +webview-assets.aws-cloud9.il-central-1.amazonaws.com +vfs.cloud9.il-central-1.amazonaws.com +webview-assets.aws-cloud9.me-south-1.amazonaws.com vfs.cloud9.me-south-1.amazonaws.com webview-assets.cloud9.me-south-1.amazonaws.com +webview-assets.aws-cloud9.sa-east-1.amazonaws.com vfs.cloud9.sa-east-1.amazonaws.com webview-assets.cloud9.sa-east-1.amazonaws.com +webview-assets.aws-cloud9.us-east-1.amazonaws.com vfs.cloud9.us-east-1.amazonaws.com webview-assets.cloud9.us-east-1.amazonaws.com +webview-assets.aws-cloud9.us-east-2.amazonaws.com vfs.cloud9.us-east-2.amazonaws.com webview-assets.cloud9.us-east-2.amazonaws.com +webview-assets.aws-cloud9.us-west-1.amazonaws.com vfs.cloud9.us-west-1.amazonaws.com webview-assets.cloud9.us-west-1.amazonaws.com +webview-assets.aws-cloud9.us-west-2.amazonaws.com vfs.cloud9.us-west-2.amazonaws.com webview-assets.cloud9.us-west-2.amazonaws.com +// AWS Directory Service +// Submitted by AWS Security +// Reference: a13203e8-42dc-4045-a0d2-2ee67bed1068 +awsapps.com + // AWS Elastic Beanstalk -// Submitted by Luke Wells -// Reference: aa202394-43a0-4857-b245-8db04549137e +// Submitted by AWS Security +// Reference: bb5a965c-dec3-4967-aa22-e306ad064797 cn-north-1.eb.amazonaws.com.cn cn-northwest-1.eb.amazonaws.com.cn elasticbeanstalk.com +af-south-1.elasticbeanstalk.com +ap-east-1.elasticbeanstalk.com ap-northeast-1.elasticbeanstalk.com ap-northeast-2.elasticbeanstalk.com ap-northeast-3.elasticbeanstalk.com ap-south-1.elasticbeanstalk.com ap-southeast-1.elasticbeanstalk.com ap-southeast-2.elasticbeanstalk.com +ap-southeast-3.elasticbeanstalk.com ca-central-1.elasticbeanstalk.com eu-central-1.elasticbeanstalk.com +eu-north-1.elasticbeanstalk.com +eu-south-1.elasticbeanstalk.com eu-west-1.elasticbeanstalk.com eu-west-2.elasticbeanstalk.com eu-west-3.elasticbeanstalk.com +il-central-1.elasticbeanstalk.com +me-south-1.elasticbeanstalk.com sa-east-1.elasticbeanstalk.com us-east-1.elasticbeanstalk.com us-east-2.elasticbeanstalk.com +us-gov-east-1.elasticbeanstalk.com us-gov-west-1.elasticbeanstalk.com us-west-1.elasticbeanstalk.com us-west-2.elasticbeanstalk.com @@ -10895,6 +12106,11 @@ us-west-2.elasticbeanstalk.com // Reference: d916759d-a08b-4241-b536-4db887383a6a awsglobalaccelerator.com +// AWS re:Post Private +// Submitted by AWS Security +// Reference: 83385945-225f-416e-9aa0-ad0632bfdcee +*.private.repost.aws + // eero // Submitted by Yue Kang // Reference: 264afe70-f62c-4c02-8ab9-b5281ed24461 @@ -10903,15 +12119,14 @@ eero-stage.online // concludes Amazon -// Amune : https://amune.org/ -// Submitted by Team Amune -t3l3p0rt.net -tele.amune.org - // Apigee : https://apigee.com/ // Submitted by Apigee Security Team apigee.io +// Apis Networks : https://apisnetworks.com +// Submitted by Matt Saladna +panel.dev + // Apphud : https://apphud.com // Submitted by Alexander Selivanov siiites.com @@ -10929,6 +12144,14 @@ appudo.net // Submitted by Thomas Orozco on-aptible.com +// Aquapal : https://aquapal.net/ +// Submitted by Aki Ueno +f5.si + +// ArvanCloud EdgeCompute +// Submitted by ArvanCloud CDN +arvanedge.ir + // ASEINet : https://www.aseinet.com/ // Submitted by Asei SEKIGUCHI user.aseinet.ne.jp @@ -10958,12 +12181,9 @@ cdn.prod.atlassian-dev.net // Submitted by Lukas Reschke translated.page -// Autocode : https://autocode.com -// Submitted by Jacob Lee -autocode.dev - // AVM : https://avm.de // Submitted by Andreas Weise +myfritz.link myfritz.net // AVStack Pte. Ltd. : https://avstack.io @@ -10975,7 +12195,7 @@ onavstack.net *.awdev.ca *.advisor.ws -// AZ.pl sp. z.o.o: https://az.pl +// AZ.pl sp. z.o.o : https://az.pl // Submitted by Krzysztof Wolski ecommerce-shop.pl @@ -10983,25 +12203,10 @@ ecommerce-shop.pl // Submitted by Olivier Benz b-data.io -// backplane : https://www.backplane.io -// Submitted by Anthony Voutas -backplaneapp.io - // Balena : https://www.balena.io // Submitted by Petros Angelatos balena-devices.com -// University of Banja Luka : https://unibl.org -// Domains for Republic of Srpska administrative entity. -// Submitted by Marko Ivanovic -rs.ba - -// Banzai Cloud -// Submitted by Janos Matyas -*.banzai.cloud -app.banzaicloud.io -*.backyards.banzaicloud.io - // BASE, Inc. : https://binc.jp // Submitted by Yuya NAGASAWA base.ec @@ -11023,9 +12228,9 @@ beagleboard.io // Submitted by Lev Nekrasov *.beget.app -// BetaInABox -// Submitted by Adrian -betainabox.com +// Besties : https://besties.house +// Submitted by Hazel Cora +pages.gay // BinaryLane : http://www.binarylane.com // Submitted by Nathan O'Sullivan @@ -11068,14 +12273,24 @@ square7.de bplaced.net square7.net +// Brave : https://brave.com +// Submitted by Andrea Brancaleoni +*.s.brave.io + // Brendly : https://brendly.rs -// Submitted by Dusan Radovanovic +// Submitted by Dusan Radovanovic +shop.brendly.hr shop.brendly.rs // BrowserSafetyMark // Submitted by Dave Tharp browsersafetymark.io +// BRS Media : https://brsmedia.com/ +// Submitted by Gavin Brown +radio.am +radio.fm + // Bytemark Hosting : https://www.bytemark.co.uk // Submitted by Paul Cammish uk0.bigv.io @@ -11086,14 +12301,12 @@ vm.bytemark.co.uk // Submitted by Antonio Lain cafjs.com -// callidomus : https://www.callidomus.com/ -// Submitted by Marcus Popp -mycd.eu - // Canva Pty Ltd : https://canva.com/ // Submitted by Joel Aquilina canva-apps.cn +*.my.canvasite.cn canva-apps.com +*.my.canva.site // Carrd : https://carrd.co // Submitted by AJ @@ -11103,75 +12316,42 @@ carrd.co crd.co ju.mp +// CDDO : https://www.gov.uk/guidance/get-an-api-domain-on-govuk +// Submitted by Jamie Tanna +api.gov.uk + +// CDN77.com : http://www.cdn77.com +// Submitted by Jan Krpes +cdn77-storage.com +rsc.contentproxy9.cz +r.cdn77.net +cdn77-ssl.net +c.cdn77.org +rsc.cdn77.org +ssl.origin.cdn77-secure.org + // CentralNic : http://www.centralnic.com/names/domains // Submitted by registry -ae.org +za.bz br.com cn.com -com.de -com.se de.com eu.com -gb.net -hu.net -jp.net jpn.com mex.com ru.com sa.com -se.net uk.com -uk.net us.com -za.bz za.com - -// No longer operated by CentralNic, these entries should be adopted and/or removed by current operators -// Submitted by Gavin Brown -ar.com -hu.com -kr.com -no.com -qc.com -uy.com - -// Africa.com Web Solutions Ltd : https://registry.africa.com -// Submitted by Gavin Brown -africa.com - -// iDOT Services Limited : http://www.domain.gr.com -// Submitted by Gavin Brown -gr.com - -// Radix FZC : http://domains.in.net -// Submitted by Gavin Brown -in.net -web.in - -// US REGISTRY LLC : http://us.org -// Submitted by Gavin Brown -us.org - -// co.com Registry, LLC : https://registry.co.com -// Submitted by Gavin Brown -co.com - -// Roar Domains LLC : https://roar.basketball/ -// Submitted by Gavin Brown -aus.basketball -nz.basketball - -// BRS Media : https://brsmedia.com/ -// Submitted by Gavin Brown -radio.am -radio.fm - -// c.la : http://www.c.la/ -c.la - -// certmgr.org : https://certmgr.org -// Submitted by B. Blechschmidt -certmgr.org +com.de +gb.net +hu.net +jp.net +se.net +uk.net +ae.org +com.se // Cityhost LLC : https://cityhost.ua // Submitted by Maksym Rivtin @@ -11182,10 +12362,6 @@ cx.ua discourse.group discourse.team -// Clever Cloud : https://www.clever-cloud.com/ -// Submitted by Quentin Adam -cleverapps.io - // Clerk : https://www.clerk.dev // Submitted by Colin Sidoti clerk.app @@ -11195,10 +12371,44 @@ clerkstage.app *.stg.dev *.stgstage.dev +// Clever Cloud : https://www.clever-cloud.com/ +// Submitted by Quentin Adam +cleverapps.cc +*.services.clever-cloud.com +cleverapps.io +cleverapps.tech + // ClickRising : https://clickrising.com/ // Submitted by Umut Gumeli clickrising.net +// Cloud DNS Ltd : http://www.cloudns.net +// Submitted by Aleksander Hristov & Boyan Peychev +cloudns.asia +cloudns.be +cloud-ip.biz +cloudns.biz +cloudns.cc +cloudns.ch +cloudns.cl +cloudns.club +dnsabr.com +ip-ddns.com +cloudns.cx +cloudns.eu +cloudns.in +cloudns.info +ddns-ip.net +dns-cloud.net +dns-dynamic.net +cloudns.nz +cloudns.org +ip-dynamic.org +cloudns.ph +cloudns.pro +cloudns.pw +cloudns.us + // Cloud66 : https://www.cloud66.com/ // Submitted by Khash Sajadi c66.me @@ -11213,11 +12423,6 @@ cloudaccess.host freesite.host cloudaccess.net -// cloudControl : https://www.cloudcontrol.com/ -// Submitted by Tobias Wilken -cloudcontrolled.com -cloudcontrolapp.com - // Cloudera, Inc. : https://www.cloudera.com/ // Submitted by Kedarnath Waikar *.cloudera.site @@ -11230,52 +12435,46 @@ trycloudflare.com pages.dev r2.dev workers.dev +cloudflare.net +cdn.cloudflare.net +cdn.cloudflareanycast.net +cdn.cloudflarecn.net +cdn.cloudflareglobal.net + +// cloudscale.ch AG : https://www.cloudscale.ch/ +// Submitted by Gaudenz Steinlin +cust.cloudscale.ch +objects.lpg.cloudscale.ch +objects.rma.cloudscale.ch // Clovyr : https://clovyr.io // Submitted by Patrick Nielsen wnext.app -// co.ca : http://registry.co.ca/ -co.ca +// CNPY : https://cnpy.gdn +// Submitted by Angelo Gladding +cnpy.gdn // Co & Co : https://co-co.nl/ // Submitted by Govert Versluis *.otap.co -// i-registry s.r.o. : http://www.i-registry.cz/ -// Submitted by Martin Semrad -co.cz - -// CDN77.com : http://www.cdn77.com -// Submitted by Jan Krpes -c.cdn77.org -cdn77-ssl.net -r.cdn77.net -rsc.cdn77.org -ssl.origin.cdn77-secure.org - -// Cloud DNS Ltd : http://www.cloudns.net -// Submitted by Aleksander Hristov -cloudns.asia -cloudns.biz -cloudns.club -cloudns.cc -cloudns.eu -cloudns.in -cloudns.info -cloudns.org -cloudns.pro -cloudns.pw -cloudns.us +// co.ca : http://registry.co.ca/ +co.ca -// CNPY : https://cnpy.gdn -// Submitted by Angelo Gladding -cnpy.gdn +// co.com Registry, LLC : https://registry.co.com +// Submitted by Gavin Brown +co.com // Codeberg e. V. : https://codeberg.org // Submitted by Moritz Marquardt codeberg.page +// CodeSandbox B.V. : https://codesandbox.io +// Submitted by Ives van Hoorne +csb.app +preview.csb.app + // CoDNS B.V. co.nl co.no @@ -11285,6 +12484,14 @@ co.no webhosting.be hosting-cluster.nl +// Contentful GmbH : https://www.contentful.com +// Submitted by Contentful Developer Experience Team +ctfcloud.net + +// Convex : https://convex.dev/ +// Submitted by James Cowling +convex.site + // Coordination Center for TLD RU and XN--P1AI : https://cctld.ru/en/domains/domens_ru/reserved/ // Submitted by George Georgievsky ac.ru @@ -11297,8 +12504,8 @@ test.ru // COSIMO GmbH : http://www.cosimo.de // Submitted by Rene Marticke dyn.cosidns.de -dynamisches-dns.de dnsupdater.de +dynamisches-dns.de internet-dns.de l-o-g-i-n.de dynamic-dns.info @@ -11306,29 +12513,29 @@ feste-ip.net knx-server.net static-access.net +// Craft Docs Ltd : https://www.craft.do/ +// Submitted by Zsombor Fuszenecker +craft.me + // Craynic, s.r.o. : http://www.craynic.com/ // Submitted by Ales Krajnik realm.cz +// Crisp IM SAS : https://crisp.chat/ +// Submitted by Baptiste Jamin +on.crisp.email + // Cryptonomic : https://cryptonomic.net/ // Submitted by Andrew Cady *.cryptonomic.net -// Cupcake : https://cupcake.io/ -// Submitted by Jonathan Rudenberg -cupcake.is - // Curv UG : https://curv-labs.de/ // Submitted by Marvin Wiesner curv.dev -// Customer OCI - Oracle Dyn https://cloud.oracle.com/home https://dyn.com/dns/ -// Submitted by Gregory Drake -// Note: This is intended to also include customer-oci.com due to wildcards implicitly including the current label -*.customer-oci.com -*.oci.customer-oci.com -*.ocp.customer-oci.com -*.ocs.customer-oci.com +// cyber_Folks S.A. : https://cyberfolks.pl +// Submitted by Bartlomiej Kida +cfolks.pl // cyon GmbH : https://www.cyon.ch/ // Submitted by Dominic Luechinger @@ -11337,23 +12544,9 @@ cyon.site // Danger Science Group: https://dangerscience.com/ // Submitted by Skylar MacDonald +platform0.app fnwk.site folionetwork.site -platform0.app - -// Daplie, Inc : https://daplie.com -// Submitted by AJ ONeal -daplie.me -localhost.daplie.me - -// Datto, Inc. : https://www.datto.com/ -// Submitted by Philipp Heckel -dattolocal.com -dattorelay.com -dattoweb.com -mydatto.com -dattolocal.net -mydatto.net // Dansk.net : http://www.dansk.net/ // Submitted by Anani Voule @@ -11367,14 +12560,10 @@ store.dk // Submitted by Abel Boldu / DAppNode Team dyndns.dappnode.io -// dapps.earth : https://dapps.earth/ -// Submitted by Daniil Burdakov -*.dapps.earth -*.bzz.dapps.earth - // Dark, Inc. : https://darklang.com // Submitted by Paul Biggar builtwithdark.com +darklang.io // DataDetect, LLC. : https://datadetect.com // Submitted by Andrew Banchich @@ -11385,14 +12574,36 @@ instance.datadetect.com // Submitted by Richard Li edgestack.me -// DDNS5 : https://ddns5.com -// Submitted by Cameron Elliott -ddns5.com +// Datto, Inc. : https://www.datto.com/ +// Submitted by Philipp Heckel +dattolocal.com +dattorelay.com +dattoweb.com +mydatto.com +dattolocal.net +mydatto.net + +// ddnss.de : https://www.ddnss.de/ +// Submitted by Robert Niedziela +ddnss.de +dyn.ddnss.de +dyndns.ddnss.de +dyn-ip24.de +dyndns1.de +home-webserver.de +dyn.home-webserver.de +myhome-server.de +ddnss.org // Debian : https://www.debian.org/ // Submitted by Peter Palfrader / Debian Sysadmin Team debian.net +// Definima : http://www.definima.com/ +// Submitted by Maxence Bitterli +definima.io +definima.net + // Deno Land Inc : https://deno.com/ // Submitted by Luca Casonato deno.dev @@ -11407,10 +12618,28 @@ dedyn.io deta.app deta.dev +// dhosting.pl Sp. z o.o.: https://dhosting.pl/ +// Submitted by Michal Kokoszkiewicz +dfirma.pl +dkonto.pl +you2.pl + +// DigitalOcean App Platform : https://www.digitalocean.com/products/app-platform/ +// Submitted by Braxton Huggins +ondigitalocean.app + +// DigitalOcean Spaces : https://www.digitalocean.com/products/spaces/ +// Submitted by Robin H. Johnson +*.digitaloceanspaces.com + +// DigitalPlat : https://www.digitalplat.org/ +// Submitted by Edward Hsing +us.kg + // Diher Solutions : https://diher.solutions // Submitted by Didi Hermawan -*.rss.my.id -*.diher.solutions +rss.my.id +diher.solutions // Discord Inc : https://discord.com // Submitted by Sahn Lam @@ -11442,6 +12671,10 @@ shoparena.pl // Submitted by Andrew Farmer dreamhosters.com +// Dreamyoungs, Inc. : https://durumis.com +// Submitted by Infra Team +durumis.com + // Drobo : http://www.drobo.com/ // Submitted by Ricardo Padilha mydrobo.com @@ -11455,91 +12688,54 @@ drud.us // Submitted by Richard Harper duckdns.org -// Bip : https://bip.sh -// Submitted by Joel Kennedy -bip.sh - -// bitbridge.net : Submitted by Craig Welch, abeliidev@gmail.com -bitbridge.net - // dy.fi : http://dy.fi/ // Submitted by Heikki Hannikainen dy.fi tunk.org // DynDNS.com : http://www.dyndns.com/services/dns/dyndns/ -dyndns-at-home.com -dyndns-at-work.com -dyndns-blog.com -dyndns-free.com -dyndns-home.com -dyndns-ip.com -dyndns-mail.com -dyndns-office.com -dyndns-pics.com -dyndns-remote.com -dyndns-server.com -dyndns-web.com -dyndns-wiki.com -dyndns-work.com dyndns.biz -dyndns.info -dyndns.org -dyndns.tv -at-band-camp.net -ath.cx -barrel-of-knowledge.info -barrell-of-knowledge.info -better-than.tv +for-better.biz +for-more.biz +for-some.biz +for-the.biz +selfip.biz +webhop.biz +ftpaccess.cc +game-server.cc +myphotos.cc +scrapping.cc blogdns.com -blogdns.net -blogdns.org -blogsite.org -boldlygoingnowhere.org -broke-it.net -buyshouses.net cechire.com dnsalias.com -dnsalias.net -dnsalias.org dnsdojo.com -dnsdojo.net -dnsdojo.org -does-it.net doesntexist.com -doesntexist.org dontexist.com -dontexist.net -dontexist.org doomdns.com -doomdns.org -dvrdns.org dyn-o-saur.com dynalias.com -dynalias.net -dynalias.org -dynathome.net -dyndns.ws -endofinternet.net -endofinternet.org -endoftheinternet.org +dyndns-at-home.com +dyndns-at-work.com +dyndns-blog.com +dyndns-free.com +dyndns-home.com +dyndns-ip.com +dyndns-mail.com +dyndns-office.com +dyndns-pics.com +dyndns-remote.com +dyndns-server.com +dyndns-web.com +dyndns-wiki.com +dyndns-work.com est-a-la-maison.com est-a-la-masion.com est-le-patron.com est-mon-blogueur.com -for-better.biz -for-more.biz -for-our.info -for-some.biz -for-the.biz -forgot.her.name -forgot.his.name from-ak.com from-al.com from-ar.com -from-az.net from-ca.com -from-co.net from-ct.com from-dc.com from-de.com @@ -11552,10 +12748,8 @@ from-il.com from-in.com from-ks.com from-ky.com -from-la.net from-ma.com from-md.com -from-me.org from-mi.com from-mn.com from-mo.com @@ -11568,7 +12762,6 @@ from-nh.com from-nj.com from-nm.com from-nv.com -from-ny.net from-oh.com from-ok.com from-or.com @@ -11586,45 +12779,18 @@ from-wa.com from-wi.com from-wv.com from-wy.com -ftpaccess.cc -fuettertdasnetz.de -game-host.org -game-server.cc getmyip.com -gets-it.net -go.dyndns.org gotdns.com -gotdns.org -groks-the.info -groks-this.info -ham-radio-op.net -here-for-more.info hobby-site.com -hobby-site.org -home.dyndns.org -homedns.org -homeftp.net -homeftp.org -homeip.net homelinux.com -homelinux.net -homelinux.org homeunix.com -homeunix.net -homeunix.org iamallama.com -in-the-band.net is-a-anarchist.com is-a-blogger.com is-a-bookkeeper.com -is-a-bruinsfan.org is-a-bulls-fan.com -is-a-candidate.org is-a-caterer.com -is-a-celticsfan.org is-a-chef.com -is-a-chef.net -is-a-chef.org is-a-conservative.com is-a-cpa.com is-a-cubicle-slave.com @@ -11633,31 +12799,25 @@ is-a-designer.com is-a-doctor.com is-a-financialadvisor.com is-a-geek.com -is-a-geek.net -is-a-geek.org is-a-green.com is-a-guru.com is-a-hard-worker.com is-a-hunter.com -is-a-knight.org is-a-landscaper.com is-a-lawyer.com is-a-liberal.com is-a-libertarian.com -is-a-linux-user.org is-a-llama.com is-a-musician.com is-a-nascarfan.com is-a-nurse.com is-a-painter.com -is-a-patsfan.org is-a-personaltrainer.com is-a-photographer.com is-a-player.com is-a-republican.com is-a-rockstar.com is-a-socialist.com -is-a-soxfan.org is-a-student.com is-a-teacher.com is-a-techie.com @@ -11669,113 +12829,150 @@ is-an-anarchist.com is-an-artist.com is-an-engineer.com is-an-entertainer.com -is-by.us is-certified.com -is-found.org is-gone.com is-into-anime.com is-into-cars.com is-into-cartoons.com is-into-games.com is-leet.com -is-lost.org is-not-certified.com -is-saved.org is-slick.com is-uberleet.com -is-very-bad.org -is-very-evil.org -is-very-good.org -is-very-nice.org -is-very-sweet.org is-with-theband.com isa-geek.com -isa-geek.net -isa-geek.org isa-hockeynut.com issmarterthanyou.com +likes-pie.com +likescandy.com +neat-url.com +saves-the-whales.com +selfip.com +sells-for-less.com +sells-for-u.com +servebbs.com +simple-url.com +space-to-rent.com +teaches-yoga.com +writesthisblog.com +ath.cx +fuettertdasnetz.de isteingeek.de istmein.de -kicks-ass.net -kicks-ass.org -knowsitall.info -land-4-sale.us lebtimnetz.de leitungsen.de -likes-pie.com -likescandy.com +traeumtgerade.de +barrel-of-knowledge.info +barrell-of-knowledge.info +dyndns.info +for-our.info +groks-the.info +groks-this.info +here-for-more.info +knowsitall.info +selfip.info +webhop.info +forgot.her.name +forgot.his.name +at-band-camp.net +blogdns.net +broke-it.net +buyshouses.net +dnsalias.net +dnsdojo.net +does-it.net +dontexist.net +dynalias.net +dynathome.net +endofinternet.net +from-az.net +from-co.net +from-la.net +from-ny.net +gets-it.net +ham-radio-op.net +homeftp.net +homeip.net +homelinux.net +homeunix.net +in-the-band.net +is-a-chef.net +is-a-geek.net +isa-geek.net +kicks-ass.net +office-on-the.net +podzone.net +scrapper-site.net +selfip.net +sells-it.net +servebbs.net +serveftp.net +thruhere.net +webhop.net merseine.nu mine.nu +shacknet.nu +blogdns.org +blogsite.org +boldlygoingnowhere.org +dnsalias.org +dnsdojo.org +doesntexist.org +dontexist.org +doomdns.org +dvrdns.org +dynalias.org +dyndns.org +go.dyndns.org +home.dyndns.org +endofinternet.org +endoftheinternet.org +from-me.org +game-host.org +gotdns.org +hobby-site.org +homedns.org +homeftp.org +homelinux.org +homeunix.org +is-a-bruinsfan.org +is-a-candidate.org +is-a-celticsfan.org +is-a-chef.org +is-a-geek.org +is-a-knight.org +is-a-linux-user.org +is-a-patsfan.org +is-a-soxfan.org +is-found.org +is-lost.org +is-saved.org +is-very-bad.org +is-very-evil.org +is-very-good.org +is-very-nice.org +is-very-sweet.org +isa-geek.org +kicks-ass.org misconfused.org -mypets.ws -myphotos.cc -neat-url.com -office-on-the.net -on-the-web.tv -podzone.net podzone.org readmyblog.org -saves-the-whales.com -scrapper-site.net -scrapping.cc -selfip.biz -selfip.com -selfip.info -selfip.net selfip.org -sells-for-less.com -sells-for-u.com -sells-it.net sellsyourhome.org -servebbs.com -servebbs.net servebbs.org -serveftp.net serveftp.org servegame.org -shacknet.nu -simple-url.com -space-to-rent.com stuff-4-sale.org -stuff-4-sale.us -teaches-yoga.com -thruhere.net -traeumtgerade.de -webhop.biz -webhop.info -webhop.net webhop.org +better-than.tv +dyndns.tv +on-the-web.tv worse-than.tv -writesthisblog.com - -// ddnss.de : https://www.ddnss.de/ -// Submitted by Robert Niedziela -ddnss.de -dyn.ddnss.de -dyndns.ddnss.de -dyndns1.de -dyn-ip24.de -home-webserver.de -dyn.home-webserver.de -myhome-server.de -ddnss.org - -// Definima : http://www.definima.com/ -// Submitted by Maxence Bitterli -definima.net -definima.io - -// DigitalOcean App Platform : https://www.digitalocean.com/products/app-platform/ -// Submitted by Braxton Huggins -ondigitalocean.app - -// DigitalOcean Spaces : https://www.digitalocean.com/products/spaces/ -// Submitted by Robin H. Johnson -*.digitaloceanspaces.com - -// dnstrace.pro : https://dnstrace.pro/ -// Submitted by Chris Partridge -bci.dnstrace.pro +is-by.us +land-4-sale.us +stuff-4-sale.us +dyndns.ws +mypets.ws // Dynu.com : https://www.dynu.com/ // Submitted by Sue Ye @@ -11795,7 +12992,6 @@ freeddns.org mywire.org webredirect.org myddns.rocks -blogsite.xyz // dynv6 : https://dynv6.com // Submitted by Dominik Menke @@ -11810,6 +13006,26 @@ e4.cz easypanel.app easypanel.host +// EasyWP : https://www.easywp.com +// Submitted by +*.ewp.live + +// eDirect Corp. : https://hosting.url.com.tw/ +// Submitted by C.S. chang +twmail.cc +twmail.net +twmail.org +mymailer.com.tw +url.tw + +// Electromagnetic Field : https://www.emfcamp.org +// Submitted by +at.emf.camp + +// Elefunc, Inc. : https://elefunc.com +// Submitted by Cetin Sert +rt.ht + // Elementor : Elementor Ltd. // Submitted by Anton Barkan elementor.cloud @@ -11820,7 +13036,7 @@ elementor.cool en-root.fr // Enalean SAS: https://www.enalean.com -// Submitted by Thomas Cottier +// Submitted by Enalean Security Team mytuleap.com tuleap-partners.com @@ -11829,11 +13045,6 @@ tuleap-partners.com encr.app encoreapi.com -// ECG Robotics, Inc: https://ecgrobotics.org -// Submitted by -onred.one -staging.onred.one - // encoway GmbH : https://www.encoway.de // Submitted by Marcel Daus eu.encoway.cloud @@ -11874,7 +13085,6 @@ kr.eu.org lt.eu.org lu.eu.org lv.eu.org -mc.eu.org me.eu.org mk.eu.org mt.eu.org @@ -11884,10 +13094,8 @@ ng.eu.org nl.eu.org no.eu.org nz.eu.org -paris.eu.org pl.eu.org pt.eu.org -q-a.eu.org ro.eu.org ru.eu.org se.eu.org @@ -11912,22 +13120,20 @@ us-2.evennode.com us-3.evennode.com us-4.evennode.com -// eDirect Corp. : https://hosting.url.com.tw/ -// Submitted by C.S. chang -twmail.cc -twmail.net -twmail.org -mymailer.com.tw -url.tw +// Evervault : https://evervault.com +// Submitted by Hannah Neary +relay.evervault.app +relay.evervault.dev + +// Expo : https://expo.dev/ +// Submitted by James Ide +expo.app +staging.expo.app // Fabrica Technologies, Inc. : https://www.fabrica.dev/ // Submitted by Eric Jiang onfabrica.com -// Facebook, Inc. -// Submitted by Peter Ruibal -apps.fbsbx.com - // FAITID : https://faitid.org/ // Submitted by Maxim Alzoba // https://www.flexireg.net/stat_info @@ -12014,8 +13220,6 @@ u.channelsdvr.net edgecompute.app fastly-edge.com fastly-terrarium.com -fastlylb.net -map.fastlylb.net freetls.fastly.net map.fastly.net a.prod.fastly.net @@ -12023,6 +13227,8 @@ global.prod.fastly.net a.ssl.fastly.net b.ssl.fastly.net global.ssl.fastly.net +fastlylb.net +map.fastlylb.net // Fastmail : https://www.fastmail.com/ // Submitted by Marc Bradshaw @@ -12036,6 +13242,12 @@ myfast.host fastvps.site myfast.space +// FearWorks Media Ltd. : https://fearworksmedia.co.uk +// submitted by Keith Fairley +conn.uk +copro.uk +hosp.uk + // Fedora : https://fedoraproject.org/ // submitted by Patrick Uiterwijk fedorainfracloud.org @@ -12044,12 +13256,6 @@ cloud.fedoraproject.org app.os.fedoraproject.org app.os.stg.fedoraproject.org -// FearWorks Media Ltd. : https://fearworksmedia.co.uk -// submitted by Keith Fairley -conn.uk -copro.uk -hosp.uk - // Fermax : https://fermax.com/ // submitted by Koen Van Isterdael mydobiss.com @@ -12061,47 +13267,33 @@ fh-muenster.io // Filegear Inc. : https://www.filegear.com // Submitted by Jason Zhu filegear.me -filegear-au.me -filegear-de.me -filegear-gb.me -filegear-ie.me -filegear-jp.me -filegear-sg.me // Firebase, Inc. // Submitted by Chris Raynor firebaseapp.com -// Firewebkit : https://www.firewebkit.com -// Submitted by Majid Qureshi -fireweb.app - -// FLAP : https://www.flap.cloud -// Submitted by Louis Chemineau -flap.id - // FlashDrive : https://flashdrive.io // Submitted by Eric Chan -onflashdrive.app fldrv.com +// FlutterFlow : https://flutterflow.io +// Submitted by Anton Emelyanov +flutterflow.app + // fly.io: https://fly.io // Submitted by Kurt Mackey fly.dev -edgeapp.net shw.io +edgeapp.net -// Flynn : https://flynn.io -// Submitted by Jonathan Rudenberg -flynnhosting.net - -// Forgerock : https://www.forgerock.com +// Forgerock : https://www.forgerock.com // Submitted by Roderick Parr forgeblocks.com id.forgerock.io // Framer : https://www.framer.com -// Submitted by Koen Rouwhorst +// Submitted by Koen Rouwhorst +framer.ai framer.app framercanvas.com framer.media @@ -12109,15 +13301,7 @@ framer.photos framer.website framer.wiki -// Frusky MEDIA&PR : https://www.frusky.de -// Submitted by Victor Pupynin -*.frusky.de - -// RavPage : https://www.ravpage.co.il -// Submitted by Roni Horowitz -ravpage.co.il - -// Frederik Braun https://frederik-braun.com +// Frederik Braun : https://frederik-braun.com // Submitted by Frederik Braun 0e.vc @@ -12138,11 +13322,33 @@ freedesktop.org // Submitted by Cadence freemyip.com +// Frusky MEDIA&PR : https://www.frusky.de +// Submitted by Victor Pupynin +*.frusky.de + // FunkFeuer - Verein zur Förderung freier Netze : https://www.funkfeuer.at // Submitted by Daniel A. Maierhofer wien.funkfeuer.at -// Futureweb OG : http://www.futureweb.at +// Future Versatile Group. : https://www.fvg-on.net/ +// T.Kabu +daemon.asia +dix.asia +mydns.bz +0am.jp +0g0.jp +0j0.jp +0t0.jp +mydns.jp +pgw.jp +wjg.jp +keyword-on.net +live-on.net +server-on.net +mydns.tw +mydns.vc + +// Futureweb GmbH : https://www.futureweb.at // Submitted by Andreas Schnederle-Wagner *.futurecms.at *.ex.futurecms.at @@ -12153,8 +13359,14 @@ futuremailing.at *.kunden.ortsinfo.at *.statics.cloud +// GCom Internet : https://www.gcom.net.au +// Submitted by Leo Julius +aliases121.com + // GDS : https://www.gov.uk/service-manual/technology/managing-domain-names // Submitted by Stephen Ford +campaign.gov.uk +service.gov.uk independent-commission.uk independent-inquest.uk independent-inquiry.uk @@ -12162,12 +13374,6 @@ independent-panel.uk independent-review.uk public-inquiry.uk royal-commission.uk -campaign.gov.uk -service.gov.uk - -// CDDO : https://www.gov.uk/guidance/get-an-api-domain-on-govuk -// Submitted by Jamie Tanna -api.gov.uk // Gehirn Inc. : https://www.gehirn.co.jp/ // Submitted by Kohei YOSHIDA @@ -12181,9 +13387,10 @@ gentlentapis.com lab.ms cdn-edges.net -// Ghost Foundation : https://ghost.org -// Submitted by Matt Hanley -ghost.io +// GetLocalCert : https://getlocalcert.net +// Submitted by William Harrison +localcert.net +localhostcert.net // GignoSystemJapan: http://gsj.bz // Submitted by GignoSystemJapan @@ -12327,105 +13534,86 @@ whitesnow.jp zombie.jp heteml.net -// GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ -// Submitted by Tom Whitwell -cloudapps.digital -london.cloudapps.digital - -// GOV.UK Pay : https://www.payments.service.gov.uk/ -// Submitted by Richard Baker -pymnt.uk - -// UKHomeOffice : https://www.gov.uk/government/organisations/home-office -// Submitted by Jon Shanks -homeoffice.gov.uk - -// GlobeHosting, Inc. -// Submitted by Zoltan Egresi -ro.im +// GoDaddy Registry : https://registry.godaddy +// Submitted by Rohan Durrant +graphic.design // GoIP DNS Services : http://www.goip.de // Submitted by Christian Poulter goip.de // Google, Inc. -// Submitted by Eduardo Vela -run.app -a.run.app -web.app -*.0emm.com -appspot.com -*.r.appspot.com -codespot.com -googleapis.com -googlecode.com -pagespeedmobilizer.com -publishproxy.com -withgoogle.com -withyoutube.com -*.gateway.dev -cloud.goog -translate.goog -*.usercontent.goog -cloudfunctions.net +// Submitted by Shannon McCabe blogspot.ae blogspot.al blogspot.am +*.hosted.app +*.run.app +web.app +blogspot.com.ar +blogspot.co.at +blogspot.com.au blogspot.ba blogspot.be blogspot.bg blogspot.bj +blogspot.com.br +blogspot.com.by blogspot.ca blogspot.cf blogspot.ch blogspot.cl -blogspot.co.at -blogspot.co.id -blogspot.co.il -blogspot.co.ke -blogspot.co.nz -blogspot.co.uk -blogspot.co.za -blogspot.com -blogspot.com.ar -blogspot.com.au -blogspot.com.br -blogspot.com.by blogspot.com.co -blogspot.com.cy -blogspot.com.ee -blogspot.com.eg -blogspot.com.es -blogspot.com.mt -blogspot.com.ng -blogspot.com.tr -blogspot.com.uy +*.0emm.com +appspot.com +*.r.appspot.com +blogspot.com +codespot.com +googleapis.com +googlecode.com +pagespeedmobilizer.com +withgoogle.com +withyoutube.com blogspot.cv +blogspot.com.cy blogspot.cz blogspot.de +*.gateway.dev blogspot.dk +blogspot.com.ee +blogspot.com.eg +blogspot.com.es blogspot.fi blogspot.fr +cloud.goog +translate.goog +*.usercontent.goog blogspot.gr blogspot.hk blogspot.hr blogspot.hu +blogspot.co.id blogspot.ie +blogspot.co.il blogspot.in blogspot.is blogspot.it blogspot.jp +blogspot.co.ke blogspot.kr blogspot.li blogspot.lt blogspot.lu blogspot.md blogspot.mk -blogspot.mr +blogspot.com.mt blogspot.mx blogspot.my +cloudfunctions.net +blogspot.com.ng blogspot.nl blogspot.no +blogspot.co.nz blogspot.pe blogspot.pt blogspot.qa @@ -12439,21 +13627,38 @@ blogspot.si blogspot.sk blogspot.sn blogspot.td +blogspot.com.tr blogspot.tw blogspot.ug +blogspot.co.uk +blogspot.com.uy blogspot.vn +blogspot.co.za // Goupile : https://goupile.fr // Submitted by Niels Martignene goupile.fr +// GOV.UK Pay : https://www.payments.service.gov.uk/ +// Submitted by Richard Baker +pymnt.uk + +// GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ +// Submitted by Tom Whitwell +cloudapps.digital +london.cloudapps.digital + // Government of the Netherlands: https://www.government.nl // Submitted by gov.nl -// Group 53, LLC : https://www.group53.com -// Submitted by Tyler Todd -awsmppl.com +// Grafana Labs: https://grafana.com/ +// Submitted by Platform Engineering +grafana-dev.net + +// GrayJay Web Solutions Inc. : https://grayjaysports.ca +// Submitted by Matt Yamkowy +grayjayleagues.com // GünstigBestellen : https://günstigbestellen.de // Submitted by Furkan Akkoc @@ -12468,10 +13673,13 @@ caa.li ua.rs conf.se -// Handshake : https://handshake.org -// Submitted by Mike Damm -hs.zone -hs.run +// Häkkinen.fi +// Submitted by Eero Häkkinen +häkkinen.fi + +// Harrison Network : https://hrsn.net +// Submitted by William Harrison +hrsn.dev // Hashbang : https://hashbang.sh hashbang.sh @@ -12481,9 +13689,28 @@ hashbang.sh hasura.app hasura-app.io +// Hatena Co., Ltd. : https://hatena.co.jp +// Submitted by Masato Nakamura +hatenablog.com +hatenadiary.com +hateblo.jp +hatenablog.jp +hatenadiary.jp +hatenadiary.org + // Heilbronn University of Applied Sciences - Faculty Informatics (GitLab Pages): https://www.hs-heilbronn.de -// Submitted by Richard Zowalla +// Submitted by Richard Zowalla pages.it.hs-heilbronn.de +pages-research.it.hs-heilbronn.de + +// HeiyuSpace: https://lazycat.cloud +// Submitted by Xia Bin +heiyu.space + +// Helio Networks : https://heliohost.org +// Submitted by Ben Frede +helioho.st +heliohost.us // Hepforge : https://www.hepforge.org // Submitted by David Grellscheid @@ -12494,11 +13721,15 @@ hepforge.org herokuapp.com herokussl.com +// Heyflow : https://www.heyflow.com +// Submitted by Mirko Nitschke +heyflow.page +heyflow.site + // Hibernating Rhinos // Submitted by Oren Eini ravendb.cloud ravendb.community -ravendb.me development.run ravendb.run @@ -12506,6 +13737,12 @@ ravendb.run // Submitted by Krzysztof Wolski homesklep.pl +// Homebase : https://homebase.id/ +// Submitted by Jason Babo +*.kin.one +*.id.pub +*.kin.pub + // Hong Kong Productivity Council: https://www.hkpc.org/ // Submitted by SECaaS Team secaas.hk @@ -12514,46 +13751,66 @@ secaas.hk // Submitted by Danilo De Franco hoplix.shop - // HOSTBIP REGISTRY : https://www.hostbip.com/ // Submitted by Atanunu Igbunuroghene orx.biz biz.gl +biz.ng +co.biz.ng +dl.biz.ng +go.biz.ng +lg.biz.ng +on.biz.ng col.ng firm.ng gen.ng ltd.ng ngo.ng -edu.scot -sch.so +plc.ng + +// HostFly : https://www.ie.ua +// Submitted by Bohdan Dub +ie.ua -// HostyHosting (hostyhosting.com) +// HostyHosting : https://hostyhosting.com hostyhosting.io -// Häkkinen.fi -// Submitted by Eero Häkkinen -häkkinen.fi +// Hugging Face: https://huggingface.co +// Submitted by Eliott Coyac +hf.space +static.hf.space + +// Hypernode B.V. : https://www.hypernode.com/ +// Submitted by Cipriano Groenendal +hypernode.io + +// I-O DATA DEVICE, INC. : http://www.iodata.com/ +// Submitted by Yuji Minagawa +iobb.net + +// i-registry s.r.o. : http://www.i-registry.cz/ +// Submitted by Martin Semrad +co.cz // Ici la Lune : http://www.icilalune.com/ // Submitted by Simon Morvan *.moonscale.io moonscale.net +// iDOT Services Limited : http://www.domain.gr.com +// Submitted by Gavin Brown +gr.com + // iki.fi // Submitted by Hannu Aronsson iki.fi -// iliad italia: https://www.iliad.it +// iliad italia : https://www.iliad.it // Submitted by Marios Makassikis ibxos.it iliadboxos.it -// Impertrix Solutions : -// Submitted by Zhixiang Zhao -impertrixcdn.com -impertrix.com - -// Incsub, LLC: https://incsub.com/ +// Incsub, LLC : https://incsub.com/ // Submitted by Aaron Edwards smushcdn.com wphostedmail.com @@ -12568,10 +13825,10 @@ in-berlin.de in-brb.de in-butter.de in-dsl.de -in-dsl.net -in-dsl.org in-vpn.de +in-dsl.net in-vpn.net +in-dsl.org in-vpn.org // info.at : http://www.info.at/ @@ -12579,7 +13836,7 @@ biz.at info.at // info.cx : http://info.cx -// Submitted by Jacob Slater +// Submitted by June Slater info.cx // Interlegis : http://www.interlegis.leg.br @@ -12616,18 +13873,43 @@ to.leg.br // Submitted by Wolfgang Schwarz pixolino.com -// Internet-Pro, LLP: https://netangels.ru/ +// Internet-Pro, LLP : https://netangels.ru/ // Submitted by Vasiliy Sheredeko na4u.ru +// IONOS SE : https://www.ionos.com/, +// IONOS Group SE: https://www.ionos-group.com/ +// submitted by Henrik Willert +apps-1and1.com +live-website.com +apps-1and1.net +websitebuilder.online +app-ionos.space + // iopsys software solutions AB : https://iopsys.eu/ // Submitted by Roman Azarenko iopsys.se +// IPFS Project : https://ipfs.tech/ +// Submitted by Interplanetary Shipyard +*.dweb.link + // IPiFony Systems, Inc. : https://www.ipifony.com/ // Submitted by Matthew Hardeman ipifony.net +// ir.md : https://nic.ir.md +// Submitted by Ali Soizi +ir.md + +// is-a-good.dev : https://is-a-good.dev +// Submitted by William Harrison +is-a-good.dev + +// is-a.dev : https://is-a.dev +// Submitted by William Harrison +is-a.dev + // IServ GmbH : https://iserv.de // Submitted by Mario Hoberg iservschule.de @@ -12637,16 +13919,10 @@ schulserver.de test-iserv.de iserv.dev -// I-O DATA DEVICE, INC. : http://www.iodata.com/ -// Submitted by Yuji Minagawa -iobb.net - // Jelastic, Inc. : https://jelastic.com/ // Submitted by Ihor Kolodyuk mel.cloudlets.com.au cloud.interhostsolutions.be -users.scale.virtualcloud.com.br -mycloud.by alp1.ae.flow.ch appengine.flow.ch es-1.axarnet.cloud @@ -12668,20 +13944,15 @@ us.reclaim.cloud ch.trendhosting.cloud de.trendhosting.cloud jele.club -amscompute.com -clicketcloud.com dopaas.com -hidora.com paas.hosted-by-previder.com rag-cloud.hosteur.com rag-cloud-ch.hosteur.com jcloud.ik-server.com jcloud-ver-jpc.ik-server.com demo.jelastic.com -kilatiron.com paas.massivegrid.com jed.wafaicloud.com -lon.wafaicloud.com ryd.wafaicloud.com j.scaleforce.com.cy jelastic.dogado.eu @@ -12693,18 +13964,14 @@ mircloud.host paas.beebyte.io sekd1.beebyteapp.io jele.io -cloud-fr1.unispace.io jc.neen.it -cloud.jelastic.open.tim.it jcloud.kz -upaas.kazteleport.kz cloudjiffy.net fra1-de.cloudjiffy.net west1-us.cloudjiffy.net jls-sto1.elastx.net jls-sto2.elastx.net jls-sto3.elastx.net -faststacks.net fr-1.paas.massivegrid.net lon-1.paas.massivegrid.net lon-2.paas.massivegrid.net @@ -12714,11 +13981,9 @@ sg-1.paas.massivegrid.net jelastic.saveincloud.net nordeste-idc.saveincloud.net j.scaleforce.net -jelastic.tsukaeru.net sdscloud.pl unicloud.pl mircloud.ru -jelastic.regruhosting.ru enscaled.sg jele.site jelastic.team @@ -12739,10 +14004,15 @@ myjino.ru // Submitted by Daniel Fariña jotelulu.cloud +// JouwWeb B.V. : https://www.jouwweb.nl +// Submitted by Camilo Sperberg +webadorsite.com +jouwweb.site + // Joyent : https://www.joyent.com/ // Submitted by Brian Bennett -*.triton.zone *.cns.joyent.com +*.triton.zone // JS.ORG : http://dns.js.org // Submitted by Stefan Keim @@ -12753,14 +14023,15 @@ js.org kaas.gg khplay.nl -// Kakao : https://www.kakaocorp.com/ -// Submitted by JaeYoong Lee -ktistory.com - // Kapsi : https://kapsi.fi // Submitted by Tomi Juntunen kapsi.fi +// Katholieke Universiteit Leuven: https://www.kuleuven.be +// Submitted by Abuse KU Leuven +ezproxy.kuleuven.be +kuleuven.cloud + // Keyweb AG : https://www.keyweb.de // Submitted by Martin Dannehl keymachine.de @@ -12778,23 +14049,14 @@ knightpoint.systems // Submitted by Iván Oliva koobin.events -// KUROKU LTD : https://kuroku.ltd/ -// Submitted by DisposaBoy -oya.to - -// Katholieke Universiteit Leuven: https://www.kuleuven.be -// Submitted by Abuse KU Leuven -kuleuven.cloud -ezproxy.kuleuven.be - -// .KRD : http://nic.krd/data/krd/Registration%20Policy.pdf -co.krd -edu.krd - // Krellian Ltd. : https://krellian.com // Submitted by Ben Francis -krellian.net webthings.io +krellian.net + +// KUROKU LTD : https://kuroku.ltd/ +// Submitted by DisposaBoy +oya.to // LCube - Professional hosting e.K. : https://www.lcube-webhosting.de // Submitted by Lars Laehn @@ -12812,6 +14074,14 @@ lpusercontent.com // Submitted by Lelux Admin lelux.site +// libp2p project : https://libp2p.io +// Submitted by Interplanetary Shipyard +libp2p.direct + +// Libre IT Ltd : https://libre.nz +// Submitted by Tomas Maggio +runcontainers.dev + // Lifetime Hosting : https://Lifetime.Hosting/ // Submitted by Mike Fillator co.business @@ -12822,14 +14092,10 @@ co.network co.place co.technology -// Lightmaker Property Manager, Inc. : https://app.lmpm.com/ -// Submitted by Greg Holland -app.lmpm.com - // linkyard ldt: https://www.linkyard.ch/ // Submitted by Mario Siegenthaler -linkyard.cloud linkyard-cloud.ch +linkyard.cloud // Linode : https://linode.com // Submitted by @@ -12842,13 +14108,23 @@ ip.linodeusercontent.com // Submitted by Victor Velchev we.bs +// Listen53 : https://www.l53.net +// Submitted by Gerry Keh +filegear-sg.me +ggff.net + // Localcert : https://localcert.dev // Submitted by Lann Martin *.user.localcert.dev -// localzone.xyz -// Submitted by Kenny Niehage -localzone.xyz +// Lodz University of Technology LODMAN regional domains https://www.man.lodz.pl/dns +// Submitted by Piotr Wilk +lodz.pl +pabianice.pl +plock.pl +sieradz.pl +skierniewice.pl +zgierz.pl // Log'in Line : https://www.loginline.com/ // Submitted by Rémi Mach @@ -12858,14 +14134,14 @@ loginline.io loginline.services loginline.site -// Lokalized : https://lokalized.nl -// Submitted by Noah Taheij -servers.run - // Lõhmus Family, The // Submitted by Heiki Lõhmus lohmus.me +// Lokalized : https://lokalized.nl +// Submitted by Noah Taheij +servers.run + // LubMAN UMCS Sp. z o.o : https://lubman.pl/ // Submitted by Ireneusz Maliszewski krasnik.pl @@ -12884,18 +14160,19 @@ lugs.org.uk // Lukanet Ltd : https://lukanet.com // Submitted by Anton Avramov barsy.bg -barsy.co.uk -barsyonline.co.uk +barsy.club barsycenter.com barsyonline.com -barsy.club barsy.de +barsy.dev barsy.eu +barsy.gr barsy.in barsy.info barsy.io barsy.me barsy.menu +barsyonline.menu barsy.mobi barsy.net barsy.online @@ -12903,42 +14180,50 @@ barsy.org barsy.pro barsy.pub barsy.ro +barsy.rs barsy.shop +barsyonline.shop barsy.site +barsy.store barsy.support barsy.uk +barsy.co.uk +barsyonline.co.uk // Magento Commerce // Submitted by Damien Tournoud *.magentosite.cloud -// May First - People Link : https://mayfirst.org/ -// Submitted by Jamie McClelland -mayfirst.info -mayfirst.org - // Mail.Ru Group : https://hb.cldmail.ru // Submitted by Ilya Zaretskiy hb.cldmail.ru -// Mail Transfer Platform : https://www.neupeer.com -// Submitted by Li Hui -cn.vu +// MathWorks : https://www.mathworks.com/ +// Submitted by Emily Reed +matlab.cloud +modelscape.com +mwcloudnonprod.com +polyspace.com + +// May First - People Link : https://mayfirst.org/ +// Submitted by Jamie McClelland +mayfirst.info +mayfirst.org // Maze Play: https://www.mazeplay.com // Submitted by Adam Humpherys mazeplay.com -// mcpe.me : https://mcpe.me -// Submitted by Noa Heyl -mcpe.me - // McHost : https://mchost.ru // Submitted by Evgeniy Subbotin mcdir.me mcdir.ru -mcpre.ru vps.mcdir.ru +mcpre.ru + +// mcpe.me : https://mcpe.me +// Submitted by Noa Heyl +mcpe.me // Mediatech : https://mediatech.by // Submitted by Evgeniy Kozhuhovskiy @@ -12949,6 +14234,10 @@ mediatech.dev // Submitted by Michael Olson hra.health +// MedusaJS, Inc : https://medusajs.com/ +// Submitted by Stevche Radevski +medusajs.app + // Memset hosting : https://www.memset.com // Submitted by Tom Whitwell miniserver.com @@ -12958,13 +14247,15 @@ memset.net // Submitted by Ruben Schmidmeister messerli.app +// Meta Platforms, Inc. : https://meta.com/ +// Submitted by Jacob Cordero +atmeta.com +apps.fbsbx.com + // MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ -// Submitted by Zdeněk Šustr +// Submitted by Zdeněk Šustr and Radim Janča *.cloud.metacentrum.cz custom.metacentrum.cz - -// MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ -// Submitted by Radim Janča flt.cloud.muni.cz usr.cloud.muni.cz @@ -12978,35 +14269,55 @@ co.pl // Microsoft Corporation : http://microsoft.com // Submitted by Public Suffix List Admin +// Managed by Corporate Domains +// Microsoft Azure : https://home.azure *.azurecontainer.io -azurewebsites.net +azure-api.net azure-mobile.net -cloudapp.net +azureedge.net +azurefd.net azurestaticapps.net 1.azurestaticapps.net 2.azurestaticapps.net 3.azurestaticapps.net +4.azurestaticapps.net +5.azurestaticapps.net +6.azurestaticapps.net +7.azurestaticapps.net centralus.azurestaticapps.net eastasia.azurestaticapps.net eastus2.azurestaticapps.net westeurope.azurestaticapps.net westus2.azurestaticapps.net +azurewebsites.net +cloudapp.net +trafficmanager.net +blob.core.windows.net +servicebus.windows.net + +// MikroTik: https://mikrotik.com +// Submitted by MikroTik SysAdmin Team +routingthecloud.com +sn.mynetname.net +routingthecloud.net +routingthecloud.org // minion.systems : http://minion.systems // Submitted by Robert Böttinger csx.cc -// Mintere : https://mintere.com/ -// Submitted by Ben Aubin -mintere.site +// Mittwald CM Service GmbH & Co. KG : https://mittwald.de +// Submitted by Marco Rieger +mydbserver.com +webspaceconfig.de +mittwald.info +mittwaldserver.info +typo3server.info +project.space -// MobileEducation, LLC : https://joinforte.com -// Submitted by Grayson Martin -forte.id - -// Mozilla Corporation : https://mozilla.com -// Submitted by Ben Francis -mozilla-iot.org +// MODX Systems LLC : https://modx.com +// Submitted by Elizabeth Southwell +modx.dev // Mozilla Foundation : https://mozilla.org/ // Submitted by glob @@ -13021,8 +14332,8 @@ pp.ru // Mythic Beasts : https://www.mythic-beasts.com // Submitted by Paul Cammish hostedpi.com -customer.mythic-beasts.com caracal.mythic-beasts.com +customer.mythic-beasts.com fentiger.mythic-beasts.com lynx.mythic-beasts.com ocelot.mythic-beasts.com @@ -13042,6 +14353,10 @@ ui.nabu.casa // Submitted by Jan Jaeschke cloud.nospamproxy.com +// Netfy Domains : https://netfy.domains +// Submitted by Suranga Ranasinghe +netfy.app + // Netlify : https://www.netlify.com // Submitted by Jessica Parsons netlify.app @@ -13050,17 +14365,134 @@ netlify.app // Submitted by Trung Tran 4u.com +// NFSN, Inc. : https://www.NearlyFreeSpeech.NET/ +// Submitted by Jeff Wheelhouse +nfshost.com + +// NFT.Storage : https://nft.storage/ +// Submitted by Vasco Santos or +ipfs.nftstorage.link + +// NGO.US Registry : https://nic.ngo.us +// Submitted by Alstra Solutions Ltd. Networking Team +ngo.us + // ngrok : https://ngrok.com/ // Submitted by Alan Shreve +ngrok.app +ngrok-free.app +ngrok.dev +ngrok-free.dev ngrok.io +ap.ngrok.io +au.ngrok.io +eu.ngrok.io +in.ngrok.io +jp.ngrok.io +sa.ngrok.io +us.ngrok.io +ngrok.pizza +ngrok.pro + +// Nicolaus Copernicus University in Torun - MSK TORMAN (https://www.man.torun.pl) +torun.pl // Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/ -// Submitted by Nicholas Ford +// Submitted by Nicholas Ford nh-serv.co.uk +nimsite.uk -// NFSN, Inc. : https://www.NearlyFreeSpeech.NET/ -// Submitted by Jeff Wheelhouse -nfshost.com +// No-IP.com : https://noip.com/ +// Submitted by Deven Reza +mmafan.biz +myftp.biz +no-ip.biz +no-ip.ca +fantasyleague.cc +gotdns.ch +3utilities.com +blogsyte.com +ciscofreak.com +damnserver.com +ddnsking.com +ditchyourip.com +dnsiskinky.com +dynns.com +geekgalaxy.com +health-carereform.com +homesecuritymac.com +homesecuritypc.com +myactivedirectory.com +mysecuritycamera.com +myvnc.com +net-freaks.com +onthewifi.com +point2this.com +quicksytes.com +securitytactics.com +servebeer.com +servecounterstrike.com +serveexchange.com +serveftp.com +servegame.com +servehalflife.com +servehttp.com +servehumour.com +serveirc.com +servemp3.com +servep2p.com +servepics.com +servequake.com +servesarcasm.com +stufftoread.com +unusualperson.com +workisboring.com +dvrcam.info +ilovecollege.info +no-ip.info +brasilia.me +ddns.me +dnsfor.me +hopto.me +loginto.me +noip.me +webhop.me +bounceme.net +ddns.net +eating-organic.net +mydissent.net +myeffect.net +mymediapc.net +mypsx.net +mysecuritycamera.net +nhlfan.net +no-ip.net +pgafan.net +privatizehealthinsurance.net +redirectme.net +serveblog.net +serveminecraft.net +sytes.net +cable-modem.org +collegefan.org +couchpotatofries.org +hopto.org +mlbfan.org +myftp.org +mysecuritycamera.org +nflfan.org +no-ip.org +read-books.org +ufcfan.org +zapto.org +no-ip.co.uk +golffan.us +noip.us +pointto.us + +// NodeArt : https://nodeart.io +// Submitted by Konstantin Nosov +stage.nodeart.io // Noop : https://noop.app // Submitted by Nathaniel Schweinberg @@ -13079,18 +14511,18 @@ noop.app // Submitted by Laurent Pellegrino noticeable.news +// Notion Labs, Inc : https://www.notion.so/ +// Submitted by Jess Yao +notion.site + // Now-DNS : https://now-dns.com // Submitted by Steve Russell dnsking.ch mypi.co n4t.co 001www.com -ddnslive.com myiphost.com forumz.info -16-b.it -32-b.it -64-b.it soundcast.me tcp4.me dnsup.net @@ -13104,123 +14536,30 @@ x443.pw now-dns.top ntdll.top freeddns.us -crafting.xyz -zapto.xyz // nsupdate.info : https://www.nsupdate.info/ // Submitted by Thomas Waldmann nsupdate.info nerdpol.ovh -// No-IP.com : https://noip.com/ -// Submitted by Deven Reza -blogsyte.com -brasilia.me -cable-modem.org -ciscofreak.com -collegefan.org -couchpotatofries.org -damnserver.com -ddns.me -ditchyourip.com -dnsfor.me -dnsiskinky.com -dvrcam.info -dynns.com -eating-organic.net -fantasyleague.cc -geekgalaxy.com -golffan.us -health-carereform.com -homesecuritymac.com -homesecuritypc.com -hopto.me -ilovecollege.info -loginto.me -mlbfan.org -mmafan.biz -myactivedirectory.com -mydissent.net -myeffect.net -mymediapc.net -mypsx.net -mysecuritycamera.com -mysecuritycamera.net -mysecuritycamera.org -net-freaks.com -nflfan.org -nhlfan.net -no-ip.ca -no-ip.co.uk -no-ip.net -noip.us -onthewifi.com -pgafan.net -point2this.com -pointto.us -privatizehealthinsurance.net -quicksytes.com -read-books.org -securitytactics.com -serveexchange.com -servehumour.com -servep2p.com -servesarcasm.com -stufftoread.com -ufcfan.org -unusualperson.com -workisboring.com -3utilities.com -bounceme.net -ddns.net -ddnsking.com -gotdns.ch -hopto.org -myftp.biz -myftp.org -myvnc.com -no-ip.biz -no-ip.info -no-ip.org -noip.me -redirectme.net -servebeer.com -serveblog.net -servecounterstrike.com -serveftp.com -servegame.com -servehalflife.com -servehttp.com -serveirc.com -serveminecraft.net -servemp3.com -servepics.com -servequake.com -sytes.net -webhop.me -zapto.org - -// NodeArt : https://nodeart.io -// Submitted by Konstantin Nosov -stage.nodeart.io +// NYC.mn : https://dot.nyc.mn/ +// Submitted by NYC.mn Subdomain Service +nyc.mn -// Nucleos Inc. : https://nucleos.com -// Submitted by Piotr Zduniak -pcloud.host +// O3O.Foundation : https://o3o.foundation/ +// Submitted by the prvcy.page Registry Team +prvcy.page -// NYC.mn : http://www.information.nyc.mn -// Submitted by Matthew Brown -nyc.mn +// Obl.ong : +// Submitted by Reese Armstrong +obl.ong // Observable, Inc. : https://observablehq.com // Submitted by Mike Bostock +observablehq.cloud static.observableusercontent.com -// Octopodal Solutions, LLC. : https://ulterius.io/ -// Submitted by Andrew Sampson -cya.gg - -// OMG.LOL : +// OMG.LOL : https://omg.lol // Submitted by Adam Newbold omg.lol @@ -13234,30 +14573,33 @@ omniwe.site // One.com: https://www.one.com/ // Submitted by Jacob Bunk Nielsen -123hjemmeside.dk -123hjemmeside.no -123homepage.it -123kotisivu.fi -123minsida.se -123miweb.es -123paginaweb.pt -123sait.ru -123siteweb.fr 123webseite.at -123webseite.de 123website.be +simplesite.com.br 123website.ch +simplesite.com +123webseite.de +123hjemmeside.dk +123miweb.es +123kotisivu.fi +123siteweb.fr +simplesite.gr +123homepage.it 123website.lu 123website.nl +123hjemmeside.no service.one -simplesite.com -simplesite.com.br -simplesite.gr simplesite.pl +123paginaweb.pt +123minsida.se -// One Fold Media : http://www.onefoldmedia.com/ -// Submitted by Eddie Jones -nid.io +// Open Domains : https://open-domains.net +// Submitted by William Harrison +is-a-fullstack.dev +is-cool.dev +is-not-a.dev +localplayer.dev +is-local.org // Open Social : https://www.getopensocial.com/ // Submitted by Alexander Varwijk @@ -13267,6 +14609,12 @@ opensocial.site // Submitted by Sven Marnach opencraft.hosting +// OpenHost : https://registry.openhost.uk +// Submitted by OpenHost Registry Team +16-b.it +32-b.it +64-b.it + // OpenResearch GmbH: https://openresearch.com/ // Submitted by Philipp Schmid orsites.com @@ -13275,10 +14623,26 @@ orsites.com // Submitted by Yngve Pettersen operaunite.com +// Oracle Dyn : https://cloud.oracle.com/home https://dyn.com/dns/ +// Submitted by Gregory Drake +// Note: This is intended to also include customer-oci.com due to wildcards implicitly including the current label +*.customer-oci.com +*.oci.customer-oci.com +*.ocp.customer-oci.com +*.ocs.customer-oci.com +*.oraclecloudapps.com +*.oraclegovcloudapps.com +*.oraclegovcloudapps.uk + // Orange : https://www.orange.com // Submitted by Alexandre Linte tech.orange +// OsSav Technology Ltd. : https://ossav.com/ +// TLD Nic: http://nic.can.re - TLD Whois Server: whois.can.re +// Submitted by OsSav Technology Ltd. +can.re + // Oursky Limited : https://authgear.com/, https://skygear.io/ // Submitted by Authgear Team , Skygear Developer authgear-staging.com @@ -13291,8 +14655,8 @@ outsystemscloud.com // OVHcloud: https://ovhcloud.com // Submitted by Vincent Cassé -*.webpaas.ovh.net *.hosting.ovh.net +*.webpaas.ovh.net // OwnProvider GmbH: http://www.ownprovider.com // Submitted by Jan Moennich @@ -13315,37 +14679,31 @@ oy.lc // Submitted by Derek Myers pgfog.com -// Pagefront : https://www.pagefronthq.com/ -// Submitted by Jason Kriss -pagefrontapp.com - // PageXL : https://pagexl.com // Submitted by Yann Guichard pagexl.com +// Pantheon Systems, Inc. : https://pantheon.io/ +// Submitted by Gary Dylina +gotpantheon.com +pantheonsite.io + // Paywhirl, Inc : https://paywhirl.com/ // Submitted by Daniel Netzer *.paywhirl.com // pcarrier.ca Software Inc: https://pcarrier.ca/ // Submitted by Pierre Carrier -bar0.net -bar1.net -bar2.net -rdv.to - -// .pl domains (grandfathered) -art.pl -gliwice.pl -krakow.pl -poznan.pl -wroc.pl -zakopane.pl +*.xmit.co +xmit.dev +madethis.site +srv.us +gh.srv.us +gl.srv.us -// Pantheon Systems, Inc. : https://pantheon.io/ -// Submitted by Gary Dylina -pantheonsite.io -gotpantheon.com +// PE Ulyanov Kirill Sergeevich : https://airy.host +// Submitted by Kirill Ulyanov +lk3.ru // Peplink | Pepwave : http://peplink.com/ // Submitted by Steve Leung @@ -13355,17 +14713,14 @@ mypep.link // Submitted by Kenneth Van Alstyne perspecta.cloud -// PE Ulyanov Kirill Sergeevich : https://airy.host -// Submitted by Kirill Ulyanov -lk3.ru - // Planet-Work : https://www.planet-work.com/ // Submitted by Frédéric VANNIÈRE on-web.fr // Platform.sh : https://platform.sh // Submitted by Nikola Kotur -bc.platform.sh +*.upsun.app +upsunapp.com ent.platform.sh eu.platform.sh us.platform.sh @@ -13378,15 +14733,9 @@ platter-app.com platter-app.dev platterp.us -// Plesk : https://www.plesk.com/ -// Submitted by Anton Akhtyamov -pdns.page -plesk.page -pleskns.com - -// Port53 : https://port53.io/ -// Submitted by Maximilian Schieder -dyn53.io +// Pley AB : https://www.pley.com/ +// Submitted by Henning Pohl +pley.games // Porter : https://porter.run/ // Submitted by Rudraksh MK @@ -13403,8 +14752,8 @@ pstmn.io mock.pstmn.io httpbin.org -//prequalifyme.today : https://prequalifyme.today -//Submitted by DeepakTiwari deepak@ivylead.io +// prequalifyme.today : https://prequalifyme.today +// Submitted by DeepakTiwari deepak@ivylead.io prequalifyme.today // prgmr.com : https://prgmr.com/ @@ -13415,14 +14764,6 @@ xen.prgmr.com // Submitted by registry priv.at -// privacytools.io : https://www.privacytools.io/ -// Submitted by Jonah Aragon -prvcy.page - -// Protocol Labs : https://protocol.ai/ -// Submitted by Michael Burns -*.dweb.link - // Protonet GmbH : http://protonet.io // Submitted by Martin Meier protonet.io @@ -13441,34 +14782,6 @@ pubtls.org pythonanywhere.com eu.pythonanywhere.com -// QOTO, Org. -// Submitted by Jeffrey Phillips Freeman -qoto.io - -// Qualifio : https://qualifio.com/ -// Submitted by Xavier De Cock -qualifioapp.com - -// QuickBackend: https://www.quickbackend.com -// Submitted by Dani Biro -qbuser.com - -// Rad Web Hosting: https://radwebhosting.com -// Submitted by Scott Claeys -cloudsite.builders - -// Redgate Software: https://red-gate.com -// Submitted by Andrew Farries -instances.spawn.cc - -// Redstar Consultants : https://www.redstarconsultants.com/ -// Submitted by Jons Slemmer -instantcloud.cn - -// Russian Academy of Sciences -// Submitted by Tech Support -ras.ru - // QA2 // Submitted by Daniel Dent (https://www.danieldent.com/) qa2.com @@ -13479,11 +14792,30 @@ qcx.io *.sys.qcx.io // QNAP System Inc : https://www.qnap.com -// Submitted by Nick Chang -dev-myqnapcloud.com +// Submitted by Nick Chang +myqnapcloud.cn alpha-myqnapcloud.com +dev-myqnapcloud.com +mycloudnas.com +mynascloud.com myqnapcloud.com +// QOTO, Org. +// Submitted by Jeffrey Phillips Freeman +qoto.io + +// Qualifio : https://qualifio.com/ +// Submitted by Xavier De Cock +qualifioapp.com + +// Quality Unit : https://qualityunit.com +// Submitted by Vasyl Tsalko +ladesk.com + +// QuickBackend: https://www.quickbackend.com +// Submitted by Dani Biro +qbuser.com + // Quip : https://quip.com // Submitted by Patrick Linehan *.quipelements.com @@ -13498,35 +14830,85 @@ vaporcloud.io rackmaze.com rackmaze.net -// Rakuten Games, Inc : https://dev.viberplay.io -// Submitted by Joshua Zhang -g.vbrplsbx.io +// Rad Web Hosting: https://radwebhosting.com +// Submitted by Scott Claeys +cloudsite.builders +myradweb.net +servername.us + +// Radix FZC : http://domains.in.net +// Submitted by Gavin Brown +web.in +in.net + +// Raidboxes GmbH : https://raidboxes.de +// Submitted by Auke Tembrink +myrdbx.io +site.rb-hosting.io // Rancher Labs, Inc : https://rancher.com // Submitted by Vincent Fiduccia -*.on-k3s.io *.on-rancher.cloud +*.on-k3s.io *.on-rio.io +// RavPage : https://www.ravpage.co.il +// Submitted by Roni Horowitz +ravpage.co.il + // Read The Docs, Inc : https://www.readthedocs.org // Submitted by David Fischer +readthedocs-hosted.com readthedocs.io // Red Hat, Inc. OpenShift : https://openshift.redhat.com/ // Submitted by Tim Kramer rhcloud.com +// Redgate Software: https://red-gate.com +// Submitted by Andrew Farries +instances.spawn.cc + // Render : https://render.com // Submitted by Anurag Goel -app.render.com onrender.com +app.render.com // Repl.it : https://repl.it -// Submitted by Lincoln Bergeson +// Submitted by Lincoln Bergeson +replit.app +id.replit.app firewalledreplit.co id.firewalledreplit.co repl.co id.repl.co +replit.dev +archer.replit.dev +bones.replit.dev +canary.replit.dev +global.replit.dev +hacker.replit.dev +id.replit.dev +janeway.replit.dev +kim.replit.dev +kira.replit.dev +kirk.replit.dev +odo.replit.dev +paris.replit.dev +picard.replit.dev +pike.replit.dev +prerelease.replit.dev +reed.replit.dev +riker.replit.dev +sisko.replit.dev +spock.replit.dev +staging.replit.dev +sulu.replit.dev +tarpit.replit.dev +teams.replit.dev +tucker.replit.dev +wesley.replit.dev +worf.replit.dev repl.run // Resin.io : https://resin.io @@ -13538,11 +14920,6 @@ devices.resinstaging.io // Submitted by Chris Kastorff hzc.io -// Revitalised Limited : http://www.revitalised.co.uk -// Submitted by Jack Price -wellbeingzone.eu -wellbeingzone.co.uk - // Rico Developments Limited : https://adimo.co // Submitted by Colin Brown adimo.co.uk @@ -13551,6 +14928,11 @@ adimo.co.uk // Submitted by Micah Anderson itcouldbewor.se +// Roar Domains LLC : https://roar.basketball/ +// Submitted by Gavin Brown +aus.basketball +nz.basketball + // Rochester Institute of Technology : http://www.rit.edu/ // Submitted by Jennifer Herting git-pages.rit.edu @@ -13572,11 +14954,78 @@ rocky.page спб.рус я.рус +// Russian Academy of Sciences +// Submitted by Tech Support +ras.ru + +// Sakura Frp : https://www.natfrp.com +// Submitted by Bobo Liu +nyat.app + +// SAKURA Internet Inc. : https://www.sakura.ad.jp/ +// Submitted by Internet Service Department +180r.com +dojin.com +sakuratan.com +sakuraweb.com +x0.com +2-d.jp +bona.jp +crap.jp +daynight.jp +eek.jp +flop.jp +halfmoon.jp +jeez.jp +matrix.jp +mimoza.jp +ivory.ne.jp +mail-box.ne.jp +mints.ne.jp +mokuren.ne.jp +opal.ne.jp +sakura.ne.jp +sumomo.ne.jp +topaz.ne.jp +netgamers.jp +nyanta.jp +o0o0.jp +rdy.jp +rgr.jp +rulez.jp +s3.isk01.sakurastorage.jp +s3.isk02.sakurastorage.jp +saloon.jp +sblo.jp +skr.jp +tank.jp +uh-oh.jp +undo.jp +rs.webaccel.jp +user.webaccel.jp +websozai.jp +xii.jp +squares.net +jpn.org +kirara.st +x0.to +from.tv +sakura.tv + // Salesforce.com, Inc. https://salesforce.com/ -// Submitted by Michael Biven +// Submitted by Salesforce Public Suffix List Team *.builder.code.com *.dev-builder.code.com *.stg-builder.code.com +*.001.test.code-builder-stg.platform.salesforce.com +*.d.crm.dev +*.w.crm.dev +*.wa.crm.dev +*.wb.crm.dev +*.wc.crm.dev +*.wd.crm.dev +*.we.crm.dev +*.wf.crm.dev // Sandstorm Development Group, Inc. : https://sandcats.io/ // Submitted by Asheesh Laroia @@ -13584,14 +15033,15 @@ sandcats.io // SBE network solutions GmbH : https://www.sbe.de/ // Submitted by Norman Meilick -logoip.de logoip.com +logoip.de // Scaleway : https://www.scaleway.com/ // Submitted by Rémy Léone fr-par-1.baremetal.scw.cloud fr-par-2.baremetal.scw.cloud nl-ams-1.baremetal.scw.cloud +cockpit.fr-par.scw.cloud fnc.fr-par.scw.cloud functions.fnc.fr-par.scw.cloud k8s.fr-par.scw.cloud @@ -13602,11 +15052,13 @@ whm.fr-par.scw.cloud priv.instances.scw.cloud pub.instances.scw.cloud k8s.scw.cloud +cockpit.nl-ams.scw.cloud k8s.nl-ams.scw.cloud nodes.k8s.nl-ams.scw.cloud s3.nl-ams.scw.cloud s3-website.nl-ams.scw.cloud whm.nl-ams.scw.cloud +cockpit.pl-waw.scw.cloud k8s.pl-waw.scw.cloud nodes.k8s.pl-waw.scw.cloud s3.pl-waw.scw.cloud @@ -13628,6 +15080,10 @@ service.gov.scot // Submitted by Shante Adam scrysec.com +// Scrypted : https://scrypted.app +// Submitted by Koushik Dutta +client.scrypted.io + // Securepoint GmbH : https://www.securepoint.de // Submitted by Erik Anders firewall-gateway.com @@ -13649,17 +15105,17 @@ seidat.net // Submitted by Yuriy Romadin sellfy.store -// Senseering GmbH : https://www.senseering.de -// Submitted by Felix Mönckemeyer -senseering.net - // Sendmsg: https://www.sendmsg.co.il // Submitted by Assaf Stern minisite.ms -// Service Magnet : https://myservicemagnet.com -// Submitted by Dave Sanders -magnet.page +// Senseering GmbH : https://www.senseering.de +// Submitted by Felix Mönckemeyer +senseering.net + +// Servebolt AS: https://servebolt.com +// Submitted by Daniel Kjeserud +servebolt.cloud // Service Online LLC : http://drs.ua/ // Submitted by Serhii Bulakh @@ -13667,10 +15123,13 @@ biz.ua co.ua pp.ua -// Shift Crypto AG : https://shiftcrypto.ch -// Submitted by alex -shiftcrypto.dev -shiftcrypto.io +// Shanghai Accounting Society : https://www.sasf.org.cn +// Submitted by Information Administration +as.sh.cn + +// Sheezy.Art : https://sheezy.art +// Submitted by Nyoom +sheezy.games // ShiftEdit : https://shiftedit.net/ // Submitted by Adam Jimenez @@ -13690,6 +15149,7 @@ shopitsite.com // shopware AG : https://shopware.com // Submitted by Jens Küper +shopware.shop shopware.store // Siemens Mobility GmbH @@ -13708,24 +15168,32 @@ vipsinaapp.com // Submitted by Skylar Challand siteleaf.net -// Skyhat : http://www.skyhat.io -// Submitted by Shante Adam -bounty-full.com -alpha.bounty-full.com -beta.bounty-full.com - // Small Technology Foundation : https://small-tech.org // Submitted by Aral Balkan small-web.org +// Smallregistry by Promopixel SARL: https://www.smallregistry.net +// Former AFNIC's SLDs +// Submitted by Jérôme Lipowicz +aeroport.fr +avocat.fr +chambagri.fr +chirurgiens-dentistes.fr +experts-comptables.fr +medecin.fr +notaires.fr +pharmacien.fr +port.fr +veterinaire.fr + // Smoove.io : https://www.smoove.io/ // Submitted by Dan Kozak vp4.me // Snowflake Inc : https://www.snowflake.com/ -// Submitted by Faith Olapade -snowflake.app -privatelink.snowflake.app +// Submitted by Sam Haar +*.snowflake.app +*.privatelink.snowflake.app streamlit.app streamlitapp.com @@ -13733,41 +15201,18 @@ streamlitapp.com // Submitted by Ian Streeter try-snowplow.com -// SourceHut : https://sourcehut.org -// Submitted by Drew DeVault -srht.site - -// Stackhero : https://www.stackhero.io -// Submitted by Adrien Gillon -stackhero-network.com - -// Staclar : https://staclar.com -// Submitted by Q Misell -musician.io -// Submitted by Matthias Merkel -novecore.site - -// staticland : https://static.land -// Submitted by Seth Vincent -static.land -dev.static.land -sites.static.land - -// Storebase : https://www.storebase.io -// Submitted by Tony Schirmer -storebase.store - -// Strategic System Consulting (eApps Hosting): https://www.eapps.com/ -// Submitted by Alex Oancea -vps-host.net -atl.jelastic.vps-host.net -njs.jelastic.vps-host.net -ric.jelastic.vps-host.net +// Software Consulting Michal Zalewski : https://www.mafelo.com +// Submitted by Michal Zalewski +mafelo.net // Sony Interactive Entertainment LLC : https://sie.com/ // Submitted by David Coles playstation-cloud.com +// SourceHut : https://sourcehut.org +// Submitted by Drew DeVault +srht.site + // SourceLair PC : https://www.sourcelair.com // Submitted by Antonis Kalipetis apps.lair.io @@ -13777,6 +15222,10 @@ apps.lair.io // Submitted by Reza Akhavan spacekit.io +// SparrowHost : https://sparrowhost.in/ +// Submitted by Anant Pandey +ind.mom + // SpeedPartner GmbH: https://www.speedpartner.de/ // Submitted by Stefan Neufeind customer.speedpartner.de @@ -13803,23 +15252,86 @@ myspreadshop.pl myspreadshop.se myspreadshop.co.uk +// StackBlitz : https://stackblitz.com +// Submitted by Dominic Elm +w-corp-staticblitz.com +w-credentialless-staticblitz.com +w-staticblitz.com + +// Stackhero : https://www.stackhero.io +// Submitted by Adrien Gillon +stackhero-network.com + +// STACKIT GmbH & Co. KG : https://www.stackit.de/en/ +// Submitted by STACKIT-DNS Team (Simon Stier) +runs.onstackit.cloud +stackit.gg +stackit.rocks +stackit.run +stackit.zone + +// Staclar : https://staclar.com +// Submitted by Q Misell +// Submitted by Matthias Merkel +musician.io +novecore.site + // Standard Library : https://stdlib.com // Submitted by Jacob Lee api.stdlib.com +// stereosense GmbH : https://www.involve.me +// Submitted by Florian Burmann +feedback.ac +forms.ac +assessments.cx +calculators.cx +funnels.cx +paynow.cx +quizzes.cx +researched.cx +tests.cx +surveys.so + +// Storebase : https://www.storebase.io +// Submitted by Tony Schirmer +storebase.store + +// Storipress : https://storipress.com +// Submitted by Benno Liu +storipress.app + // Storj Labs Inc. : https://storj.io/ // Submitted by Philip Hutchins storj.farm -// Studenten Net Twente : http://www.snt.utwente.nl/ -// Submitted by Silke Hofstra -utwente.io +// Strapi : https://strapi.io/ +// Submitted by Florent Baldino +strapiapp.com +media.strapiapp.com + +// Strategic System Consulting (eApps Hosting): https://www.eapps.com/ +// Submitted by Alex Oancea +vps-host.net +atl.jelastic.vps-host.net +njs.jelastic.vps-host.net +ric.jelastic.vps-host.net + +// Streak : https://streak.com +// Submitted by Blake Kadatz +streak-link.com +streaklinks.com +streakusercontent.com // Student-Run Computing Facility : https://www.srcf.net/ // Submitted by Edwin Balani soc.srcf.net user.srcf.net +// Studenten Net Twente : http://www.snt.utwente.nl/ +// Submitted by Silke Hofstra +utwente.io + // Sub 6 Limited: http://www.sub6.com // Submitted by Dan Miller temp-dns.com @@ -13829,12 +15341,6 @@ temp-dns.com supabase.co supabase.in supabase.net -su.paba.se - -// Symfony, SAS : https://symfony.com/ -// Submitted by Fabien Potencier -*.s5y.io -*.sensiosite.cloud // Syncloud : https://syncloud.org // Submitted by Boris Rybalkin @@ -13856,31 +15362,40 @@ dsmynas.net familyds.net dsmynas.org familyds.org -vpnplus.to direct.quickconnect.to +vpnplus.to // Tabit Technologies Ltd. : https://tabit.cloud/ // Submitted by Oren Agiv -tabitorder.co.il -mytabit.co.il mytabit.com +mytabit.co.il +tabitorder.co.il // TAIFUN Software AG : http://taifun-software.de // Submitted by Bjoern Henke taifun-dns.de // Tailscale Inc. : https://www.tailscale.com -// Submitted by David Anderson -beta.tailscale.net +// Submitted by David Anderson ts.net +*.c.ts.net -// TASK geographical domains (www.task.gda.pl/uslugi/dns) +// TASK geographical domains (https://www.task.gda.pl/uslugi/dns) gda.pl gdansk.pl gdynia.pl med.pl sopot.pl +// Tave Creative Corp : https://tave.com/ +// Submitted by Adrian Ziemkowski +taveusercontent.com + +// tawk.to, Inc : https://www.tawk.to +// Submitted by tawk.to developer team +p.tawk.email +p.tawkto.email + // team.blue https://team.blue // Submitted by Cedric Dubois site.tb-hosting.com @@ -13903,11 +15418,11 @@ telebit.io reservd.com thingdustdata.com cust.dev.thingdust.io +reservd.dev.thingdust.io cust.disrec.thingdust.io +reservd.disrec.thingdust.io cust.prod.thingdust.io cust.testing.thingdust.io -reservd.dev.thingdust.io -reservd.disrec.thingdust.io reservd.testing.thingdust.io // ticket i/O GmbH : https://ticket.io @@ -13921,13 +15436,12 @@ azimuth.network tlon.network // Tor Project, Inc. : https://torproject.org -// Submitted by Antoine Beaupré torproject.net pages.torproject.net // TownNews.com : http://www.townnews.com // Submitted by Dustin Ward -bloxcms.com townnews-staging.com // TrafficPlex GmbH : https://www.trafficplex.de/ @@ -13953,14 +15467,11 @@ webspace.rocks lima.zone // TransIP : https://www.transip.nl -// Submitted by Rory Breuk +// Submitted by Rory Breuk and Cedric Dubois *.transurl.be *.transurl.eu -*.transurl.nl - -// TransIP: https://www.transip.nl -// Submitted by Cedric Dubois site.transip.me +*.transurl.nl // TuxFamily : http://tuxfamily.org // Submitted by TuxFamily administrators @@ -13969,8 +15480,6 @@ tuxfamily.org // TwoDNS : https://www.twodns.de/ // Submitted by TwoDNS-Support dd-dns.de -diskstation.eu -diskstation.org dray-dns.de draydns.de dyn-vpn.de @@ -13981,6 +15490,8 @@ my-wan.de syno-ds.de synology-diskstation.de synology-ds.de +diskstation.eu +diskstation.org // Typedream : https://typedream.com // Submitted by Putri Karunia @@ -13992,20 +15503,29 @@ pro.typeform.com // Uberspace : https://uberspace.de // Submitted by Moritz Werner -uber.space *.uberspace.de +uber.space // UDR Limited : http://www.udr.hk.com // Submitted by registry hk.com -hk.org -ltd.hk inc.hk +ltd.hk +hk.org // UK Intis Telecom LTD : https://it.com // Submitted by ITComdomains it.com +// Unison Computing, PBC : https://unison.cloud +// Submitted by Simon Højberg +unison-services.cloud + +// United Gameserver GmbH : https://united-gameserver.de +// Submitted by Stefan Schwarz +virtual-user.de +virtualuser.de + // UNIVERSAL DOMAIN REGISTRY : https://www.udr.org.yt/ // see also: whois -h whois.udr.org.yt help // Submitted by Atanunu Igbunuroghene @@ -14015,10 +15535,14 @@ biz.wf sch.wf org.yt -// United Gameserver GmbH : https://united-gameserver.de -// Submitted by Stefan Schwarz -virtualuser.de -virtual-user.de +// University of Banja Luka : https://unibl.org +// Domains for Republic of Srpska administrative entity. +// Submitted by Marko Ivanovic +rs.ba + +// University of Bielsko-Biala regional domain: http://dns.bielsko.pl/ +// Submitted by Marcin +bielsko.pl // Upli : https://upli.io // Submitted by Lenny Bakkalian @@ -14029,20 +15553,31 @@ upli.io urown.cloud dnsupdate.info -// .US -// Submitted by Ed Moore -lib.de.us +// US REGISTRY LLC : http://us.org +// Submitted by Gavin Brown +us.org -// VeryPositive SIA : http://very.lv -// Submitted by Danko Aleksejevs -2038.io +// V.UA Domain Administrator : https://domain.v.ua/ +// Submitted by Serhii Rostilo +v.ua + +// Val Town, Inc : https://val.town/ +// Submitted by Tom MacWright +express.val.run +web.val.run // Vercel, Inc : https://vercel.com/ -// Submitted by Connor Davis +// Submitted by Max Leiter vercel.app +v0.build vercel.dev +vusercontent.net now.sh +// VeryPositive SIA : http://very.lv +// Submitted by Danko Aleksejevs +2038.io + // Viprinet Europe GmbH : http://www.viprinet.com // Submitted by Simon Kissel router.management @@ -14055,52 +15590,6 @@ v-info.info // Submitted by Nathan van Bakel voorloper.cloud -// Voxel.sh DNS : https://voxel.sh/dns/ -// Submitted by Mia Rehlinger -neko.am -nyaa.am -be.ax -cat.ax -es.ax -eu.ax -gg.ax -mc.ax -us.ax -xy.ax -nl.ci -xx.gl -app.gp -blog.gt -de.gt -to.gt -be.gy -cc.hn -blog.kg -io.kg -jp.kg -tv.kg -uk.kg -us.kg -de.ls -at.md -de.md -jp.md -to.md -indie.porn -vxl.sh -ch.tc -me.tc -we.tc -nyan.to -at.vg -blog.vu -dev.vu -me.vu - -// V.UA Domain Administrator : https://domain.v.ua/ -// Submitted by Serhii Rostilo -v.ua - // Vultr Objects : https://www.vultr.com/products/object-storage/ // Submitted by Niels Maumenee *.vultrobjects.com @@ -14109,42 +15598,70 @@ v.ua // Submitted by Masayuki Note wafflecell.com -// WebHare bv: https://www.webhare.com/ +// Webflow, Inc. : https://www.webflow.com +// Submitted by Webflow Security Team +webflow.io +webflowtest.io + +// WebHare bv : https://www.webhare.com/ // Submitted by Arnold Hendriks *.webhare.dev -// WebHotelier Technologies Ltd: https://www.webhotelier.net/ +// WebHotelier Technologies Ltd : https://www.webhotelier.net/ // Submitted by Apostolos Tsakpinis -reserve-online.net -reserve-online.com bookonline.app hotelwithflight.com +reserve-online.com +reserve-online.net + +// WebPros International, LLC : https://webpros.com/ +// Submitted by Nicolas Rochelemagne +cprapid.com +pleskns.com +wp2.host +pdns.page +plesk.page +wpsquared.site -// WeDeploy by Liferay, Inc. : https://www.wedeploy.com -// Submitted by Henrique Vicente -wedeploy.io -wedeploy.me -wedeploy.sh +// WebWaddle Ltd : https://webwaddle.com/ +// Submitted by Merlin Glander +*.wadl.top // Western Digital Technologies, Inc : https://www.wdc.com // Submitted by Jung Jin remotewd.com +// Whatbox Inc. : https://whatbox.ca/ +// Submitted by Anthony Ryan +box.ca + // WIARD Enterprises : https://wiardweb.com // Submitted by Kidd Hustle pages.wiardweb.com // Wikimedia Labs : https://wikitech.wikimedia.org // Submitted by Arturo Borrero Gonzalez -wmflabs.org toolforge.org wmcloud.org +wmflabs.org + +// William Harrison : https://wdh.gg +// Submitted by William Harrison +wdh.app // WISP : https://wisp.gg // Submitted by Stepan Fedotov panel.gg daemon.panel.gg +// Wix.com, Inc. : https://www.wix.com +// Submitted by Shahar Talmi / Alon Kochba +wixsite.com +wixstudio.com +editorx.io +wixstudio.io +wix.run + // Wizard Zines : https://wizardzines.com // Submitted by Julia Evans messwithdns.com @@ -14170,11 +15687,6 @@ weeklylottery.org.uk wpenginepowered.com js.wpenginepowered.com -// Wix.com, Inc. : https://www.wix.com -// Submitted by Shahar Talmi -wixsite.com -editorx.io - // XenonCloud GbR: https://xenoncloud.net // Submitted by Julian Uphoff half.host @@ -14191,7 +15703,7 @@ cistron.nl demon.nl xs4all.space -// Yandex.Cloud LLC: https://cloud.yandex.com +// Yandex.Cloud LLC : https://cloud.yandex.com // Submitted by Alexander Lodin yandexcloud.net storage.yandexcloud.net @@ -14207,13 +15719,7 @@ yolasite.com // Yombo : https://yombo.net // Submitted by Mitch Schwenk -ybo.faith yombo.me -homelink.one -ybo.party -ybo.review -ybo.science -ybo.trade // Yunohost : https://yunohost.org // Submitted by Valentin Grimaud @@ -14226,6 +15732,14 @@ noho.st za.net za.org +// ZAP-Hosting GmbH & Co. KG : https://zap-hosting.com +// Submitted by Julian Alker +zap.cloud + +// Zeabur : https://zeabur.com/ +// Submitted by Zeabur Team +zeabur.app + // Zine EOOD : https://zine.bg/ // Submitted by Martin Angelov bss.design diff --git a/okhttp/src/test/resources/web-platform-test-toascii.json b/okhttp/src/jvmTest/resources/web-platform-test-toascii.json similarity index 100% rename from okhttp/src/test/resources/web-platform-test-toascii.json rename to okhttp/src/jvmTest/resources/web-platform-test-toascii.json diff --git a/okhttp/src/test/resources/web-platform-test-urltestdata.txt b/okhttp/src/jvmTest/resources/web-platform-test-urltestdata.txt similarity index 100% rename from okhttp/src/test/resources/web-platform-test-urltestdata.txt rename to okhttp/src/jvmTest/resources/web-platform-test-urltestdata.txt diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/HttpStatusCodes.kt b/okhttp/src/main/kotlin/okhttp3/internal/http/HttpStatusCodes.kt deleted file mode 100644 index 04baa39b8f64..000000000000 --- a/okhttp/src/main/kotlin/okhttp3/internal/http/HttpStatusCodes.kt +++ /dev/null @@ -1,264 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -package okhttp3.internal.http - -// HTTP Status Codes -// -// https://datatracker.ietf.org/doc/html/rfc7231#page-47 -// -// From https://github.com/apache/httpcomponents-core/blob/master/httpcore5/src/main/java/org/apache/hc/core5/http/HttpStatus.java - -// --- 1xx Informational --- -// /** `100 1xx Informational` (HTTP/1.1 - RFC 7231) */ -// const val HTTP_INFORMATIONAL = 100 - -/** `100 Continue` (HTTP/1.1 - RFC 7231) */ -const val HTTP_CONTINUE = 100 - -/** `101 Switching Protocols` (HTTP/1.1 - RFC 7231) */ -const val HTTP_SWITCHING_PROTOCOLS = 101 - -/** `102 Processing` (WebDAV - RFC 2518) */ -const val HTTP_PROCESSING = 102 - -/** `103 Early Hints (Early Hints - RFC 8297)` */ -const val HTTP_EARLY_HINTS = 103 - -// --- 2xx Success --- -// /** `2xx Success` (HTTP/1.0 - RFC 7231) */ -// const val HTTP_SUCCESS = 200 - -/** `200 OK` (HTTP/1.0 - RFC 7231) */ -const val HTTP_OK = 200 - -/** `201 Created` (HTTP/1.0 - RFC 7231) */ -const val HTTP_CREATED = 201 - -/** `202 Accepted` (HTTP/1.0 - RFC 7231) */ -const val HTTP_ACCEPTED = 202 - -/** `203 Non Authoritative Information` (HTTP/1.1 - RFC 7231) */ -const val HTTP_NOT_AUTHORITATIVE = 203 - -/** `204 No Content` (HTTP/1.0 - RFC 7231) */ -const val HTTP_NO_CONTENT = 204 - -/** `205 Reset Content` (HTTP/1.1 - RFC 7231) */ -const val HTTP_RESET_CONTENT = 205 - -/** `206 Partial Content` (HTTP/1.1 - RFC 7231) */ -const val HTTP_PARTIAL_CONTENT = 206 - -/** - * `207 Multi-Status` (WebDAV - RFC 2518) - * or - * `207 Partial Update OK` (HTTP/1.1 - draft-ietf-http-v11-spec-rev-01?) - */ -const val HTTP_MULTI_STATUS = 207 - -/** - * `208 Already Reported` (WebDAV - RFC 5842, p.30, section 7.1) - */ -const val HTTP_ALREADY_REPORTED = 208 - -/** - * `226 IM Used` (Delta encoding in HTTP - RFC 3229, p. 30, section 10.4.1) - */ -const val HTTP_IM_USED = 226 - -// --- 3xx Redirection --- -// /** `3xx Redirection` (HTTP/1.1 - RFC 7231) */ -// const val HTTP_REDIRECTION = 300 - -/** `300 Multiple Choices` (HTTP/1.1 - RFC 7231) */ -const val HTTP_MULT_CHOICE = 300 - -/** `301 Moved Permanently` (HTTP/1.0 - RFC 7231) */ -const val HTTP_MOVED_PERM = 301 - -/** `302 Moved Temporarily` (Sometimes `Found`) (HTTP/1.0 - RFC 7231) */ -const val HTTP_MOVED_TEMP = 302 - -/** `303 See Other` (HTTP/1.1 - RFC 7231) */ -const val HTTP_SEE_OTHER = 303 - -/** `304 Not Modified` (HTTP/1.0 - RFC 7231) */ -const val HTTP_NOT_MODIFIED = 304 - -/** `305 Use Proxy` (HTTP/1.1 - RFC 7231) */ -const val HTTP_USE_PROXY = 305 - -/** `307 Temporary Redirect` (HTTP/1.1 - RFC 7231) */ -const val HTTP_TEMP_REDIRECT = 307 - -/** `308 Permanent Redirect` (HTTP/1.1 - RFC 7538) */ -const val HTTP_PERM_REDIRECT = 308 - -// --- 4xx Client Error --- -// /** `4xx Client Error` (HTTP/1.1 - RFC 7231) */ -// const val HTTP_CLIENT_ERROR = 400 - -/** `400 Bad Request` (HTTP/1.1 - RFC 7231) */ -const val HTTP_BAD_REQUEST = 400 - -/** `401 Unauthorized` (HTTP/1.0 - RFC 7231) */ -const val HTTP_UNAUTHORIZED = 401 - -/** `402 Payment Required` (HTTP/1.1 - RFC 7231) */ -const val HTTP_PAYMENT_REQUIRED = 402 - -/** `403 Forbidden` (HTTP/1.0 - RFC 7231) */ -const val HTTP_FORBIDDEN = 403 - -/** `404 Not Found` (HTTP/1.0 - RFC 7231) */ -const val HTTP_NOT_FOUND = 404 - -/** `405 Method Not Allowed` (HTTP/1.1 - RFC 7231) */ -const val HTTP_BAD_METHOD = 405 - -/** `406 Not Acceptable` (HTTP/1.1 - RFC 7231) */ -const val HTTP_NOT_ACCEPTABLE = 406 - -/** `407 Proxy Authentication Required` (HTTP/1.1 - RFC 7231) */ -const val HTTP_PROXY_AUTH = 407 - -/** `408 Request Timeout` (HTTP/1.1 - RFC 7231) */ -const val HTTP_CLIENT_TIMEOUT = 408 - -/** `409 Conflict` (HTTP/1.1 - RFC 7231) */ -const val HTTP_CONFLICT = 409 - -/** `410 Gone` (HTTP/1.1 - RFC 7231) */ -const val HTTP_GONE = 410 - -/** `411 Length Required` (HTTP/1.1 - RFC 7231) */ -const val HTTP_LENGTH_REQUIRED = 411 - -/** `412 Precondition Failed` (HTTP/1.1 - RFC 7231) */ -const val HTTP_PRECONDITION_FAILED = 412 - -/** `413 Request Entity Too Large` (HTTP/1.1 - RFC 7231) */ -const val HTTP_REQUEST_TOO_LONG = 413 - -/** `414 Request-URI Too Long` (HTTP/1.1 - RFC 7231) */ -const val HTTP_REQ_TOO_LONG = 414 - -/** `415 Unsupported Media Type` (HTTP/1.1 - RFC 7231) */ -const val HTTP_UNSUPPORTED_MEDIA_TYPE = 415 - -/** `416 Requested Range Not Satisfiable` (HTTP/1.1 - RFC 7231) */ -const val HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416 - -/** `417 Expectation Failed` (HTTP/1.1 - RFC 7231) */ -const val HTTP_EXPECTATION_FAILED = 417 - -/** `421 Misdirected Request` (HTTP/2 - RFC 7540) */ -const val HTTP_MISDIRECTED_REQUEST = 421 - -/** - * Static constant for a 419 error. - * `419 Insufficient Space on Resource` - * (WebDAV - draft-ietf-webdav-protocol-05?) - * or `419 Proxy Reauthentication Required` - * (HTTP/1.1 drafts?) - */ -const val HTTP_INSUFFICIENT_SPACE_ON_RESOURCE = 419 - -/** - * Static constant for a 420 error. - * `420 Method Failure` - * (WebDAV - draft-ietf-webdav-protocol-05?) - */ -const val HTTP_METHOD_FAILURE = 420 - -/** `422 Unprocessable Entity` (WebDAV - RFC 2518) */ -const val HTTP_UNPROCESSABLE_ENTITY = 422 - -/** `423 Locked` (WebDAV - RFC 2518) */ -const val HTTP_LOCKED = 423 - -/** `424 Failed Dependency` (WebDAV - RFC 2518) */ -const val HTTP_FAILED_DEPENDENCY = 424 - -/** `425 Too Early` (Using Early Data in HTTP - RFC 8470) */ -const val HTTP_TOO_EARLY = 425 - -/** `426 Upgrade Dependency` (HTTP/1.1 - RFC 2817) */ -const val HTTP_UPGRADE_REQUIRED = 426 - -/** `428 Precondition Required` (Additional HTTP Status Codes - RFC 6585) */ -const val HTTP_PRECONDITION_REQUIRED = 428 - -/** `429 Too Many Requests` (Additional HTTP Status Codes - RFC 6585) */ -const val HTTP_TOO_MANY_REQUESTS = 429 - -/** `431 Request Header Fields Too Large` (Additional HTTP Status Codes - RFC 6585) */ -const val HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431 - -/** `451 Unavailable For Legal Reasons` (Legal Obstacles - RFC 7725) */ -const val HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451 - -// --- 5xx Server Error --- -// /** `500 Server Error` (HTTP/1.0 - RFC 7231) */ -// const val HTTP_SERVER_ERROR = 500 - -/** `500 Internal Server Error` (HTTP/1.0 - RFC 7231) */ -const val HTTP_INTERNAL_SERVER_ERROR = 500 - -/** `501 Not Implemented` (HTTP/1.0 - RFC 7231) */ -const val HTTP_NOT_IMPLEMENTED = 501 - -/** `502 Bad Gateway` (HTTP/1.0 - RFC 7231) */ -const val HTTP_BAD_GATEWAY = 502 - -/** `503 Service Unavailable` (HTTP/1.0 - RFC 7231) */ -const val HTTP_UNAVAILABLE = 503 - -/** `504 Gateway Timeout` (HTTP/1.1 - RFC 7231) */ -const val HTTP_GATEWAY_TIMEOUT = 504 - -/** `505 HTTP Version Not Supported` (HTTP/1.1 - RFC 7231) */ -const val HTTP_HTTP_VERSION_NOT_SUPPORTED = 505 - -/** `506 Variant Also Negotiates` ( Transparent Content Negotiation - RFC 2295) */ -const val HTTP_VARIANT_ALSO_NEGOTIATES = 506 - -/** `507 Insufficient Storage` (WebDAV - RFC 2518) */ -const val HTTP_INSUFFICIENT_STORAGE = 507 - -/** - * `508 Loop Detected` (WebDAV - RFC 5842, p.33, section 7.2) - */ -const val HTTP_LOOP_DETECTED = 508 - -/** - * `510 Not Extended` (An HTTP Extension Framework - RFC 2774, p. 10, section 7) - */ -const val HTTP_NOT_EXTENDED = 510 - -/** `511 Network Authentication Required` (Additional HTTP Status Codes - RFC 6585) */ -const val HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511 diff --git a/okhttp/src/main/resources/META-INF/native-image/okhttp/okhttp/native-image.properties b/okhttp/src/main/resources/META-INF/native-image/okhttp/okhttp/native-image.properties index fdb2df990d20..75cbefcdc5c1 100644 --- a/okhttp/src/main/resources/META-INF/native-image/okhttp/okhttp/native-image.properties +++ b/okhttp/src/main/resources/META-INF/native-image/okhttp/okhttp/native-image.properties @@ -1 +1 @@ -Args = -H:+AddAllCharsets -H:EnableURLProtocols=http,https --enable-https --features=okhttp3.internal.graal.OkHttpFeature +Args = -H:+AddAllCharsets --enable-http --enable-https --features=okhttp3.internal.graal.OkHttpFeature --report-unsupported-elements-at-runtime diff --git a/okhttp/src/main/resources/okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz b/okhttp/src/main/resources/okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz deleted file mode 100644 index 1e552b5aacf7..000000000000 Binary files a/okhttp/src/main/resources/okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz and /dev/null differ diff --git a/okhttp/src/test/java/okhttp3/internal/connection/ConnectionPoolTest.kt b/okhttp/src/test/java/okhttp3/internal/connection/ConnectionPoolTest.kt deleted file mode 100644 index 1cfa0f774702..000000000000 --- a/okhttp/src/test/java/okhttp3/internal/connection/ConnectionPoolTest.kt +++ /dev/null @@ -1,260 +0,0 @@ -/* - * 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.internal.connection - -import assertk.assertThat -import assertk.assertions.isEmpty -import assertk.assertions.isEqualTo -import assertk.assertions.isFalse -import assertk.assertions.isNotEmpty -import assertk.assertions.isTrue -import okhttp3.ConnectionPool -import okhttp3.FakeRoutePlanner -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.TestUtil.awaitGarbageCollection -import okhttp3.TestValueFactory -import okhttp3.internal.concurrent.TaskRunner -import org.junit.jupiter.api.AfterEach -import org.junit.jupiter.api.Test - -class ConnectionPoolTest { - private val factory = TestValueFactory() - - /** The fake task runner prevents the cleanup runnable from being started. */ - private val addressA = factory.newAddress("a") - private val routeA1 = factory.newRoute(addressA) - private val addressB = factory.newAddress("b") - private val routeB1 = factory.newRoute(addressB) - private val addressC = factory.newAddress("c") - private val routeC1 = factory.newRoute(addressC) - - private val routePlanner = FakeRoutePlanner(factory.taskFaker) - - @AfterEach fun tearDown() { - factory.close() - } - - @Test fun connectionsEvictedWhenIdleLongEnough() { - val pool = factory.newConnectionPool() - val c1 = factory.newConnection(pool, routeA1, 50L) - - // Running at time 50, the pool returns that nothing can be evicted until time 150. - assertThat(pool.cleanup(50L)).isEqualTo(100L) - assertThat(pool.connectionCount()).isEqualTo(1) - assertThat(c1.socket().isClosed).isFalse() - - // Running at time 60, the pool returns that nothing can be evicted until time 150. - assertThat(pool.cleanup(60L)).isEqualTo(90L) - assertThat(pool.connectionCount()).isEqualTo(1) - assertThat(c1.socket().isClosed).isFalse() - - // Running at time 149, the pool returns that nothing can be evicted until time 150. - assertThat(pool.cleanup(149L)).isEqualTo(1L) - assertThat(pool.connectionCount()).isEqualTo(1) - assertThat(c1.socket().isClosed).isFalse() - - // Running at time 150, the pool evicts. - assertThat(pool.cleanup(150L)).isEqualTo(0) - assertThat(pool.connectionCount()).isEqualTo(0) - assertThat(c1.socket().isClosed).isTrue() - - // Running again, the pool reports that no further runs are necessary. - assertThat(pool.cleanup(150L)).isEqualTo(-1) - assertThat(pool.connectionCount()).isEqualTo(0) - assertThat(c1.socket().isClosed).isTrue() - } - - @Test fun inUseConnectionsNotEvicted() { - val pool = factory.newConnectionPool() - val poolApi = ConnectionPool(pool) - val c1 = factory.newConnection(pool, routeA1, 50L) - val client = - OkHttpClient.Builder() - .connectionPool(poolApi) - .build() - val call = client.newCall(Request(addressA.url)) as RealCall - call.enterNetworkInterceptorExchange(call.request(), true, factory.newChain(call)) - synchronized(c1) { call.acquireConnectionNoEvents(c1) } - - // Running at time 50, the pool returns that nothing can be evicted until time 150. - assertThat(pool.cleanup(50L)).isEqualTo(100L) - assertThat(pool.connectionCount()).isEqualTo(1) - assertThat(c1.socket().isClosed).isFalse() - - // Running at time 60, the pool returns that nothing can be evicted until time 160. - assertThat(pool.cleanup(60L)).isEqualTo(100L) - assertThat(pool.connectionCount()).isEqualTo(1) - assertThat(c1.socket().isClosed).isFalse() - - // Running at time 160, the pool returns that nothing can be evicted until time 260. - assertThat(pool.cleanup(160L)).isEqualTo(100L) - assertThat(pool.connectionCount()).isEqualTo(1) - assertThat(c1.socket().isClosed).isFalse() - } - - @Test fun cleanupPrioritizesEarliestEviction() { - val pool = factory.newConnectionPool() - val c1 = factory.newConnection(pool, routeA1, 75L) - val c2 = factory.newConnection(pool, routeB1, 50L) - - // Running at time 75, the pool returns that nothing can be evicted until time 150. - assertThat(pool.cleanup(75L)).isEqualTo(75L) - assertThat(pool.connectionCount()).isEqualTo(2) - - // Running at time 149, the pool returns that nothing can be evicted until time 150. - assertThat(pool.cleanup(149L)).isEqualTo(1L) - assertThat(pool.connectionCount()).isEqualTo(2) - - // Running at time 150, the pool evicts c2. - assertThat(pool.cleanup(150L)).isEqualTo(0L) - assertThat(pool.connectionCount()).isEqualTo(1) - assertThat(c1.socket().isClosed).isFalse() - assertThat(c2.socket().isClosed).isTrue() - - // Running at time 150, the pool returns that nothing can be evicted until time 175. - assertThat(pool.cleanup(150L)).isEqualTo(25L) - assertThat(pool.connectionCount()).isEqualTo(1) - - // Running at time 175, the pool evicts c1. - assertThat(pool.cleanup(175L)).isEqualTo(0L) - assertThat(pool.connectionCount()).isEqualTo(0) - assertThat(c1.socket().isClosed).isTrue() - assertThat(c2.socket().isClosed).isTrue() - } - - @Test fun oldestConnectionsEvictedIfIdleLimitExceeded() { - val pool = - factory.newConnectionPool( - maxIdleConnections = 2, - ) - val c1 = factory.newConnection(pool, routeA1, 50L) - val c2 = factory.newConnection(pool, routeB1, 75L) - - // With 2 connections, there's no need to evict until the connections time out. - assertThat(pool.cleanup(100L)).isEqualTo(50L) - assertThat(pool.connectionCount()).isEqualTo(2) - assertThat(c1.socket().isClosed).isFalse() - assertThat(c2.socket().isClosed).isFalse() - - // Add a third connection - val c3 = factory.newConnection(pool, routeC1, 75L) - - // The third connection bounces the first. - assertThat(pool.cleanup(100L)).isEqualTo(0L) - assertThat(pool.connectionCount()).isEqualTo(2) - assertThat(c1.socket().isClosed).isTrue() - assertThat(c2.socket().isClosed).isFalse() - assertThat(c3.socket().isClosed).isFalse() - } - - @Test fun leakedAllocation() { - val pool = factory.newConnectionPool() - val poolApi = ConnectionPool(pool) - val c1 = factory.newConnection(pool, routeA1, 0L) - allocateAndLeakAllocation(poolApi, c1) - awaitGarbageCollection() - assertThat(pool.cleanup(100L)).isEqualTo(0L) - assertThat(c1.calls).isEmpty() - - // Can't allocate once a leak has been detected. - assertThat(c1.noNewExchanges).isTrue() - } - - @Test fun interruptStopsThread() { - val realTaskRunner = TaskRunner.INSTANCE - val pool = - factory.newConnectionPool( - taskRunner = TaskRunner.INSTANCE, - maxIdleConnections = 2, - ) - factory.newConnection(pool, routeA1) - assertThat(realTaskRunner.activeQueues()).isNotEmpty() - Thread.sleep(100) - val threads = arrayOfNulls(Thread.activeCount() * 2) - Thread.enumerate(threads) - for (t in threads) { - if (t != null && t.name == "OkHttp TaskRunner") { - t.interrupt() - } - } - Thread.sleep(100) - assertThat(realTaskRunner.activeQueues()).isEmpty() - } - - @Test fun connectionPreWarming() { - // TODO this test spins forever due to bugs in TaskFaker.runTasks() - - // routePlanner.autoGeneratePlans = true - // routePlanner.defaultConnectionIdleAtNanos = System.nanoTime() + 1_000_000_000_000 - // val address = routePlanner.address - // val pool = factory.newConnectionPool(routePlanner = routePlanner) - // - // // Connections are created as soon as a policy is set - // setPolicy(pool, address, ConnectionPool.AddressPolicy(2)) - // assertThat(pool.connectionCount()).isEqualTo(2) - // - // // Connections are replaced if they idle out or are evicted from the pool - // evictAllConnections(pool) - // assertThat(pool.connectionCount()).isEqualTo(2) - // forceConnectionsToExpire(pool, routePlanner) - // assertThat(pool.connectionCount()).isEqualTo(2) - // - // // Excess connections aren't removed until they idle out, even if no longer needed - // setPolicy(pool, address, ConnectionPool.AddressPolicy(1)) - // assertThat(pool.connectionCount()).isEqualTo(2) - // forceConnectionsToExpire(pool, routePlanner) - // assertThat(pool.connectionCount()).isEqualTo(1) - - // TODO test that http/2 connections will be opened/closed based on concurrent stream settings - } - - // private fun setPolicy( - // pool: RealConnectionPool, - // address: Address, - // policy: ConnectionPool.AddressPolicy - // ) { - // pool.setPolicy(address, policy) - // factory.taskFaker.runTasks() - // } - // - // private fun evictAllConnections(pool: RealConnectionPool) { - // pool.evictAll() - // assertThat(pool.connectionCount()).isEqualTo(0) - // factory.taskFaker.runTasks() - // } - // - // private fun forceConnectionsToExpire(pool: RealConnectionPool, routePlanner: FakeRoutePlanner) { - // val idleTimeNanos = routePlanner.defaultConnectionIdleAtNanos + pool.keepAliveDurationNs - // repeat(pool.connectionCount()) { pool.cleanup(idleTimeNanos) } - // assertThat(pool.connectionCount()).isEqualTo(0) - // factory.taskFaker.runTasks() - // } - - /** Use a helper method so there's no hidden reference remaining on the stack. */ - private fun allocateAndLeakAllocation( - pool: ConnectionPool, - connection: RealConnection, - ) { - val client = - OkHttpClient.Builder() - .connectionPool(pool) - .build() - val call = client.newCall(Request(connection.route().address.url)) as RealCall - call.enterNetworkInterceptorExchange(call.request(), true, factory.newChain(call)) - synchronized(connection) { call.acquireConnectionNoEvents(connection) } - } -} diff --git a/samples/compare/src/test/kotlin/okhttp3/compare/ApacheHttpClientTest.kt b/samples/compare/src/test/kotlin/okhttp3/compare/ApacheHttpClientTest.kt index bf1031a20a31..81474b0d831f 100644 --- a/samples/compare/src/test/kotlin/okhttp3/compare/ApacheHttpClientTest.kt +++ b/samples/compare/src/test/kotlin/okhttp3/compare/ApacheHttpClientTest.kt @@ -58,7 +58,6 @@ class ApacheHttpClientTest { val recorded = server.takeRequest() assertThat(recorded.headers["Accept"]).isEqualTo("text/plain") assertThat(recorded.headers["Accept-Encoding"]).isEqualTo("gzip, x-gzip, deflate") - assertThat(recorded.headers["Connection"]).isEqualTo("keep-alive") assertThat(recorded.headers["User-Agent"]!!).startsWith("Apache-HttpClient/") } } diff --git a/samples/guide/src/main/java/okhttp3/recipes/CheckHandshake.java b/samples/guide/src/main/java/okhttp3/recipes/CheckHandshake.java index fcd3ccf5aed5..e852e68d0439 100644 --- a/samples/guide/src/main/java/okhttp3/recipes/CheckHandshake.java +++ b/samples/guide/src/main/java/okhttp3/recipes/CheckHandshake.java @@ -28,14 +28,14 @@ public final class CheckHandshake { /** Rejects otherwise-trusted certificates. */ private static final Interceptor CHECK_HANDSHAKE_INTERCEPTOR = new Interceptor() { - final Set blacklist = Collections.singleton( + final Set denylist = Collections.singleton( "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig="); @Override public Response intercept(Chain chain) throws IOException { for (Certificate certificate : chain.connection().handshake().peerCertificates()) { String pin = CertificatePinner.pin(certificate); - if (blacklist.contains(pin)) { - throw new IOException("Blacklisted peer certificate: " + pin); + if (denylist.contains(pin)) { + throw new IOException("Denylisted peer certificate: " + pin); } } return chain.proceed(chain.request()); diff --git a/samples/guide/src/main/java/okhttp3/recipes/UploadProgress.java b/samples/guide/src/main/java/okhttp3/recipes/UploadProgress.java new file mode 100644 index 000000000000..134c5ea165d0 --- /dev/null +++ b/samples/guide/src/main/java/okhttp3/recipes/UploadProgress.java @@ -0,0 +1,138 @@ +/* + * 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.recipes; + +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okio.Buffer; +import okio.BufferedSink; +import okio.ForwardingSink; +import okio.Okio; +import okio.Sink; +import java.io.File; +import java.io.IOException; + +public final class UploadProgress { + private static final String IMGUR_CLIENT_ID = "9199fdef135c122"; + private static final MediaType MEDIA_TYPE_PNG = MediaType.get("image/png"); + + private final OkHttpClient client = new OkHttpClient(); + + public void run() throws Exception { + // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image + final ProgressListener progressListener = new ProgressListener() { + boolean firstUpdate = true; + + @Override public void update(long bytesWritten, long contentLength, boolean done) { + if (done) { + System.out.println("completed"); + } else { + if (firstUpdate) { + firstUpdate = false; + if (contentLength == -1) { + System.out.println("content-length: unknown"); + } else { + System.out.format("content-length: %d\n", contentLength); + } + } + + System.out.println(bytesWritten); + + if (contentLength != -1) { + System.out.format("%d%% done\n", (100 * bytesWritten) / contentLength); + } + } + } + }; + + RequestBody requestBody = RequestBody.create( + new File("docs/images/logo-square.png"), + MEDIA_TYPE_PNG); + + Request request = new Request.Builder() + .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID) + .url("https://api.imgur.com/3/image") + .post(new ProgressRequestBody(requestBody, progressListener)) + .build(); + + Response response = client.newCall(request).execute(); + if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + + System.out.println(response.body().string()); + } + + public static void main(String... args) throws Exception { + new UploadProgress().run(); + } + + private static class ProgressRequestBody extends RequestBody { + + private final ProgressListener progressListener; + private final RequestBody delegate; + + public ProgressRequestBody(RequestBody delegate, ProgressListener progressListener) { + this.delegate = delegate; + this.progressListener = progressListener; + } + + @Override + public MediaType contentType() { + return delegate.contentType(); + } + + @Override + public long contentLength() throws IOException { + return delegate.contentLength(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + BufferedSink bufferedSink = Okio.buffer(sink(sink)); + delegate.writeTo(bufferedSink); + bufferedSink.flush(); + } + + public Sink sink(Sink sink) { + return new ForwardingSink(sink) { + private long totalBytesWritten = 0L; + private boolean completed = false; + + @Override + public void write(Buffer source, long byteCount) throws IOException { + super.write(source, byteCount); + totalBytesWritten += byteCount; + progressListener.update(totalBytesWritten, contentLength(), completed); + } + + @Override + public void close() throws IOException { + super.close(); + if (!completed) { + completed = true; + progressListener.update(totalBytesWritten, contentLength(), completed); + } + } + }; + } + } + + interface ProgressListener { + void update(long bytesWritten, long contentLength, boolean done); + } +} diff --git a/samples/tlssurvey/build.gradle.kts b/samples/tlssurvey/build.gradle.kts index 586fbfbbf7f6..37400b86988c 100644 --- a/samples/tlssurvey/build.gradle.kts +++ b/samples/tlssurvey/build.gradle.kts @@ -1,7 +1,7 @@ plugins { kotlin("jvm") application - id("com.google.devtools.ksp").version("1.9.23-1.0.19") + id("com.google.devtools.ksp").version(libs.versions.ksp) } application { @@ -13,12 +13,12 @@ dependencies { implementation(projects.okhttpCoroutines) implementation(libs.conscrypt.openjdk) - implementation("com.squareup.retrofit2:retrofit:2.11.0") - implementation("com.squareup.retrofit2:converter-moshi:2.11.0") + implementation(libs.retrofit) + implementation(libs.converter.moshi) implementation(libs.squareup.moshi) implementation(libs.squareup.moshi.kotlin) - ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.1") + ksp(libs.squareup.moshi.compiler) } tasks.compileJava { diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt index 5427864e79b5..ae0541fde032 100644 --- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt +++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt @@ -18,7 +18,7 @@ package okhttp3.survey import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.OkHttpClient import okhttp3.Request -import okhttp3.executeAsync +import okhttp3.coroutines.executeAsync import okhttp3.survey.types.SuiteId import okio.ByteString.Companion.decodeHex import okio.IOException diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt index dfb272b72e13..543ffae84510 100644 --- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt +++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt @@ -31,7 +31,7 @@ suspend fun main() { val client = OkHttpClient.Builder() - .cache(Cache("build/okhttp_cache".toPath(), 100_000_000, FileSystem.SYSTEM)) + .cache(Cache(FileSystem.SYSTEM, "build/okhttp_cache".toPath(), 100_000_000)) .build() val sslLabsClients = SslLabsClient(client).clients() diff --git a/settings.gradle.kts b/settings.gradle.kts index 212d8251adf2..0bb5a2ddcecc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,9 @@ +import java.util.Properties + rootProject.name = "okhttp-parent" plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version("0.8.0") + id("org.gradle.toolchains.foojay-resolver-convention") version("0.9.0") } include(":mockwebserver") @@ -35,6 +37,7 @@ include(":okhttp-hpacktests") include(":okhttp-idna-mapping-table") include(":okhttp-java-net-cookiejar") include(":okhttp-logging-interceptor") +include(":okhttp-osgi-tests") include(":okhttp-sse") include(":okhttp-testing-support") include(":okhttp-tls") @@ -51,31 +54,17 @@ include(":container-tests") project(":okhttp-logging-interceptor").name = "logging-interceptor" -if (!isKnownBrokenIntelliJ()) { - include(":okhttp-android") +val androidHome = System.getenv("ANDROID_HOME") +val localProperties = Properties().apply { + val file = File("local.properties") + if (file.exists()) { + load(file.inputStream()) + } +} +val sdkDir = localProperties.getProperty("sdk.dir") +if (androidHome != null || sdkDir != null) { include(":android-test") include(":android-test-app") } enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") - -/** - * Avoid a crash in IntelliJ triggered by Android submodules. - * - * ``` - * java.lang.AssertionError: Can't find built-in class kotlin.Cloneable - * at org.jetbrains.kotlin.builtins.KotlinBuiltIns.getBuiltInClassByFqName(KotlinBuiltIns.java:217) - * at org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMapper.mapJavaToKotlin(JavaToKotlinClassMapper.kt:41) - * ... - * ``` - */ -fun isKnownBrokenIntelliJ(): Boolean { - val ideaVersionString = System.getProperty("idea.version") ?: return false - - return try { - val (major, minor, _) = ideaVersionString.split(".", limit = 3) - KotlinVersion(major.toInt(), minor.toInt()) < KotlinVersion(2023, 2) - } catch (e: Exception) { - false // Unknown version, presumably compatible. - } -} diff --git a/test_docs.sh b/test_docs.sh index 18fd7389089b..ba482f0bf3bd 100755 --- a/test_docs.sh +++ b/test_docs.sh @@ -9,7 +9,7 @@ set -ex # Test generating the javadoc jars -./gradlew publishToMavenLocal +./gradlew publishToMavenLocal -DRELEASE_SIGNING_ENABLED=false # Generate the API docs ./gradlew dokkaHtmlMultiModule