From 99d172d9f8df1e95c58d4335d599ff20ac0d29e6 Mon Sep 17 00:00:00 2001 From: Leonid Stashevsky Date: Mon, 12 Jul 2021 13:01:06 +0300 Subject: [PATCH] KTOR-2763 Fix Warnings and Enable -Werror flag (#2496) * KTOR-2763 Fix warnings in ktor-io * KTOR-2763 Fix warnings in ktor-utils * KTOR-2763 Fix warnings in ktor-http * KTOR-2763 Fix warnings in ktor-network * KTOR-2763 Fix warnings in ktor-features * KTOR-2763 Fix warnings in ktor-server * KTOR-2763 Fix warnings in ktor-client * KTOR-2763 Fix warnings in ktor-shared & ktor-test-dispatcher * KTOR-2763 Update configuration --- build.gradle.kts | 43 +- buildSrc/src/main/kotlin/Compilations.kt | 15 + buildSrc/src/main/kotlin/KotlinExtensions.kt | 19 +- .../src/main/kotlin/KtorBuildProperties.kt | 69 +++ buildSrc/src/main/kotlin/Train.kt | 2 +- gradle/darwin.gradle | 11 +- gradle/jvm.gradle | 23 +- gradle/posix.gradle | 13 +- gradle/utility.gradle | 25 +- .../engine/android/AndroidClientEngine.kt | 14 +- .../android/AndroidURLConnectionUtils.kt | 4 + .../ktor/client/engine/apache/ApacheEngine.kt | 2 + .../engine/apache/ApacheRequestProducer.kt | 4 + .../engine/apache/RequestProducerTest.kt | 6 + .../engine/apache/ResponseConsumerTest.kt | 1 + .../io/ktor/client/engine/cio/CIOEngine.kt | 1 + .../src/io/ktor/client/engine/cio/Endpoint.kt | 4 +- .../src/io/ktor/client/engine/cio/utils.kt | 4 + .../io/ktor/client/engine/cio/Exceptions.kt | 1 + .../io/ktor/client/engine/cio/LoaderNative.kt | 2 + ktor-client/ktor-client-core/build.gradle.kts | 1 - .../common/src/io/ktor/client/HttpClient.kt | 4 +- .../src/io/ktor/client/call/Compatibility.kt | 1 + .../src/io/ktor/client/call/HttpClientCall.kt | 3 + .../src/io/ktor/client/call/SavedCall.kt | 7 +- .../ktor/client/content/ObservableContent.kt | 1 + .../io/ktor/client/engine/HttpClientEngine.kt | 1 + .../io/ktor/client/plugins/BodyProgress.kt | 1 + .../ktor/client/plugins/DefaultTransform.kt | 2 + .../ktor/client/plugins/HttpCallValidator.kt | 2 + .../io/ktor/client/plugins/HttpRedirect.kt | 1 + .../src/io/ktor/client/plugins/HttpTimeout.kt | 1 - .../io/ktor/client/plugins/cache/HttpCache.kt | 2 + .../client/plugins/cache/HttpCacheEntry.kt | 2 + .../client/plugins/cookies/HttpCookies.kt | 1 + .../client/plugins/observer/DelegatedCall.kt | 7 +- .../plugins/observer/ResponseObserver.kt | 1 + .../plugins/websocket/WebSocketContent.kt | 1 + .../client/plugins/websocket/WebSockets.kt | 2 +- .../src/io/ktor/client/request/HttpRequest.kt | 4 + .../src/io/ktor/client/request/RequestBody.kt | 1 + .../io/ktor/client/statement/Compatibility.kt | 2 + .../io/ktor/client/statement/HttpStatement.kt | 5 +- .../src/io/ktor/client/statement/Readers.kt | 4 + .../io/ktor/client/utils/ByteChannelUtils.kt | 1 + .../common/test/CacheExpiresTest.kt | 2 + .../test/MultiPartFormDataContentTest.kt | 8 +- .../ktor/client/engine/js/JsClientEngine.kt | 10 +- .../src/io/ktor/client/engine/js/JsUtils.kt | 2 + .../client/engine/js/compatibility/Utils.kt | 1 + .../ktor/client/engine/js/node/NodeFetch.kt | 2 +- .../js/src/io/ktor/client/fetch/LibDom.kt | 12 +- .../plugins/websocket/JsWebSocketSession.kt | 12 +- .../network/sockets/TimeoutExceptions.kt | 1 + .../client/plugins/DefaultTransformersJvm.kt | 2 + .../jvm/src/io/ktor/client/utils/CIOJvm.kt | 1 - .../jvm/test/ExceptionsTest.kt | 2 + .../posix/src/io/ktor/client/HttpClient.kt | 2 + .../posix/test/ExceptionsTest.kt | 2 + ktor-client/ktor-client-curl/build.gradle.kts | 5 +- .../src/io/ktor/client/engine/curl/Curl.kt | 3 + .../client/engine/curl/CurlClientEngine.kt | 2 + .../engine/curl/internal/CurlAdapters.kt | 2 + .../client/engine/curl/internal/CurlRaw.kt | 1 + ktor-client/ktor-client-ios/build.gradle.kts | 1 - .../src/io/ktor/client/engine/ios/Ios.kt | 2 + .../ktor/client/engine/ios/IosClientEngine.kt | 2 + .../client/engine/ios/IosResponseReader.kt | 5 +- .../src/io/ktor/client/engine/ios/IosUtils.kt | 1 + .../ios/certificates/PinnedCertificate.kt | 2 +- .../src/io/ktor/client/engine/java/Java.kt | 2 + .../ktor/client/engine/java/JavaHttpEngine.kt | 2 +- .../client/engine/java/JavaHttpRequest.kt | 3 + .../java/JavaHttpResponseBodyHandler.kt | 6 +- .../client/engine/java/JavaHttpWebSocket.kt | 11 +- .../client/engine/java/RequestProducerTest.kt | 1 + .../client/engine/jetty/JettyHttp2Engine.kt | 1 + .../client/engine/jetty/JettyHttpRequest.kt | 4 + .../engine/jetty/JettyResponseListener.kt | 7 +- .../io/ktor/client/engine/mock/MockEngine.kt | 2 + .../ktor/client/engine/okhttp/OkHttpEngine.kt | 7 +- .../engine/okhttp/OkHttpWebsocketSession.kt | 12 +- .../src/io/ktor/client/plugins/auth/Auth.kt | 2 + .../ktor/client/plugins/auth/AuthProvider.kt | 1 + .../auth/providers/BasicAuthProvider.kt | 2 + .../auth/providers/DigestAuthProvider.kt | 7 +- .../io/ktor/client/plugins/auth/AuthTest.kt | 9 +- .../client/plugins/auth/DigestProviderTest.kt | 6 +- .../build.gradle.kts | 2 - .../ktor-client-encoding/build.gradle.kts | 5 - .../common/src/ContentEncoding.kt | 4 +- .../ktor-client-json/build.gradle.kts | 2 - .../io/ktor/client/plugins/json/JsonPlugin.kt | 2 + .../common/test/JsonPluginTest.kt | 1 + .../common/test/KotlinxSerializerTest.kt | 8 +- .../io/ktor/client/plugins/json/DefaultJs.kt | 5 +- .../io/ktor/client/plugins/json/DefaultJvm.kt | 1 + .../client/plugins/json/GsonSerializer.kt | 1 + .../client/plugins/json/tests/GsonTest.kt | 1 + .../ktor-client-jackson/build.gradle.kts | 2 + .../client/plugins/json/JacksonSerializer.kt | 2 + .../client/plugins/json/tests/JacksonTest.kt | 1 + .../client/plugins/json/tests/JsonTest.kt | 24 +- .../jvm/test/DefaultSerializerJsonTest.kt | 1 + .../json/serializer/KotlinxSerializer.kt | 2 + .../test/CollectionsSerializationTest.kt | 1 + .../test/ContextualSerializationTest.kt | 1 + .../js/src/SerializerInitializer.kt | 1 + .../jvm/test/KotlinxSerializerTest.kt | 2 + .../posix/src/SerializerInitializer.kt | 3 + .../ktor/client/plugins/json/DefaultPosix.kt | 5 +- .../io/ktor/client/plugins/logging/Logging.kt | 2 + .../client/plugins/logging/ObservingUtils.kt | 1 + .../tests/plugins/WebSocketRemoteTest.kt | 2 +- .../ktor-client-tests/build.gradle.kts | 41 +- .../io/ktor/client/tests/utils/Assertions.kt | 8 +- .../ktor/client/tests/utils/ClientLoader.kt | 7 +- .../tests/utils/CommonClientTestUtils.kt | 5 +- .../io/ktor/client/tests/utils/Generators.kt | 9 +- .../io/ktor/client/tests/BodyProgressTest.kt | 49 +- .../ktor/client/tests/ClientPipelinesTest.kt | 2 + .../test/io/ktor/client/tests/ContentTest.kt | 2 +- .../io/ktor/client/tests/ExceptionsTest.kt | 8 +- .../io/ktor/client/tests/HttpStatementTest.kt | 2 +- .../io/ktor/client/tests/HttpTimeoutTest.kt | 2 +- .../ktor/client/tests/LoggingMockedTests.kt | 4 +- .../test/io/ktor/client/tests/LoggingTest.kt | 5 +- .../test/io/ktor/client/tests/PluginsTest.kt | 2 + .../io/ktor/client/tests/engine/UtilsTest.kt | 2 + .../io/ktor/client/tests/plugins/CacheTest.kt | 1 + .../io/ktor/client/tests/utils/Logging.kt | 6 +- .../ktor/client/tests/utils/AssertionsJs.kt | 8 +- .../ktor/client/tests/utils/ClientLoaderJs.kt | 23 +- .../ktor/client/tests/utils/AssertionsJvm.kt | 7 +- .../client/tests/utils/ClientLoaderJvm.kt | 28 +- .../ktor/client/tests/utils/TestTcpServer.kt | 1 + .../io/ktor/client/tests/ExceptionsJvmTest.kt | 2 + .../io/ktor/client/tests/JvmContentTest.kt | 2 +- .../client/tests/utils/AssertionsNative.kt | 7 +- .../client/tests/utils/ClientLoaderNative.kt | 12 +- ktor-http/common/src/io/ktor/http/Codecs.kt | 23 +- .../common/src/io/ktor/http/ContentTypes.kt | 4 +- .../io/ktor/http/HeaderValueWithParameters.kt | 13 +- ktor-http/common/src/io/ktor/http/Headers.kt | 2 - .../src/io/ktor/http/HttpHeaderValueParser.kt | 6 +- .../common/src/io/ktor/http/HttpHeaders.kt | 5 +- .../common/src/io/ktor/http/Parameters.kt | 2 - .../common/src/io/ktor/http/URLParser.kt | 2 +- ktor-http/common/src/io/ktor/http/Url.kt | 1 + .../src/io/ktor/http/auth/HttpAuthHeader.kt | 4 +- .../io/ktor/http/content/OutgoingContent.kt | 1 + .../test/io/ktor/tests/http/URLBuilderTest.kt | 2 +- .../tests/http/BlockingContentParkingTest.kt | 2 + .../test/io/ktor/tests/http/URLBuilderTest.kt | 6 +- ktor-http/ktor-http-cio/api/ktor-http-cio.api | 4 - .../common/src/io/ktor/http/cio/CIOHeaders.kt | 1 - .../ktor/http/cio/ChunkedTransferEncoding.kt | 3 + .../common/src/io/ktor/http/cio/HttpBody.kt | 2 +- .../src/io/ktor/http/cio/HttpHeadersMap.kt | 4 +- .../common/src/io/ktor/http/cio/HttpParser.kt | 2 +- .../ktor/http/cio/internals/AsciiCharTree.kt | 6 +- .../http/cio/internals/CharArrayBuilder.kt | 28 +- .../src/io/ktor/http/cio/internals/Chars.kt | 42 +- .../ktor/http/cio/internals/MutableRange.kt | 1 - .../http/cio/websocket/WebSocketSession.kt | 1 - .../io/ktor/http/cio/CIOMultipartDataBase.kt | 2 +- .../jvm/src/io/ktor/http/cio/Multipart.kt | 7 +- .../jvm/src/io/ktor/http/cio/Pipeline.kt | 2 + .../websocket/DefaultWebSocketSessionImpl.kt | 8 +- .../websocket/WebSocketDeflateExtension.kt | 3 +- .../http/cio/websocket/WebSocketWriter.kt | 4 +- .../ktor/server/cio/backend/ServerPipeline.kt | 6 +- .../io/ktor/tests/http/cio/MultipartTest.kt | 4 +- .../ktor/tests/http/cio/ServerPipelineTest.kt | 3 +- .../io/ktor/tests/http/cio/TestHttpServer.kt | 8 +- .../tests/http/cio/WeakTimeoutQueueTest.kt | 2 + ktor-io/api/ktor-io.api | 498 +++++++++--------- ktor-io/build.gradle.kts | 4 +- .../io/ktor/utils/io/ByteChannelSequential.kt | 5 +- .../src/io/ktor/utils/io/ByteWriteChannel.kt | 3 +- .../common/src/io/ktor/utils/io/Coroutines.kt | 2 + .../src/io/ktor/utils/io/NativeUtils.kt | 4 - .../src/io/ktor/utils/io/ReadSession.kt | 1 - .../src/io/ktor/utils/io/WriterSession.kt | 1 - .../src/io/ktor/utils/io/bits/ByteOrder.kt | 11 - .../src/io/ktor/utils/io/bits/Memory.kt | 3 - .../io/ktor/utils/io/bits/MemoryFactory.kt | 9 +- .../io/ktor/utils/io/bits/PrimiteArrays.kt | 16 + .../src/io/ktor/utils/io/charsets/Encoding.kt | 12 - .../src/io/ktor/utils/io/concurrent/Shared.kt | 2 - .../src/io/ktor/utils/io/core/Buffer.kt | 15 +- .../ktor/utils/io/core/BufferCompatibility.kt | 80 +-- .../io/ktor/utils/io/core/BufferFactory.kt | 2 - .../io/ktor/utils/io/core/BufferPrimitives.kt | 18 +- .../src/io/ktor/utils/io/core/Buffers.kt | 6 +- .../src/io/ktor/utils/io/core/Builder.kt | 1 + .../ktor/utils/io/core/BytePacketBuilder.kt | 15 +- .../common/src/io/ktor/utils/io/core/Input.kt | 24 +- .../ktor/utils/io/core/InputLittleEndian.kt | 12 + .../src/io/ktor/utils/io/core/Output.kt | 26 +- .../ktor/utils/io/core/OutputLittleEndian.kt | 6 + .../src/io/ktor/utils/io/core/PacketDirect.kt | 1 + .../src/io/ktor/utils/io/core/Preview.kt | 2 +- .../src/io/ktor/utils/io/core/Strings.kt | 7 +- .../utils/io/core/internal/ChunkBuffer.kt | 2 - .../io/ktor/utils/io/core/internal/UTF8.kt | 46 +- .../io/ktor/utils/io/core/internal/Unsafe.kt | 15 +- .../utils/io/ByteBufferChannelScenarioTest.kt | 1 + .../ktor/utils/io/ByteChannelSessionsTest.kt | 10 +- .../io/ktor/utils/io/ByteChannelSmokeTest.kt | 1 + .../test/io/ktor/utils/io/ByteChannelTest.kt | 7 +- .../io/ktor/utils/io/BytePacketBuildTest.kt | 8 +- .../io/ktor/utils/io/BytePacketStringTest.kt | 13 +- .../common/test/io/ktor/utils/io/InputTest.kt | 2 +- .../test/io/ktor/utils/io/OutputTest.kt | 4 +- .../io/ktor/utils/io/PrimitiveArraysTest.kt | 1 + .../io/ktor/utils/io/PrimitiveCodecTest.kt | 1 + .../test/io/ktor/utils/io/ReadBufferTest.kt | 18 +- .../test/io/ktor/utils/io/ReaderTest.kt | 3 +- .../test/io/ktor/utils/io/UnconfinedTests.kt | 2 + .../io/ktor/utils/io/ByteWriteChannelJs.kt | 1 - .../js/src/io/ktor/utils/io/NativeUtilsJs.kt | 4 - .../io/ktor/utils/io/bits/MemoryFactoryJs.kt | 1 + .../js/src/io/ktor/utils/io/bits/MemoryJs.kt | 2 +- .../io/ktor/utils/io/charsets/CharsetJS.kt | 3 +- .../src/io/ktor/utils/io/charsets/ISO88591.kt | 2 +- .../io/ktor/utils/io/concurrent/SharedJs.kt | 5 +- .../io/ktor/utils/io/core/BufferUtilsJs.kt | 4 + .../io/ktor/utils/io/core/InputArraysJS.kt | 4 +- ktor-io/js/src/io/ktor/utils/io/js/Decoder.kt | 1 + .../ktor/utils/io/js/TextDecoderFallback.kt | 2 +- .../ktor/utils/io/TextDecoderFallbackTest.kt | 4 +- .../src/io/ktor/utils/io/ByteBufferChannel.kt | 14 +- .../jvm/src/io/ktor/utils/io/ByteChannel.kt | 1 - .../ktor/utils/io/ByteChannelSequentialJVM.kt | 9 +- .../src/io/ktor/utils/io/ByteWriteChannel.kt | 1 - ktor-io/jvm/src/io/ktor/utils/io/Delimited.kt | 7 + .../src/io/ktor/utils/io/ExceptionUtilsJvm.kt | 2 +- .../src/io/ktor/utils/io/LookAheadSession.kt | 6 +- .../src/io/ktor/utils/io/NativeUtilsJvm.kt | 2 - .../io/ktor/utils/io/bits/MemoryFactoryJvm.kt | 1 + .../src/io/ktor/utils/io/bits/MemoryJvm.kt | 3 +- .../src/io/ktor/utils/io/charsets/Strings.kt | 8 +- .../jvm/src/io/ktor/utils/io/charsets/UTF.kt | 27 +- .../io/ktor/utils/io/concurrent/SharedJvm.kt | 4 +- .../io/ktor/utils/io/core/BufferUtilsJvm.kt | 8 +- .../src/io/ktor/utils/io/core/ByteBuffers.kt | 11 +- .../ktor/utils/io/internal/ReadSessionImpl.kt | 1 + .../src/io/ktor/utils/io/internal/Strings.kt | 8 +- .../utils/io/internal/WriteSessionImpl.kt | 3 +- .../io/ktor/utils/io/jvm/javaio/Reading.kt | 4 +- .../jvm/src/io/ktor/utils/io/nio/Channels.kt | 2 +- .../io/ktor/utils/io/pool/ByteBufferPools.kt | 2 - .../BlockingAdaptersOnProhibitedThreadTest.kt | 1 + .../io/ByteBufferChannelLookAheadTest.kt | 1 + .../io/ktor/utils/io/ByteBufferChannelTest.kt | 1 + .../utils/io/BytePacketBuildTestExtended.kt | 9 +- .../jvm/test/io/ktor/utils/io/ChannelsTest.kt | 2 +- .../ktor/utils/io/ByteWriteChannelNative.kt | 1 - .../src/io/ktor/utils/io/NativeUtilsNative.kt | 3 - .../ktor/utils/io/bits/MemoryFactoryNative.kt | 3 +- .../src/io/ktor/utils/io/bits/MemoryNative.kt | 2 +- .../ktor/utils/io/charsets/CharsetNative.kt | 10 +- .../ktor/utils/io/concurrent/SharedNative.kt | 1 - .../ktor/utils/io/core/BufferUtilsNative.kt | 2 + .../io/ktor/utils/io/errors/PosixErrors.kt | 18 - .../io/ktor/utils/io/streams/PosixInput.kt | 2 - .../src/io/ktor/utils/io/streams/PosixIo.kt | 19 - .../io/ktor/utils/io/streams/PosixOutput.kt | 2 - .../io/ByteChannelNativeConcurrentTest.kt | 2 + .../utils/io/BytePacketBuilderExtendedTest.kt | 9 +- .../io/ktor/utils/io/ChunkBufferNativeTest.kt | 14 +- .../test/io/ktor/utils/io/PosixIoTest.kt | 42 +- ktor-network/build.gradle.kts | 3 +- .../network/selector/SelectorManagerCommon.kt | 3 - .../io/ktor/network/sockets/TypeOfService.kt | 6 +- .../network/selector/SelectorManagerJs.kt | 3 - .../selector/InterestSuspensionsMap.kt | 10 +- .../io/ktor/network/selector/JvmSelector.kt | 3 - .../network/selector/LockFreeMPSCQueue.kt | 1 - .../ktor/network/selector/SelectorManager.kt | 4 +- .../src/io/ktor/network/sockets/CIOReader.kt | 1 - .../src/io/ktor/network/sockets/CIOWriter.kt | 3 +- .../network/sockets/DatagramSendChannel.kt | 1 - .../src/io/ktor/network/sockets/SocketImpl.kt | 4 - .../network/sockets/TCPSocketBuilderJvm.kt | 1 + .../jvm/src/io/ktor/network/util/Pools.kt | 5 - .../network/sockets/tests/UDPSocketTest.kt | 7 +- .../io/ktor/network/util/StartTimeoutTest.kt | 1 + .../common/src/io/ktor/network/tls/OID.kt | 2 - .../tls/extensions/SignatureAlgorithm.kt | 1 - .../jvm/src/io/ktor/network/tls/Headers.kt | 2 - .../jvm/src/io/ktor/network/tls/Render.kt | 2 +- .../ktor/network/tls/TLSClientSessionJvm.kt | 6 +- .../jvm/src/io/ktor/network/tls/Utils.kt | 7 +- .../ktor/network/tls/tests/ConnectionTests.kt | 3 +- .../network/tls/tests/TLSConfigBuilderTest.kt | 1 + .../io/ktor/network/selector/SelectUtils.kt | 2 + .../ktor/network/selector/SelectorManager.kt | 3 - .../network/sockets/ConnectUtilsNative.kt | 4 +- .../network/sockets/TCPServerSocketNative.kt | 3 +- .../ktor/network/sockets/TCPSocketNative.kt | 19 +- .../src/io/ktor/network/util/SocketAddress.kt | 5 +- .../ktor/network/util/SocketAddressUtils.kt | 2 + .../src/io/ktor/network/util/SocketUtils.kt | 4 +- ktor-network/posix/test/SocketTest.kt | 2 + ktor-server/api/ktor-server.api | 1 - .../io/ktor/server/application/Application.kt | 1 + .../server/application/ApplicationPlugin.kt | 3 +- .../server/config/MapApplicationConfig.kt | 6 +- .../jvm/src/io/ktor/server/http/Push.kt | 1 + .../http/content/StaticContentResolution.kt | 1 + .../server/plugins/OriginConnectionPoint.kt | 2 + .../response/ApplicationResponseFunctions.kt | 3 +- .../io/ktor/server/routing/RouteSelector.kt | 8 +- .../jvm/src/io/ktor/server/routing/Routing.kt | 1 + .../io/ktor/server/routing/RoutingBuilder.kt | 2 + .../io/ktor/server/util/CopyOnWriteHashMap.kt | 3 + .../jvm/src/io/ktor/server/util/Parameters.kt | 7 - .../jvm/src/io/ktor/server/util/Paths.kt | 3 +- .../ktor/tests/http/PathNormalizationTest.kt | 16 +- .../content/StaticContentResolutionTest.kt | 2 + .../tests/utils/CopyOnWriteHashMapTest.kt | 2 + .../io/ktor/server/cio/CIOApplicationCall.kt | 1 + .../ktor/server/cio/CIOApplicationEngine.kt | 5 +- .../ktor/server/cio/CIOApplicationRequest.kt | 3 + .../io/ktor/server/cio/backend/HttpServer.kt | 2 +- .../io/ktor/tests/server/cio/RAWExample.kt | 1 + .../engine/ApplicationEngineEnvironment.kt | 1 + .../server/engine/BaseApplicationEngine.kt | 1 + .../src/io/ktor/server/engine/CommandLine.kt | 1 + .../server/engine/DefaultEnginePipeline.kt | 2 + .../io/ktor/server/engine/DefaultTransform.kt | 3 + .../io/ktor/server/engine/EmbeddedServer.kt | 1 + .../engine/EngineContextCancellationHelper.kt | 2 + ...licationEngineEnvironmentReloadingTests.kt | 3 + .../hosts/ReceiveBlockingPrimitiveTest.kt | 2 +- .../ktor/server/jetty/JettyApplicationCall.kt | 2 + .../server/jetty/JettyApplicationEngine.kt | 2 + .../jetty/JettyApplicationEngineBase.kt | 1 + .../server/jetty/JettyApplicationResponse.kt | 4 +- .../io/ktor/server/jetty/JettyKtorHandler.kt | 5 +- .../server/jetty/internal/JettyUpgradeImpl.kt | 2 + .../ktor/server/netty/NettyApplicationCall.kt | 6 +- .../netty/NettyApplicationCallHandler.kt | 6 +- .../server/netty/NettyApplicationEngine.kt | 1 + .../server/netty/NettyApplicationResponse.kt | 3 +- .../server/netty/NettyChannelInitializer.kt | 3 +- .../server/netty/cio/NettyRequestQueue.kt | 21 +- .../server/netty/cio/NettyResponsePipeline.kt | 13 +- .../server/netty/cio/RequestBodyHandler.kt | 26 +- .../netty/http1/NettyHttp1ApplicationCall.kt | 2 + .../http1/NettyHttp1ApplicationRequest.kt | 2 + .../http1/NettyHttp1ApplicationResponse.kt | 5 +- .../server/netty/http1/NettyHttp1Handler.kt | 2 + .../netty/http2/NettyHttp2ApplicationCall.kt | 2 + .../http2/NettyHttp2ApplicationRequest.kt | 2 + .../http2/NettyHttp2ApplicationResponse.kt | 4 +- .../server/netty/http2/NettyHttp2Handler.kt | 11 +- .../io/ktor/server/auth/jwt/JWTAuthSchemes.kt | 6 +- .../jvm/src/io/ktor/server/auth/ldap/Ldap.kt | 2 +- .../io/ktor/tests/auth/ldap/LdapAuthTest.kt | 1 + .../ktor-server-cors/api/ktor-server-cors.api | 2 +- .../jvm/src/io/ktor/server/plugins/CORS.kt | 3 + .../io/ktor/server/plugins/KotlinTimeJvm.kt | 4 +- .../io/ktor/server/plugins/DefaultHeaders.kt | 2 +- .../server/plugins/ForwardHeaderSupport.kt | 2 + .../ktor-server-hsts/api/ktor-server-hsts.api | 2 +- .../io/ktor/server/plugins/KotlinTimeJvm.kt | 4 +- .../api/ktor-server-sessions.api | 2 +- .../jvm/src/io/ktor/server/sessions/Cache.kt | 29 +- .../io/ktor/server/sessions/CacheStorage.kt | 2 - .../ktor/server/sessions/DirectoryStorage.kt | 2 + .../io/ktor/server/sessions/KotlinTimeJvm.kt | 4 +- .../src/io/ktor/server/sessions/Sessions.kt | 4 +- .../io/ktor/server/velocity/VelocityTools.kt | 7 +- .../ktor/tests/velocity/VelocityToolsTest.kt | 2 + .../api/ktor-server-websockets.api | 6 +- .../ktor/server/websocket/KotlinDurations.kt | 6 +- .../src/io/ktor/server/websocket/Routing.kt | 1 + .../ktor/server/websocket/WebSocketUpgrade.kt | 2 + .../tests/websocket/DefaultWebSocketTest.kt | 5 +- .../io/ktor/tests/websocket/ParserTest.kt | 6 +- .../ktor/tests/websocket/RawWebSocketTest.kt | 4 +- .../tests/websocket/WebSocketEngineSuite.kt | 4 +- .../io/ktor/tests/websocket/WebSocketTest.kt | 4 +- .../io/ktor/server/servlet/BlockingServlet.kt | 3 + .../src/io/ktor/server/servlet/JAASBridge.kt | 3 + .../src/io/ktor/server/servlet/KtorServlet.kt | 4 +- .../servlet/ServletApplicationEngine.kt | 1 + .../io/ktor/server/servlet/ServletReader.kt | 12 +- .../io/ktor/server/servlet/ServletUpgrade.kt | 1 + .../io/ktor/server/servlet/ServletWriter.kt | 4 +- .../io/ktor/server/servlet/WebResources.kt | 2 + .../io/ktor/server/testing/EngineTestBase.kt | 29 +- .../server/testing/HighLoadHttpGenerator.kt | 2 +- .../server/testing/TestApplicationCall.kt | 8 +- .../server/testing/TestApplicationEngine.kt | 21 +- .../server/testing/TestApplicationResponse.kt | 1 + .../testing/client/TestHttpClientEngine.kt | 3 +- .../jvm/src/io/ktor/server/testing/Utils.kt | 11 +- .../testing/suites/CompressionTestSuite.kt | 3 + .../testing/suites/HttpServerTestSuite.kt | 2 + .../testing/suites/SustainabilityTestSuite.kt | 10 +- .../ktor/tests/server/http/DefaultPushTest.kt | 2 + .../tests/server/plugins/CallLoggingTest.kt | 4 +- .../tests/server/plugins/StatusPageTest.kt | 3 +- .../server/routing/RoutingResolveTest.kt | 4 +- .../ktor/tests/server/sessions/SessionTest.kt | 55 +- .../server/tomcat/TomcatApplicationEngine.kt | 39 +- .../ktor/tests/http/PathNormalizationTest.kt | 9 +- .../content/StaticContentResolutionTest.kt | 1 + .../tests/utils/CopyOnWriteHashMapTest.kt | 1 + .../common/src/io/ktor/events/Events.kt | 2 + .../jvm/src/GsonConverter.kt | 2 +- .../build.gradle.kts | 2 + ktor-test-dispatcher/build.gradle.kts | 3 +- ktor-test-dispatcher/js/src/TestJs.kt | 1 + ktor-utils/api/ktor-utils.api | 4 +- ktor-utils/build.gradle.kts | 3 +- ktor-utils/common/src/io/ktor/util/Base64.kt | 6 - .../common/src/io/ktor/util/ByteChannels.kt | 2 +- .../src/io/ktor/util/CaseInsensitiveMap.kt | 1 - ktor-utils/common/src/io/ktor/util/Charset.kt | 4 +- .../common/src/io/ktor/util/Collections.kt | 2 - .../src/io/ktor/util/CoroutinesUtils.kt | 3 - ktor-utils/common/src/io/ktor/util/Crypto.kt | 4 - ktor-utils/common/src/io/ktor/util/Lock.kt | 2 - .../common/src/io/ktor/util/PlatformUtils.kt | 1 - ktor-utils/common/src/io/ktor/util/Ranges.kt | 1 - .../common/src/io/ktor/util/StringValues.kt | 3 - ktor-utils/common/src/io/ktor/util/Text.kt | 8 +- .../common/src/io/ktor/util/cio/Readers.kt | 1 + .../io/ktor/util/collections/ConcurrentMap.kt | 1 - .../io/ktor/util/collections/ConcurrentSet.kt | 1 - .../util/collections/internal/SharedList.kt | 2 - .../io/ktor/util/converters/DataConversion.kt | 8 +- .../common/src/io/ktor/util/date/Date.kt | 4 +- .../src/io/ktor/util/date/GMTDateParser.kt | 1 - .../io/ktor/util/network/NetworkAddress.kt | 2 + .../src/io/ktor/util/pipeline/Pipeline.kt | 1 - .../common/test/io/ktor/util/ChannelTest.kt | 3 + .../common/test/io/ktor/util/GMTDateTest.kt | 4 +- .../js/src/io/ktor/util/CoroutinesUtilsJs.kt | 1 - ktor-utils/js/src/io/ktor/util/CryptoJs.kt | 8 +- ktor-utils/js/src/io/ktor/util/LockJs.kt | 1 - .../jvm/src/io/ktor/util/BufferViewJvm.kt | 1 - .../jvm/src/io/ktor/util/CollectionsJvm.kt | 1 - .../src/io/ktor/util/CoroutinesUtilsJvm.kt | 1 - ktor-utils/jvm/src/io/ktor/util/CryptoJvm.kt | 5 +- ktor-utils/jvm/src/io/ktor/util/Deflater.kt | 2 + ktor-utils/jvm/src/io/ktor/util/LockJvm.kt | 1 - ktor-utils/jvm/src/io/ktor/util/NIO.kt | 5 - ktor-utils/jvm/src/io/ktor/util/Nonce.kt | 116 ++-- .../jvm/src/io/ktor/util/cio/FileChannels.kt | 1 + .../jvm/src/io/ktor/util/date/DateJvm.kt | 1 - .../ktor/util/internal/LockFreeLinkedList.kt | 7 - .../tests/utils/PipelineStackFramesTest.kt | 118 ----- .../test/io/ktor/tests/utils/PipelineTest.kt | 15 - .../src/io/ktor/util/CollectionsNative.kt | 1 - .../src/io/ktor/util/CoroutinesUtilsNative.kt | 1 - .../posix/src/io/ktor/util/CryptoNative.kt | 2 - .../posix/src/io/ktor/util/LockNative.kt | 1 - .../posix/src/io/ktor/util/PlatformUtils.kt | 1 - .../ktor/util/network/NetworkAddressNative.kt | 2 + settings.gradle | 138 ----- settings.gradle.kts | 140 +++++ 467 files changed, 1861 insertions(+), 1741 deletions(-) create mode 100644 buildSrc/src/main/kotlin/Compilations.kt create mode 100644 buildSrc/src/main/kotlin/KtorBuildProperties.kt delete mode 100644 ktor-client/ktor-client-plugins/ktor-client-encoding/build.gradle.kts delete mode 100644 ktor-utils/jvm/test/io/ktor/tests/utils/PipelineStackFramesTest.kt delete mode 100644 settings.gradle create mode 100644 settings.gradle.kts diff --git a/build.gradle.kts b/build.gradle.kts index 6db770d2025..4fe598914fd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -77,11 +77,8 @@ extra["publishLocal"] = project.hasProperty("publishLocal") val configuredVersion: String by extra -apply(from = "gradle/experimental.gradle") apply(from = "gradle/verifier.gradle") -val experimentalAnnotations: List by extra - /** * `darwin` is subset of `posix`. * Don't create `posix` and `darwin` sourceSets in single project. @@ -146,6 +143,7 @@ allprojects { if (nonDefaultProjectStructure.contains(project.name)) return@allprojects apply(plugin = "kotlin-multiplatform") + apply(plugin = "kotlinx-atomicfu") apply(from = rootProject.file("gradle/utility.gradle")) @@ -166,30 +164,39 @@ allprojects { maybeCreate("testOutput") } + kotlin { + targets.all { + + if (this is org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget) { + irTarget?.compilations?.all { + configureCompilation() + } + + } + compilations.all { + configureCompilation() + } + } + if (!disabledExplicitApiModeProjects.contains(project.name)) { explicitApi() } - sourceSets.matching { !(it.name in listOf("main", "test")) }.all { - val srcDir = if (name.endsWith("Main")) "src" else "test" - val resourcesPrefix = if (name.endsWith("Test")) "test-" else "" - val platform = name.dropLast(4) + sourceSets + .matching { it.name !in listOf("main", "test") } + .all { + val srcDir = if (name.endsWith("Main")) "src" else "test" + val resourcesPrefix = if (name.endsWith("Test")) "test-" else "" + val platform = name.dropLast(4) - kotlin.srcDir("$platform/$srcDir") - resources.srcDir("$platform/${resourcesPrefix}resources") + kotlin.srcDir("$platform/$srcDir") + resources.srcDir("$platform/${resourcesPrefix}resources") - languageSettings.apply { - progressiveMode = true - experimentalAnnotations.forEach { optIn(it) } - - if (project.path.startsWith(":ktor-server:ktor-server") - && project.name != "ktor-server-core" - ) { - optIn("io.ktor.server.engine.EngineAPI") + languageSettings.apply { + progressiveMode = true } } - } } val skipPublish: List by rootProject.extra diff --git a/buildSrc/src/main/kotlin/Compilations.kt b/buildSrc/src/main/kotlin/Compilations.kt new file mode 100644 index 00000000000..f92b7c453e3 --- /dev/null +++ b/buildSrc/src/main/kotlin/Compilations.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +import org.jetbrains.kotlin.gradle.dsl.* +import org.jetbrains.kotlin.gradle.plugin.* + +fun KotlinCompilation.configureCompilation() { + kotlinOptions { + if (platformType == KotlinPlatformType.jvm) { + allWarningsAsErrors = true + } + freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn" + } +} diff --git a/buildSrc/src/main/kotlin/KotlinExtensions.kt b/buildSrc/src/main/kotlin/KotlinExtensions.kt index c0ca1e91b75..aebd4caff49 100644 --- a/buildSrc/src/main/kotlin/KotlinExtensions.kt +++ b/buildSrc/src/main/kotlin/KotlinExtensions.kt @@ -1,12 +1,25 @@ -import org.gradle.api.* -import org.gradle.kotlin.dsl.* -import org.jetbrains.kotlin.gradle.dsl.* /* * Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +import org.gradle.api.* +import org.gradle.kotlin.dsl.* +import org.jetbrains.kotlin.gradle.dsl.* +import org.jetbrains.kotlin.gradle.plugin.* fun Project.kotlin(block: KotlinMultiplatformExtension.() -> Unit) { configure(block) } val Project.kotlin: KotlinMultiplatformExtension get() = the() + +val NamedDomainObjectContainer.jvmMain: NamedDomainObjectProvider + get() = named("jvmMain") + +val NamedDomainObjectContainer.jvmTest: NamedDomainObjectProvider + get() = named("jvmTest") + +val NamedDomainObjectContainer.commonMain: NamedDomainObjectProvider + get() = named("commonMain") + +val NamedDomainObjectContainer.commonTest: NamedDomainObjectProvider + get() = named("commonTest") diff --git a/buildSrc/src/main/kotlin/KtorBuildProperties.kt b/buildSrc/src/main/kotlin/KtorBuildProperties.kt new file mode 100644 index 00000000000..efae91e0858 --- /dev/null +++ b/buildSrc/src/main/kotlin/KtorBuildProperties.kt @@ -0,0 +1,69 @@ +import KtorBuildProperties.jdk8Modules +import org.gradle.api.* + +/* + * Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +private val java_version: String = System.getProperty("java.version", "8.0.0") + +private val versionComponents = java_version + .split(".") + .take(2) + .filter { it.isNotBlank() } + .map { Integer.parseInt(it) } + +object KtorBuildProperties { + + val jettyAlpnBootVersion: String? = when (java_version) { + "1.8.0_191", + "1.8.0_192", + "1.8.0_201", + "1.8.0_202", + "1.8.0_211", + "1.8.0_212", + "1.8.0_221", + "1.8.0_222", + "1.8.0_231", + "1.8.0_232", + "1.8.0_241", + "1.8.0_242" -> "8.1.13.v20181017" + else -> null + } + + @JvmStatic + val ideaActive: Boolean = System.getProperty("idea.active") == "true" + + @JvmStatic + val currentJdk = if (versionComponents[0] == 1) versionComponents[1] else versionComponents[0] + + val jdk8Modules = listOf( + "ktor-client-tests", + + "ktor-server-core", "ktor-server-host-common", "ktor-server-servlet", "ktor-server-netty", "ktor-server-tomcat", + "ktor-server-test-host", "ktor-server-test-suites", + + "ktor-websockets", "ktor-webjars", "ktor-metrics", "ktor-server-sessions", "ktor-auth", "ktor-auth-jwt", + + "ktor-network-tls-certificates" + ) + + val jdk7Modules = listOf( + "ktor-http", + "ktor-utils", + "ktor-network-tls", + "ktor-websockets" + ) + + val jdk11Modules = listOf( + "ktor-client-java" + ) + + @JvmStatic + fun projectJdk(name: String): Int = when (name) { + in jdk8Modules -> 8 + in jdk11Modules -> 11 + in jdk7Modules -> 7 + else -> 6 + } +} diff --git a/buildSrc/src/main/kotlin/Train.kt b/buildSrc/src/main/kotlin/Train.kt index ddc48c2bca7..a7772386c5c 100644 --- a/buildSrc/src/main/kotlin/Train.kt +++ b/buildSrc/src/main/kotlin/Train.kt @@ -54,7 +54,7 @@ fun Project.setupTrainForSubproject() { val serialization_version: String by extra extra["kotlin_version"] = rootProject.properties["kotlin_snapshot_version"] - var kotlin_version: String by extra + val kotlin_version: String by extra println("Using Kotlin $kotlin_version for project $this") val deployVersion = properties["DeployVersion"] if (deployVersion != null) version = deployVersion diff --git a/gradle/darwin.gradle b/gradle/darwin.gradle index 50b1b01c4be..5dbbfb5864e 100644 --- a/gradle/darwin.gradle +++ b/gradle/darwin.gradle @@ -1,10 +1,8 @@ apply from: rootProject.file("gradle/ide.gradle") -apply plugin: "kotlinx-atomicfu" - kotlin { targets { - if (project.ext.ideaActive) { + if (KtorBuildProperties.ideaActive) { fromPreset(project.ext.ideaPreset, 'darwin') } else { fromPreset(presets.iosArm64, 'iosArm64') @@ -20,15 +18,10 @@ kotlin { } } sourceSets { - darwinMain.dependencies { - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" - implementation "org.jetbrains.kotlinx:atomicfu:$atomicfu_version" - } - darwinMain { dependsOn commonMain } darwinTest - if (!project.ext.ideaActive) { + if (!KtorBuildProperties.ideaActive) { configure([iosArm32Main, iosArm64Main, iosX64Main, macosX64Main, tvosArm64Main, tvosX64Main, watchosArm32Main, watchosArm64Main, watchosX86Main, watchosX64Main]) { dependsOn darwinMain } diff --git a/gradle/jvm.gradle b/gradle/jvm.gradle index e5796eb7c25..efcb86cebff 100644 --- a/gradle/jvm.gradle +++ b/gradle/jvm.gradle @@ -2,17 +2,7 @@ * Copyright 2014-2020 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -apply from: rootProject.file('gradle/jdk.gradle') - -def jdk = 6 - -if (project.name in project.ext.jdk11Modules) { - jdk = 11 -} else if (project.name in project.ext.jdk8Modules) { - jdk = 8 -} else if (project.name in project.ext.jdk7Modules) { - jdk = 7 -} +def jdk = KtorBuildProperties.projectJdk(name) String lookupJdk(int startingFrom) { return (startingFrom..20) @@ -23,19 +13,8 @@ String lookupJdk(int startingFrom) { def jdkHome = lookupJdk(jdk) -int currentJdk = ext.currentJdk - -apply plugin: "kotlinx-atomicfu" - kotlin { jvm { - compilations.all { - if (rootProject.ext.jvm_ir_enabled) { - kotlinOptions.useIR = true - } - - kotlinOptions.freeCompilerArgs += ["-XXLanguage:+InlineClasses", "-Xuse-14-inline-classes-mangling-scheme"] - } } task jarTest(type: Jar, dependsOn: jvmTestClasses) { diff --git a/gradle/posix.gradle b/gradle/posix.gradle index 2a0be95451a..74be2d17c28 100644 --- a/gradle/posix.gradle +++ b/gradle/posix.gradle @@ -1,7 +1,5 @@ apply from: rootProject.file("gradle/ide.gradle") -apply plugin: "kotlinx-atomicfu" - def getHostName() { def target = System.getProperty("os.name") if (target == 'Linux') return 'linux' @@ -46,7 +44,7 @@ if (host == 'windows' && skipMingw) return kotlin { targets { - if (project.ext.ideaActive) { + if (KtorBuildProperties.ideaActive) { project.ext.hostname = host fromPreset(project.ext.ideaPreset, 'posix') project.ext.nativeTargets = [posix] @@ -109,15 +107,10 @@ kotlin { project.ext.nativeCompilations += project.ext.nativeTargets.collect { it.compilations.main } } sourceSets { - posixMain.dependencies { - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" - implementation "org.jetbrains.kotlinx:atomicfu:$atomicfu_version" - } - - posixTest posixMain { dependsOn commonMain } + posixTest - if (!project.ext.ideaActive) { + if (!KtorBuildProperties.ideaActive) { configure(project.ext.nativeTargets.collect { getByName(it.name + 'Main') }) { dependsOn posixMain } diff --git a/gradle/utility.gradle b/gradle/utility.gradle index 3bffb151ee0..88c35bb037c 100644 --- a/gradle/utility.gradle +++ b/gradle/utility.gradle @@ -1,4 +1,3 @@ -project.ext.ideaActive = System.getProperty('idea.active') == 'true' kotlin { targets { @@ -11,7 +10,7 @@ kotlin { project.ext.isMacosHost = macosEnabled project.ext.isWinHost = winEnabled - if (project.ext.ideaActive) { + if (KtorBuildProperties.ideaActive) { def ideaPreset = presets.linuxX64 if (macosEnabled) ideaPreset = presets.macosX64 if (winEnabled) ideaPreset = presets.mingwX64 @@ -20,25 +19,3 @@ kotlin { } } } - -def java_version = System.properties["java.version"] - -switch (java_version) { - case '1.8.0_191': - case '1.8.0_192': - case '1.8.0_201': - case '1.8.0_202': - case '1.8.0_211': - case '1.8.0_212': - case '1.8.0_221': - case '1.8.0_222': - case '1.8.0_231': - case '1.8.0_232': - case '1.8.0_241': - case '1.8.0_242': - project.ext.jetty_alpn_boot_version = "8.1.13.v20181017" - break - default: - project.ext.jetty_alpn_boot_version = null - break -} diff --git a/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt b/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt index a68868cb85d..ac7dbd1ace1 100644 --- a/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt +++ b/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt @@ -11,6 +11,7 @@ import io.ktor.client.request.* import io.ktor.client.utils.* import io.ktor.http.* import io.ktor.http.content.* +import io.ktor.util.* import io.ktor.util.date.* import io.ktor.utils.io.* import io.ktor.utils.io.jvm.javaio.* @@ -26,6 +27,7 @@ private val METHODS_WITHOUT_BODY = listOf(HttpMethod.Get, HttpMethod.Head) /** * Android client engine */ +@OptIn(InternalAPI::class) public class AndroidClientEngine(override val config: AndroidEngineConfig) : HttpClientEngineBase("ktor-android") { override val dispatcher: CoroutineDispatcher by lazy { @@ -85,14 +87,14 @@ public class AndroidClientEngine(override val config: AndroidEngineConfig) : Htt outgoingContent.writeTo(outputStream, callContext) } - return connection.timeoutAwareConnection(data) { connection -> - val responseCode = connection.responseCode - val responseMessage = connection.responseMessage + return connection.timeoutAwareConnection(data) { current -> + val responseCode = current.responseCode + val responseMessage = current.responseMessage val statusCode = responseMessage?.let { HttpStatusCode(responseCode, it) } ?: HttpStatusCode.fromValue(responseCode) - val content: ByteReadChannel = connection.content(callContext, data) - val headerFields: Map> = connection.headerFields + val content: ByteReadChannel = current.content(callContext, data) + val headerFields: Map> = current.headerFields .mapKeys { it.key?.lowercase(Locale.getDefault()) ?: "" } .filter { it.key.isNotBlank() } @@ -110,6 +112,8 @@ public class AndroidClientEngine(override val config: AndroidEngineConfig) : Htt } } +@OptIn(DelicateCoroutinesApi::class) +@Suppress("BlockingMethodInNonBlockingContext") internal suspend fun OutgoingContent.writeTo( stream: OutputStream, callContext: CoroutineContext diff --git a/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidURLConnectionUtils.kt b/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidURLConnectionUtils.kt index 1d5c1501709..5ee33b908a9 100644 --- a/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidURLConnectionUtils.kt +++ b/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidURLConnectionUtils.kt @@ -7,6 +7,7 @@ package io.ktor.client.engine.android import io.ktor.client.network.sockets.* import io.ktor.client.plugins.* import io.ktor.client.request.* +import io.ktor.util.* import io.ktor.util.cio.* import io.ktor.utils.io.* import io.ktor.utils.io.jvm.javaio.* @@ -18,6 +19,7 @@ import kotlin.coroutines.* /** * Setup [HttpURLConnection] timeout configuration using [HttpTimeout.HttpTimeoutCapabilityConfiguration] as a source. */ +@OptIn(InternalAPI::class) internal fun HttpURLConnection.setupTimeoutAttributes(requestData: HttpRequestData) { requestData.getCapabilityOrNull(HttpTimeout)?.let { timeoutAttributes -> timeoutAttributes.connectTimeoutMillis?.let { connectTimeout = convertLongTimeoutToIntWithInfiniteAsZero(it) } @@ -30,6 +32,7 @@ internal fun HttpURLConnection.setupTimeoutAttributes(requestData: HttpRequestDa * Update [HttpURLConnection] timeout configuration to support request timeout. Required to support blocking * [HttpURLConnection.connect] call. */ +@OptIn(InternalAPI::class) private fun HttpURLConnection.setupRequestTimeoutAttributes( timeoutAttributes: HttpTimeout.HttpTimeoutCapabilityConfiguration ) { @@ -65,6 +68,7 @@ internal suspend fun HttpURLConnection.timeoutAwareConnection( /** * Establish connection and return correspondent [ByteReadChannel]. */ +@OptIn(InternalAPI::class) internal fun HttpURLConnection.content(callContext: CoroutineContext, request: HttpRequestData): ByteReadChannel = try { inputStream?.buffered() } catch (_: IOException) { diff --git a/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/ApacheEngine.kt b/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/ApacheEngine.kt index ff011de08c8..c1719700741 100644 --- a/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/ApacheEngine.kt +++ b/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/ApacheEngine.kt @@ -8,6 +8,7 @@ import io.ktor.client.engine.* import io.ktor.client.plugins.* import io.ktor.client.request.* import io.ktor.client.utils.* +import io.ktor.util.* import kotlinx.coroutines.* import org.apache.http.* import org.apache.http.impl.nio.client.* @@ -17,6 +18,7 @@ import java.net.* private const val MAX_CONNECTIONS_COUNT = 1000 private const val IO_THREAD_COUNT_DEFAULT = 4 +@OptIn(InternalAPI::class) internal class ApacheEngine(override val config: ApacheEngineConfig) : HttpClientEngineBase("ktor-apache") { override val dispatcher by lazy { diff --git a/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/ApacheRequestProducer.kt b/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/ApacheRequestProducer.kt index ca00824ee9a..502f59cb52a 100644 --- a/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/ApacheRequestProducer.kt +++ b/ktor-client/ktor-client-apache/jvm/src/io/ktor/client/engine/apache/ApacheRequestProducer.kt @@ -10,6 +10,7 @@ import io.ktor.client.plugins.* import io.ktor.client.request.* import io.ktor.http.* import io.ktor.http.content.* +import io.ktor.util.* import io.ktor.utils.io.* import kotlinx.coroutines.* import org.apache.http.* @@ -25,6 +26,7 @@ import org.apache.http.protocol.* import java.nio.* import kotlin.coroutines.* +@OptIn(InternalAPI::class) internal class ApacheRequestProducer( private val requestData: HttpRequestData, private val config: ApacheEngineConfig, @@ -41,6 +43,7 @@ internal class ApacheRequestProducer( private val producerJob = Job() override val coroutineContext: CoroutineContext = callContext + producerJob + @OptIn(DelicateCoroutinesApi::class) private val channel: ByteReadChannel = when (val body = requestData.body) { is OutgoingContent.ByteArrayContent -> ByteReadChannel(body.bytes()) is OutgoingContent.ProtocolUpgrade -> throw UnsupportedContentTypeException(body) @@ -152,6 +155,7 @@ internal class ApacheRequestProducer( } } +@OptIn(InternalAPI::class) private fun RequestConfig.Builder.setupTimeoutAttributes(requestData: HttpRequestData): RequestConfig.Builder = also { requestData.getCapabilityOrNull(HttpTimeout)?.let { timeoutAttributes -> timeoutAttributes.connectTimeoutMillis?.let { setConnectTimeout(convertLongTimeoutToIntWithInfiniteAsZero(it)) } diff --git a/ktor-client/ktor-client-apache/jvm/test/io/ktor/client/engine/apache/RequestProducerTest.kt b/ktor-client/ktor-client-apache/jvm/test/io/ktor/client/engine/apache/RequestProducerTest.kt index b566cd5d4cb..8f88e1e5857 100644 --- a/ktor-client/ktor-client-apache/jvm/test/io/ktor/client/engine/apache/RequestProducerTest.kt +++ b/ktor-client/ktor-client-apache/jvm/test/io/ktor/client/engine/apache/RequestProducerTest.kt @@ -17,8 +17,10 @@ import java.nio.* import kotlin.coroutines.* import kotlin.test.* +@kotlin.Suppress("BlockingMethodInNonBlockingContext") class RequestProducerTest { + @OptIn(InternalAPI::class) @Test fun testHeadersMerge() = runBlocking { val request = ApacheRequestProducer( @@ -82,6 +84,7 @@ class RequestProducerTest { producer.close() } + @OptIn(DelicateCoroutinesApi::class) @Test fun testProducingReadChannelContent() = runBlocking { val content = ByteChannel(true) @@ -120,6 +123,7 @@ class RequestProducerTest { producer.close() } + @OptIn(DelicateCoroutinesApi::class) @Test fun testProducingWriteChannelContent() = runBlocking { val body = ChannelWriterContent( @@ -157,6 +161,7 @@ class RequestProducerTest { producer.close() } + @OptIn(DelicateCoroutinesApi::class) @Test fun testProducingWriteChannelContentOnScale() = runBlocking { repeat(5000) { @@ -188,6 +193,7 @@ class RequestProducerTest { } } + @OptIn(InternalAPI::class) private fun producer(body: OutgoingContent, context: CoroutineContext) = ApacheRequestProducer( requestData = HttpRequestData( URLBuilder("https://example.com").build(), diff --git a/ktor-client/ktor-client-apache/jvm/test/io/ktor/client/engine/apache/ResponseConsumerTest.kt b/ktor-client/ktor-client-apache/jvm/test/io/ktor/client/engine/apache/ResponseConsumerTest.kt index 57c65b80bc9..3b87db8dbfb 100644 --- a/ktor-client/ktor-client-apache/jvm/test/io/ktor/client/engine/apache/ResponseConsumerTest.kt +++ b/ktor-client/ktor-client-apache/jvm/test/io/ktor/client/engine/apache/ResponseConsumerTest.kt @@ -17,6 +17,7 @@ import kotlin.test.* class ResponseConsumerTest { private val parentContext = Dispatchers.Main + Job() + @OptIn(InternalAPI::class) @Test fun testConsumeContent() { val body = object : OutgoingContent.WriteChannelContent() { diff --git a/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOEngine.kt b/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOEngine.kt index 7993699def6..7620f7577d8 100644 --- a/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOEngine.kt +++ b/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/CIOEngine.kt @@ -19,6 +19,7 @@ import kotlinx.coroutines.* import kotlinx.coroutines.channels.* import kotlin.coroutines.* +@OptIn(InternalAPI::class, DelicateCoroutinesApi::class) internal class CIOEngine( override val config: CIOEngineConfig ) : HttpClientEngineBase("ktor-cio") { diff --git a/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/Endpoint.kt b/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/Endpoint.kt index 48b782498d8..f0e198a4ddc 100644 --- a/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/Endpoint.kt +++ b/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/Endpoint.kt @@ -10,6 +10,7 @@ import io.ktor.client.plugins.* import io.ktor.client.request.* import io.ktor.network.sockets.* import io.ktor.network.tls.* +import io.ktor.util.* import io.ktor.util.date.* import io.ktor.util.network.* import io.ktor.utils.io.* @@ -76,7 +77,7 @@ internal class Endpoint( } private suspend fun makePipelineRequest(task: RequestTask) { - if (deliveryPoint.offer(task)) return + if (deliveryPoint.trySend(task).isSuccess) return val connections = connections.value if (connections < config.endpoint.maxConnectionsPerRoute) { @@ -91,6 +92,7 @@ internal class Endpoint( deliveryPoint.send(task) } + @OptIn(InternalAPI::class) private fun makeDedicatedRequest( task: RequestTask ): Job = launch(task.context + CoroutineName("DedicatedRequest")) { diff --git a/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/utils.kt b/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/utils.kt index 73c821cfb3c..405fc0ff82c 100644 --- a/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/utils.kt +++ b/ktor-client/ktor-client-cio/common/src/io/ktor/client/engine/cio/utils.kt @@ -10,6 +10,7 @@ import io.ktor.client.request.* import io.ktor.http.* import io.ktor.http.cio.* import io.ktor.http.content.* +import io.ktor.util.* import io.ktor.util.date.* import io.ktor.utils.io.* import io.ktor.utils.io.core.* @@ -18,6 +19,7 @@ import io.ktor.utils.io.errors.EOFException import kotlinx.coroutines.* import kotlin.coroutines.* +@OptIn(InternalAPI::class) internal suspend fun HttpRequestData.write( output: ByteWriteChannel, callContext: CoroutineContext, @@ -104,6 +106,7 @@ internal suspend fun HttpRequestData.write( } } +@OptIn(DelicateCoroutinesApi::class) internal suspend fun readResponse( requestTime: GMTDate, request: HttpRequestData, @@ -214,6 +217,7 @@ internal fun HttpStatusCode.isInformational(): Boolean = (value / 100) == 1 /** * Wrap channel so that [ByteWriteChannel.close] of the resulting channel doesn't lead to closing of the base channel. */ +@OptIn(DelicateCoroutinesApi::class) internal fun ByteWriteChannel.withoutClosePropagation( coroutineContext: CoroutineContext, closeOnCoroutineCompletion: Boolean = true diff --git a/ktor-client/ktor-client-cio/jvm/src/io/ktor/client/engine/cio/Exceptions.kt b/ktor-client/ktor-client-cio/jvm/src/io/ktor/client/engine/cio/Exceptions.kt index b847ffbf612..d9b5ad194f3 100644 --- a/ktor-client/ktor-client-cio/jvm/src/io/ktor/client/engine/cio/Exceptions.kt +++ b/ktor-client/ktor-client-cio/jvm/src/io/ktor/client/engine/cio/Exceptions.kt @@ -8,6 +8,7 @@ import io.ktor.client.plugins.* import io.ktor.client.request.* import io.ktor.util.* +@OptIn(InternalAPI::class) internal actual fun Throwable.mapToKtor(request: HttpRequestData): Throwable = when (cause?.rootCause) { is java.net.SocketTimeoutException -> SocketTimeoutException(request, cause) else -> cause diff --git a/ktor-client/ktor-client-cio/posix/src/io/ktor/client/engine/cio/LoaderNative.kt b/ktor-client/ktor-client-cio/posix/src/io/ktor/client/engine/cio/LoaderNative.kt index 213ee5ed478..a75c7d6efdf 100644 --- a/ktor-client/ktor-client-cio/posix/src/io/ktor/client/engine/cio/LoaderNative.kt +++ b/ktor-client/ktor-client-cio/posix/src/io/ktor/client/engine/cio/LoaderNative.kt @@ -5,9 +5,11 @@ package io.ktor.client.engine.cio import io.ktor.client.engine.* +import io.ktor.util.* private val initHook = CIO +@OptIn(InternalAPI::class) internal actual fun addToLoader() { engines.append(CIO) } diff --git a/ktor-client/ktor-client-core/build.gradle.kts b/ktor-client/ktor-client-core/build.gradle.kts index 4b1fbe7e282..db2ea831799 100644 --- a/ktor-client/ktor-client-core/build.gradle.kts +++ b/ktor-client/ktor-client-core/build.gradle.kts @@ -1,6 +1,5 @@ description = "Ktor http client" -val ideaActive: Boolean by project val coroutines_version: String by project val node_fetch_version: String by project diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt index bae8bc33624..41effaec7e8 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt @@ -69,7 +69,7 @@ public fun HttpClient( * This is a generic implementation that uses a specific engine [HttpClientEngine]. * @property engine: [HttpClientEngine] for executing requests. */ -@OptIn(InternalCoroutinesApi::class) +@OptIn(InternalCoroutinesApi::class, InternalAPI::class) public class HttpClient( public val engine: HttpClientEngine, private val userConfig: HttpClientConfig = HttpClientConfig() @@ -182,7 +182,7 @@ public class HttpClient( } /** - * Creates a new [HttpRequest] from a request [data] and a specific client [call]. + * Creates a new [HttpClientCall] from a request [builder]. */ internal suspend fun execute(builder: HttpRequestBuilder): HttpClientCall { monitor.raise(HttpRequestCreated, builder) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/call/Compatibility.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/call/Compatibility.kt index 09e2f7ea358..0433f14206c 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/call/Compatibility.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/call/Compatibility.kt @@ -32,5 +32,6 @@ public suspend inline fun HttpResponse.receive(): T = error("Use `bo * @throws NoTransformationFoundException If no transformation is found for the type [info]. * @throws DoubleReceiveException If already called [receive]. */ +@Suppress("UNUSED_PARAMETER") @Deprecated("Use `body` method instead", replaceWith = ReplaceWith("this.body(info)"), level = DeprecationLevel.ERROR) public suspend fun receive(info: TypeInfo): Any = error("Use `body` method instead") diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/call/HttpClientCall.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/call/HttpClientCall.kt index 4293af94ba9..125f76a3e27 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/call/HttpClientCall.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/call/HttpClientCall.kt @@ -71,6 +71,7 @@ public open class HttpClientCall internal constructor( protected open val allowDoubleReceive: Boolean = false + @OptIn(InternalAPI::class) protected open suspend fun getResponseContent(): ByteReadChannel = response.content /** @@ -80,6 +81,7 @@ public open class HttpClientCall internal constructor( * @throws NoTransformationFoundException If no transformation is found for the type [info]. * @throws DoubleReceiveException If already called [body]. */ + @OptIn(InternalAPI::class) public suspend fun body(info: TypeInfo): Any { try { if (response.instanceOf(info.type)) return response @@ -153,6 +155,7 @@ public suspend inline fun HttpResponse.body(): T = call.body(typeInf * @throws NoTransformationFoundException If no transformation is found for the type info [typeInfo]. * @throws DoubleReceiveException If already called [body]. */ +@Suppress("UNCHECKED_CAST") public suspend fun HttpResponse.body(typeInfo: TypeInfo): T = call.body(typeInfo) as T /** diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/call/SavedCall.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/call/SavedCall.kt index 94ddb5f6d31..7d04bb48230 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/call/SavedCall.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/call/SavedCall.kt @@ -17,7 +17,10 @@ import kotlin.coroutines.* internal class SavedHttpCall(client: HttpClient, private val responseBody: ByteArray) : HttpClientCall(client) { - /** Returns new read channel of a response body */ + /** + * Returns a channel with [responseBody] data. + */ + @OptIn(InternalAPI::class) override suspend fun getResponseContent(): ByteReadChannel { return ByteReadChannel(responseBody) } @@ -49,12 +52,14 @@ internal class SavedHttpResponse( override val coroutineContext: CoroutineContext = origin.coroutineContext + context + @OptIn(InternalAPI::class) override val content: ByteReadChannel = ByteReadChannel(body) } /** * Fetch data for [HttpClientCall] and close the origin. */ +@OptIn(InternalAPI::class) public suspend fun HttpClientCall.save(): HttpClientCall { val currentClient = client ?: error("Failed to save call in different native thread.") diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/content/ObservableContent.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/content/ObservableContent.kt index b0a4cb3e5ed..9daa79b9ea2 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/content/ObservableContent.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/content/ObservableContent.kt @@ -26,6 +26,7 @@ internal class ObservableContent( private val listener: ProgressListener ) : OutgoingContent.ReadChannelContent() { + @OptIn(DelicateCoroutinesApi::class) private val content: ByteReadChannel = when (delegate) { is ByteArrayContent -> ByteReadChannel(delegate.bytes()) is ProtocolUpgrade -> throw UnsupportedContentTypeException(delegate) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngine.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngine.kt index d0341bd3e64..f0399f47be7 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngine.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngine.kt @@ -85,6 +85,7 @@ public interface HttpClientEngine : CoroutineScope, Closeable { /** * Create call context and use it as a coroutine context to [execute] request. */ + @OptIn(InternalAPI::class) private suspend fun executeWithinCallContext(requestData: HttpRequestData): HttpResponseData { val callContext = createCallContext(requestData.executionContext) callContext.makeShared() diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/BodyProgress.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/BodyProgress.kt index 37909d6ceaa..b607f9fc50b 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/BodyProgress.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/BodyProgress.kt @@ -61,6 +61,7 @@ public class BodyProgress internal constructor() { } } +@OptIn(InternalAPI::class) internal fun HttpResponse.withObservableDownload(listener: ProgressListener): HttpResponse { val observableByteChannel = content.observable(coroutineContext, contentLength(), listener) return wrapWithContent(observableByteChannel) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultTransform.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultTransform.kt index b6011da6ac9..3097fdcbe41 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultTransform.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/DefaultTransform.kt @@ -9,6 +9,7 @@ import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* import io.ktor.http.content.* +import io.ktor.util.* import io.ktor.utils.io.* import io.ktor.utils.io.core.* import kotlinx.coroutines.* @@ -19,6 +20,7 @@ import kotlinx.coroutines.CancellationException * Usually installed by default so there is no need to use it * unless you have disabled it via [HttpClientConfig.useDefaultTransformers]. */ +@OptIn(InternalAPI::class) public fun HttpClient.defaultTransformers() { val client = this diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpCallValidator.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpCallValidator.kt index 33ae6274721..b4bc31cde2e 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpCallValidator.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpCallValidator.kt @@ -98,6 +98,7 @@ public class HttpCallValidator internal constructor( override fun prepare(block: Config.() -> Unit): HttpCallValidator { val config = Config().apply(block) + @Suppress("DEPRECATION") return HttpCallValidator( config.responseValidators.reversed(), config.responseExceptionHandlers.reversed(), @@ -105,6 +106,7 @@ public class HttpCallValidator internal constructor( ) } + @OptIn(InternalAPI::class) override fun install(plugin: HttpCallValidator, scope: HttpClient) { scope.requestPipeline.intercept(HttpRequestPipeline.Before) { try { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRedirect.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRedirect.kt index 25483b3a06e..6c2227d25ba 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRedirect.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRedirect.kt @@ -65,6 +65,7 @@ public class HttpRedirect { } } + @OptIn(InternalAPI::class) private suspend fun Sender.handleCall( context: HttpRequestBuilder, origin: HttpClientCall, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpTimeout.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpTimeout.kt index 7705c172e2c..1eedf97f961 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpTimeout.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpTimeout.kt @@ -32,7 +32,6 @@ public class HttpTimeout( /** * Creates a new instance of [HttpTimeoutCapabilityConfiguration]. */ - @InternalAPI public constructor( requestTimeoutMillis: Long? = null, connectTimeoutMillis: Long? = null, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCache.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCache.kt index be9fc4e614d..01134da7801 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCache.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCache.kt @@ -66,6 +66,7 @@ public class HttpCache( } } + @OptIn(InternalAPI::class) override fun install(plugin: HttpCache, scope: HttpClient) { val CachePhase = PipelinePhase("Cache") scope.sendPipeline.insertPhaseAfter(HttpSendPipeline.State, CachePhase) @@ -177,6 +178,7 @@ public class HttpCache( } } +@OptIn(InternalAPI::class) private fun mergedHeadersLookup( content: OutgoingContent, headerExtractor: (String) -> String?, diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCacheEntry.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCacheEntry.kt index 2a3c3224a80..e62bb1c40c5 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCacheEntry.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cache/HttpCacheEntry.kt @@ -7,10 +7,12 @@ package io.ktor.client.plugins.cache import io.ktor.client.call.* import io.ktor.client.statement.* import io.ktor.http.* +import io.ktor.util.* import io.ktor.util.date.* import io.ktor.utils.io.* import io.ktor.utils.io.core.* +@OptIn(InternalAPI::class) internal suspend fun HttpCacheEntry(response: HttpResponse): HttpCacheEntry { val body = response.content.readRemaining().readBytes() response.complete() diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/HttpCookies.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/HttpCookies.kt index 35e4d339387..03a82058da2 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/HttpCookies.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/cookies/HttpCookies.kt @@ -25,6 +25,7 @@ public class HttpCookies( private val storage: CookiesStorage, private val defaults: List Unit> ) : Closeable { + @OptIn(DelicateCoroutinesApi::class) private val initializer: Job = GlobalScope.launch(Dispatchers.Unconfined) { defaults.forEach { it(storage) } } diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/DelegatedCall.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/DelegatedCall.kt index b9217a95de7..ef894e7a966 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/DelegatedCall.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/DelegatedCall.kt @@ -9,6 +9,7 @@ import io.ktor.client.call.* import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* +import io.ktor.util.* import io.ktor.util.date.* import io.ktor.utils.io.* import kotlin.coroutines.* @@ -21,6 +22,7 @@ import kotlin.coroutines.* ReplaceWith("wrapWithContent(content)"), level = DeprecationLevel.ERROR ) +@Suppress("UNUSED_PARAMETER") public fun HttpClientCall.wrapWithContent( content: ByteReadChannel, shouldCloseOrigin: Boolean @@ -38,10 +40,12 @@ public fun HttpClientCall.wrapWithContent(content: ByteReadChannel): HttpClientC /** * Wrap existing [HttpResponse] with new [content]. */ +@OptIn(InternalAPI::class) internal fun HttpResponse.wrapWithContent(content: ByteReadChannel): HttpResponse { return DelegatedResponse(call, content, this) } +@OptIn(InternalAPI::class) internal class DelegatedCall( client: HttpClient, content: ByteReadChannel, @@ -59,7 +63,8 @@ internal class DelegatedRequest( origin: HttpRequest ) : HttpRequest by origin -internal class DelegatedResponse( +@InternalAPI +internal class DelegatedResponse constructor( override val call: HttpClientCall, override val content: ByteReadChannel, private val origin: HttpResponse diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/ResponseObserver.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/ResponseObserver.kt index 211916f9fbd..e1842d62857 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/ResponseObserver.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/observer/ResponseObserver.kt @@ -40,6 +40,7 @@ public class ResponseObserver( override fun prepare(block: Config.() -> Unit): ResponseObserver = ResponseObserver(Config().apply(block).responseHandler) + @OptIn(InternalAPI::class) override fun install(plugin: ResponseObserver, scope: HttpClient) { scope.receivePipeline.intercept(HttpReceivePipeline.After) { response -> val (loggingContent, responseContent) = response.content.split(response) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/WebSocketContent.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/WebSocketContent.kt index fd5c575a42a..31a356ff25a 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/WebSocketContent.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/WebSocketContent.kt @@ -12,6 +12,7 @@ import io.ktor.util.* private const val WEBSOCKET_VERSION = "13" private const val NONCE_SIZE = 16 +@OptIn(InternalAPI::class) internal class WebSocketContent : ClientUpgradeContent() { private val nonce: String = buildString { val nonce = generateNonce(NONCE_SIZE) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/WebSockets.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/WebSockets.kt index 64215d97d80..07f0ec76ed9 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/WebSockets.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/websocket/WebSockets.kt @@ -147,7 +147,7 @@ internal constructor( return WebSockets(config.pingInterval, config.maxFrameSize, config.extensionsConfig) } - @OptIn(ExperimentalWebSocketExtensionApi::class) + @OptIn(ExperimentalWebSocketExtensionApi::class, InternalAPI::class) override fun install(plugin: WebSockets, scope: HttpClient) { val extensionsSupported = scope.engine.supportedCapabilities.contains(WebSocketExtensionsCapability) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/HttpRequest.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/HttpRequest.kt index ff440d86042..05fa98bea30 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/HttpRequest.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/HttpRequest.kt @@ -112,6 +112,7 @@ public class HttpRequestBuilder : HttpMessageBuilder { /** * Create immutable [HttpRequestData] */ + @OptIn(InternalAPI::class) public fun build(): HttpRequestData = HttpRequestData( url.build(), method, @@ -140,6 +141,7 @@ public class HttpRequestBuilder : HttpMessageBuilder { /** * Mutates [this] copying all the data but execution context from another [builder] using it as base. */ + @OptIn(InternalAPI::class) public fun takeFrom(builder: HttpRequestBuilder): HttpRequestBuilder { method = builder.method body = builder.body @@ -224,6 +226,7 @@ public fun HttpRequestBuilder.headers(block: HeadersBuilder.() -> Unit): Headers /** * Mutates [this] copying all the data from another [request] using it as base. */ +@OptIn(InternalAPI::class) public fun HttpRequestBuilder.takeFrom(request: HttpRequest): HttpRequestBuilder { method = request.method body = request.content @@ -242,6 +245,7 @@ public fun HttpRequestBuilder.url(block: URLBuilder.() -> Unit): Unit = block(ur /** * Sets the [HttpRequestBuilder] from [request]. */ +@OptIn(InternalAPI::class) public fun HttpRequestBuilder.takeFrom(request: HttpRequestData): HttpRequestBuilder { method = request.method body = request.body diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/RequestBody.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/RequestBody.kt index 6da1d3c36cc..9ac99177e9e 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/request/RequestBody.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/request/RequestBody.kt @@ -13,6 +13,7 @@ import kotlin.native.concurrent.* @SharedImmutable internal val BodyTypeAttributeKey: AttributeKey = AttributeKey("BodyTypeAttributeKey") +@OptIn(InternalAPI::class) public inline fun HttpRequestBuilder.setBody(body: T) { when (body) { null -> { diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/Compatibility.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/Compatibility.kt index 2829172b176..84a074191bc 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/Compatibility.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/Compatibility.kt @@ -2,6 +2,8 @@ * Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +@file:Suppress("UNUSED_PARAMETER") + package io.ktor.client.statement import io.ktor.client.* diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt index ac1de24a2c3..7d0ca6f19d9 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/HttpStatement.kt @@ -11,6 +11,7 @@ import io.ktor.client.plugins.* import io.ktor.client.request.* import io.ktor.client.utils.* import io.ktor.http.* +import io.ktor.util.* import io.ktor.utils.io.* import io.ktor.utils.io.charsets.* import io.ktor.utils.io.core.* @@ -67,7 +68,7 @@ public class HttpStatement( * * Note if T is a streaming type, you should manage how to close it manually. */ - @OptIn(ExperimentalStdlibApi::class) + @OptIn(ExperimentalStdlibApi::class, InternalAPI::class) public suspend inline fun body(): T { val response = executeUnsafe() return try { @@ -96,6 +97,7 @@ public class HttpStatement( * Return [HttpResponse] with open streaming body. */ @PublishedApi + @OptIn(InternalAPI::class) internal suspend fun executeUnsafe(): HttpResponse { val builder = HttpRequestBuilder().takeFromWithExecutionContext(builder) @@ -107,6 +109,7 @@ public class HttpStatement( * Complete [HttpResponse] and release resources. */ @PublishedApi + @OptIn(InternalAPI::class) internal suspend fun HttpResponse.cleanup() { val job = coroutineContext[Job]!! as CompletableJob diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/Readers.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/Readers.kt index f7bc4dd48de..73c52ce1faf 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/Readers.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/statement/Readers.kt @@ -4,12 +4,14 @@ package io.ktor.client.statement +import io.ktor.util.* import io.ktor.utils.io.* import io.ktor.utils.io.core.* /** * Exactly reads [count] bytes of the [HttpResponse.content]. */ +@OptIn(InternalAPI::class) public suspend fun HttpResponse.readBytes(count: Int): ByteArray = ByteArray(count).also { content.readFully(it) } @@ -18,11 +20,13 @@ public suspend fun HttpResponse.readBytes(count: Int): ByteArray = ByteArray(cou * Reads the whole [HttpResponse.content] if Content-Length was specified. * Otherwise it just reads one byte. */ +@OptIn(InternalAPI::class) public suspend fun HttpResponse.readBytes(): ByteArray = content.readRemaining().readBytes() /** * Efficiently discards the remaining bytes of [HttpResponse.content]. */ +@OptIn(InternalAPI::class) public suspend fun HttpResponse.discardRemaining() { content.discard() } diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/ByteChannelUtils.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/ByteChannelUtils.kt index e3550c87fee..7ab0f8cf87b 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/ByteChannelUtils.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/utils/ByteChannelUtils.kt @@ -10,6 +10,7 @@ import io.ktor.utils.io.pool.* import kotlinx.coroutines.* import kotlin.coroutines.* +@OptIn(DelicateCoroutinesApi::class) internal fun ByteReadChannel.observable( context: CoroutineContext, contentLength: Long?, diff --git a/ktor-client/ktor-client-core/common/test/CacheExpiresTest.kt b/ktor-client/ktor-client-core/common/test/CacheExpiresTest.kt index 97af8309d63..cfaacb83db4 100644 --- a/ktor-client/ktor-client-core/common/test/CacheExpiresTest.kt +++ b/ktor-client/ktor-client-core/common/test/CacheExpiresTest.kt @@ -8,6 +8,7 @@ import io.ktor.client.plugins.cache.* import io.ktor.client.statement.* import io.ktor.client.utils.* import io.ktor.http.* +import io.ktor.util.* import io.ktor.util.date.* import io.ktor.utils.io.* import kotlin.coroutines.* @@ -93,6 +94,7 @@ class CacheExpiresTest { get() = error("Shouldn't be used") override val responseTime: GMTDate get() = error("Shouldn't be used") + @OptIn(InternalAPI::class) override val content: ByteReadChannel get() = error("Shouldn't be used") override val coroutineContext: CoroutineContext diff --git a/ktor-client/ktor-client-core/common/test/MultiPartFormDataContentTest.kt b/ktor-client/ktor-client-core/common/test/MultiPartFormDataContentTest.kt index f3645fa0be0..208fa4f370e 100644 --- a/ktor-client/ktor-client-core/common/test/MultiPartFormDataContentTest.kt +++ b/ktor-client/ktor-client-core/common/test/MultiPartFormDataContentTest.kt @@ -24,9 +24,9 @@ class MultiPartFormDataContentTest { val actual = channel.readRemaining().readBytes() - assertNotEquals('\r'.toByte(), actual[0]) - assertNotEquals('\n'.toByte(), actual[1]) - assertNotEquals('\r'.toByte(), actual[2]) - assertNotEquals('\n'.toByte(), actual[3]) + assertNotEquals('\r'.code.toByte(), actual[0]) + assertNotEquals('\n'.code.toByte(), actual[1]) + assertNotEquals('\r'.code.toByte(), actual[2]) + assertNotEquals('\n'.code.toByte(), actual[3]) } } diff --git a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsClientEngine.kt b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsClientEngine.kt index adb42719743..f1b7f7b3fdf 100644 --- a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsClientEngine.kt +++ b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsClientEngine.kt @@ -28,6 +28,7 @@ internal class JsClientEngine(override val config: HttpClientEngineConfig) : Htt check(config.proxy == null) { "Proxy unsupported in Js engine." } } + @OptIn(InternalAPI::class) override suspend fun execute(data: HttpRequestData): HttpResponseData { val callContext = callContext() @@ -57,18 +58,18 @@ internal class JsClientEngine(override val config: HttpClientEngineConfig) : Htt // Adding "_capturingHack" to reduce chances of JS IR backend to rename variable, // so it can be accessed inside js("") function - private fun createWebSocket(urlString_capturingHack: String, headers: Headers): WebSocket { - return if (PlatformUtils.IS_NODE) { + @Suppress("UNUSED_PARAMETER", "UnsafeCastFromDynamic", "UNUSED_VARIABLE", "LocalVariableName") + private fun createWebSocket(urlString_capturingHack: String, headers: Headers): WebSocket = + if (PlatformUtils.IS_NODE) { val ws_capturingHack = js("eval('require')('ws')") val headers_capturingHack: dynamic = object {} headers.forEach { name, values -> headers_capturingHack[name] = values.joinToString(",") } - js("new ws_capturingHack(urlString_capturingHack, { headers: headers_capturingHack } )") + js("new ws_capturingHack(urlString_capturingHack, { headers: headers_capturingHack })") } else { js("new WebSocket(urlString_capturingHack)") } - } private suspend fun executeWebSocketRequest( request: HttpRequestData, @@ -134,4 +135,5 @@ private fun io.ktor.client.fetch.Headers.mapToKtor(): Headers = buildHeaders { * Wrapper for javascript `error` objects. * @property origin: fail reason */ +@Suppress("MemberVisibilityCanBePrivate") public class JsError(public val origin: dynamic) : Throwable("Error from javascript[$origin].") diff --git a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsUtils.kt b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsUtils.kt index 59ec73c3fe0..73e6b62d9cf 100644 --- a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsUtils.kt +++ b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsUtils.kt @@ -8,6 +8,7 @@ import io.ktor.client.engine.* import io.ktor.client.fetch.RequestInit import io.ktor.client.request.* import io.ktor.http.content.* +import io.ktor.util.* import io.ktor.utils.io.* import io.ktor.utils.io.core.* import kotlinx.coroutines.* @@ -15,6 +16,7 @@ import org.khronos.webgl.Uint8Array import org.w3c.fetch.* import kotlin.coroutines.* +@OptIn(InternalAPI::class, DelicateCoroutinesApi::class) internal suspend fun HttpRequestData.toRaw(callContext: CoroutineContext): RequestInit { val jsHeaders = js("({})") mergeHeaders(this@toRaw.headers, this@toRaw.body) { key, value -> diff --git a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt index 8646faa8b74..2237669d403 100644 --- a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt +++ b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt @@ -43,6 +43,7 @@ internal fun AbortController(): AbortController { return if (PlatformUtils.IS_BROWSER) { js("new AbortController()") } else { + @Suppress("UNUSED_VARIABLE") val controller = js("eval('require')('abort-controller')") js("new controller()") } diff --git a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/node/NodeFetch.kt b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/node/NodeFetch.kt index e09ee4b1ecd..ebe610bbd9a 100644 --- a/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/node/NodeFetch.kt +++ b/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/node/NodeFetch.kt @@ -18,7 +18,7 @@ internal fun CoroutineScope.readBodyNode(response: Response): ByteReadChannel = val responseData = Channel(1) body.on("data") { chunk: ArrayBuffer -> - val result = responseData.offer(Uint8Array(chunk).asByteArray()) + responseData.trySend(Uint8Array(chunk).asByteArray()).isSuccess body.pause() } diff --git a/ktor-client/ktor-client-core/js/src/io/ktor/client/fetch/LibDom.kt b/ktor-client/ktor-client-core/js/src/io/ktor/client/fetch/LibDom.kt index 7e1e8613ca2..cf42a729dae 100644 --- a/ktor-client/ktor-client-core/js/src/io/ktor/client/fetch/LibDom.kt +++ b/ktor-client/ktor-client-core/js/src/io/ktor/client/fetch/LibDom.kt @@ -288,16 +288,16 @@ public external interface AbortSignal : EventTarget { options: EventListenerOptions? = definedExternally ) - override fun removeEventListener(type: String, listener: EventListener, options: Boolean?) - override fun removeEventListener(type: String, listener: EventListener, options: EventListenerOptions?) - override fun removeEventListener(type: String, listener: EventListenerObject, options: Boolean?) - override fun removeEventListener(type: String, listener: EventListenerObject, options: EventListenerOptions?) + override fun removeEventListener(type: String, callback: EventListener, options: Boolean?) + override fun removeEventListener(type: String, callback: EventListener, options: EventListenerOptions?) + override fun removeEventListener(type: String, callback: EventListenerObject, options: Boolean?) + override fun removeEventListener(type: String, callback: EventListenerObject, options: EventListenerOptions?) public fun addEventListener(type: K, listener: (AbortSignal, ev: Any) -> Any) override fun addEventListener(type: String, listener: EventListener) override fun addEventListener(type: String, listener: EventListenerObject) public fun removeEventListener(type: K, listener: (AbortSignal, ev: Any) -> Any) - override fun removeEventListener(type: String, listener: EventListener) - override fun removeEventListener(type: String, listener: EventListenerObject) + override fun removeEventListener(type: String, callback: EventListener) + override fun removeEventListener(type: String, callback: EventListenerObject) } public external interface EventTarget { diff --git a/ktor-client/ktor-client-core/js/src/io/ktor/client/plugins/websocket/JsWebSocketSession.kt b/ktor-client/ktor-client-core/js/src/io/ktor/client/plugins/websocket/JsWebSocketSession.kt index b7d3cdc09c2..b8603182974 100644 --- a/ktor-client/ktor-client-core/js/src/io/ktor/client/plugins/websocket/JsWebSocketSession.kt +++ b/ktor-client/ktor-client-core/js/src/io/ktor/client/plugins/websocket/JsWebSocketSession.kt @@ -5,6 +5,7 @@ package io.ktor.client.plugins.websocket import io.ktor.http.cio.websocket.* +import io.ktor.util.* import io.ktor.utils.io.core.* import kotlinx.coroutines.* import kotlinx.coroutines.channels.* @@ -12,6 +13,7 @@ import org.khronos.webgl.* import org.w3c.dom.* import kotlin.coroutines.* +@Suppress("CAST_NEVER_SUCCEEDS") internal class JsWebSocketSession( override val coroutineContext: CoroutineContext, private val websocket: WebSocket @@ -24,13 +26,14 @@ internal class JsWebSocketSession( override val outgoing: SendChannel = _outgoing @ExperimentalWebSocketExtensionApi - override val extensions: List> get() = emptyList() + override val extensions: List> + get() = emptyList() override val closeReason: Deferred = _closeReason override var maxFrameSize: Long get() = Long.MAX_VALUE - set(value) {} + set(_) {} init { websocket.binaryType = BinaryType.ARRAYBUFFER @@ -53,7 +56,7 @@ internal class JsWebSocketSession( } } - _incoming.offer(frame) + _incoming.trySend(frame).isSuccess } } ) @@ -126,7 +129,7 @@ internal class JsWebSocketSession( } } - @OptIn(ExperimentalWebSocketExtensionApi::class) + @OptIn(ExperimentalWebSocketExtensionApi::class, InternalAPI::class) override fun start(negotiatedExtensions: List>) { require(negotiatedExtensions.isEmpty()) { "Extensions are not supported." } } @@ -145,6 +148,7 @@ internal class JsWebSocketSession( websocket.close() } + @OptIn(InternalAPI::class) private fun Short.isReservedStatusCode(): Boolean { return CloseReason.Codes.byCode(this).let { resolved -> @Suppress("DEPRECATION") diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/network/sockets/TimeoutExceptions.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/network/sockets/TimeoutExceptions.kt index b54e49c5537..add84a4fe9f 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/network/sockets/TimeoutExceptions.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/network/sockets/TimeoutExceptions.kt @@ -32,6 +32,7 @@ public actual class SocketTimeoutException actual constructor( * Creates [ByteChannel] that maps close exceptions (close the channel with [SocketTimeoutException] if asked to * close it with [SocketTimeoutException]). */ +@OptIn(InternalAPI::class) internal actual fun ByteChannelWithMappedExceptions(request: HttpRequestData): ByteChannel = ByteChannel { cause -> when (cause?.rootCause) { is java.net.SocketTimeoutException -> SocketTimeoutException(request, cause) diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/plugins/DefaultTransformersJvm.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/plugins/DefaultTransformersJvm.kt index f1a4dc6ba1f..ac1c09e8783 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/plugins/DefaultTransformersJvm.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/plugins/DefaultTransformersJvm.kt @@ -6,11 +6,13 @@ package io.ktor.client.plugins import io.ktor.client.* import io.ktor.client.statement.* +import io.ktor.util.* import io.ktor.utils.io.* import io.ktor.utils.io.jvm.javaio.* import kotlinx.coroutines.* import java.io.* +@OptIn(InternalAPI::class) internal actual fun HttpClient.platformDefaultTransformers() { responsePipeline.intercept(HttpResponsePipeline.Parse) { (info, body) -> if (body !is ByteReadChannel) return@intercept diff --git a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/CIOJvm.kt b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/CIOJvm.kt index 46ddd6517cb..f3e1ba8cada 100644 --- a/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/CIOJvm.kt +++ b/ktor-client/ktor-client-core/jvm/src/io/ktor/client/utils/CIOJvm.kt @@ -12,7 +12,6 @@ import java.nio.* /** * Singleton pool of [ByteBuffer] objects used for [HttpClient]. */ -@InternalAPI public val HttpClientDefaultPool: ByteBufferPool = ByteBufferPool() @InternalAPI diff --git a/ktor-client/ktor-client-core/jvm/test/ExceptionsTest.kt b/ktor-client/ktor-client-core/jvm/test/ExceptionsTest.kt index c80f4029aa6..7e3271bf504 100644 --- a/ktor-client/ktor-client-core/jvm/test/ExceptionsTest.kt +++ b/ktor-client/ktor-client-core/jvm/test/ExceptionsTest.kt @@ -6,6 +6,7 @@ import io.ktor.client.call.* import io.ktor.client.plugins.* import io.ktor.client.statement.* import io.ktor.http.* +import io.ktor.util.* import io.ktor.util.date.* import io.ktor.utils.io.* import java.io.* @@ -38,6 +39,7 @@ class ExceptionsTest { } } +@OptIn(InternalAPI::class) private fun createResponseException(): ResponseException = ResponseException( object : HttpResponse() { override val call: HttpClientCall diff --git a/ktor-client/ktor-client-core/posix/src/io/ktor/client/HttpClient.kt b/ktor-client/ktor-client-core/posix/src/io/ktor/client/HttpClient.kt index 9a5af5e6d8a..e7c8a7712a4 100644 --- a/ktor-client/ktor-client-core/posix/src/io/ktor/client/HttpClient.kt +++ b/ktor-client/ktor-client-core/posix/src/io/ktor/client/HttpClient.kt @@ -5,6 +5,7 @@ package io.ktor.client import io.ktor.client.engine.* +import io.ktor.util.* /** * Constructs an asynchronous [HttpClient] using optional [block] for configuring this client. @@ -12,6 +13,7 @@ import io.ktor.client.engine.* * The [HttpClientEngine] is selected from the dependencies. * https://ktor.io/clients/http-client/engines.html */ +@OptIn(InternalAPI::class) @HttpClientDsl public actual fun HttpClient( block: HttpClientConfig<*>.() -> Unit diff --git a/ktor-client/ktor-client-core/posix/test/ExceptionsTest.kt b/ktor-client/ktor-client-core/posix/test/ExceptionsTest.kt index 72f0707f236..b4ecc52c785 100644 --- a/ktor-client/ktor-client-core/posix/test/ExceptionsTest.kt +++ b/ktor-client/ktor-client-core/posix/test/ExceptionsTest.kt @@ -5,6 +5,7 @@ import io.ktor.client.call.* import io.ktor.client.plugins.* import io.ktor.client.statement.* import io.ktor.http.* +import io.ktor.util.* import io.ktor.util.date.* import io.ktor.utils.io.* import kotlin.coroutines.* @@ -32,6 +33,7 @@ class ExceptionsTest { } } +@OptIn(InternalAPI::class) private fun createResponseException(): ResponseException = ResponseException( object : HttpResponse() { override val call: HttpClientCall diff --git a/ktor-client/ktor-client-curl/build.gradle.kts b/ktor-client/ktor-client-curl/build.gradle.kts index 5c7a5a35a82..c2f49dd5b4e 100644 --- a/ktor-client/ktor-client-curl/build.gradle.kts +++ b/ktor-client/ktor-client-curl/build.gradle.kts @@ -2,7 +2,6 @@ import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget -val ideaActive: Boolean by project.extra val serialization_version: String by project.extra plugins { @@ -12,7 +11,7 @@ plugins { kotlin { targets.apply { val current = mutableListOf() - if (ideaActive) { + if (KtorBuildProperties.ideaActive) { current.add(getByName("posix")) } else { current.addAll(listOf(getByName("macosX64"), getByName("linuxX64"), getByName("mingwX64"))) @@ -76,7 +75,7 @@ kotlin { } // Hack: register the Native interop klibs as outputs of Kotlin source sets: - if (!ideaActive) { + if (!KtorBuildProperties.ideaActive) { val libcurlInterop by creating getByName("posixMain").dependsOn(libcurlInterop) apply(from = "$rootDir/gradle/interop-as-source-set-klib.gradle") diff --git a/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/Curl.kt b/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/Curl.kt index d31090292b7..c0c3617345a 100644 --- a/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/Curl.kt +++ b/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/Curl.kt @@ -5,6 +5,7 @@ package io.ktor.client.engine.curl import io.ktor.client.engine.* +import io.ktor.util.* import kotlinx.cinterop.* import libcurl.* import kotlin.native.SharedImmutable @@ -17,12 +18,14 @@ import kotlin.native.SharedImmutable @SharedImmutable private val curlGlobalInitReturnCode = curl_global_init(CURL_GLOBAL_ALL.convert()) +@Suppress("unused") private val initHook = Curl /** * [HttpClientEngineFactory] using a curl library in implementation * with the the associated configuration [HttpClientEngineConfig]. */ +@OptIn(InternalAPI::class) public object Curl : HttpClientEngineFactory { init { engines.append(this) diff --git a/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/CurlClientEngine.kt b/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/CurlClientEngine.kt index 8c4c611db79..50a360b3af1 100644 --- a/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/CurlClientEngine.kt +++ b/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/CurlClientEngine.kt @@ -10,6 +10,7 @@ import io.ktor.client.plugins.* import io.ktor.client.request.* import io.ktor.http.* import io.ktor.http.cio.* +import io.ktor.util.* import io.ktor.util.date.* import io.ktor.utils.io.* import kotlinx.coroutines.* @@ -29,6 +30,7 @@ internal class CurlClientEngine( } } + @OptIn(InternalAPI::class) override suspend fun execute(data: HttpRequestData): HttpResponseData { val callContext = callContext() diff --git a/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/internal/CurlAdapters.kt b/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/internal/CurlAdapters.kt index 54d9b0aa1fb..7a16556e457 100644 --- a/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/internal/CurlAdapters.kt +++ b/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/internal/CurlAdapters.kt @@ -8,6 +8,7 @@ import io.ktor.client.engine.* import io.ktor.client.engine.curl.* import io.ktor.client.request.* import io.ktor.http.* +import io.ktor.util.* import kotlinx.cinterop.* import libcurl.* @@ -55,6 +56,7 @@ internal fun EasyHandle.getInfo(info: CURLINFO, optionValue: CPointer<*>) { curl_easy_getinfo(this, info, optionValue).verify() } +@OptIn(InternalAPI::class) internal fun HttpRequestData.headersToCurl(): CPointer { var result: CPointer? = null diff --git a/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/internal/CurlRaw.kt b/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/internal/CurlRaw.kt index a8a7ee140e9..69143865944 100644 --- a/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/internal/CurlRaw.kt +++ b/ktor-client/ktor-client-curl/posix/src/io/ktor/client/engine/curl/internal/CurlRaw.kt @@ -72,6 +72,7 @@ internal class CurlFail( override fun toString(): String = "CurlFail($cause)" } +@OptIn(DelicateCoroutinesApi::class) internal suspend fun OutgoingContent.toCurlByteArray(): ByteArray = when (this@toCurlByteArray) { is OutgoingContent.ByteArrayContent -> bytes() is OutgoingContent.WriteChannelContent -> GlobalScope.writer(coroutineContext) { diff --git a/ktor-client/ktor-client-ios/build.gradle.kts b/ktor-client/ktor-client-ios/build.gradle.kts index ec2904a1b88..b3220696070 100644 --- a/ktor-client/ktor-client-ios/build.gradle.kts +++ b/ktor-client/ktor-client-ios/build.gradle.kts @@ -1,5 +1,4 @@ -val ideaActive: Boolean by project.extra val serialization_version: String by project.extra kotlin.sourceSets { diff --git a/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/Ios.kt b/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/Ios.kt index 52bc7826e3f..0f94725b8c1 100644 --- a/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/Ios.kt +++ b/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/Ios.kt @@ -5,6 +5,7 @@ package io.ktor.client.engine.ios import io.ktor.client.engine.* +import io.ktor.util.* import platform.Foundation.* private val initHook = Ios @@ -13,6 +14,7 @@ private val initHook = Ios * [HttpClientEngineFactory] using a [NSURLRequest] in implementation * with the the associated requestConfig [HttpClientEngineConfig]. */ +@OptIn(InternalAPI::class) public object Ios : HttpClientEngineFactory { init { engines.append(this) diff --git a/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/IosClientEngine.kt b/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/IosClientEngine.kt index 817ae704350..671258ceaa6 100644 --- a/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/IosClientEngine.kt +++ b/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/IosClientEngine.kt @@ -8,6 +8,7 @@ import io.ktor.client.engine.* import io.ktor.client.plugins.* import io.ktor.client.request.* import io.ktor.http.* +import io.ktor.util.* import kotlinx.coroutines.* import platform.Foundation.* import kotlin.native.concurrent.* @@ -18,6 +19,7 @@ internal class IosClientEngine(override val config: IosClientEngineConfig) : Htt override val supportedCapabilities = setOf(HttpTimeout) + @OptIn(InternalAPI::class) override suspend fun execute(data: HttpRequestData): HttpResponseData { val callContext = callContext() val responseReader = IosResponseReader(callContext, data, config) diff --git a/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/IosResponseReader.kt b/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/IosResponseReader.kt index 48442ac2d1d..7a7a52091c8 100644 --- a/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/IosResponseReader.kt +++ b/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/IosResponseReader.kt @@ -26,7 +26,8 @@ internal class IosResponseReader( private val requestTime = GMTDate() - public suspend fun awaitResponse(): HttpResponseData { + @OptIn(DelicateCoroutinesApi::class) + suspend fun awaitResponse(): HttpResponseData { val response = rawResponse.await() @Suppress("UNCHECKED_CAST") @@ -70,7 +71,7 @@ internal class IosResponseReader( val content = didReceiveData.toByteArray() try { - chunks.offer(content) + chunks.trySend(content).isSuccess } catch (cause: CancellationException) { dataTask.cancel() } diff --git a/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/IosUtils.kt b/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/IosUtils.kt index fdf3cc076e2..8219269d1a9 100644 --- a/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/IosUtils.kt +++ b/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/IosUtils.kt @@ -14,6 +14,7 @@ import kotlinx.cinterop.* import kotlinx.coroutines.* import platform.Foundation.* +@OptIn(DelicateCoroutinesApi::class) internal suspend fun OutgoingContent.toNSData(): NSData? = when (this) { is OutgoingContent.ByteArrayContent -> bytes().toNSData() is OutgoingContent.WriteChannelContent -> GlobalScope.writer(Dispatchers.Unconfined) { diff --git a/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/certificates/PinnedCertificate.kt b/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/certificates/PinnedCertificate.kt index d67cded1e08..bf34f7cd773 100644 --- a/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/certificates/PinnedCertificate.kt +++ b/ktor-client/ktor-client-ios/darwin/src/io/ktor/client/engine/ios/certificates/PinnedCertificate.kt @@ -75,7 +75,7 @@ public data class PinnedCertificate( ) { "Unexpected pattern: $pattern" } - val canonicalPattern = pattern.toLowerCase() + val canonicalPattern = pattern.lowercase() return when { pin.startsWith(HASH_ALGORITHM_SHA_1) -> { val hash = pin.substring(HASH_ALGORITHM_SHA_1.length) diff --git a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/Java.kt b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/Java.kt index f17c8f11c2a..a6447bfd871 100644 --- a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/Java.kt +++ b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/Java.kt @@ -6,12 +6,14 @@ package io.ktor.client.engine.java import io.ktor.client.* import io.ktor.client.engine.* +import io.ktor.util.* /** * [HttpClientEngineFactory] using a [Java] based backend implementation * with the the associated configuration [JavaHttpConfig]. */ public object Java : HttpClientEngineFactory { + @OptIn(InternalAPI::class) override fun create(block: JavaHttpConfig.() -> Unit): HttpClientEngine = JavaHttpEngine(JavaHttpConfig().apply(block)) } diff --git a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpEngine.kt b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpEngine.kt index 8a1133a479d..9e1d9bb6460 100644 --- a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpEngine.kt +++ b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpEngine.kt @@ -16,7 +16,6 @@ import java.net.http.* import java.time.* import java.util.concurrent.* -@InternalAPI public class JavaHttpEngine(override val config: JavaHttpConfig) : HttpClientEngineBase("ktor-java") { private val executorThreadCounter = atomic(0L) @@ -49,6 +48,7 @@ public class JavaHttpEngine(override val config: JavaHttpConfig) : HttpClientEng } } + @OptIn(InternalAPI::class) override suspend fun execute(data: HttpRequestData): HttpResponseData { val engine = getJavaHttpClient(data) val callContext = callContext() diff --git a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpRequest.kt b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpRequest.kt index 9671d9ce1cd..1bfe53880cf 100644 --- a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpRequest.kt +++ b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpRequest.kt @@ -11,6 +11,7 @@ import io.ktor.client.request.* import io.ktor.http.* import io.ktor.http.HttpHeaders import io.ktor.http.content.* +import io.ktor.util.* import io.ktor.utils.io.* import kotlinx.coroutines.* import java.net.http.HttpRequest @@ -34,6 +35,7 @@ internal val DISALLOWED_HEADERS = TreeSet(String.CASE_INSENSITIVE_ORDER).apply { ) } +@OptIn(InternalAPI::class) internal fun HttpRequestData.convertToHttpRequest(callContext: CoroutineContext): HttpRequest { val builder = HttpRequest.newBuilder(url.toURI()) @@ -56,6 +58,7 @@ internal fun HttpRequestData.convertToHttpRequest(callContext: CoroutineContext) return builder.build() } +@OptIn(DelicateCoroutinesApi::class) internal fun OutgoingContent.convertToHttpRequestBody( callContext: CoroutineContext ): HttpRequest.BodyPublisher = when (this) { diff --git a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpResponseBodyHandler.kt b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpResponseBodyHandler.kt index 7bb58c9e363..83dc36e8121 100644 --- a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpResponseBodyHandler.kt +++ b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpResponseBodyHandler.kt @@ -27,7 +27,7 @@ internal class JavaHttpResponseBodyHandler( } private class JavaHttpResponseBodySubscriber( - private val callContext: CoroutineContext, + callContext: CoroutineContext, response: HttpResponse.ResponseInfo, requestTime: GMTDate ) : HttpResponse.BodySubscriber, CoroutineScope { @@ -61,7 +61,7 @@ internal class JavaHttpResponseBodyHandler( try { queue.consume { while (isActive) { - var buffer = queue.poll() + var buffer = queue.tryReceive().getOrNull() if (buffer == null) { subscription.value?.request(1) buffer = queue.receive() @@ -109,7 +109,7 @@ internal class JavaHttpResponseBodyHandler( override fun onNext(items: List) { items.forEach { if (it.hasRemaining()) { - queue.offer(it) + queue.trySend(it).isSuccess } } } diff --git a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpWebSocket.kt b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpWebSocket.kt index 0c51a86ca48..8788d7f2fff 100644 --- a/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpWebSocket.kt +++ b/ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpWebSocket.kt @@ -11,6 +11,7 @@ import io.ktor.client.request.* import io.ktor.http.* import io.ktor.http.HttpHeaders import io.ktor.http.cio.websocket.* +import io.ktor.util.* import io.ktor.util.date.* import io.ktor.utils.io.core.* import kotlinx.coroutines.* @@ -51,6 +52,7 @@ internal suspend fun HttpClient.executeWebSocketRequest( } } +@OptIn(DelicateCoroutinesApi::class) internal class JavaHttpWebSocket( private val callContext: CoroutineContext, private val httpClient: HttpClient, @@ -127,6 +129,7 @@ internal class JavaHttpWebSocket( } } + @OptIn(InternalAPI::class) suspend fun getResponse(): HttpResponseData { val builder = httpClient.newWebSocketBuilder() @@ -161,22 +164,22 @@ internal class JavaHttpWebSocket( } override fun onText(webSocket: WebSocket, data: CharSequence, last: Boolean): CompletionStage<*> = async { - _incoming.offer(Frame.Text(last, data.toString().toByteArray())) + _incoming.trySend(Frame.Text(last, data.toString().toByteArray())).isSuccess webSocket.request(1) }.asCompletableFuture() override fun onBinary(webSocket: WebSocket, data: ByteBuffer, last: Boolean): CompletionStage<*> = async { - _incoming.offer(Frame.Binary(last, data)) + _incoming.trySend(Frame.Binary(last, data)).isSuccess webSocket.request(1) }.asCompletableFuture() override fun onPing(webSocket: WebSocket, message: ByteBuffer): CompletionStage<*> = async { - _incoming.offer(Frame.Ping(message)) + _incoming.trySend(Frame.Ping(message)).isSuccess webSocket.request(1) }.asCompletableFuture() override fun onPong(webSocket: WebSocket, message: ByteBuffer): CompletionStage<*> = async { - _incoming.offer(Frame.Pong(message)) + _incoming.trySend(Frame.Pong(message)).isSuccess webSocket.request(1) }.asCompletableFuture() diff --git a/ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/RequestProducerTest.kt b/ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/RequestProducerTest.kt index a2a5c308b2a..bdce27f5eb9 100644 --- a/ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/RequestProducerTest.kt +++ b/ktor-client/ktor-client-java/jvm/test/io/ktor/client/engine/java/RequestProducerTest.kt @@ -18,6 +18,7 @@ import kotlin.test.* class RequestProducerTest { + @OptIn(InternalAPI::class) @Test fun testHeadersMerge() { val request = HttpRequestData( diff --git a/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyHttp2Engine.kt b/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyHttp2Engine.kt index b5ee13c800b..b94755b3a9d 100644 --- a/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyHttp2Engine.kt +++ b/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyHttp2Engine.kt @@ -13,6 +13,7 @@ import kotlinx.coroutines.* import org.eclipse.jetty.http2.client.* import org.eclipse.jetty.util.thread.* +@OptIn(InternalAPI::class) internal class JettyHttp2Engine( override val config: JettyEngineConfig ) : HttpClientEngineBase("ktor-jetty") { diff --git a/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyHttpRequest.kt b/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyHttpRequest.kt index 918066e2df3..eb9494aeb36 100644 --- a/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyHttpRequest.kt +++ b/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyHttpRequest.kt @@ -10,6 +10,7 @@ import io.ktor.client.request.* import io.ktor.client.utils.* import io.ktor.http.* import io.ktor.http.content.* +import io.ktor.util.* import io.ktor.util.cio.* import io.ktor.util.date.* import io.ktor.utils.io.* @@ -66,6 +67,7 @@ internal suspend fun HTTP2Client.connect( connect(factory, InetSocketAddress(url.host, url.port), Session.Listener.Adapter(), promise) } +@OptIn(InternalAPI::class) private fun HttpRequestData.prepareHeadersFrame(): HeadersFrame { val rawHeaders = HttpFields() @@ -86,6 +88,7 @@ private fun HttpRequestData.prepareHeadersFrame(): HeadersFrame { return HeadersFrame(meta, null, body is OutgoingContent.NoContent) } +@OptIn(DelicateCoroutinesApi::class) private fun sendRequestBody(request: JettyHttp2Request, content: OutgoingContent, callContext: CoroutineContext) { when (content) { is OutgoingContent.NoContent -> return @@ -102,6 +105,7 @@ private fun sendRequestBody(request: JettyHttp2Request, content: OutgoingContent } } +@OptIn(InternalAPI::class, DelicateCoroutinesApi::class) private fun writeRequest( from: ByteReadChannel, request: JettyHttp2Request, diff --git a/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyResponseListener.kt b/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyResponseListener.kt index 4e9eb7b32d2..3d2f071be38 100644 --- a/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyResponseListener.kt +++ b/ktor-client/ktor-client-jetty/jvm/src/io/ktor/client/engine/jetty/JettyResponseListener.kt @@ -9,7 +9,6 @@ import io.ktor.http.* import io.ktor.http.HttpMethod import io.ktor.utils.io.* import kotlinx.coroutines.* -import kotlinx.coroutines.channels.* import kotlinx.coroutines.channels.Channel import org.eclipse.jetty.http.* import org.eclipse.jetty.http2.* @@ -68,7 +67,7 @@ internal class JettyResponseListener( override fun onData(stream: Stream, frame: DataFrame, callback: Callback) { val data = frame.data!! try { - if (!backendChannel.offer(JettyResponseChunk(data, callback))) { + if (!backendChannel.trySend(JettyResponseChunk(data, callback)).isSuccess) { throw IOException("backendChannel.offer() failed") } @@ -115,10 +114,10 @@ internal class JettyResponseListener( return StatusWithHeaders(statusCode, headersBuilder.build()) } + @OptIn(DelicateCoroutinesApi::class) private fun runResponseProcessing() = GlobalScope.launch(callContext) { - @OptIn(ExperimentalCoroutinesApi::class) while (true) { - val (buffer, callback) = backendChannel.receiveOrNull() ?: break + val (buffer, callback) = backendChannel.receiveCatching().getOrNull() ?: break try { if (buffer.remaining() > 0) channel.writeFully(buffer) callback.succeeded() diff --git a/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngine.kt b/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngine.kt index a92ae916985..6df8f7949dc 100644 --- a/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngine.kt +++ b/ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngine.kt @@ -18,6 +18,7 @@ import kotlinx.coroutines.* * [HttpClientEngine] for writing tests without network. */ public class MockEngine(override val config: MockEngineConfig) : HttpClientEngineBase("ktor-mock") { + @OptIn(InternalAPI::class) override val dispatcher: CoroutineDispatcher = Dispatchers.clientDispatcher(config.threadsCount) override val supportedCapabilities: Set> = setOf( HttpTimeout, @@ -49,6 +50,7 @@ public class MockEngine(override val config: MockEngineConfig) : HttpClientEngin */ public val responseHistory: List get() = _responseHistory + @OptIn(InternalAPI::class) override suspend fun execute(data: HttpRequestData): HttpResponseData { val callContext = callContext() diff --git a/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpEngine.kt b/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpEngine.kt index 3675cf70dd1..29dcc9fca64 100644 --- a/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpEngine.kt +++ b/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpEngine.kt @@ -24,8 +24,8 @@ import java.io.* import java.util.concurrent.* import kotlin.coroutines.* -@InternalAPI @Suppress("KDocMissingDocumentation") +@OptIn(InternalAPI::class, DelicateCoroutinesApi::class) public class OkHttpEngine(override val config: OkHttpConfig) : HttpClientEngineBase("ktor-okhttp") { public override val dispatcher: CoroutineDispatcher by lazy { @@ -61,6 +61,7 @@ public class OkHttpEngine(override val config: OkHttpConfig) : HttpClientEngineB client.connectionPool.evictAll() client.dispatcher.executorService.shutdown() } + @Suppress("BlockingMethodInNonBlockingContext") (dispatcher as Closeable).close() } } @@ -155,6 +156,7 @@ public class OkHttpEngine(override val config: OkHttpConfig) : HttpClientEngineB } } +@OptIn(DelicateCoroutinesApi::class) private fun BufferedSource.toChannel(context: CoroutineContext, requestData: HttpRequestData): ByteReadChannel = GlobalScope.writer(context) { use { source -> @@ -176,6 +178,7 @@ private fun mapExceptions(cause: Throwable, request: HttpRequestData): Throwable else -> cause } +@OptIn(InternalAPI::class) private fun HttpRequestData.convertToOkHttpRequest(callContext: CoroutineContext): Request { val builder = Request.Builder() @@ -198,6 +201,7 @@ private fun HttpRequestData.convertToOkHttpRequest(callContext: CoroutineContext return builder.build() } +@OptIn(DelicateCoroutinesApi::class) internal fun OutgoingContent.convertToOkHttpBody(callContext: CoroutineContext): RequestBody = when (this) { is OutgoingContent.ByteArrayContent -> bytes().let { it.toRequestBody(null, 0, it.size) @@ -214,6 +218,7 @@ internal fun OutgoingContent.convertToOkHttpBody(callContext: CoroutineContext): * Update [OkHttpClient.Builder] setting timeout configuration taken from * [HttpTimeout.HttpTimeoutCapabilityConfiguration]. */ +@OptIn(InternalAPI::class) private fun OkHttpClient.Builder.setupTimeoutAttributes( timeoutAttributes: HttpTimeout.HttpTimeoutCapabilityConfiguration ): OkHttpClient.Builder { diff --git a/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpWebsocketSession.kt b/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpWebsocketSession.kt index 582eb8d294b..c9fa913664a 100644 --- a/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpWebsocketSession.kt +++ b/ktor-client/ktor-client-okhttp/jvm/src/io/ktor/client/engine/okhttp/OkHttpWebsocketSession.kt @@ -6,6 +6,7 @@ package io.ktor.client.engine.okhttp import io.ktor.client.plugins.websocket.* import io.ktor.http.cio.websocket.* +import io.ktor.util.* import kotlinx.coroutines.* import kotlinx.coroutines.channels.* import okhttp3.* @@ -51,7 +52,7 @@ internal class OkHttpWebsocketSession( override val closeReason: Deferred get() = _closeReason - @OptIn(ExperimentalWebSocketExtensionApi::class) + @OptIn(ExperimentalWebSocketExtensionApi::class, InternalAPI::class) override fun start(negotiatedExtensions: List>) { require(negotiatedExtensions.isEmpty()) { "Extensions are not supported." } } @@ -97,12 +98,12 @@ internal class OkHttpWebsocketSession( override fun onMessage(webSocket: WebSocket, bytes: ByteString) { super.onMessage(webSocket, bytes) - _incoming.sendBlocking(Frame.Binary(true, bytes.toByteArray())) + _incoming.trySendBlocking(Frame.Binary(true, bytes.toByteArray())) } override fun onMessage(webSocket: WebSocket, text: String) { super.onMessage(webSocket, text) - _incoming.sendBlocking(Frame.Text(true, text.toByteArray())) + _incoming.trySendBlocking(Frame.Text(true, text.toByteArray())) } override fun onClosed(webSocket: WebSocket, code: Int, reason: String) { @@ -122,7 +123,7 @@ internal class OkHttpWebsocketSession( _closeReason.complete(CloseReason(code.toShort(), reason)) try { - outgoing.sendBlocking(Frame.Close(CloseReason(code.toShort(), reason))) + outgoing.trySendBlocking(Frame.Close(CloseReason(code.toShort(), reason))) } catch (ignore: Throwable) { } _incoming.close() @@ -162,11 +163,12 @@ internal class OkHttpWebsocketSession( public class UnsupportedFrameTypeException( private val frame: Frame ) : IllegalArgumentException("Unsupported frame type: $frame"), CopyableThrowable { - override fun createCopy(): UnsupportedFrameTypeException? = UnsupportedFrameTypeException(frame).also { + override fun createCopy(): UnsupportedFrameTypeException = UnsupportedFrameTypeException(frame).also { it.initCause(this) } } +@OptIn(InternalAPI::class) @Suppress("DEPRECATION") private fun CloseReason.isReserved() = CloseReason.Codes.byCode(code).let { recognized -> recognized == null || recognized == CloseReason.Codes.CLOSED_ABNORMALLY diff --git a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/Auth.kt b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/Auth.kt index 6b3169f609d..e4c09848f14 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/Auth.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/Auth.kt @@ -27,6 +27,7 @@ public class Auth( return Auth().apply(block) } + @OptIn(InternalAPI::class) override fun install(plugin: Auth, scope: HttpClient) { scope.requestPipeline.intercept(HttpRequestPipeline.State) { plugin.providers.filter { it.sendWithoutRequest(context) }.forEach { @@ -81,6 +82,7 @@ public fun HttpClientConfig<*>.Auth(block: Auth.() -> Unit) { * parameter to AuthProvider.addRequestHeaders instead in the future and the attribute will * be removed after that. */ +@OptIn(InternalAPI::class) @PublicAPICandidate("1.6.0") @SharedImmutable internal val AuthHeaderAttribute = AttributeKey("AuthHeader") diff --git a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/AuthProvider.kt b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/AuthProvider.kt index 653f6d1a75b..e55fb9e9305 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/AuthProvider.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/AuthProvider.kt @@ -20,6 +20,7 @@ public interface AuthProvider { @Deprecated("Please use sendWithoutRequest function instead") public val sendWithoutRequest: Boolean + @Suppress("DEPRECATION") public fun sendWithoutRequest(request: HttpRequestBuilder): Boolean = sendWithoutRequest /** diff --git a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/BasicAuthProvider.kt b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/BasicAuthProvider.kt index bc718abbf0e..cf16c103cf0 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/BasicAuthProvider.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/BasicAuthProvider.kt @@ -49,8 +49,10 @@ public class BasicAuthConfig { */ public var realm: String? = null + @Suppress("DEPRECATION") internal var _sendWithoutRequest: (HttpRequestBuilder) -> Boolean = { sendWithoutRequest } + @Suppress("DEPRECATION") internal var _credentials: suspend () -> BasicAuthCredentials? = { BasicAuthCredentials(username = username, password = password) } diff --git a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/DigestAuthProvider.kt b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/DigestAuthProvider.kt index 75b35a0b15f..a369b665b6c 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/DigestAuthProvider.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-auth/common/src/io/ktor/client/plugins/auth/providers/DigestAuthProvider.kt @@ -49,6 +49,7 @@ public class DigestAuthConfig { */ public var realm: String? = null + @Suppress("DEPRECATION") internal var _credentials: suspend () -> DigestAuthCredentials? = { DigestAuthCredentials(username = username, password = password) } @@ -114,6 +115,7 @@ public class DigestAuthProvider( override fun sendWithoutRequest(request: HttpRequestBuilder): Boolean = false + @Suppress("DEPRECATION") override fun isApplicable(auth: HttpAuthHeader): Boolean { if (auth !is HttpAuthHeader.Parameterized || auth.authScheme != AuthScheme.Digest @@ -135,9 +137,10 @@ public class DigestAuthProvider( return true } + @Suppress("DEPRECATION") override suspend fun addRequestHeaders(request: HttpRequestBuilder) { val nonceCount = requestCounter.incrementAndGet() - val methodName = request.method.value.toUpperCase() + val methodName = request.method.value.uppercase() val url = URLBuilder().takeFrom(request.url).build() val nonce = serverNonce.value!! @@ -185,6 +188,8 @@ public class DigestAuthProvider( return true } + @Suppress("DEPRECATION") + @OptIn(InternalAPI::class) private suspend fun makeDigest(data: String): ByteArray { val digest = Digest(algorithmName) return digest.build(data.toByteArray(Charsets.UTF_8)) diff --git a/ktor-client/ktor-client-plugins/ktor-client-auth/common/test/io/ktor/client/plugins/auth/AuthTest.kt b/ktor-client/ktor-client-plugins/ktor-client-auth/common/test/io/ktor/client/plugins/auth/AuthTest.kt index 4ab59c2cfc4..a51eda8ba8d 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-auth/common/test/io/ktor/client/plugins/auth/AuthTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-auth/common/test/io/ktor/client/plugins/auth/AuthTest.kt @@ -13,12 +13,13 @@ import io.ktor.client.request.get import io.ktor.client.statement.* import io.ktor.client.tests.utils.* import io.ktor.http.* -import io.ktor.utils.io.concurrent.* +import io.ktor.util.* import kotlinx.coroutines.* import kotlin.test.* class AuthTest : ClientLoader() { + @OptIn(InternalAPI::class) @Test fun testDigestAuthLegacy() = clientTests(listOf("Js", "native")) { config { @@ -184,6 +185,7 @@ class AuthTest : ClientLoader() { } } + @OptIn(InternalAPI::class) @Test fun testBasicAuthMultiple() = clientTests(listOf("Js")) { config { @@ -202,7 +204,7 @@ class AuthTest : ClientLoader() { test { client -> client.get("$TEST_SERVER/auth/basic-fixed").bodyAsText() client.post("$TEST_SERVER/auth/basic") { - body = "{\"test\":\"text\"}" + setBody("{\"test\":\"text\"}") }.bodyAsText() } } @@ -225,7 +227,7 @@ class AuthTest : ClientLoader() { test { client -> client.get("$TEST_SERVER/auth/basic-fixed").bodyAsText() client.post("$TEST_SERVER/auth/basic") { - body = "{\"test\":\"text\"}" + setBody("{\"test\":\"text\"}") }.bodyAsText() } } @@ -351,6 +353,7 @@ class AuthTest : ClientLoader() { private var clientWithAuth: HttpClient? by shared(null) @Suppress("JoinDeclarationAndAssignment") + @OptIn(DelicateCoroutinesApi::class) @Test fun testRefreshWithSameClient() = clientTests { test { client -> diff --git a/ktor-client/ktor-client-plugins/ktor-client-auth/common/test/io/ktor/client/plugins/auth/DigestProviderTest.kt b/ktor-client/ktor-client-plugins/ktor-client-auth/common/test/io/ktor/client/plugins/auth/DigestProviderTest.kt index ab8f8b8880d..034184e5e7f 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-auth/common/test/io/ktor/client/plugins/auth/DigestProviderTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-auth/common/test/io/ktor/client/plugins/auth/DigestProviderTest.kt @@ -2,6 +2,8 @@ * Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +@file:Suppress("DEPRECATION") + package io.ktor.client.plugins.auth import io.ktor.client.plugins.auth.providers.* @@ -32,7 +34,7 @@ class DigestProviderTest { DigestAuthProvider({ DigestAuthCredentials("username", "password") }, "realm") } - lateinit var requestBuilder: HttpRequestBuilder + private lateinit var requestBuilder: HttpRequestBuilder @BeforeTest fun setup() { @@ -62,6 +64,7 @@ class DigestProviderTest { fun addRequestHeadersMissingRealm() = testSuspend { if (!PlatformUtils.IS_JVM) return@testSuspend + @Suppress("DEPRECATION") val providerWithoutRealm = DigestAuthProvider("username", "pass", null) val authHeader = parseAuthorizationHeader(authAllFields)!! requestBuilder.attributes.put(AuthHeaderAttribute, authHeader) @@ -77,6 +80,7 @@ class DigestProviderTest { fun addRequestHeadersChangedRealm() = testSuspend { if (!PlatformUtils.IS_JVM) return@testSuspend + @Suppress("DEPRECATION") val providerWithoutRealm = DigestAuthProvider("username", "pass", "wrong!") val authHeader = parseAuthorizationHeader(authAllFields)!! requestBuilder.attributes.put(AuthHeaderAttribute, authHeader) diff --git a/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/build.gradle.kts b/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/build.gradle.kts index 67e1d80cd85..4b4f814989d 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/build.gradle.kts +++ b/ktor-client/ktor-client-plugins/ktor-client-content-negotiation/build.gradle.kts @@ -4,8 +4,6 @@ description = "Ktor client Content Negotiation support" -val ideaActive: Boolean by project.extra - plugins { id("kotlinx-serialization") } diff --git a/ktor-client/ktor-client-plugins/ktor-client-encoding/build.gradle.kts b/ktor-client/ktor-client-plugins/ktor-client-encoding/build.gradle.kts deleted file mode 100644 index c149dcacdbb..00000000000 --- a/ktor-client/ktor-client-plugins/ktor-client-encoding/build.gradle.kts +++ /dev/null @@ -1,5 +0,0 @@ -/* -* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. -*/ - -val ideaActive: Boolean by project.extra diff --git a/ktor-client/ktor-client-plugins/ktor-client-encoding/common/src/ContentEncoding.kt b/ktor-client/ktor-client-plugins/ktor-client-encoding/common/src/ContentEncoding.kt index 02498aa3e84..871bb91603f 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-encoding/common/src/ContentEncoding.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-encoding/common/src/ContentEncoding.kt @@ -42,7 +42,7 @@ public class ContentEncoding( } private fun CoroutineScope.decode(headers: Headers, content: ByteReadChannel): ByteReadChannel { - val encodings = headers[HttpHeaders.ContentEncoding]?.split(",")?.map { it.trim().toLowerCase() } + val encodings = headers[HttpHeaders.ContentEncoding]?.split(",")?.map { it.trim().lowercase() } ?: return content var current = content @@ -99,7 +99,7 @@ public class ContentEncoding( */ public fun customEncoder(encoder: ContentEncoder, quality: Float? = null) { val name = encoder.name - encoders[name.toLowerCase()] = encoder + encoders[name.lowercase()] = encoder if (quality == null) { qualityValues.remove(name) diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/build.gradle.kts b/ktor-client/ktor-client-plugins/ktor-client-json/build.gradle.kts index 78eccf3c814..46e1b8054ae 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/build.gradle.kts +++ b/ktor-client/ktor-client-plugins/ktor-client-json/build.gradle.kts @@ -4,8 +4,6 @@ description = "Ktor client JSON support" -val ideaActive: Boolean by project.extra - plugins { id("kotlinx-serialization") } diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/common/src/io/ktor/client/plugins/json/JsonPlugin.kt b/ktor-client/ktor-client-plugins/ktor-client-json/common/src/io/ktor/client/plugins/json/JsonPlugin.kt index 4b91c932aa2..bb80133a761 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/common/src/io/ktor/client/plugins/json/JsonPlugin.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/common/src/io/ktor/client/plugins/json/JsonPlugin.kt @@ -2,6 +2,8 @@ * Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +@file:Suppress("DEPRECATION") + package io.ktor.client.plugins.json import io.ktor.client.* diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/common/test/JsonPluginTest.kt b/ktor-client/ktor-client-plugins/ktor-client-json/common/test/JsonPluginTest.kt index 84641376363..40eee28cf87 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/common/test/JsonPluginTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/common/test/JsonPluginTest.kt @@ -7,6 +7,7 @@ package io.ktor.client.plugins.json import io.ktor.http.* import kotlin.test.* +@Suppress("DEPRECATION") class JsonPluginTest { @Test fun testDefaultContentTypes() { diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/common/test/KotlinxSerializerTest.kt b/ktor-client/ktor-client-plugins/ktor-client-json/common/test/KotlinxSerializerTest.kt index 5696bc1c3c9..f581a2b801d 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/common/test/KotlinxSerializerTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/common/test/KotlinxSerializerTest.kt @@ -22,13 +22,7 @@ internal data class User(val id: Long, val login: String) @Serializable internal data class Photo(val id: Long, val path: String) -@Serializable -data class GithubProfile( - val login: String, - val id: Int, - val name: String -) - +@Suppress("DEPRECATION") class KotlinxSerializerTest : ClientLoader() { @Test fun testRegisterCustom() { diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/js/src/io/ktor/client/plugins/json/DefaultJs.kt b/ktor-client/ktor-client-plugins/ktor-client-json/js/src/io/ktor/client/plugins/json/DefaultJs.kt index fa1c8b35424..f798ba80c83 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/js/src/io/ktor/client/plugins/json/DefaultJs.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/js/src/io/ktor/client/plugins/json/DefaultJs.kt @@ -2,6 +2,8 @@ * Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +@file:Suppress("DEPRECATION") + package io.ktor.client.plugins.json import io.ktor.util.* @@ -9,9 +11,10 @@ import io.ktor.util.* /** * Platform default serializer. */ +@OptIn(InternalAPI::class) public actual fun defaultSerializer(): JsonSerializer = serializersStore.first() @Suppress("KDocMissingDocumentation") @InternalAPI -public val serializersStore: MutableList = mutableListOf() +public val serializersStore: MutableList = mutableListOf() diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/jvm/src/io/ktor/client/plugins/json/DefaultJvm.kt b/ktor-client/ktor-client-plugins/ktor-client-json/jvm/src/io/ktor/client/plugins/json/DefaultJvm.kt index 8149a726688..0d010849cde 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/jvm/src/io/ktor/client/plugins/json/DefaultJvm.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/jvm/src/io/ktor/client/plugins/json/DefaultJvm.kt @@ -6,6 +6,7 @@ package io.ktor.client.plugins.json import java.util.* +@Suppress("DEPRECATION") public actual fun defaultSerializer(): JsonSerializer { val serializers = ServiceLoader.load(JsonSerializer::class.java) .toList() diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-gson/jvm/src/io/ktor/client/plugins/json/GsonSerializer.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-gson/jvm/src/io/ktor/client/plugins/json/GsonSerializer.kt index cbe2f622548..200d4edc9b8 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-gson/jvm/src/io/ktor/client/plugins/json/GsonSerializer.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-gson/jvm/src/io/ktor/client/plugins/json/GsonSerializer.kt @@ -13,6 +13,7 @@ import io.ktor.utils.io.core.* /** * [JsonSerializer] using [Gson] as backend. */ +@Suppress("DEPRECATION") @Deprecated("Please use ContentNegotiation plugin and its converters") public class GsonSerializer(block: GsonBuilder.() -> Unit = {}) : JsonSerializer { private val backend: Gson = GsonBuilder().apply(block).create() diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-gson/jvm/test/io/ktor/client/plugins/json/tests/GsonTest.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-gson/jvm/test/io/ktor/client/plugins/json/tests/GsonTest.kt index d8dec9c9a5b..ef0e5fcea36 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-gson/jvm/test/io/ktor/client/plugins/json/tests/GsonTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-gson/jvm/test/io/ktor/client/plugins/json/tests/GsonTest.kt @@ -6,6 +6,7 @@ package io.ktor.client.plugins.json.tests import io.ktor.client.plugins.json.* +@Suppress("DEPRECATION") class GsonTest : JsonTest() { override val serializerImpl = GsonSerializer() } diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-jackson/build.gradle.kts b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-jackson/build.gradle.kts index 5d12b8306c4..9b07994c522 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-jackson/build.gradle.kts +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-jackson/build.gradle.kts @@ -1,3 +1,4 @@ +val kotlin_version: String by project.extra val jackson_version: String by project.extra val jackson_kotlin_version: String by project.extra @@ -8,6 +9,7 @@ kotlin.sourceSets { api("com.fasterxml.jackson.core:jackson-databind:$jackson_version") api("com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_kotlin_version") + implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version") } } val jvmTest by getting { diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-jackson/jvm/src/io/ktor/client/plugins/json/JacksonSerializer.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-jackson/jvm/src/io/ktor/client/plugins/json/JacksonSerializer.kt index 10f31362afe..6183dfb7e5d 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-jackson/jvm/src/io/ktor/client/plugins/json/JacksonSerializer.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-jackson/jvm/src/io/ktor/client/plugins/json/JacksonSerializer.kt @@ -2,6 +2,8 @@ * Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +@file:Suppress("DEPRECATION") + package io.ktor.client.plugins.json import com.fasterxml.jackson.databind.* diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-jackson/jvm/test/io/ktor/client/plugins/json/tests/JacksonTest.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-jackson/jvm/test/io/ktor/client/plugins/json/tests/JacksonTest.kt index 1b4e18a9878..44f0c760ea3 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-jackson/jvm/test/io/ktor/client/plugins/json/tests/JacksonTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-jackson/jvm/test/io/ktor/client/plugins/json/tests/JacksonTest.kt @@ -17,6 +17,7 @@ import io.ktor.server.response.* import io.ktor.server.routing.* import kotlin.test.* +@Suppress("DEPRECATION") class JacksonTest : JsonTest() { override val serializerImpl = JacksonSerializer() diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-json-tests/jvm/src/io/ktor/client/plugins/json/tests/JsonTest.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-json-tests/jvm/src/io/ktor/client/plugins/json/tests/JsonTest.kt index 562e96d52c3..a2f373d3e07 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-json-tests/jvm/src/io/ktor/client/plugins/json/tests/JsonTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-json-tests/jvm/src/io/ktor/client/plugins/json/tests/JsonTest.kt @@ -28,8 +28,8 @@ import kotlinx.serialization.* import kotlin.test.* /** Base class for JSON tests. */ -@Suppress("KDocMissingDocumentation") -public abstract class JsonTest : TestWithKtor() { +@Suppress("KDocMissingDocumentation", "DEPRECATION") +abstract class JsonTest : TestWithKtor() { private val widget = Widget("Foo", 1000, listOf("bar", "baz", "qux")) private val users = listOf( User("vasya", 10), @@ -93,8 +93,8 @@ public abstract class JsonTest : TestWithKtor() { } } - @org.junit.Test - public fun testEmptyBody() = testWithEngine(MockEngine) { + @Test + fun testEmptyBody() = testWithEngine(MockEngine) { config { engine { addHandler { request -> @@ -120,7 +120,7 @@ public abstract class JsonTest : TestWithKtor() { } @Test - public fun testSerializeSimple() = testWithEngine(CIO) { + fun testSerializeSimple() = testWithEngine(CIO) { configClient() test { client -> @@ -135,7 +135,7 @@ public abstract class JsonTest : TestWithKtor() { } @Test - public fun testSerializeNested() = testWithEngine(CIO) { + fun testSerializeNested() = testWithEngine(CIO) { configClient() test { client -> @@ -148,7 +148,7 @@ public abstract class JsonTest : TestWithKtor() { } @Test - public fun testCustomContentTypes() = testWithEngine(CIO) { + fun testCustomContentTypes() = testWithEngine(CIO) { configCustomContentTypeClient { acceptContentTypes = listOf(customContentType) } @@ -187,7 +187,7 @@ public abstract class JsonTest : TestWithKtor() { } @Test - public fun testCustomContentTypesMultiple() = testWithEngine(CIO) { + fun testCustomContentTypesMultiple() = testWithEngine(CIO) { configCustomContentTypeClient { acceptContentTypes = listOf(ContentType.Application.Json, customContentType) } @@ -206,7 +206,7 @@ public abstract class JsonTest : TestWithKtor() { } @Test - public fun testCustomContentTypesWildcard() = testWithEngine(CIO) { + fun testCustomContentTypesWildcard() = testWithEngine(CIO) { configCustomContentTypeClient { acceptContentTypes = listOf(ContentType.Application.Any) } @@ -239,20 +239,20 @@ public abstract class JsonTest : TestWithKtor() { } @Serializable - public data class Response( + data class Response( val ok: Boolean, val result: T? ) @Serializable - public data class Widget( + data class Widget( val name: String, val value: Int, val tags: List = emptyList() ) @Serializable - public data class User( + data class User( val name: String, val age: Int ) diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-json-tests/jvm/test/DefaultSerializerJsonTest.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-json-tests/jvm/test/DefaultSerializerJsonTest.kt index 58c9804f171..33f00173cac 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-json-tests/jvm/test/DefaultSerializerJsonTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-json-tests/jvm/test/DefaultSerializerJsonTest.kt @@ -5,6 +5,7 @@ import io.ktor.client.plugins.json.* import io.ktor.client.plugins.json.tests.* +@Suppress("DEPRECATION") class DefaultSerializerJsonTest : JsonTest() { // Force JsonPlugin to use defaultSerializer() override val serializerImpl: JsonSerializer = GsonSerializer() diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/src/io/ktor/client/plugins/json/serializer/KotlinxSerializer.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/src/io/ktor/client/plugins/json/serializer/KotlinxSerializer.kt index feb98735e2e..8b3cf6cb4b0 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/src/io/ktor/client/plugins/json/serializer/KotlinxSerializer.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/src/io/ktor/client/plugins/json/serializer/KotlinxSerializer.kt @@ -2,6 +2,8 @@ * Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +@file:Suppress("DEPRECATION") + package io.ktor.client.plugins.json.serializer import io.ktor.client.plugins.json.* diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/test/CollectionsSerializationTest.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/test/CollectionsSerializationTest.kt index 4e9f5d1a5a7..2d6a8258b51 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/test/CollectionsSerializationTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/test/CollectionsSerializationTest.kt @@ -9,6 +9,7 @@ import io.ktor.http.content.* import kotlinx.serialization.json.* import kotlin.test.* +@Suppress("DEPRECATION") class CollectionsSerializationTest { private val testSerializer = KotlinxSerializer() diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/test/ContextualSerializationTest.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/test/ContextualSerializationTest.kt index 346f1a21dcf..54667643294 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/test/ContextualSerializationTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/common/test/ContextualSerializationTest.kt @@ -29,6 +29,7 @@ object UserDataSerializer : KSerializer { } } +@Suppress("DEPRECATION") class ContextualSerializationTest { @Test diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/js/src/SerializerInitializer.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/js/src/SerializerInitializer.kt index 2f7f31e2bac..881a3abfa5a 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/js/src/SerializerInitializer.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/js/src/SerializerInitializer.kt @@ -13,6 +13,7 @@ public val initializer: SerializerInitializer = SerializerInitializer @InternalAPI public object SerializerInitializer { init { + @Suppress("DEPRECATION") serializersStore += KotlinxSerializer() } } diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/jvm/test/KotlinxSerializerTest.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/jvm/test/KotlinxSerializerTest.kt index b1d22c5c07e..b70139a6651 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/jvm/test/KotlinxSerializerTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/jvm/test/KotlinxSerializerTest.kt @@ -2,6 +2,8 @@ * Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +@file:Suppress("DEPRECATION") + import io.ktor.client.plugins.json.serializer.* import io.ktor.util.reflect.* import io.ktor.utils.io.streams.* diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/posix/src/SerializerInitializer.kt b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/posix/src/SerializerInitializer.kt index a0d0869f40d..d29be8fe10a 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/posix/src/SerializerInitializer.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/ktor-client-serialization/posix/src/SerializerInitializer.kt @@ -5,10 +5,13 @@ package io.ktor.client.plugins.json.serializer import io.ktor.client.plugins.json.* +import io.ktor.util.* @Suppress("unused") private val InitHook = SerializerInitializer +@Suppress("DEPRECATION") +@OptIn(InternalAPI::class) private object SerializerInitializer { init { serializers.add(KotlinxSerializer()) diff --git a/ktor-client/ktor-client-plugins/ktor-client-json/posix/src/io/ktor/client/plugins/json/DefaultPosix.kt b/ktor-client/ktor-client-plugins/ktor-client-json/posix/src/io/ktor/client/plugins/json/DefaultPosix.kt index 1545795eee9..7a00d47e534 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-json/posix/src/io/ktor/client/plugins/json/DefaultPosix.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-json/posix/src/io/ktor/client/plugins/json/DefaultPosix.kt @@ -2,6 +2,8 @@ * Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +@file:Suppress("DEPRECATION") + package io.ktor.client.plugins.json import io.ktor.util.* @@ -10,10 +12,11 @@ import io.ktor.util.* * Platform default serializer. */ +@OptIn(InternalAPI::class) public actual fun defaultSerializer(): JsonSerializer = serializers.first() @InternalAPI @Suppress("KDocMissingDocumentation") public val serializers: MutableList by lazy { - mutableListOf() + mutableListOf() } diff --git a/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logging.kt b/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logging.kt index 54fb02fc7d6..5b09f5d6351 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logging.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/Logging.kt @@ -135,6 +135,7 @@ public class Logging( log("-> $key: $value") } + @OptIn(DelicateCoroutinesApi::class) private suspend fun logRequestBody(content: OutgoingContent): OutgoingContent? { logger.log("BODY Content-Type: ${content.contentType}") @@ -159,6 +160,7 @@ public class Logging( return Logging(config.logger, config.level, config.filters) } + @OptIn(InternalAPI::class) override fun install(plugin: Logging, scope: HttpClient) { scope.sendPipeline.intercept(HttpSendPipeline.Monitoring) { val response = if (plugin.filters.isEmpty() || plugin.filters.any { it(context) }) { diff --git a/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/ObservingUtils.kt b/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/ObservingUtils.kt index 373b2c56a35..bed3186d8d0 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/ObservingUtils.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-logging/common/src/io/ktor/client/plugins/logging/ObservingUtils.kt @@ -34,5 +34,6 @@ internal suspend fun OutgoingContent.observe(log: ByteWriteChannel): OutgoingCon } } +@OptIn(DelicateCoroutinesApi::class) private fun OutgoingContent.WriteChannelContent.toReadChannel(): ByteReadChannel = GlobalScope.writer(Dispatchers.Unconfined) { writeTo(channel) }.channel diff --git a/ktor-client/ktor-client-plugins/ktor-client-websockets/common/test/io/ktor/client/tests/plugins/WebSocketRemoteTest.kt b/ktor-client/ktor-client-plugins/ktor-client-websockets/common/test/io/ktor/client/tests/plugins/WebSocketRemoteTest.kt index d0c3d645164..1b02d0e300e 100644 --- a/ktor-client/ktor-client-plugins/ktor-client-websockets/common/test/io/ktor/client/tests/plugins/WebSocketRemoteTest.kt +++ b/ktor-client/ktor-client-plugins/ktor-client-websockets/common/test/io/ktor/client/tests/plugins/WebSocketRemoteTest.kt @@ -70,7 +70,7 @@ class WebSocketRemoteTest : ClientLoader() { } test { client -> - val session = client.webSocket(echoWebsocket) { + client.webSocket(echoWebsocket) { close(CloseReason(CloseReason.Codes.NORMAL, "OK")) } } diff --git a/ktor-client/ktor-client-tests/build.gradle.kts b/ktor-client/ktor-client-tests/build.gradle.kts index 76ca83e645a..a1694bda351 100644 --- a/ktor-client/ktor-client-tests/build.gradle.kts +++ b/ktor-client/ktor-client-tests/build.gradle.kts @@ -13,8 +13,6 @@ val kotlin_version: String by project.extra val logback_version: String by project.extra val coroutines_version: String by project -val ideaActive: Boolean by project.extra - plugins { id("kotlinx-serialization") } @@ -93,7 +91,7 @@ kotlin.sourceSets { runtimeOnly(project(":ktor-client:ktor-client-cio")) runtimeOnly(project(":ktor-client:ktor-client-android")) runtimeOnly(project(":ktor-client:ktor-client-okhttp")) - if (project.ext["currentJdk"] as Int >= 11) { + if (KtorBuildProperties.currentJdk as Int >= 11) { runtimeOnly(project(":ktor-client:ktor-client-java")) } } @@ -104,6 +102,41 @@ kotlin.sourceSets { api(project(":ktor-client:ktor-client-js")) } } + + if (rootProject.ext.get("native_targets_enabled") as Boolean) { + if (!KtorBuildProperties.ideaActive) { + listOf("linuxX64Test", "mingwX64Test", "macosX64Test").map { getByName(it) }.forEach { + it.dependencies { + api(project(":ktor-client:ktor-client-curl")) + } + } + + if (!osName.startsWith("Windows")) { + listOf("linuxX64Test", "macosX64Test", "iosX64Test").map { getByName(it) }.forEach { + it.dependencies { + api(project(":ktor-client:ktor-client-cio")) + } + } + } + listOf("iosX64Test", "macosX64Test").map { getByName(it) }.forEach { + it.dependencies { + // api(project(":ktor-client:ktor-client-ios")) + } + } + } else { + val posixTest by getting { + dependencies { + val hostname: String by project.ext + // api(project(":ktor-client:ktor-client-ios")) + api(project(":ktor-client:ktor-client-curl")) + + if (!hostname.startsWith("win")) { + api(project(":ktor-client:ktor-client-cio")) + } + } + } + } + } } val startTestServer = task("startTestServer") { @@ -127,7 +160,7 @@ val testTasks = mutableListOf( "darwinTest" ) -if (!ideaActive) { +if (!KtorBuildProperties.ideaActive) { testTasks += listOf( "macosX64Test", "linuxX64Test", diff --git a/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/Assertions.kt b/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/Assertions.kt index 849555cce9b..e0651fcb428 100644 --- a/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/Assertions.kt +++ b/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/Assertions.kt @@ -4,16 +4,12 @@ package io.ktor.client.tests.utils -import io.ktor.util.* - /** * Asserts that [block] completed with given type of root cause. */ -@InternalAPI -public expect inline fun assertFailsAndContainsCause(block: () -> Unit) +expect inline fun assertFailsAndContainsCause(block: () -> Unit) /** * Asserts that a [block] fails with a specific exception of type [T] being thrown. */ -@InternalAPI -public expect inline fun assertFailsWith(block: () -> Unit) +expect inline fun assertFailsWith(block: () -> Unit) diff --git a/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/ClientLoader.kt b/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/ClientLoader.kt index c319d8090a1..d568031b61d 100644 --- a/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/ClientLoader.kt +++ b/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/ClientLoader.kt @@ -5,16 +5,17 @@ package io.ktor.client.tests.utils import io.ktor.client.engine.* +import io.ktor.util.* import kotlin.jvm.* /** * Helper interface to test client. */ -public expect abstract class ClientLoader(timeoutSeconds: Int = 60) { +expect abstract class ClientLoader(timeoutSeconds: Int = 60) { /** * Perform test against all clients from dependencies. */ - public fun clientTests( + fun clientTests( skipEngines: List = emptyList(), block: suspend TestClientBuilder.() -> Unit ) @@ -22,5 +23,5 @@ public expect abstract class ClientLoader(timeoutSeconds: Int = 60) { /** * Print coroutines in debug mode. */ - public fun dumpCoroutines() + fun dumpCoroutines() } diff --git a/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/CommonClientTestUtils.kt b/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/CommonClientTestUtils.kt index 65251aa6088..7d03e0fd111 100644 --- a/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/CommonClientTestUtils.kt +++ b/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/CommonClientTestUtils.kt @@ -59,6 +59,7 @@ private fun testWithClient( /** * Perform test with selected client engine [factory]. */ +@OptIn(DelicateCoroutinesApi::class) fun testWithEngine( factory: HttpClientEngineFactory, loader: ClientLoader? = null, @@ -104,7 +105,6 @@ private suspend fun concurrency(level: Int, block: suspend (Int) -> Unit) { } } -@InternalAPI class TestClientBuilder( var config: HttpClientConfig.() -> Unit = {}, var test: suspend TestInfo.(client: HttpClient) -> Unit = {}, @@ -114,17 +114,14 @@ class TestClientBuilder( var concurrency: Int = 1 ) -@InternalAPI fun TestClientBuilder.config(block: HttpClientConfig.() -> Unit) { config = block } -@InternalAPI fun TestClientBuilder<*>.test(block: suspend TestInfo.(client: HttpClient) -> Unit) { test = block } -@InternalAPI fun TestClientBuilder<*>.after(block: suspend (client: HttpClient) -> Unit): Unit { // ktlint-disable no-unit-return after = block } diff --git a/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/Generators.kt b/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/Generators.kt index 371bd790158..e66e5248daf 100644 --- a/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/Generators.kt +++ b/ktor-client/ktor-client-tests/common/src/io/ktor/client/tests/utils/Generators.kt @@ -10,16 +10,13 @@ import io.ktor.util.* import io.ktor.utils.io.charsets.* import io.ktor.utils.io.core.* -@InternalAPI -public fun makeArray(size: Int): ByteArray = buildPacket { repeat(size) { writeByte(it.toByte()) } }.readBytes() +fun makeArray(size: Int): ByteArray = buildPacket { repeat(size) { writeByte(it.toByte()) } }.readBytes() -@InternalAPI -public fun makeString(size: Int): String = buildString { repeat(size) { append(it.toChar()) } } +fun makeString(size: Int): String = buildString { repeat(size) { append(it.toChar()) } } .encodeBase64() .take(size) -@InternalAPI -public fun List.makeString(): String = buildString { +fun List.makeString(): String = buildString { val list = this@makeString list.forEach { append("${it.name!!}\n") diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/BodyProgressTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/BodyProgressTest.kt index 5dab2a738ce..da7e2eefc63 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/BodyProgressTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/BodyProgressTest.kt @@ -2,6 +2,8 @@ * Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +@file:Suppress("DEPRECATION") + package io.ktor.client.tests import io.ktor.client.call.* @@ -21,6 +23,7 @@ import kotlinx.coroutines.* import kotlinx.serialization.* import kotlin.test.* +@OptIn(DelicateCoroutinesApi::class) class BodyProgressTest : ClientLoader() { @Serializable @@ -42,7 +45,7 @@ class BodyProgressTest : ClientLoader() { val response: HttpResponse = client.post("$TEST_SERVER/content/echo") { contentType(ContentType.Application.Json) - body = User("123".repeat(5000), 1) + setBody(User("123".repeat(5000), 1)) onUpload(listener) } assertEquals("""{"login":"${"123".repeat(5000)}","id":1}""", response.body()) @@ -57,14 +60,16 @@ class BodyProgressTest : ClientLoader() { val listener: ProgressListener = { _, _ -> invokedCount++ } val response: HttpResponse = client.post("$TEST_SERVER/content/echo") { - body = object : OutgoingContent.WriteChannelContent() { - override val contentType = ContentType.Application.OctetStream - override suspend fun writeTo(channel: ByteWriteChannel) { - channel.writeFully(ByteArray(8 * 1025) { 1 }) - channel.writeFully(ByteArray(8 * 1025) { 1 }) - channel.close() + setBody( + object : OutgoingContent.WriteChannelContent() { + override val contentType = ContentType.Application.OctetStream + override suspend fun writeTo(channel: ByteWriteChannel) { + channel.writeFully(ByteArray(8 * 1025) { 1 }) + channel.writeFully(ByteArray(8 * 1025) { 1 }) + channel.close() + } } - } + ) onUpload(listener) } assertContentEquals(ByteArray(16 * 1025) { 1 }, response.body()) @@ -76,7 +81,7 @@ class BodyProgressTest : ClientLoader() { fun testSendChannel() = clientTests { test { client -> invokedCount = 0 - val listener: ProgressListener = { count, total -> invokedCount++ } + val listener: ProgressListener = { _, _ -> invokedCount++ } val channel = ByteChannel() GlobalScope.launch { @@ -86,7 +91,7 @@ class BodyProgressTest : ClientLoader() { } val response: HttpResponse = client.post("$TEST_SERVER/content/echo") { - body = channel + setBody(channel) onUpload(listener) } assertContentEquals(ByteArray(16 * 1025) { 1 }, response.body()) @@ -98,10 +103,10 @@ class BodyProgressTest : ClientLoader() { fun testSendByteArray() = clientTests { test { client -> invokedCount = 0 - val listener: ProgressListener = { count, total -> invokedCount++ } + val listener: ProgressListener = { _, _ -> invokedCount++ } val response: HttpResponse = client.post("$TEST_SERVER/content/echo") { - body = ByteArray(1025 * 16) { 1 } + setBody(ByteArray(1025 * 16) { 1 }) onUpload(listener) } assertContentEquals(ByteArray(16 * 1025) { 1 }, response.body()) @@ -122,8 +127,8 @@ class BodyProgressTest : ClientLoader() { } assertFailsWith { - val response: HttpResponse = client.post("$TEST_SERVER/content/echo") { - body = channel + client.post("$TEST_SERVER/content/echo") { + setBody(channel) onUpload(listener) } } @@ -166,7 +171,7 @@ class BodyProgressTest : ClientLoader() { test { client -> invokedCount = 0 - val listener: ProgressListener = { sent, _ -> invokedCount++ } + val listener: ProgressListener = { _, _ -> invokedCount++ } client.prepareGet("$TEST_SERVER/json/users-long") { contentType(ContentType.Application.Json) @@ -183,7 +188,7 @@ class BodyProgressTest : ClientLoader() { fun testReceiveChannelWithExecute() = clientTests { test { client -> invokedCount = 0 - val listener: ProgressListener = { count, total -> invokedCount++ } + val listener: ProgressListener = { _, _ -> invokedCount++ } val channel = ByteChannel() GlobalScope.launch { @@ -193,7 +198,7 @@ class BodyProgressTest : ClientLoader() { } client.preparePost("$TEST_SERVER/content/echo") { - body = channel + setBody(channel) onDownload(listener) }.execute { val result = it.body().readRemaining().readBytes() @@ -207,7 +212,7 @@ class BodyProgressTest : ClientLoader() { fun testReceiveChannelWithReceive() = clientTests { test { client -> invokedCount = 0 - val listener: ProgressListener = { count, total -> invokedCount++ } + val listener: ProgressListener = { _, _ -> invokedCount++ } val channel = ByteChannel() GlobalScope.launch { @@ -217,7 +222,7 @@ class BodyProgressTest : ClientLoader() { } client.preparePost("$TEST_SERVER/content/echo") { - body = channel + setBody(channel) onDownload(listener) }.body { val result = it.readRemaining().readBytes() @@ -231,10 +236,10 @@ class BodyProgressTest : ClientLoader() { fun testReceiveByteArrayWithExecute() = clientTests { test { client -> invokedCount = 0 - val listener: ProgressListener = { count, total -> invokedCount++ } + val listener: ProgressListener = { _, _ -> invokedCount++ } client.preparePost("$TEST_SERVER/content/echo") { - body = ByteArray(1025 * 16) { 1 } + setBody(ByteArray(1025 * 16) { 1 }) onDownload(listener) }.execute { val result = it.body() @@ -251,7 +256,7 @@ class BodyProgressTest : ClientLoader() { val listener: ProgressListener = { _, _ -> invokedCount++ } client.preparePost("$TEST_SERVER/content/echo") { - body = ByteArray(1025 * 16) { 1 } + setBody(ByteArray(1025 * 16) { 1 }) onDownload(listener) }.body { assertContentEquals(ByteArray(16 * 1025) { 1 }, it) diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ClientPipelinesTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ClientPipelinesTest.kt index 505281bebd6..178dc3b2d4b 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ClientPipelinesTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ClientPipelinesTest.kt @@ -10,12 +10,14 @@ import io.ktor.client.statement.* import io.ktor.client.tests.utils.* import io.ktor.client.utils.* import io.ktor.http.* +import io.ktor.util.* import io.ktor.util.date.* import io.ktor.utils.io.* import kotlin.coroutines.* import kotlin.test.* class ClientPipelinesTest : ClientLoader() { + @OptIn(InternalAPI::class) @Test fun testCanAddHeaders() = clientTests { config { diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ContentTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ContentTest.kt index d8c91b20bf7..096453c3d07 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ContentTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ContentTest.kt @@ -272,6 +272,6 @@ class ContentTest : ClientLoader() { private suspend inline fun HttpClient.echo( body: Any ): Response = post("$TEST_SERVER/content/echo") { - this.body = body + setBody(body) }.body() } diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ExceptionsTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ExceptionsTest.kt index 6da821ca174..20ba308a079 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ExceptionsTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/ExceptionsTest.kt @@ -35,7 +35,7 @@ class ExceptionsTest : ClientLoader() { try { client.get("www.google.com").body() } catch (exception: ResponseException) { - val text = exception.response?.bodyAsText() + val text = exception.response.bodyAsText() assertEquals(HttpStatusCode.BadRequest.description, text) } } @@ -130,9 +130,9 @@ class ExceptionsTest : ClientLoader() { assertFailsWith { client.prepareGet(requestBuilder).execute { response -> try { - CoroutineScope(response.coroutineContext) - .launch { throw IllegalStateException("failed on receive") } - .join() + CoroutineScope(response.coroutineContext).launch { + throw IllegalStateException("failed on receive") + }.join() } catch (cause: Exception) { } response.body() diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpStatementTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpStatementTest.kt index de486ee54fa..20de53d0cf2 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpStatementTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpStatementTest.kt @@ -31,7 +31,7 @@ class HttpStatementTest : ClientLoader() { assertArrayEquals("Invalid content", expected, actual) } - val response = client.prepareGet("$TEST_SERVER/content/hello") { {} }.execute() + val response = client.prepareGet("$TEST_SERVER/content/hello").execute() assertEquals("hello", response.body()) } } diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpTimeoutTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpTimeoutTest.kt index b584f22840f..91600d33622 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpTimeoutTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpTimeoutTest.kt @@ -67,7 +67,7 @@ class HttpTimeoutTest : ClientLoader() { val requestBuilder = HttpRequestBuilder().apply { method = HttpMethod.Get url("$TEST_URL/with-delay") - parameter("delay", 60 * 1000) + parameter("delay", 60000) } val exception = assertFails { diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/LoggingMockedTests.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/LoggingMockedTests.kt index 0f625dd85ed..a1ea47b332a 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/LoggingMockedTests.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/LoggingMockedTests.kt @@ -89,7 +89,7 @@ class LoggingMockedTests { config { engine { - addHandler { request -> + addHandler { respondOk("Hello") } } @@ -151,7 +151,7 @@ class LoggingMockedTests { config { engine { - addHandler { request -> + addHandler { respondOk("Hello") } } diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/LoggingTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/LoggingTest.kt index 1a7dd8d30c6..268621e6b93 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/LoggingTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/LoggingTest.kt @@ -19,6 +19,7 @@ import kotlinx.coroutines.* import kotlinx.serialization.* import kotlin.test.* +@OptIn(DelicateCoroutinesApi::class) class LoggingTest : ClientLoader() { private val content = "Response data" private val serverPort = 8080 @@ -497,7 +498,7 @@ class LoggingTest : ClientLoader() { val response = client.request { method = HttpMethod.Post url("$TEST_SERVER/content/echo") - this.body = body + setBody(body) }.receive() response.discard() } @@ -560,7 +561,7 @@ class LoggingTest : ClientLoader() { port = serverPort } - body?.let { this@request.body = body } + body?.let { setBody(body) } }.body() } diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/PluginsTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/PluginsTest.kt index 261b169ad28..737cab15809 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/PluginsTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/PluginsTest.kt @@ -9,6 +9,7 @@ import io.ktor.client.call.* import io.ktor.client.plugins.observer.* import io.ktor.client.request.* import io.ktor.client.tests.utils.* +import io.ktor.util.* import kotlinx.coroutines.* import kotlin.test.* @@ -40,6 +41,7 @@ class PluginsTest : ClientLoader() { } } + @OptIn(InternalAPI::class) @Test fun testBodyObserver() = clientTests(listOf("CIO", "Curl")) { val body = "Hello, world" diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/engine/UtilsTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/engine/UtilsTest.kt index 9dd0478d600..216c3c08eb3 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/engine/UtilsTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/engine/UtilsTest.kt @@ -7,9 +7,11 @@ package io.ktor.client.tests.engine import io.ktor.client.engine.* import io.ktor.client.utils.* import io.ktor.http.* +import io.ktor.util.* import kotlin.test.* class UtilsTest { + @OptIn(InternalAPI::class) @Test fun testMergeHeaders() { val headers = HeadersBuilder().apply { diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/plugins/CacheTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/plugins/CacheTest.kt index 4ed6bea0d6e..81ff993c8ec 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/plugins/CacheTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/plugins/CacheTest.kt @@ -216,6 +216,7 @@ class CacheTest : ClientLoader() { } } + @OptIn(InternalAPI::class) @Test fun testNoVaryIn304() = clientTests(listOf("Js")) { config { diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/utils/Logging.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/utils/Logging.kt index 350ab73fe3c..66b58b55e63 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/utils/Logging.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/utils/Logging.kt @@ -35,8 +35,8 @@ internal class TestLogger(private vararg val expectedLog: String) : Logger { val stashed = ArrayList() while (expectedIndex < expectedLog.size && actualIndex < log.size) { - var expected = expectedLog[expectedIndex].toLowerCase() - val actual = log[actualIndex].toLowerCase() + var expected = expectedLog[expectedIndex].lowercase() + val actual = log[actualIndex].lowercase() var flaky = false var optional = false @@ -96,7 +96,7 @@ internal class TestLogger(private vararg val expectedLog: String) : Logger { } while (actualIndex < log.size && stashed.isNotEmpty()) { - val actual = log[actualIndex].toLowerCase() + val actual = log[actualIndex].lowercase() if (actual in stashed) { actualIndex++ stashed.remove(actual) diff --git a/ktor-client/ktor-client-tests/js/src/io/ktor/client/tests/utils/AssertionsJs.kt b/ktor-client/ktor-client-tests/js/src/io/ktor/client/tests/utils/AssertionsJs.kt index ef317854a58..71e99be9dda 100644 --- a/ktor-client/ktor-client-tests/js/src/io/ktor/client/tests/utils/AssertionsJs.kt +++ b/ktor-client/ktor-client-tests/js/src/io/ktor/client/tests/utils/AssertionsJs.kt @@ -4,21 +4,17 @@ package io.ktor.client.tests.utils -import io.ktor.util.* - /** * Check that [block] completed with given type of root cause. */ -@InternalAPI -public actual inline fun assertFailsAndContainsCause(block: () -> Unit) { +actual inline fun assertFailsAndContainsCause(block: () -> Unit) { assertFailsWith(block) } /** * Asserts that a [block] fails with a specific exception of type [T] being thrown. */ -@InternalAPI -public actual inline fun assertFailsWith(block: () -> Unit) { +actual inline fun assertFailsWith(block: () -> Unit) { try { block() error("Expected ${T::class} exception, but it wasn't thrown") diff --git a/ktor-client/ktor-client-tests/js/src/io/ktor/client/tests/utils/ClientLoaderJs.kt b/ktor-client/ktor-client-tests/js/src/io/ktor/client/tests/utils/ClientLoaderJs.kt index e674190b87c..ed5d72ccf0f 100644 --- a/ktor-client/ktor-client-tests/js/src/io/ktor/client/tests/utils/ClientLoaderJs.kt +++ b/ktor-client/ktor-client-tests/js/src/io/ktor/client/tests/utils/ClientLoaderJs.kt @@ -12,23 +12,28 @@ import kotlinx.coroutines.* /** * Helper interface to test client. */ -public actual abstract class ClientLoader actual constructor(private val timeoutSeconds: Int) { +actual abstract class ClientLoader actual constructor(private val timeoutSeconds: Int) { /** * Perform test against all clients from dependencies. */ - public actual fun clientTests( + @OptIn(DelicateCoroutinesApi::class) + actual fun clientTests( skipEngines: List, block: suspend TestClientBuilder.() -> Unit - ): dynamic = { - val skipEnginesLowerCase = skipEngines.map { it.toLowerCase() } - if (skipEnginesLowerCase.contains("js")) GlobalScope.async {}.asPromise() else testWithEngine(Js) { - withTimeout(timeoutSeconds.toLong() * 1000) { - block() + ): dynamic { + val skipEnginesLowerCase = skipEngines.map { it.lowercase() } + return if (skipEnginesLowerCase.contains("js")) { + GlobalScope.async {}.asPromise() + } else { + testWithEngine(Js) { + withTimeout(timeoutSeconds.toLong() * 1000) { + block() + } } } - }() + } - public actual fun dumpCoroutines() { + actual fun dumpCoroutines() { error("Debug probes unsupported[js]") } } diff --git a/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/AssertionsJvm.kt b/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/AssertionsJvm.kt index b169dd942ab..ac5ee93adb2 100644 --- a/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/AssertionsJvm.kt +++ b/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/AssertionsJvm.kt @@ -4,14 +4,12 @@ package io.ktor.client.tests.utils -import io.ktor.util.* import kotlin.test.* /** * Check that [block] completed with given type of root cause. */ -@InternalAPI -public actual inline fun assertFailsAndContainsCause(block: () -> Unit) { +actual inline fun assertFailsAndContainsCause(block: () -> Unit) { var cause = assertFails(block) while (true) { @@ -25,7 +23,6 @@ public actual inline fun assertFailsAndContainsCause(blo /** * Asserts that a [block] fails with a specific exception of type [T] being thrown. */ -@InternalAPI -public actual inline fun assertFailsWith(block: () -> Unit) { +actual inline fun assertFailsWith(block: () -> Unit) { kotlin.test.assertFailsWith { block() } } diff --git a/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/ClientLoaderJvm.kt b/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/ClientLoaderJvm.kt index 84ee4db597c..7e0ec9d81bb 100644 --- a/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/ClientLoaderJvm.kt +++ b/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/ClientLoaderJvm.kt @@ -6,6 +6,7 @@ package io.ktor.client.tests.utils import io.ktor.client.* import io.ktor.client.engine.* +import io.ktor.util.* import kotlinx.coroutines.* import kotlinx.coroutines.debug.* import kotlinx.coroutines.debug.junit4.* @@ -18,23 +19,24 @@ import java.util.* * Helper interface to test client. */ @RunWith(Parameterized::class) -public actual abstract class ClientLoader actual constructor(timeoutSeconds: Int) { +actual abstract class ClientLoader actual constructor(timeoutSeconds: Int) { @Parameterized.Parameter - public lateinit var engine: HttpClientEngineContainer + lateinit var engine: HttpClientEngineContainer @get:Rule - public open val timeout: CoroutinesTimeout = CoroutinesTimeout.seconds(timeoutSeconds) + open val timeout: CoroutinesTimeout = CoroutinesTimeout.seconds(timeoutSeconds) /** * Perform test against all clients from dependencies. */ - public actual fun clientTests( + actual fun clientTests( skipEngines: List, block: suspend TestClientBuilder.() -> Unit ) { + val locale = Locale.getDefault() for (skipEngine in skipEngines) { - val skipEngineArray = skipEngine.toLowerCase().split(":") + val skipEngineArray = skipEngine.lowercase(locale).split(":") val (platform, engine) = when (skipEngineArray.size) { 2 -> skipEngineArray[0] to skipEngineArray[1] @@ -43,19 +45,21 @@ public actual abstract class ClientLoader actual constructor(timeoutSeconds: Int } val platformShouldBeSkipped = "*" == platform || OS_NAME == platform - val engineShouldBeSkipped = "*" == engine || this.engine.toString().toLowerCase() == engine + val engineShouldBeSkipped = "*" == engine || this.engine.toString().lowercase(locale) == engine if (platformShouldBeSkipped && engineShouldBeSkipped) { return } } - if (skipEngines.map { it.toLowerCase() }.contains(engine.toString().toLowerCase())) return + + val enginesToSkip = skipEngines.map { it.lowercase(locale) } + if (engine.toString().lowercase(locale) in enginesToSkip) return testWithEngine(engine.factory, this, block) } @OptIn(ExperimentalCoroutinesApi::class) - public actual fun dumpCoroutines() { + actual fun dumpCoroutines() { DebugProbes.dumpCoroutines() } @@ -66,7 +70,7 @@ public actual abstract class ClientLoader actual constructor(timeoutSeconds: Int */ // @After @OptIn(ExperimentalCoroutinesApi::class) - public fun waitForAllCoroutines() { + fun waitForAllCoroutines() { check(DebugProbes.isInstalled) { "Debug probes isn't installed." } @@ -85,10 +89,10 @@ public actual abstract class ClientLoader actual constructor(timeoutSeconds: Int error(message) } - public companion object { + companion object { @JvmStatic @Parameterized.Parameters(name = "{0}") - public fun engines(): List = HttpClientEngineContainer::class.java.let { + fun engines(): List = HttpClientEngineContainer::class.java.let { ServiceLoader.load(it, it.classLoader).toList() } } @@ -96,7 +100,7 @@ public actual abstract class ClientLoader actual constructor(timeoutSeconds: Int private val OS_NAME: String get() { - val os = System.getProperty("os.name", "unknown").toLowerCase() + val os = System.getProperty("os.name", "unknown").lowercase(Locale.getDefault()) return when { os.contains("win") -> "win" os.contains("mac") -> "mac" diff --git a/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/TestTcpServer.kt b/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/TestTcpServer.kt index 0c1d35fd56b..668d7899bf5 100644 --- a/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/TestTcpServer.kt +++ b/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/TestTcpServer.kt @@ -12,6 +12,7 @@ import java.io.* import java.net.* import kotlin.coroutines.* +@OptIn(DelicateCoroutinesApi::class) internal class TestTcpServer(val port: Int, handler: suspend (Socket) -> Unit) : CoroutineScope, Closeable { private val selector = ActorSelectorManager(Dispatchers.IO) override val coroutineContext: CoroutineContext diff --git a/ktor-client/ktor-client-tests/jvm/test/io/ktor/client/tests/ExceptionsJvmTest.kt b/ktor-client/ktor-client-tests/jvm/test/io/ktor/client/tests/ExceptionsJvmTest.kt index 5496719578b..ca5a70015ea 100644 --- a/ktor-client/ktor-client-tests/jvm/test/io/ktor/client/tests/ExceptionsJvmTest.kt +++ b/ktor-client/ktor-client-tests/jvm/test/io/ktor/client/tests/ExceptionsJvmTest.kt @@ -14,6 +14,7 @@ import org.junit.* import java.net.* import kotlin.io.use +@Suppress("BlockingMethodInNonBlockingContext", "ControlFlowWithEmptyBody") class ExceptionsJvmTest { @Test @@ -27,6 +28,7 @@ class ExceptionsJvmTest { } } + @OptIn(DelicateCoroutinesApi::class) @Test fun testConnectionClosedDuringRequest(): Unit = runBlocking { val server = ServerSocket(0) diff --git a/ktor-client/ktor-client-tests/jvm/test/io/ktor/client/tests/JvmContentTest.kt b/ktor-client/ktor-client-tests/jvm/test/io/ktor/client/tests/JvmContentTest.kt index a449f1f0706..7069d769b3e 100644 --- a/ktor-client/ktor-client-tests/jvm/test/io/ktor/client/tests/JvmContentTest.kt +++ b/ktor-client/ktor-client-tests/jvm/test/io/ktor/client/tests/JvmContentTest.kt @@ -40,7 +40,7 @@ class JvmContentTest : ClientLoader() { body: Any, crossinline block: (Response) -> T ): T = preparePost("$TEST_SERVER/content/echo") { - this.body = body + setBody(body) }.body { block(it) } diff --git a/ktor-client/ktor-client-tests/posix/src/io/ktor/client/tests/utils/AssertionsNative.kt b/ktor-client/ktor-client-tests/posix/src/io/ktor/client/tests/utils/AssertionsNative.kt index f68e41258ef..9d73e1510d2 100644 --- a/ktor-client/ktor-client-tests/posix/src/io/ktor/client/tests/utils/AssertionsNative.kt +++ b/ktor-client/ktor-client-tests/posix/src/io/ktor/client/tests/utils/AssertionsNative.kt @@ -4,14 +4,12 @@ package io.ktor.client.tests.utils -import io.ktor.util.* import kotlin.test.* /** * Check that [block] completed with given type of root cause. */ -@InternalAPI -public actual inline fun assertFailsAndContainsCause(block: () -> Unit) { +actual inline fun assertFailsAndContainsCause(block: () -> Unit) { var cause = assertFails(block) while (cause.cause != null) { @@ -25,7 +23,6 @@ public actual inline fun assertFailsAndContainsCause(blo /** * Asserts that a [block] fails with a specific exception of type [T] being thrown. */ -@InternalAPI -public actual inline fun assertFailsWith(block: () -> Unit) { +actual inline fun assertFailsWith(block: () -> Unit) { kotlin.test.assertFailsWith { block() } } diff --git a/ktor-client/ktor-client-tests/posix/src/io/ktor/client/tests/utils/ClientLoaderNative.kt b/ktor-client/ktor-client-tests/posix/src/io/ktor/client/tests/utils/ClientLoaderNative.kt index 2ff3fc26321..c01e40548f2 100644 --- a/ktor-client/ktor-client-tests/posix/src/io/ktor/client/tests/utils/ClientLoaderNative.kt +++ b/ktor-client/ktor-client-tests/posix/src/io/ktor/client/tests/utils/ClientLoaderNative.kt @@ -5,6 +5,7 @@ package io.ktor.client.tests.utils import io.ktor.client.engine.* +import io.ktor.util.* import kotlinx.coroutines.* private class TestFailure(val name: String, val cause: Throwable) { @@ -20,19 +21,20 @@ private class TestFailure(val name: String, val cause: Throwable) { /** * Helper interface to test client. */ -public actual abstract class ClientLoader actual constructor(private val timeoutSeconds: Int) { +actual abstract class ClientLoader actual constructor(private val timeoutSeconds: Int) { /** * Perform test against all clients from dependencies. */ - public actual fun clientTests( + @OptIn(InternalAPI::class) + actual fun clientTests( skipEngines: List, block: suspend TestClientBuilder.() -> Unit ) { if (skipEngines.any { it.startsWith("native") }) return - val skipEnginesLowerCase = skipEngines.map { it.toLowerCase() }.toSet() + val skipEnginesLowerCase = skipEngines.map { it.lowercase() }.toSet() val filteredEngines = engines.filter { - val name = it.toString().toLowerCase() + val name = it.toString().lowercase() !skipEnginesLowerCase.contains(name) && !skipEnginesLowerCase.contains("native:$name") } @@ -58,7 +60,7 @@ public actual abstract class ClientLoader actual constructor(private val timeout error(failures.joinToString("\n")) } - public actual fun dumpCoroutines() { + actual fun dumpCoroutines() { error("Debug probes unsupported native.") } } diff --git a/ktor-http/common/src/io/ktor/http/Codecs.kt b/ktor-http/common/src/io/ktor/http/Codecs.kt index f409a0bcfe0..da3cdf6bf49 100644 --- a/ktor-http/common/src/io/ktor/http/Codecs.kt +++ b/ktor-http/common/src/io/ktor/http/Codecs.kt @@ -3,13 +3,12 @@ */ package io.ktor.http -import io.ktor.util.* import io.ktor.utils.io.charsets.* import io.ktor.utils.io.core.* import kotlin.native.concurrent.* @SharedImmutable -private val URL_ALPHABET = (('a'..'z') + ('A'..'Z') + ('0'..'9')).map { it.toByte() } +private val URL_ALPHABET = (('a'..'z') + ('A'..'Z') + ('0'..'9')).map { it.code.toByte() } @SharedImmutable private val URL_ALPHABET_CHARS = (('a'..'z') + ('A'..'Z') + ('0'..'9')) @@ -25,7 +24,7 @@ private val URL_PROTOCOL_PART = listOf( ':', '/', '?', '#', '[', ']', '@', // general '!', '$', '&', '\'', '(', ')', '*', ',', ';', '=', // sub-components '-', '.', '_', '~', '+' // unreserved -).map { it.toByte() } +).map { it.code.toByte() } /** * from `pchar` in https://tools.ietf.org/html/rfc3986#section-2 @@ -42,15 +41,7 @@ private val VALID_PATH_PART = listOf( * https://tools.ietf.org/html/rfc5849#section-3.6 */ @SharedImmutable -private val OAUTH_SYMBOLS = listOf('-', '.', '_', '~').map { it.toByte() } - -internal val LETTERS_AND_NUMBERS = ('a'..'z').toSet() + ('A'..'Z').toSet() + ('0'..'9').toSet() - -/** - * https://tools.ietf.org/html/rfc7230#section-3.2.6 - */ -internal val TOKENS: Set = - setOf('!', '#', '%', '&', '\'', '*', '+', '-', '.', '^', '_', '`', '|', '~') + LETTERS_AND_NUMBERS +private val OAUTH_SYMBOLS = listOf('-', '.', '_', '~').map { it.code.toByte() } /** * Encode url part as specified in @@ -64,8 +55,8 @@ public fun String.encodeURLQueryComponent( val content = charset.newEncoder().encode(this@encodeURLQueryComponent) content.forEach { when { - it == ' '.toByte() -> if (spaceToPlus) append('+') else append("%20") - it in URL_ALPHABET || (!encodeFull && it in URL_PROTOCOL_PART) -> append(it.toChar()) + it == ' '.code.toByte() -> if (spaceToPlus) append('+') else append("%20") + it in URL_ALPHABET || (!encodeFull && it in URL_PROTOCOL_PART) -> append(it.toInt().toChar()) else -> append(it.percentEncode()) } } @@ -123,8 +114,8 @@ public fun String.encodeURLParameter( val content = Charsets.UTF_8.newEncoder().encode(this@encodeURLParameter) content.forEach { when { - it in URL_ALPHABET || it in OAUTH_SYMBOLS -> append(it.toChar()) - spaceToPlus && it == ' '.toByte() -> append('+') + it in URL_ALPHABET || it in OAUTH_SYMBOLS -> append(it.toInt().toChar()) + spaceToPlus && it == ' '.code.toByte() -> append('+') else -> append(it.percentEncode()) } } diff --git a/ktor-http/common/src/io/ktor/http/ContentTypes.kt b/ktor-http/common/src/io/ktor/http/ContentTypes.kt index 44040129005..67cb4aa9d9f 100644 --- a/ktor-http/common/src/io/ktor/http/ContentTypes.kt +++ b/ktor-http/common/src/io/ktor/http/ContentTypes.kt @@ -100,8 +100,8 @@ public class ContentType private constructor( parameters == other.parameters override fun hashCode(): Int { - var result = contentType.toLowerCase().hashCode() - result += 31 * result + contentSubtype.toLowerCase().hashCode() + var result = contentType.lowercase().hashCode() + result += 31 * result + contentSubtype.lowercase().hashCode() result += 31 * parameters.hashCode() return result } diff --git a/ktor-http/common/src/io/ktor/http/HeaderValueWithParameters.kt b/ktor-http/common/src/io/ktor/http/HeaderValueWithParameters.kt index 9eabec034e9..006746d0b9d 100644 --- a/ktor-http/common/src/io/ktor/http/HeaderValueWithParameters.kt +++ b/ktor-http/common/src/io/ktor/http/HeaderValueWithParameters.kt @@ -33,11 +33,11 @@ public abstract class HeaderValueWithParameters( override fun toString(): String = when { parameters.isEmpty() -> content else -> { - val size = content.length + parameters.sumBy { it.name.length + it.value.length + 3 } + val size = content.length + parameters.sumOf { it.name.length + it.value.length + 3 } StringBuilder(size).apply { append(content) - for (index in 0 until parameters.size) { - val (name, value) = parameters[index] + for (element in parameters) { + val (name, value) = element append("; ") append(name) append("=") @@ -68,7 +68,6 @@ public fun StringValuesBuilder.append(name: String, value: HeaderValueWithParame /** * Escape using double quotes if needed or keep as is if no dangerous strings found */ -@InternalAPI public fun String.escapeIfNeeded(): String = when { checkNeedEscape() -> quote() else -> this @@ -77,7 +76,7 @@ public fun String.escapeIfNeeded(): String = when { @Suppress("NOTHING_TO_INLINE") private inline fun String.escapeIfNeededTo(out: StringBuilder) { when { - checkNeedEscape() -> out.append(this.quote()) + checkNeedEscape() -> out.append(quote()) else -> out.append(this) } } @@ -126,14 +125,12 @@ private fun String.isQuoted(): Boolean { /** * Escape string using double quotes */ -@InternalAPI public fun String.quote(): String = buildString { this@quote.quoteTo(this) } private fun String.quoteTo(out: StringBuilder) { out.append("\"") for (i in 0 until length) { - val ch = this[i] - when (ch) { + when (val ch = this[i]) { '\\' -> out.append("\\\\") '\n' -> out.append("\\n") '\r' -> out.append("\\r") diff --git a/ktor-http/common/src/io/ktor/http/Headers.kt b/ktor-http/common/src/io/ktor/http/Headers.kt index 8d124512a85..efa59f03bb0 100644 --- a/ktor-http/common/src/io/ktor/http/Headers.kt +++ b/ktor-http/common/src/io/ktor/http/Headers.kt @@ -79,7 +79,6 @@ public fun headersOf(name: String, values: List): Headers = HeadersSingl */ public fun headersOf(vararg pairs: Pair>): Headers = HeadersImpl(pairs.asList().toMap()) -@InternalAPI @Suppress("KDocMissingDocumentation") public class HeadersImpl( values: Map> = emptyMap() @@ -87,7 +86,6 @@ public class HeadersImpl( override fun toString(): String = "Headers ${entries()}" } -@InternalAPI @Suppress("KDocMissingDocumentation") public class HeadersSingleImpl( name: String, diff --git a/ktor-http/common/src/io/ktor/http/HttpHeaderValueParser.kt b/ktor-http/common/src/io/ktor/http/HttpHeaderValueParser.kt index aa5762d0b50..3a560a42a7b 100644 --- a/ktor-http/common/src/io/ktor/http/HttpHeaderValueParser.kt +++ b/ktor-http/common/src/io/ktor/http/HttpHeaderValueParser.kt @@ -4,8 +4,6 @@ package io.ktor.http -import io.ktor.util.* - /** * Represents a single value parameter * @property name of parameter @@ -19,8 +17,8 @@ public data class HeaderValueParam(val name: String, val value: String) { } override fun hashCode(): Int { - var result = name.toLowerCase().hashCode() - result += 31 * result + value.toLowerCase().hashCode() + var result = name.lowercase().hashCode() + result += 31 * result + value.lowercase().hashCode() return result } } diff --git a/ktor-http/common/src/io/ktor/http/HttpHeaders.kt b/ktor-http/common/src/io/ktor/http/HttpHeaders.kt index a5128ca89be..f5c5b7deeb8 100644 --- a/ktor-http/common/src/io/ktor/http/HttpHeaders.kt +++ b/ktor-http/common/src/io/ktor/http/HttpHeaders.kt @@ -120,6 +120,7 @@ public object HttpHeaders { public val XForwardedProto: String = "X-Forwarded-Proto" public val XForwardedFor: String = "X-Forwarded-For" + @OptIn(InternalAPI::class) @PublicAPICandidate("2.0.0") internal val XForwardedPort: String = "X-Forwarded-Port" @@ -185,7 +186,7 @@ public class UnsafeHeaderException(header: String) : IllegalArgumentException( public class IllegalHeaderNameException(public val headerName: String, public val position: Int) : IllegalArgumentException( "Header name '$headerName' contains illegal character '${headerName[position]}'" + - " (code ${(headerName[position].toInt() and 0xff)})" + " (code ${(headerName[position].code and 0xff)})" ) /** @@ -197,7 +198,7 @@ public class IllegalHeaderNameException(public val headerName: String, public va public class IllegalHeaderValueException(public val headerValue: String, public val position: Int) : IllegalArgumentException( "Header value '$headerValue' contains illegal character '${headerValue[position]}'" + - " (code ${(headerValue[position].toInt() and 0xff)})" + " (code ${(headerValue[position].code and 0xff)})" ) private fun isDelimiter(ch: Char): Boolean = ch in "\"(),/:;<=>?@[\\]{}" diff --git a/ktor-http/common/src/io/ktor/http/Parameters.kt b/ktor-http/common/src/io/ktor/http/Parameters.kt index a2a73f37a9a..7ef03f0eb31 100644 --- a/ktor-http/common/src/io/ktor/http/Parameters.kt +++ b/ktor-http/common/src/io/ktor/http/Parameters.kt @@ -63,14 +63,12 @@ public fun parametersOf(name: String, values: List): Parameters = Parame public fun parametersOf(vararg pairs: Pair>): Parameters = ParametersImpl(pairs.asList().toMap()) @Suppress("KDocMissingDocumentation") -@InternalAPI public class ParametersImpl(values: Map> = emptyMap()) : Parameters, StringValuesImpl(true, values) { override fun toString(): String = "Parameters ${entries()}" } @Suppress("KDocMissingDocumentation") -@InternalAPI public class ParametersSingleImpl(name: String, values: List) : Parameters, StringValuesSingleImpl(true, name, values) { override fun toString(): String = "Parameters ${entries()}" diff --git a/ktor-http/common/src/io/ktor/http/URLParser.kt b/ktor-http/common/src/io/ktor/http/URLParser.kt index b74e997e30e..be877386aab 100644 --- a/ktor-http/common/src/io/ktor/http/URLParser.kt +++ b/ktor-http/common/src/io/ktor/http/URLParser.kt @@ -255,4 +255,4 @@ private fun String.indexOfColonInHostPort(startIndex: Int, endIndex: Int): Int { return -1 } -private fun Char.isLetter(): Boolean = toLowerCase() in 'a'..'z' +private fun Char.isLetter(): Boolean = lowercaseChar() in 'a'..'z' diff --git a/ktor-http/common/src/io/ktor/http/Url.kt b/ktor-http/common/src/io/ktor/http/Url.kt index 5855442d71d..055d0ead45c 100644 --- a/ktor-http/common/src/io/ktor/http/Url.kt +++ b/ktor-http/common/src/io/ktor/http/Url.kt @@ -108,6 +108,7 @@ public class Url internal constructor( public companion object } +@Suppress("UNUSED_PARAMETER") @Deprecated( "Url is not a data class anymore. Please use URLBuilder(url)", level = DeprecationLevel.ERROR, diff --git a/ktor-http/common/src/io/ktor/http/auth/HttpAuthHeader.kt b/ktor-http/common/src/io/ktor/http/auth/HttpAuthHeader.kt index b9a776ce01b..40465e2f673 100644 --- a/ktor-http/common/src/io/ktor/http/auth/HttpAuthHeader.kt +++ b/ktor-http/common/src/io/ktor/http/auth/HttpAuthHeader.kt @@ -177,7 +177,7 @@ public sealed class HttpAuthHeader(public val authScheme: String) { } override fun hashCode(): Int { - return Hash.combine(authScheme.toLowerCase(), blob.toLowerCase()) + return Hash.combine(authScheme.lowercase(), blob.lowercase()) } } @@ -259,7 +259,7 @@ public sealed class HttpAuthHeader(public val authScheme: String) { } override fun hashCode(): Int { - return Hash.combine(authScheme.toLowerCase(), parameters) + return Hash.combine(authScheme.lowercase(), parameters) } } diff --git a/ktor-http/common/src/io/ktor/http/content/OutgoingContent.kt b/ktor-http/common/src/io/ktor/http/content/OutgoingContent.kt index ca0317f7d43..b50f6dea43a 100644 --- a/ktor-http/common/src/io/ktor/http/content/OutgoingContent.kt +++ b/ktor-http/common/src/io/ktor/http/content/OutgoingContent.kt @@ -79,6 +79,7 @@ public sealed class OutgoingContent { /** * Provides [ByteReadChannel] for the given range of the content */ + @OptIn(DelicateCoroutinesApi::class) public open fun readFrom(range: LongRange): ByteReadChannel = if (range.isEmpty()) { ByteReadChannel.Empty } else { diff --git a/ktor-http/common/test/io/ktor/tests/http/URLBuilderTest.kt b/ktor-http/common/test/io/ktor/tests/http/URLBuilderTest.kt index 70097e0cbb0..d273e377580 100644 --- a/ktor-http/common/test/io/ktor/tests/http/URLBuilderTest.kt +++ b/ktor-http/common/test/io/ktor/tests/http/URLBuilderTest.kt @@ -279,6 +279,6 @@ internal class URLBuilderTest { * Checks that the given [url] and the result of [URLBuilder.buildString] is equal (case insensitive). */ private fun testBuildString(url: String) { - assertEquals(url.toLowerCase(), URLBuilder(url).buildString().toLowerCase()) + assertEquals(url.lowercase(), URLBuilder(url).buildString().lowercase()) } } diff --git a/ktor-http/jvm/test/io/ktor/tests/http/BlockingContentParkingTest.kt b/ktor-http/jvm/test/io/ktor/tests/http/BlockingContentParkingTest.kt index 67df6653dda..0bd07770e4c 100644 --- a/ktor-http/jvm/test/io/ktor/tests/http/BlockingContentParkingTest.kt +++ b/ktor-http/jvm/test/io/ktor/tests/http/BlockingContentParkingTest.kt @@ -13,8 +13,10 @@ import kotlin.test.* @Suppress("BlockingMethodInNonBlockingContext") class BlockingContentParkingTest { + @OptIn(ExperimentalCoroutinesApi::class) private val dispatcher = newSingleThreadContext("BlockingContentParkingTest") private val channel = ByteChannel(true) + @OptIn(DelicateCoroutinesApi::class) private val consumer = GlobalScope.launch { channel.discard() } diff --git a/ktor-http/jvm/test/io/ktor/tests/http/URLBuilderTest.kt b/ktor-http/jvm/test/io/ktor/tests/http/URLBuilderTest.kt index 7b509f85239..de4baac8162 100644 --- a/ktor-http/jvm/test/io/ktor/tests/http/URLBuilderTest.kt +++ b/ktor-http/jvm/test/io/ktor/tests/http/URLBuilderTest.kt @@ -7,6 +7,7 @@ package io.ktor.tests.http import io.ktor.http.* import java.net.* +import java.util.* import kotlin.test.* class URLBuilderTestJvm { @@ -81,7 +82,10 @@ class URLBuilderTestJvm { @Test fun testCapitalize() { val url = URLBuilder().apply { - takeFrom(URI.create("custom://localhost:8080/path".capitalize())) + val uri = "custom://localhost:8080/path".replaceFirstChar { + if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() + } + takeFrom(URI.create(uri)) } assertEquals("custom://localhost:8080/path", url.buildString()) diff --git a/ktor-http/ktor-http-cio/api/ktor-http-cio.api b/ktor-http/ktor-http-cio/api/ktor-http-cio.api index 8ec576dcb20..dce088a944a 100644 --- a/ktor-http/ktor-http-cio/api/ktor-http-cio.api +++ b/ktor-http/ktor-http-cio/api/ktor-http-cio.api @@ -70,10 +70,6 @@ public final class io/ktor/http/cio/HttpHeadersMap { public final fun valueAt (I)Ljava/lang/CharSequence; } -public final class io/ktor/http/cio/HttpHeadersMapKt { - public static final fun dumpTo (Lio/ktor/http/cio/HttpHeadersMap;Ljava/lang/String;Ljava/lang/Appendable;)V -} - public abstract class io/ktor/http/cio/HttpMessage : java/io/Closeable { public fun close ()V public final fun getHeaders ()Lio/ktor/http/cio/HttpHeadersMap; diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/CIOHeaders.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/CIOHeaders.kt index 351df9c9f15..5d2bf6750ee 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/CIOHeaders.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/CIOHeaders.kt @@ -10,7 +10,6 @@ import io.ktor.util.* /** * An adapter from CIO low-level headers map to ktor [Headers] interface */ -@InternalAPI public class CIOHeaders(private val headers: HttpHeadersMap) : Headers { private val names: Set by lazy(LazyThreadSafetyMode.NONE) { diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/ChunkedTransferEncoding.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/ChunkedTransferEncoding.kt index bdc22187d3d..7fba32151ee 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/ChunkedTransferEncoding.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/ChunkedTransferEncoding.kt @@ -43,6 +43,7 @@ public fun CoroutineScope.decodeChunked(input: ByteReadChannel): DecoderJob = /** * Start a chunked stream decoder coroutine */ +@Suppress("UNUSED_PARAMETER") public fun CoroutineScope.decodeChunked(input: ByteReadChannel, contentLength: Long): DecoderJob = writer(coroutineContext) { decodeChunked(input, channel) @@ -67,6 +68,7 @@ public suspend fun decodeChunked(input: ByteReadChannel, out: ByteWriteChannel) level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("decodeChunked(input, out)") ) +@Suppress("UNUSED_PARAMETER") public suspend fun decodeChunked(input: ByteReadChannel, out: ByteWriteChannel, contentLength: Long) { val chunkSizeBuffer = ChunkSizeBufferPool.borrow() var totalBytesCopied = 0L @@ -116,6 +118,7 @@ public typealias EncoderJob = ReaderJob /** * Start chunked stream encoding coroutine */ +@OptIn(DelicateCoroutinesApi::class) public suspend fun encodeChunked( output: ByteWriteChannel, coroutineContext: CoroutineContext diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpBody.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpBody.kt index 35e7c0522f4..2decee4c583 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpBody.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpBody.kt @@ -132,7 +132,7 @@ private fun isTransferEncodingChunked(transferEncoding: CharSequence): Boolean { var chunked = false transferEncoding.split(",").forEach { - when (val name = it.trim().toLowerCase()) { + when (val name = it.trim().lowercase()) { "chunked" -> { if (chunked) { throw IllegalArgumentException("Double-chunked TE is not supported: $transferEncoding") diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpHeadersMap.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpHeadersMap.kt index c1be7cad57d..0e572b9c7a6 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpHeadersMap.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpHeadersMap.kt @@ -32,7 +32,6 @@ private val EMPTY_INT_ARRAY = IntArray(0) * A headers map data structure used in CIO */ @Suppress("KDocMissingDocumentation") -@InternalAPI public class HttpHeadersMap internal constructor(private val builder: CharArrayBuilder) { public var size: Int = 0 private set @@ -138,8 +137,7 @@ public class HttpHeadersMap internal constructor(private val builder: CharArrayB /** * Dump header values to [out], useful for debugging */ -@InternalAPI -public fun HttpHeadersMap.dumpTo(indent: String, out: Appendable) { +internal fun HttpHeadersMap.dumpTo(indent: String, out: Appendable) { for (i in 0 until size) { out.append(indent) out.append(nameAt(i)) diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpParser.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpParser.kt index 8b965c443d4..ccfcf5a6c34 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpParser.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/HttpParser.kt @@ -281,7 +281,7 @@ private fun noColonFound(text: CharSequence, range: MutableRange): Nothing { } private fun characterIsNotAllowed(text: CharSequence, ch: Char): Nothing = - throw ParserException("Character with code ${(ch.toInt() and 0xff)} is not allowed in header names, \n$text") + throw ParserException("Character with code ${(ch.code and 0xff)} is not allowed in header names, \n$text") private fun isDelimiter(ch: Char): Boolean { return ch <= ' ' || ch in "\"(),/:;<=>?@[\\]{}" diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/AsciiCharTree.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/AsciiCharTree.kt index f1a28457443..af1972a5162 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/AsciiCharTree.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/AsciiCharTree.kt @@ -6,7 +6,7 @@ package io.ktor.http.cio.internals internal class AsciiCharTree(val root: Node) { public class Node(val ch: Char, val exact: List, val children: List>) { - val array = Array(0x100) { chi -> children.singleOrNull { it.ch.toInt() == chi } } + val array = Array(0x100) { chi -> children.singleOrNull { it.ch.code == chi } } } public fun search( @@ -21,12 +21,12 @@ internal class AsciiCharTree(val root: Node) { for (index in fromIdx until end) { val current = sequence[index] - val currentCode = current.toInt() + val currentCode = current.code if (stopPredicate(current, currentCode)) break val nextNode = node.array[currentCode] - ?: (if (lowerCase) node.array[current.toLowerCase().toInt()] else null) + ?: (if (lowerCase) node.array[current.lowercaseChar().code] else null) ?: return emptyList() node = nextNode diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/CharArrayBuilder.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/CharArrayBuilder.kt index 4dce7d48fef..0ae228d841a 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/CharArrayBuilder.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/CharArrayBuilder.kt @@ -4,12 +4,10 @@ package io.ktor.http.cio.internals -import io.ktor.util.* import io.ktor.utils.io.pool.* import kotlin.math.* @Suppress("LoopToCallChain", "ReplaceRangeToWithUntil", "KDocMissingDocumentation") -@InternalAPI internal class CharArrayBuilder(val pool: ObjectPool = CharArrayPool) : CharSequence, Appendable { private var buffers: MutableList? = null private var current: CharArray? = null @@ -48,25 +46,25 @@ internal class CharArrayBuilder(val pool: ObjectPool = CharArrayPool) override fun hashCode(): Int = stringified?.hashCode() ?: hashCodeImpl(0, length) - override fun append(c: Char): Appendable { - nonFullBuffer()[current!!.size - remaining] = c + override fun append(value: Char): Appendable { + nonFullBuffer()[current!!.size - remaining] = value stringified = null remaining -= 1 length++ return this } - override fun append(csq: CharSequence?, start: Int, end: Int): Appendable { - csq ?: return this + override fun append(value: CharSequence?, startIndex: Int, endIndex: Int): Appendable { + value ?: return this - var current = start - while (current < end) { + var current = startIndex + while (current < endIndex) { val buffer = nonFullBuffer() val offset = buffer.size - remaining - val bytesToCopy = min(end - current, remaining) + val bytesToCopy = min(endIndex - current, remaining) for (i in 0 until bytesToCopy) { - buffer[offset + i] = csq[current + i] + buffer[offset + i] = value[current + i] } current += bytesToCopy @@ -74,13 +72,13 @@ internal class CharArrayBuilder(val pool: ObjectPool = CharArrayPool) } stringified = null - length += end - start + length += endIndex - startIndex return this } - override fun append(csq: CharSequence?): Appendable { - csq ?: return this - return append(csq, 0, csq.length) + override fun append(value: CharSequence?): Appendable { + value ?: return this + return append(value, 0, value.length) } public fun release() { @@ -214,7 +212,7 @@ internal class CharArrayBuilder(val pool: ObjectPool = CharArrayPool) private fun hashCodeImpl(start: Int, end: Int): Int { var hc = 0 for (i in start until end) { - hc = 31 * hc + getImpl(i).toInt() + hc = 31 * hc + getImpl(i).code } return hc diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/Chars.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/Chars.kt index fee088a98c0..2593a7e983d 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/Chars.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/Chars.kt @@ -6,7 +6,6 @@ package io.ktor.http.cio.internals import io.ktor.http.* import io.ktor.utils.io.* -import io.ktor.utils.io.core.* import kotlin.native.concurrent.* internal const val HTAB: Char = '\u0009' @@ -14,7 +13,7 @@ internal const val HTAB: Char = '\u0009' internal fun CharSequence.hashCodeLowerCase(start: Int = 0, end: Int = length): Int { var hashCode = 0 for (pos in start until end) { - val v = get(pos).toInt().toLowerCase() + val v = get(pos).code.toLowerCase() hashCode = 31 * hashCode + v } @@ -25,7 +24,7 @@ internal fun CharSequence.equalsLowerCase(start: Int = 0, end: Int = length, oth if (end - start != other.length) return false for (pos in start until end) { - if (get(pos).toInt().toLowerCase() != other[pos - start].toInt().toLowerCase()) return false + if (get(pos).code.toLowerCase() != other[pos - start].code.toLowerCase()) return false } return true @@ -33,7 +32,7 @@ internal fun CharSequence.equalsLowerCase(start: Int = 0, end: Int = length, oth @Suppress("NOTHING_TO_INLINE") private inline fun Int.toLowerCase() = - if (this in 'A'.toInt()..'Z'.toInt()) 'a'.toInt() + (this - 'A'.toInt()) else this + if (this in 'A'.code..'Z'.code) 'a'.code + (this - 'A'.code) else this @SharedImmutable internal val DefaultHttpMethods = @@ -43,22 +42,22 @@ internal val DefaultHttpMethods = private val HexTable = (0..0xff).map { v -> when { v in 0x30..0x39 -> v - 0x30L - v >= 'a'.toLong() && v <= 'f'.toLong() -> v - 'a'.toLong() + 10 - v >= 'A'.toLong() && v <= 'F'.toLong() -> v - 'A'.toLong() + 10 + v >= 'a'.code.toLong() && v <= 'f'.code.toLong() -> v - 'a'.code.toLong() + 10 + v >= 'A'.code.toLong() && v <= 'F'.code.toLong() -> v - 'A'.code.toLong() + 10 else -> -1L } }.toLongArray() @SharedImmutable internal val HexLetterTable: ByteArray = (0..0xf).map { - if (it < 0xa) (0x30 + it).toByte() else ('a' + it - 0x0a).toInt().toByte() + if (it < 0xa) (0x30 + it).toByte() else ('a' + it - 0x0a).code.toByte() }.toByteArray() internal fun CharSequence.parseHexLong(): Long { var result = 0L val table = HexTable for (i in 0 until length) { - val v = this[i].toInt() and 0xffff + val v = this[i].code and 0xffff val digit = if (v < 0xff) table[v] else -1L if (digit == -1L) hexNumberFormatException(this, i) result = (result shl 4) or digit @@ -74,7 +73,7 @@ internal fun CharSequence.parseDecLong(): Long { var result = 0L for (i in 0 until length) { - val digit = this[i].toLong() - 0x30L + val digit = this[i].code.toLong() - 0x30L if (digit < 0 || digit > 9) numberFormatException(this, i) result = (result shl 3) + (result shl 1) + digit @@ -86,7 +85,7 @@ internal fun CharSequence.parseDecLong(): Long { private fun CharSequence.parseDecLongWithCheck(): Long { var result = 0L for (i in 0 until length) { - val digit = this[i].toLong() - 0x30L + val digit = this[i].code.toLong() - 0x30L if (digit < 0 || digit > 9) numberFormatException(this, i) result = (result shl 3) + (result shl 1) + digit @@ -96,29 +95,6 @@ private fun CharSequence.parseDecLongWithCheck(): Long { return result } -internal fun Buffer.writeIntHex(value: Int) { - require(value > 0) { "Does only work for positive numbers" } // zero is not included! - var current = value - val table = HexLetterTable - var digits = 0 - - while (digits++ < 8) { - val v = current ushr 28 - current = current shl 4 - - if (v != 0) { - writeByte(table[v]) - break - } - } - - while (digits++ < 8) { - val v = current ushr 28 - current = current shl 4 - writeByte(table[v]) - } -} - internal suspend fun ByteWriteChannel.writeIntHex(value: Int) { require(value > 0) { "Does only work for positive numbers" } // zero is not included! var current = value diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/MutableRange.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/MutableRange.kt index c18fa5a7ade..64b67fdc6d7 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/MutableRange.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/internals/MutableRange.kt @@ -11,7 +11,6 @@ import io.ktor.util.* * @param start points to the first character * @param end points to the next character after the last one */ -@InternalAPI public class MutableRange(public var start: Int, public var end: Int) { override fun toString(): String = "MutableRange(start=$start, end=$end)" } diff --git a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/websocket/WebSocketSession.kt b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/websocket/WebSocketSession.kt index 26e488f488f..79bbf6b5331 100644 --- a/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/websocket/WebSocketSession.kt +++ b/ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/websocket/WebSocketSession.kt @@ -125,7 +125,6 @@ public suspend fun WebSocketSession.close(cause: Throwable?) { /** * Closes session with normal or error close reason, depending on whether [cause] is cancellation or not. */ -@InternalAPI public suspend fun WebSocketSession.closeExceptionally(cause: Throwable) { val reason = when (cause) { is CancellationException -> CloseReason(CloseReason.Codes.NORMAL, "") diff --git a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/CIOMultipartDataBase.kt b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/CIOMultipartDataBase.kt index 92d3ad6f7be..c0229ff73e3 100644 --- a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/CIOMultipartDataBase.kt +++ b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/CIOMultipartDataBase.kt @@ -31,7 +31,7 @@ public class CIOMultipartDataBase( override suspend fun readPart(): PartData? { while (true) { - val event = events.poll() ?: break + val event = events.tryReceive().getOrNull() ?: break eventToData(event)?.let { return it } } diff --git a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/Multipart.kt b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/Multipart.kt index 12141ed04d6..b277e21aa83 100644 --- a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/Multipart.kt +++ b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/Multipart.kt @@ -184,7 +184,6 @@ private suspend fun parsePartBodyImpl( /** * Skip multipart boundary */ -@OptIn(ExperimentalIoApi::class) @Deprecated("This is going to be removed. Use parseMultipart instead.", level = DeprecationLevel.ERROR) public suspend fun boundary(boundaryPrefixed: ByteBuffer, input: ByteReadChannel): Boolean { return skipBoundary(boundaryPrefixed, input) @@ -382,7 +381,7 @@ private suspend fun copyUntilBoundary( } } -private const val PrefixChar = '-'.toByte() +private const val PrefixChar = '-'.code.toByte() private fun findBoundary(contentType: CharSequence): Int { var state = 0 // 0 header value, 1 param name, 2 param value unquoted, 3 param value quoted, 4 escaped @@ -477,7 +476,7 @@ internal fun parseBoundaryInternal(contentType: CharSequence): ByteBuffer { loop@ for (i in boundaryStart until contentType.length) { val ch = contentType[i] - val v = ch.toInt() and 0xffff + val v = ch.code and 0xffff if (v and 0xffff > 0x7f) { throw IOException( "Failed to parse multipart: wrong boundary byte 0x${v.toString(16)} - should be 7bit character" @@ -549,6 +548,7 @@ internal fun parseBoundaryInternal(contentType: CharSequence): ByteBuffer { * Tries to skip the specified [delimiter] or fails if encounters bytes differs from the required. * @return `true` if the delimiter was found and skipped or `false` when EOF. */ +@Suppress("DEPRECATION") internal suspend fun ByteReadChannel.skipDelimiterOrEof(delimiter: ByteBuffer): Boolean { require(delimiter.hasRemaining()) require(delimiter.remaining() <= DEFAULT_BUFFER_SIZE) { @@ -568,6 +568,7 @@ internal suspend fun ByteReadChannel.skipDelimiterOrEof(delimiter: ByteBuffer): return trySkipDelimiterSuspend(delimiter) } +@Suppress("DEPRECATION") private suspend fun ByteReadChannel.trySkipDelimiterSuspend(delimiter: ByteBuffer): Boolean { var result = true diff --git a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/Pipeline.kt b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/Pipeline.kt index 3839bdd5bcf..1b24f7ab452 100644 --- a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/Pipeline.kt +++ b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/Pipeline.kt @@ -6,6 +6,7 @@ package io.ktor.http.cio import io.ktor.http.cio.internals.* import io.ktor.server.cio.backend.* +import io.ktor.util.* import io.ktor.utils.io.* import kotlinx.coroutines.* @@ -54,6 +55,7 @@ public val RequestHandlerCoroutine: CoroutineName = CoroutineName("request-handl * * @return pipeline job */ +@OptIn(InternalAPI::class) @Deprecated( "This is going to become internal. " + "Start ktor server or raw cio server from ktor-server-cio module instead of constructing server from parts.", diff --git a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/websocket/DefaultWebSocketSessionImpl.kt b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/websocket/DefaultWebSocketSessionImpl.kt index f22c1e2be2d..20d13331656 100644 --- a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/websocket/DefaultWebSocketSessionImpl.kt +++ b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/websocket/DefaultWebSocketSessionImpl.kt @@ -64,7 +64,7 @@ public class DefaultWebSocketSessionImpl( } override val closeReason: Deferred = closeReasonRef - @OptIn(ExperimentalWebSocketExtensionApi::class) + @OptIn(ExperimentalWebSocketExtensionApi::class, InternalAPI::class) override fun start(negotiatedExtensions: List>) { if (!started.compareAndSet(false, true)) { error("WebSocket session is already started.") @@ -103,7 +103,7 @@ public class DefaultWebSocketSessionImpl( raw.cancel() } - @OptIn(ExperimentalWebSocketExtensionApi::class) + @OptIn(ExperimentalWebSocketExtensionApi::class, io.ktor.util.InternalAPI::class) private fun runIncomingProcessor(ponger: SendChannel): Job = launch( IncomingProcessorCoroutineName + Dispatchers.Unconfined ) { @@ -204,6 +204,7 @@ public class DefaultWebSocketSessionImpl( } } + @OptIn(InternalAPI::class) private suspend fun sendCloseSequence(reason: CloseReason?) { if (!tryClose()) return context.complete() @@ -236,7 +237,8 @@ public class DefaultWebSocketSessionImpl( // that will cause it to terminate connection on timeout pinger.getAndSet(newPinger)?.close() - newPinger?.offer(EmptyPong) // it is safe here to send dummy pong because pinger will ignore it + // it is safe here to send dummy pong because pinger will ignore it + newPinger?.trySend(EmptyPong)?.isSuccess if (closed.value && newPinger != null) { runOrCancelPinger() diff --git a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/websocket/WebSocketDeflateExtension.kt b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/websocket/WebSocketDeflateExtension.kt index a111ce1f1fe..e5b632abb05 100644 --- a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/websocket/WebSocketDeflateExtension.kt +++ b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/websocket/WebSocketDeflateExtension.kt @@ -6,6 +6,7 @@ package io.ktor.http.cio.websocket import io.ktor.http.cio.internals.* import io.ktor.util.* +import java.util.* import java.util.zip.* private const val SERVER_MAX_WINDOW_BITS: String = "server_max_window_bits" @@ -84,7 +85,7 @@ public class WebSocketDeflateExtension internal constructor( val parameters = mutableListOf() for ((key, value) in protocol.parseParameters()) { - when (key.toLowerCase()) { + when (key.lowercase(Locale.getDefault())) { SERVER_MAX_WINDOW_BITS -> { check(value.toInt() == MAX_WINDOW_BITS) { "Only $MAX_WINDOW_BITS window size is supported" } } diff --git a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/websocket/WebSocketWriter.kt b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/websocket/WebSocketWriter.kt index cb25f6a9720..de01c4e6e5c 100644 --- a/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/websocket/WebSocketWriter.kt +++ b/ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/websocket/WebSocketWriter.kt @@ -72,7 +72,7 @@ public class WebSocketWriter( try { do { - val message = queue.poll() ?: break + val message = queue.tryReceive().getOrNull() ?: break when (message) { is Frame.Close -> { } // ignore @@ -96,7 +96,7 @@ public class WebSocketWriter( // initially serializer has at least one message queued while (true) { while (flush == null && !closeSent && serializer.remainingCapacity > 0) { - val message = queue.poll() ?: break + val message = queue.tryReceive().getOrNull() ?: break when (message) { is FlushRequest -> flush = message is Frame.Close -> { diff --git a/ktor-http/ktor-http-cio/jvm/src/io/ktor/server/cio/backend/ServerPipeline.kt b/ktor-http/ktor-http-cio/jvm/src/io/ktor/server/cio/backend/ServerPipeline.kt index d152ce60604..9d1444f9538 100644 --- a/ktor-http/ktor-http-cio/jvm/src/io/ktor/server/cio/backend/ServerPipeline.kt +++ b/ktor-http/ktor-http-cio/jvm/src/io/ktor/server/cio/backend/ServerPipeline.kt @@ -60,7 +60,7 @@ public fun CoroutineScope.startServerConnectionPipeline( } catch (parseFailed: Throwable) { // try to write 400 Bad Request // TODO log parseFailed? val bc = ByteChannel() - if (outputsActor.offer(bc)) { + if (outputsActor.trySend(bc).isSuccess) { bc.writePacket(BadRequestPacket.copy()) bc.close() } @@ -182,6 +182,7 @@ public fun CoroutineScope.startServerConnectionPipeline( } } +@OptIn(InternalAPI::class) private suspend fun pipelineWriterLoop( channel: ReceiveChannel, timeout: WeakTimeoutQueue, @@ -189,8 +190,7 @@ private suspend fun pipelineWriterLoop( ) { val receiveChildOrNull = suspendLambda { - @OptIn(ExperimentalCoroutinesApi::class) - channel.receiveOrNull() + channel.receiveCatching().getOrNull() } while (true) { val child = timeout.withTimeout(receiveChildOrNull) ?: break diff --git a/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/MultipartTest.kt b/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/MultipartTest.kt index 433c17067a7..6868e492e7b 100644 --- a/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/MultipartTest.kt +++ b/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/MultipartTest.kt @@ -10,7 +10,7 @@ import kotlinx.coroutines.* import kotlinx.coroutines.channels.* import kotlin.test.* -@OptIn(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class, DelicateCoroutinesApi::class) class MultipartTest { @Test fun smokeTest() = runBlocking { @@ -213,6 +213,7 @@ class MultipartTest { assertEquals(380, fileContent.length) } + @OptIn(DelicateCoroutinesApi::class) @Test fun testMultipartFormDataChunkedEncoded() = runBlocking { val body = """ @@ -337,6 +338,7 @@ class MultipartTest { } } + @OptIn(DelicateCoroutinesApi::class) @Test fun testEmptyPayload() = runBlocking { val body = "POST /add HTTP/1.1\r\n" + diff --git a/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/ServerPipelineTest.kt b/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/ServerPipelineTest.kt index 764e095d66c..90910536529 100644 --- a/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/ServerPipelineTest.kt +++ b/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/ServerPipelineTest.kt @@ -7,6 +7,7 @@ package io.ktor.tests.http.cio import io.ktor.http.* import io.ktor.http.cio.internals.* import io.ktor.server.cio.backend.* +import io.ktor.util.* import io.ktor.utils.io.* import io.ktor.utils.io.core.* import kotlinx.coroutines.* @@ -20,7 +21,7 @@ import kotlin.coroutines.* import kotlin.test.* import kotlin.test.Test -@OptIn(InternalCoroutinesApi::class) +@OptIn(InternalAPI::class, InternalCoroutinesApi::class) class ServerPipelineTest : CoroutineScope { @get:Rule val testName = TestName() diff --git a/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/TestHttpServer.kt b/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/TestHttpServer.kt index 86760a83047..f5f1b9f2e11 100644 --- a/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/TestHttpServer.kt +++ b/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/TestHttpServer.kt @@ -8,6 +8,7 @@ import io.ktor.http.cio.* import io.ktor.http.cio.internals.WeakTimeoutQueue import io.ktor.network.util.* import io.ktor.server.cio.backend.* +import io.ktor.util.* import io.ktor.utils.io.* import kotlinx.coroutines.* import java.net.* @@ -16,6 +17,8 @@ import java.util.concurrent.* import kotlin.coroutines.* // this is only suitable for tests, do not use in production +@Suppress("BlockingMethodInNonBlockingContext") +@OptIn(DelicateCoroutinesApi::class) internal fun testHttpServer( port: Int = 9096, ioCoroutineContext: CoroutineContext, @@ -36,7 +39,7 @@ internal fun testHttpServer( try { while (true) { val client = server.accept() ?: break - live.put(client, Unit) + live[client] = Unit client(client, ioCoroutineContext, callDispatcher, handler) } } catch (expected: ClosedChannelException) { @@ -62,6 +65,7 @@ internal fun testHttpServer( return Pair(j, deferred) } +@OptIn(InternalAPI::class, DelicateCoroutinesApi::class) private suspend fun client( socket: SocketChannel, ioCoroutineContext: CoroutineContext, @@ -82,6 +86,7 @@ private suspend fun client( buffer.flip() while (buffer.hasRemaining()) { + @Suppress("BlockingMethodInNonBlockingContext") socket.write(buffer) } } @@ -96,6 +101,7 @@ private suspend fun client( try { while (true) { buffer.clear() + @Suppress("BlockingMethodInNonBlockingContext") val rc = socket.read(buffer) if (rc == -1) break diff --git a/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/WeakTimeoutQueueTest.kt b/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/WeakTimeoutQueueTest.kt index 9b5d1ed3978..67ae20cdb5b 100644 --- a/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/WeakTimeoutQueueTest.kt +++ b/ktor-http/ktor-http-cio/jvm/test/io/ktor/tests/http/cio/WeakTimeoutQueueTest.kt @@ -5,6 +5,7 @@ package io.ktor.tests.http.cio import io.ktor.http.cio.internals.* +import io.ktor.util.* import kotlinx.atomicfu.* import kotlinx.coroutines.* import kotlinx.coroutines.debug.junit4.* @@ -12,6 +13,7 @@ import org.junit.Rule import java.time.* import kotlin.test.* +@OptIn(InternalAPI::class) class WeakTimeoutQueueTest { private val testClock = TestClock(0L) private val q = WeakTimeoutQueue(1000L, clock = { testClock.millis() }) diff --git a/ktor-io/api/ktor-io.api b/ktor-io/api/ktor-io.api index e1565b576eb..9b037adadca 100644 --- a/ktor-io/api/ktor-io.api +++ b/ktor-io/api/ktor-io.api @@ -45,7 +45,7 @@ public abstract class io/ktor/utils/io/ByteChannelSequentialBase : io/ktor/utils protected final fun getWritable ()Lio/ktor/utils/io/core/BytePacketBuilder; public fun isClosedForRead ()Z public fun isClosedForWrite ()Z - public final fun peekTo-vHUFkk8 (Ljava/nio/ByteBuffer;JJJJLkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun peekTo-lBXzO7A (Ljava/nio/ByteBuffer;JJJJLkotlin/coroutines/Continuation;)Ljava/lang/Object; protected final fun prepareFlushedBytes ()V public fun readAvailable (Lio/ktor/utils/io/core/internal/ChunkBuffer;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun readAvailable ([BIILkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -75,7 +75,7 @@ public abstract class io/ktor/utils/io/ByteChannelSequentialBase : io/ktor/utils public fun writeFloat (FLkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun writeFully (Lio/ktor/utils/io/core/Buffer;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun writeFully ([BIILkotlin/coroutines/Continuation;)Ljava/lang/Object; - public fun writeFully-rGWNHyQ (Ljava/nio/ByteBuffer;IILkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun writeFully-JT6ljtQ (Ljava/nio/ByteBuffer;IILkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun writeInt (ILkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun writeLong (JLkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun writePacket (Lio/ktor/utils/io/core/ByteReadPacket;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -112,7 +112,7 @@ public abstract interface class io/ktor/utils/io/ByteReadChannel { public abstract fun isClosedForWrite ()Z public abstract fun lookAhead (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public abstract fun lookAheadSuspend (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public abstract fun peekTo-vHUFkk8 (Ljava/nio/ByteBuffer;JJJJLkotlin/coroutines/Continuation;)Ljava/lang/Object; + public abstract fun peekTo-lBXzO7A (Ljava/nio/ByteBuffer;JJJJLkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun read (ILkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun readAvailable (ILkotlin/jvm/functions/Function1;)I public abstract fun readAvailable (Lio/ktor/utils/io/core/internal/ChunkBuffer;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -141,7 +141,7 @@ public final class io/ktor/utils/io/ByteReadChannel$Companion { } public final class io/ktor/utils/io/ByteReadChannel$DefaultImpls { - public static synthetic fun peekTo-vHUFkk8$default (Lio/ktor/utils/io/ByteReadChannel;Ljava/nio/ByteBuffer;JJJJLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public static synthetic fun peekTo-lBXzO7A$default (Lio/ktor/utils/io/ByteReadChannel;Ljava/nio/ByteBuffer;JJJJLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static synthetic fun read$default (Lio/ktor/utils/io/ByteReadChannel;ILkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static synthetic fun readAvailable$default (Lio/ktor/utils/io/ByteReadChannel;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)I } @@ -188,7 +188,7 @@ public abstract interface class io/ktor/utils/io/ByteWriteChannel { public abstract fun writeFully (Lio/ktor/utils/io/core/Buffer;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun writeFully (Ljava/nio/ByteBuffer;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun writeFully ([BIILkotlin/coroutines/Continuation;)Ljava/lang/Object; - public abstract fun writeFully-rGWNHyQ (Ljava/nio/ByteBuffer;IILkotlin/coroutines/Continuation;)Ljava/lang/Object; + public abstract fun writeFully-JT6ljtQ (Ljava/nio/ByteBuffer;IILkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun writeInt (ILkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun writeLong (JLkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun writePacket (Lio/ktor/utils/io/core/ByteReadPacket;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -399,8 +399,8 @@ public final class io/ktor/utils/io/bits/ByteOrderKt { public final class io/ktor/utils/io/bits/DefaultAllocator : io/ktor/utils/io/bits/Allocator { public static final field INSTANCE Lio/ktor/utils/io/bits/DefaultAllocator; - public fun alloc-SK3TCg8 (I)Ljava/nio/ByteBuffer; - public fun alloc-SK3TCg8 (J)Ljava/nio/ByteBuffer; + public fun alloc-gFv-Zug (I)Ljava/nio/ByteBuffer; + public fun alloc-gFv-Zug (J)Ljava/nio/ByteBuffer; public fun free-3GNKZMM (Ljava/nio/ByteBuffer;)V } @@ -408,8 +408,8 @@ public final class io/ktor/utils/io/bits/Memory { public static final field Companion Lio/ktor/utils/io/bits/Memory$Companion; public static final synthetic fun box-impl (Ljava/nio/ByteBuffer;)Lio/ktor/utils/io/bits/Memory; public static fun constructor-impl (Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer; - public static final fun copyTo-f5Ywojk (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;III)V - public static final fun copyTo-iAfECsU (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;JJJ)V + public static final fun copyTo-JT6ljtQ (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;III)V + public static final fun copyTo-JT6ljtQ (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;JJJ)V public fun equals (Ljava/lang/Object;)Z public static fun equals-impl (Ljava/nio/ByteBuffer;Ljava/lang/Object;)Z public static final fun equals-impl0 (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)Z @@ -420,8 +420,8 @@ public final class io/ktor/utils/io/bits/Memory { public static fun hashCode-impl (Ljava/nio/ByteBuffer;)I public static final fun loadAt-impl (Ljava/nio/ByteBuffer;I)B public static final fun loadAt-impl (Ljava/nio/ByteBuffer;J)B - public static final fun slice-SK3TCg8 (Ljava/nio/ByteBuffer;II)Ljava/nio/ByteBuffer; - public static final fun slice-SK3TCg8 (Ljava/nio/ByteBuffer;JJ)Ljava/nio/ByteBuffer; + public static final fun slice-87lwejk (Ljava/nio/ByteBuffer;II)Ljava/nio/ByteBuffer; + public static final fun slice-87lwejk (Ljava/nio/ByteBuffer;JJ)Ljava/nio/ByteBuffer; public static final fun storeAt-impl (Ljava/nio/ByteBuffer;IB)V public static final fun storeAt-impl (Ljava/nio/ByteBuffer;JB)V public fun toString ()Ljava/lang/String; @@ -447,148 +447,148 @@ public final class io/ktor/utils/io/bits/MemoryFactoryKt { } public final class io/ktor/utils/io/bits/MemoryJvmKt { - public static final fun copyTo-Fs5fovk (Ljava/nio/ByteBuffer;[BIII)V - public static final fun copyTo-jqM8g04 (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;I)V - public static final fun copyTo-odTdu9Q (Ljava/nio/ByteBuffer;[BJII)V - public static final fun copyTo-rB7MWs8 (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;J)V - public static final fun copyTo-rDIWIdE (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;I)V - public static final fun fill-Bd10AMI (Ljava/nio/ByteBuffer;IIB)V - public static final fun fill-syO9epc (Ljava/nio/ByteBuffer;JJB)V + public static final fun copyTo-62zg_DM (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;I)V + public static final fun copyTo-62zg_DM (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;J)V + public static final fun copyTo-9zorpBc (Ljava/nio/ByteBuffer;[BIII)V + public static final fun copyTo-9zorpBc (Ljava/nio/ByteBuffer;[BJII)V + public static final fun copyTo-SG11BkQ (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;I)V + public static final fun fill-JT6ljtQ (Ljava/nio/ByteBuffer;IIB)V + public static final fun fill-JT6ljtQ (Ljava/nio/ByteBuffer;JJB)V } public final class io/ktor/utils/io/bits/MemoryKt { - public static final fun copyTo-f8252NU (Ljava/nio/ByteBuffer;[BJI)V - public static final fun copyTo-ylBjBJw (Ljava/nio/ByteBuffer;[BII)V - public static final fun get-pkUVrfw (Ljava/nio/ByteBuffer;J)B - public static final fun get-xtk156I (Ljava/nio/ByteBuffer;I)B - public static final fun set-bxgQ-Fg (Ljava/nio/ByteBuffer;IB)V - public static final fun set-sgt2R-Q (Ljava/nio/ByteBuffer;JB)V - public static final fun storeAt-Fn34HUQ (Ljava/nio/ByteBuffer;IB)V - public static final fun storeAt-SVZKsBI (Ljava/nio/ByteBuffer;JB)V + public static final fun copyTo-JT6ljtQ (Ljava/nio/ByteBuffer;[BII)V + public static final fun copyTo-JT6ljtQ (Ljava/nio/ByteBuffer;[BJI)V + public static final fun get-eY85DW0 (Ljava/nio/ByteBuffer;I)B + public static final fun get-eY85DW0 (Ljava/nio/ByteBuffer;J)B + public static final fun set-62zg_DM (Ljava/nio/ByteBuffer;IB)V + public static final fun set-62zg_DM (Ljava/nio/ByteBuffer;JB)V + public static final fun storeAt-OEmREl0 (Ljava/nio/ByteBuffer;IB)V + public static final fun storeAt-OEmREl0 (Ljava/nio/ByteBuffer;JB)V } public final class io/ktor/utils/io/bits/MemoryPrimitivesJvmKt { - public static final fun loadDoubleAt-pkUVrfw (Ljava/nio/ByteBuffer;J)D - public static final fun loadDoubleAt-xtk156I (Ljava/nio/ByteBuffer;I)D - public static final fun loadFloatAt-pkUVrfw (Ljava/nio/ByteBuffer;J)F - public static final fun loadFloatAt-xtk156I (Ljava/nio/ByteBuffer;I)F - public static final fun loadIntAt-pkUVrfw (Ljava/nio/ByteBuffer;J)I - public static final fun loadIntAt-xtk156I (Ljava/nio/ByteBuffer;I)I - public static final fun loadLongAt-pkUVrfw (Ljava/nio/ByteBuffer;J)J - public static final fun loadLongAt-xtk156I (Ljava/nio/ByteBuffer;I)J - public static final fun loadShortAt-pkUVrfw (Ljava/nio/ByteBuffer;J)S - public static final fun loadShortAt-xtk156I (Ljava/nio/ByteBuffer;I)S - public static final fun storeDoubleAt-KOHjTOE (Ljava/nio/ByteBuffer;JD)V - public static final fun storeDoubleAt-Zzg3DGc (Ljava/nio/ByteBuffer;ID)V - public static final fun storeFloatAt-r2iD9jY (Ljava/nio/ByteBuffer;IF)V - public static final fun storeFloatAt-t3dZL90 (Ljava/nio/ByteBuffer;JF)V - public static final fun storeIntAt-5Mw_xsg (Ljava/nio/ByteBuffer;II)V - public static final fun storeIntAt-Ywqd6oY (Ljava/nio/ByteBuffer;JI)V - public static final fun storeLongAt-PxUP_Lw (Ljava/nio/ByteBuffer;JJ)V - public static final fun storeLongAt-USuK2a8 (Ljava/nio/ByteBuffer;IJ)V - public static final fun storeShortAt-tJtnceY (Ljava/nio/ByteBuffer;IS)V - public static final fun storeShortAt-zC5p9Kc (Ljava/nio/ByteBuffer;JS)V + public static final fun loadDoubleAt-eY85DW0 (Ljava/nio/ByteBuffer;I)D + public static final fun loadDoubleAt-eY85DW0 (Ljava/nio/ByteBuffer;J)D + public static final fun loadFloatAt-eY85DW0 (Ljava/nio/ByteBuffer;I)F + public static final fun loadFloatAt-eY85DW0 (Ljava/nio/ByteBuffer;J)F + public static final fun loadIntAt-eY85DW0 (Ljava/nio/ByteBuffer;I)I + public static final fun loadIntAt-eY85DW0 (Ljava/nio/ByteBuffer;J)I + public static final fun loadLongAt-eY85DW0 (Ljava/nio/ByteBuffer;I)J + public static final fun loadLongAt-eY85DW0 (Ljava/nio/ByteBuffer;J)J + public static final fun loadShortAt-eY85DW0 (Ljava/nio/ByteBuffer;I)S + public static final fun loadShortAt-eY85DW0 (Ljava/nio/ByteBuffer;J)S + public static final fun storeDoubleAt-62zg_DM (Ljava/nio/ByteBuffer;ID)V + public static final fun storeDoubleAt-62zg_DM (Ljava/nio/ByteBuffer;JD)V + public static final fun storeFloatAt-62zg_DM (Ljava/nio/ByteBuffer;IF)V + public static final fun storeFloatAt-62zg_DM (Ljava/nio/ByteBuffer;JF)V + public static final fun storeIntAt-62zg_DM (Ljava/nio/ByteBuffer;II)V + public static final fun storeIntAt-62zg_DM (Ljava/nio/ByteBuffer;JI)V + public static final fun storeLongAt-62zg_DM (Ljava/nio/ByteBuffer;IJ)V + public static final fun storeLongAt-62zg_DM (Ljava/nio/ByteBuffer;JJ)V + public static final fun storeShortAt-62zg_DM (Ljava/nio/ByteBuffer;IS)V + public static final fun storeShortAt-62zg_DM (Ljava/nio/ByteBuffer;JS)V } public final class io/ktor/utils/io/bits/MemoryPrimitivesKt { - public static final fun loadUIntAt-pkUVrfw (Ljava/nio/ByteBuffer;J)I - public static final fun loadUIntAt-xtk156I (Ljava/nio/ByteBuffer;I)I - public static final fun loadULongAt-pkUVrfw (Ljava/nio/ByteBuffer;J)J - public static final fun loadULongAt-xtk156I (Ljava/nio/ByteBuffer;I)J - public static final fun loadUShortAt-pkUVrfw (Ljava/nio/ByteBuffer;J)S - public static final fun loadUShortAt-xtk156I (Ljava/nio/ByteBuffer;I)S - public static final fun storeUIntAt-0Rnu8j8 (Ljava/nio/ByteBuffer;JI)V - public static final fun storeUIntAt-sLALDiY (Ljava/nio/ByteBuffer;II)V - public static final fun storeULongAt-K5D3Yio (Ljava/nio/ByteBuffer;IJ)V - public static final fun storeULongAt-vUOAiV4 (Ljava/nio/ByteBuffer;JJ)V - public static final fun storeUShortAt-OsIYvYc (Ljava/nio/ByteBuffer;IS)V - public static final fun storeUShortAt-_uj5-7g (Ljava/nio/ByteBuffer;JS)V + public static final fun loadUIntAt-eY85DW0 (Ljava/nio/ByteBuffer;I)I + public static final fun loadUIntAt-eY85DW0 (Ljava/nio/ByteBuffer;J)I + public static final fun loadULongAt-eY85DW0 (Ljava/nio/ByteBuffer;I)J + public static final fun loadULongAt-eY85DW0 (Ljava/nio/ByteBuffer;J)J + public static final fun loadUShortAt-eY85DW0 (Ljava/nio/ByteBuffer;I)S + public static final fun loadUShortAt-eY85DW0 (Ljava/nio/ByteBuffer;J)S + public static final fun storeUIntAt-c9EmHqw (Ljava/nio/ByteBuffer;II)V + public static final fun storeUIntAt-c9EmHqw (Ljava/nio/ByteBuffer;JI)V + public static final fun storeULongAt-zwzI6Wg (Ljava/nio/ByteBuffer;IJ)V + public static final fun storeULongAt-zwzI6Wg (Ljava/nio/ByteBuffer;JJ)V + public static final fun storeUShortAt-4ET0KQI (Ljava/nio/ByteBuffer;IS)V + public static final fun storeUShortAt-4ET0KQI (Ljava/nio/ByteBuffer;JS)V } public final class io/ktor/utils/io/bits/PrimiteArraysKt { - public static final fun loadByteArray-1sQv-GY (Ljava/nio/ByteBuffer;I[BII)V - public static synthetic fun loadByteArray-1sQv-GY$default (Ljava/nio/ByteBuffer;I[BIIILjava/lang/Object;)V - public static final fun loadByteArray-tS5kjXo (Ljava/nio/ByteBuffer;J[BII)V - public static synthetic fun loadByteArray-tS5kjXo$default (Ljava/nio/ByteBuffer;J[BIIILjava/lang/Object;)V - public static final fun loadUByteArray-MNnqWwU (Ljava/nio/ByteBuffer;I[BII)V - public static synthetic fun loadUByteArray-MNnqWwU$default (Ljava/nio/ByteBuffer;I[BIIILjava/lang/Object;)V - public static final fun loadUByteArray-zUZJq0w (Ljava/nio/ByteBuffer;J[BII)V - public static synthetic fun loadUByteArray-zUZJq0w$default (Ljava/nio/ByteBuffer;J[BIIILjava/lang/Object;)V - public static final fun loadUIntArray-IiM6BKY (Ljava/nio/ByteBuffer;J[III)V - public static synthetic fun loadUIntArray-IiM6BKY$default (Ljava/nio/ByteBuffer;J[IIIILjava/lang/Object;)V - public static final fun loadUIntArray-c9ghqu0 (Ljava/nio/ByteBuffer;I[III)V - public static synthetic fun loadUIntArray-c9ghqu0$default (Ljava/nio/ByteBuffer;I[IIIILjava/lang/Object;)V - public static final fun loadULongArray--ReD1cY (Ljava/nio/ByteBuffer;I[JII)V - public static synthetic fun loadULongArray--ReD1cY$default (Ljava/nio/ByteBuffer;I[JIIILjava/lang/Object;)V - public static final fun loadULongArray-LZRIK90 (Ljava/nio/ByteBuffer;J[JII)V - public static synthetic fun loadULongArray-LZRIK90$default (Ljava/nio/ByteBuffer;J[JIIILjava/lang/Object;)V - public static final fun loadUShortArray-Fd_0kgM (Ljava/nio/ByteBuffer;I[SII)V - public static synthetic fun loadUShortArray-Fd_0kgM$default (Ljava/nio/ByteBuffer;I[SIIILjava/lang/Object;)V - public static final fun loadUShortArray-ItsHwlw (Ljava/nio/ByteBuffer;J[SII)V - public static synthetic fun loadUShortArray-ItsHwlw$default (Ljava/nio/ByteBuffer;J[SIIILjava/lang/Object;)V - public static final fun storeByteArray-1sQv-GY (Ljava/nio/ByteBuffer;I[BII)V - public static synthetic fun storeByteArray-1sQv-GY$default (Ljava/nio/ByteBuffer;I[BIIILjava/lang/Object;)V - public static final fun storeByteArray-tS5kjXo (Ljava/nio/ByteBuffer;J[BII)V - public static synthetic fun storeByteArray-tS5kjXo$default (Ljava/nio/ByteBuffer;J[BIIILjava/lang/Object;)V - public static final fun storeUByteArray-MNnqWwU (Ljava/nio/ByteBuffer;I[BII)V - public static synthetic fun storeUByteArray-MNnqWwU$default (Ljava/nio/ByteBuffer;I[BIIILjava/lang/Object;)V - public static final fun storeUByteArray-zUZJq0w (Ljava/nio/ByteBuffer;J[BII)V - public static synthetic fun storeUByteArray-zUZJq0w$default (Ljava/nio/ByteBuffer;J[BIIILjava/lang/Object;)V - public static final fun storeUIntArray-IiM6BKY (Ljava/nio/ByteBuffer;J[III)V - public static synthetic fun storeUIntArray-IiM6BKY$default (Ljava/nio/ByteBuffer;J[IIIILjava/lang/Object;)V - public static final fun storeUIntArray-c9ghqu0 (Ljava/nio/ByteBuffer;I[III)V - public static synthetic fun storeUIntArray-c9ghqu0$default (Ljava/nio/ByteBuffer;I[IIIILjava/lang/Object;)V - public static final fun storeULongArray--ReD1cY (Ljava/nio/ByteBuffer;I[JII)V - public static synthetic fun storeULongArray--ReD1cY$default (Ljava/nio/ByteBuffer;I[JIIILjava/lang/Object;)V - public static final fun storeULongArray-LZRIK90 (Ljava/nio/ByteBuffer;J[JII)V - public static synthetic fun storeULongArray-LZRIK90$default (Ljava/nio/ByteBuffer;J[JIIILjava/lang/Object;)V - public static final fun storeUShortArray-Fd_0kgM (Ljava/nio/ByteBuffer;I[SII)V - public static synthetic fun storeUShortArray-Fd_0kgM$default (Ljava/nio/ByteBuffer;I[SIIILjava/lang/Object;)V - public static final fun storeUShortArray-ItsHwlw (Ljava/nio/ByteBuffer;J[SII)V - public static synthetic fun storeUShortArray-ItsHwlw$default (Ljava/nio/ByteBuffer;J[SIIILjava/lang/Object;)V + public static final fun loadByteArray-9zorpBc (Ljava/nio/ByteBuffer;I[BII)V + public static final fun loadByteArray-9zorpBc (Ljava/nio/ByteBuffer;J[BII)V + public static synthetic fun loadByteArray-9zorpBc$default (Ljava/nio/ByteBuffer;I[BIIILjava/lang/Object;)V + public static synthetic fun loadByteArray-9zorpBc$default (Ljava/nio/ByteBuffer;J[BIIILjava/lang/Object;)V + public static final fun loadUByteArray-KqtU1YU (Ljava/nio/ByteBuffer;I[BII)V + public static final fun loadUByteArray-KqtU1YU (Ljava/nio/ByteBuffer;J[BII)V + public static synthetic fun loadUByteArray-KqtU1YU$default (Ljava/nio/ByteBuffer;I[BIIILjava/lang/Object;)V + public static synthetic fun loadUByteArray-KqtU1YU$default (Ljava/nio/ByteBuffer;J[BIIILjava/lang/Object;)V + public static final fun loadUIntArray-EM3dPTA (Ljava/nio/ByteBuffer;I[III)V + public static final fun loadUIntArray-EM3dPTA (Ljava/nio/ByteBuffer;J[III)V + public static synthetic fun loadUIntArray-EM3dPTA$default (Ljava/nio/ByteBuffer;I[IIIILjava/lang/Object;)V + public static synthetic fun loadUIntArray-EM3dPTA$default (Ljava/nio/ByteBuffer;J[IIIILjava/lang/Object;)V + public static final fun loadULongArray-bNlDJKc (Ljava/nio/ByteBuffer;I[JII)V + public static final fun loadULongArray-bNlDJKc (Ljava/nio/ByteBuffer;J[JII)V + public static synthetic fun loadULongArray-bNlDJKc$default (Ljava/nio/ByteBuffer;I[JIIILjava/lang/Object;)V + public static synthetic fun loadULongArray-bNlDJKc$default (Ljava/nio/ByteBuffer;J[JIIILjava/lang/Object;)V + public static final fun loadUShortArray-m8CCUi4 (Ljava/nio/ByteBuffer;I[SII)V + public static final fun loadUShortArray-m8CCUi4 (Ljava/nio/ByteBuffer;J[SII)V + public static synthetic fun loadUShortArray-m8CCUi4$default (Ljava/nio/ByteBuffer;I[SIIILjava/lang/Object;)V + public static synthetic fun loadUShortArray-m8CCUi4$default (Ljava/nio/ByteBuffer;J[SIIILjava/lang/Object;)V + public static final fun storeByteArray-9zorpBc (Ljava/nio/ByteBuffer;I[BII)V + public static final fun storeByteArray-9zorpBc (Ljava/nio/ByteBuffer;J[BII)V + public static synthetic fun storeByteArray-9zorpBc$default (Ljava/nio/ByteBuffer;I[BIIILjava/lang/Object;)V + public static synthetic fun storeByteArray-9zorpBc$default (Ljava/nio/ByteBuffer;J[BIIILjava/lang/Object;)V + public static final fun storeUByteArray-KqtU1YU (Ljava/nio/ByteBuffer;I[BII)V + public static final fun storeUByteArray-KqtU1YU (Ljava/nio/ByteBuffer;J[BII)V + public static synthetic fun storeUByteArray-KqtU1YU$default (Ljava/nio/ByteBuffer;I[BIIILjava/lang/Object;)V + public static synthetic fun storeUByteArray-KqtU1YU$default (Ljava/nio/ByteBuffer;J[BIIILjava/lang/Object;)V + public static final fun storeUIntArray-EM3dPTA (Ljava/nio/ByteBuffer;I[III)V + public static final fun storeUIntArray-EM3dPTA (Ljava/nio/ByteBuffer;J[III)V + public static synthetic fun storeUIntArray-EM3dPTA$default (Ljava/nio/ByteBuffer;I[IIIILjava/lang/Object;)V + public static synthetic fun storeUIntArray-EM3dPTA$default (Ljava/nio/ByteBuffer;J[IIIILjava/lang/Object;)V + public static final fun storeULongArray-bNlDJKc (Ljava/nio/ByteBuffer;I[JII)V + public static final fun storeULongArray-bNlDJKc (Ljava/nio/ByteBuffer;J[JII)V + public static synthetic fun storeULongArray-bNlDJKc$default (Ljava/nio/ByteBuffer;I[JIIILjava/lang/Object;)V + public static synthetic fun storeULongArray-bNlDJKc$default (Ljava/nio/ByteBuffer;J[JIIILjava/lang/Object;)V + public static final fun storeUShortArray-m8CCUi4 (Ljava/nio/ByteBuffer;I[SII)V + public static final fun storeUShortArray-m8CCUi4 (Ljava/nio/ByteBuffer;J[SII)V + public static synthetic fun storeUShortArray-m8CCUi4$default (Ljava/nio/ByteBuffer;I[SIIILjava/lang/Object;)V + public static synthetic fun storeUShortArray-m8CCUi4$default (Ljava/nio/ByteBuffer;J[SIIILjava/lang/Object;)V } public final class io/ktor/utils/io/bits/PrimitiveArraysJvmKt { - public static final fun loadDoubleArray-KUjKYZc (Ljava/nio/ByteBuffer;I[DII)V - public static synthetic fun loadDoubleArray-KUjKYZc$default (Ljava/nio/ByteBuffer;I[DIIILjava/lang/Object;)V - public static final fun loadDoubleArray-XWWvNjo (Ljava/nio/ByteBuffer;J[DII)V - public static synthetic fun loadDoubleArray-XWWvNjo$default (Ljava/nio/ByteBuffer;J[DIIILjava/lang/Object;)V - public static final fun loadFloatArray-4iahAcY (Ljava/nio/ByteBuffer;I[FII)V - public static synthetic fun loadFloatArray-4iahAcY$default (Ljava/nio/ByteBuffer;I[FIIILjava/lang/Object;)V - public static final fun loadFloatArray-ECwikis (Ljava/nio/ByteBuffer;J[FII)V - public static synthetic fun loadFloatArray-ECwikis$default (Ljava/nio/ByteBuffer;J[FIIILjava/lang/Object;)V - public static final fun loadIntArray-fL2E08M (Ljava/nio/ByteBuffer;I[III)V - public static synthetic fun loadIntArray-fL2E08M$default (Ljava/nio/ByteBuffer;I[IIIILjava/lang/Object;)V - public static final fun loadIntArray-yGba50k (Ljava/nio/ByteBuffer;J[III)V - public static synthetic fun loadIntArray-yGba50k$default (Ljava/nio/ByteBuffer;J[IIIILjava/lang/Object;)V - public static final fun loadLongArray-7oynhWg (Ljava/nio/ByteBuffer;J[JII)V - public static synthetic fun loadLongArray-7oynhWg$default (Ljava/nio/ByteBuffer;J[JIIILjava/lang/Object;)V - public static final fun loadLongArray-v7_xXSA (Ljava/nio/ByteBuffer;I[JII)V - public static synthetic fun loadLongArray-v7_xXSA$default (Ljava/nio/ByteBuffer;I[JIIILjava/lang/Object;)V - public static final fun loadShortArray-96Q0Wk8 (Ljava/nio/ByteBuffer;I[SII)V - public static synthetic fun loadShortArray-96Q0Wk8$default (Ljava/nio/ByteBuffer;I[SIIILjava/lang/Object;)V - public static final fun loadShortArray-c7X_M7M (Ljava/nio/ByteBuffer;J[SII)V - public static synthetic fun loadShortArray-c7X_M7M$default (Ljava/nio/ByteBuffer;J[SIIILjava/lang/Object;)V - public static final fun storeDoubleArray-KUjKYZc (Ljava/nio/ByteBuffer;I[DII)V - public static synthetic fun storeDoubleArray-KUjKYZc$default (Ljava/nio/ByteBuffer;I[DIIILjava/lang/Object;)V - public static final fun storeDoubleArray-XWWvNjo (Ljava/nio/ByteBuffer;J[DII)V - public static synthetic fun storeDoubleArray-XWWvNjo$default (Ljava/nio/ByteBuffer;J[DIIILjava/lang/Object;)V - public static final fun storeFloatArray-4iahAcY (Ljava/nio/ByteBuffer;I[FII)V - public static synthetic fun storeFloatArray-4iahAcY$default (Ljava/nio/ByteBuffer;I[FIIILjava/lang/Object;)V - public static final fun storeFloatArray-ECwikis (Ljava/nio/ByteBuffer;J[FII)V - public static synthetic fun storeFloatArray-ECwikis$default (Ljava/nio/ByteBuffer;J[FIIILjava/lang/Object;)V - public static final fun storeIntArray-fL2E08M (Ljava/nio/ByteBuffer;I[III)V - public static synthetic fun storeIntArray-fL2E08M$default (Ljava/nio/ByteBuffer;I[IIIILjava/lang/Object;)V - public static final fun storeIntArray-yGba50k (Ljava/nio/ByteBuffer;J[III)V - public static synthetic fun storeIntArray-yGba50k$default (Ljava/nio/ByteBuffer;J[IIIILjava/lang/Object;)V - public static final fun storeLongArray-7oynhWg (Ljava/nio/ByteBuffer;J[JII)V - public static synthetic fun storeLongArray-7oynhWg$default (Ljava/nio/ByteBuffer;J[JIIILjava/lang/Object;)V - public static final fun storeLongArray-v7_xXSA (Ljava/nio/ByteBuffer;I[JII)V - public static synthetic fun storeLongArray-v7_xXSA$default (Ljava/nio/ByteBuffer;I[JIIILjava/lang/Object;)V - public static final fun storeShortArray-96Q0Wk8 (Ljava/nio/ByteBuffer;I[SII)V - public static synthetic fun storeShortArray-96Q0Wk8$default (Ljava/nio/ByteBuffer;I[SIIILjava/lang/Object;)V - public static final fun storeShortArray-c7X_M7M (Ljava/nio/ByteBuffer;J[SII)V - public static synthetic fun storeShortArray-c7X_M7M$default (Ljava/nio/ByteBuffer;J[SIIILjava/lang/Object;)V + public static final fun loadDoubleArray-9zorpBc (Ljava/nio/ByteBuffer;I[DII)V + public static final fun loadDoubleArray-9zorpBc (Ljava/nio/ByteBuffer;J[DII)V + public static synthetic fun loadDoubleArray-9zorpBc$default (Ljava/nio/ByteBuffer;I[DIIILjava/lang/Object;)V + public static synthetic fun loadDoubleArray-9zorpBc$default (Ljava/nio/ByteBuffer;J[DIIILjava/lang/Object;)V + public static final fun loadFloatArray-9zorpBc (Ljava/nio/ByteBuffer;I[FII)V + public static final fun loadFloatArray-9zorpBc (Ljava/nio/ByteBuffer;J[FII)V + public static synthetic fun loadFloatArray-9zorpBc$default (Ljava/nio/ByteBuffer;I[FIIILjava/lang/Object;)V + public static synthetic fun loadFloatArray-9zorpBc$default (Ljava/nio/ByteBuffer;J[FIIILjava/lang/Object;)V + public static final fun loadIntArray-9zorpBc (Ljava/nio/ByteBuffer;I[III)V + public static final fun loadIntArray-9zorpBc (Ljava/nio/ByteBuffer;J[III)V + public static synthetic fun loadIntArray-9zorpBc$default (Ljava/nio/ByteBuffer;I[IIIILjava/lang/Object;)V + public static synthetic fun loadIntArray-9zorpBc$default (Ljava/nio/ByteBuffer;J[IIIILjava/lang/Object;)V + public static final fun loadLongArray-9zorpBc (Ljava/nio/ByteBuffer;I[JII)V + public static final fun loadLongArray-9zorpBc (Ljava/nio/ByteBuffer;J[JII)V + public static synthetic fun loadLongArray-9zorpBc$default (Ljava/nio/ByteBuffer;I[JIIILjava/lang/Object;)V + public static synthetic fun loadLongArray-9zorpBc$default (Ljava/nio/ByteBuffer;J[JIIILjava/lang/Object;)V + public static final fun loadShortArray-9zorpBc (Ljava/nio/ByteBuffer;I[SII)V + public static final fun loadShortArray-9zorpBc (Ljava/nio/ByteBuffer;J[SII)V + public static synthetic fun loadShortArray-9zorpBc$default (Ljava/nio/ByteBuffer;I[SIIILjava/lang/Object;)V + public static synthetic fun loadShortArray-9zorpBc$default (Ljava/nio/ByteBuffer;J[SIIILjava/lang/Object;)V + public static final fun storeDoubleArray-9zorpBc (Ljava/nio/ByteBuffer;I[DII)V + public static final fun storeDoubleArray-9zorpBc (Ljava/nio/ByteBuffer;J[DII)V + public static synthetic fun storeDoubleArray-9zorpBc$default (Ljava/nio/ByteBuffer;I[DIIILjava/lang/Object;)V + public static synthetic fun storeDoubleArray-9zorpBc$default (Ljava/nio/ByteBuffer;J[DIIILjava/lang/Object;)V + public static final fun storeFloatArray-9zorpBc (Ljava/nio/ByteBuffer;I[FII)V + public static final fun storeFloatArray-9zorpBc (Ljava/nio/ByteBuffer;J[FII)V + public static synthetic fun storeFloatArray-9zorpBc$default (Ljava/nio/ByteBuffer;I[FIIILjava/lang/Object;)V + public static synthetic fun storeFloatArray-9zorpBc$default (Ljava/nio/ByteBuffer;J[FIIILjava/lang/Object;)V + public static final fun storeIntArray-9zorpBc (Ljava/nio/ByteBuffer;I[III)V + public static final fun storeIntArray-9zorpBc (Ljava/nio/ByteBuffer;J[III)V + public static synthetic fun storeIntArray-9zorpBc$default (Ljava/nio/ByteBuffer;I[IIIILjava/lang/Object;)V + public static synthetic fun storeIntArray-9zorpBc$default (Ljava/nio/ByteBuffer;J[IIIILjava/lang/Object;)V + public static final fun storeLongArray-9zorpBc (Ljava/nio/ByteBuffer;I[JII)V + public static final fun storeLongArray-9zorpBc (Ljava/nio/ByteBuffer;J[JII)V + public static synthetic fun storeLongArray-9zorpBc$default (Ljava/nio/ByteBuffer;I[JIIILjava/lang/Object;)V + public static synthetic fun storeLongArray-9zorpBc$default (Ljava/nio/ByteBuffer;J[JIIILjava/lang/Object;)V + public static final fun storeShortArray-9zorpBc (Ljava/nio/ByteBuffer;I[SII)V + public static final fun storeShortArray-9zorpBc (Ljava/nio/ByteBuffer;J[SII)V + public static synthetic fun storeShortArray-9zorpBc$default (Ljava/nio/ByteBuffer;I[SIIILjava/lang/Object;)V + public static synthetic fun storeShortArray-9zorpBc$default (Ljava/nio/ByteBuffer;J[SIIILjava/lang/Object;)V } public final class io/ktor/utils/io/charsets/CharsetJVMKt { @@ -627,8 +627,6 @@ public final class io/ktor/utils/io/charsets/UTFKt { public static final fun decodeUTF (Ljava/nio/ByteBuffer;[CII)J public static final fun decodeUTF8Line (Ljava/nio/ByteBuffer;[CII)J public static synthetic fun decodeUTF8Line$default (Ljava/nio/ByteBuffer;[CIIILjava/lang/Object;)J - public static final fun decodeUtf8Result (II)J - public static final fun decodeUtf8ResultCombine (JJ)J } public final class io/ktor/utils/io/concurrent/SharedJvmKt { @@ -683,7 +681,7 @@ public final class io/ktor/utils/io/core/BufferCompatibilityKt { public static final fun append (Lio/ktor/utils/io/core/Buffer;[CII)Lio/ktor/utils/io/core/Buffer; public static final fun fill (Lio/ktor/utils/io/core/Buffer;IB)V public static final fun fill (Lio/ktor/utils/io/core/Buffer;JB)V - public static final fun fill-3Qyljrw (Lio/ktor/utils/io/core/Buffer;IB)V + public static final fun fill-sEu17AQ (Lio/ktor/utils/io/core/Buffer;IB)V public static final fun flush (Lio/ktor/utils/io/core/Buffer;)V public static final fun makeView (Lio/ktor/utils/io/core/Buffer;)Lio/ktor/utils/io/core/Buffer; public static final fun makeView (Lio/ktor/utils/io/core/internal/ChunkBuffer;)Lio/ktor/utils/io/core/internal/ChunkBuffer; @@ -734,14 +732,14 @@ public final class io/ktor/utils/io/core/BufferPrimitivesKt { public static synthetic fun readAvailable$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)I public static synthetic fun readAvailable$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)I public static synthetic fun readAvailable$default (Lio/ktor/utils/io/core/internal/ChunkBuffer;[BIIILjava/lang/Object;)I - public static final fun readAvailable-d1ESLyo (Lio/ktor/utils/io/core/Buffer;[SII)I - public static synthetic fun readAvailable-d1ESLyo$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)I - public static final fun readAvailable-eOostTs (Lio/ktor/utils/io/core/Buffer;[JII)I - public static synthetic fun readAvailable-eOostTs$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)I - public static final fun readAvailable-mPGAOow (Lio/ktor/utils/io/core/Buffer;[BII)I - public static synthetic fun readAvailable-mPGAOow$default (Lio/ktor/utils/io/core/Buffer;[BIIILjava/lang/Object;)I - public static final fun readAvailable-uM_xt_c (Lio/ktor/utils/io/core/Buffer;[III)I - public static synthetic fun readAvailable-uM_xt_c$default (Lio/ktor/utils/io/core/Buffer;[IIIILjava/lang/Object;)I + public static final fun readAvailable-Wt3Bwxc (Lio/ktor/utils/io/core/Buffer;[SII)I + public static synthetic fun readAvailable-Wt3Bwxc$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)I + public static final fun readAvailable-o1GoV1E (Lio/ktor/utils/io/core/Buffer;[BII)I + public static synthetic fun readAvailable-o1GoV1E$default (Lio/ktor/utils/io/core/Buffer;[BIIILjava/lang/Object;)I + public static final fun readAvailable-o2ZM2JE (Lio/ktor/utils/io/core/Buffer;[III)I + public static synthetic fun readAvailable-o2ZM2JE$default (Lio/ktor/utils/io/core/Buffer;[IIIILjava/lang/Object;)I + public static final fun readAvailable-pqYNikA (Lio/ktor/utils/io/core/Buffer;[JII)I + public static synthetic fun readAvailable-pqYNikA$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)I public static final fun readDouble (Lio/ktor/utils/io/core/Buffer;)D public static final fun readDouble (Lio/ktor/utils/io/core/internal/ChunkBuffer;)D public static final fun readExact (Lio/ktor/utils/io/core/Buffer;ILjava/lang/String;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; @@ -763,14 +761,14 @@ public final class io/ktor/utils/io/core/BufferPrimitivesKt { public static synthetic fun readFully$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)V public static synthetic fun readFully$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)V public static synthetic fun readFully$default (Lio/ktor/utils/io/core/internal/ChunkBuffer;[BIIILjava/lang/Object;)V - public static final fun readFully-d1ESLyo (Lio/ktor/utils/io/core/Buffer;[SII)V - public static synthetic fun readFully-d1ESLyo$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)V - public static final fun readFully-eOostTs (Lio/ktor/utils/io/core/Buffer;[JII)V - public static synthetic fun readFully-eOostTs$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)V - public static final fun readFully-mPGAOow (Lio/ktor/utils/io/core/Buffer;[BII)V - public static synthetic fun readFully-mPGAOow$default (Lio/ktor/utils/io/core/Buffer;[BIIILjava/lang/Object;)V - public static final fun readFully-uM_xt_c (Lio/ktor/utils/io/core/Buffer;[III)V - public static synthetic fun readFully-uM_xt_c$default (Lio/ktor/utils/io/core/Buffer;[IIIILjava/lang/Object;)V + public static final fun readFully-Wt3Bwxc (Lio/ktor/utils/io/core/Buffer;[SII)V + public static synthetic fun readFully-Wt3Bwxc$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)V + public static final fun readFully-o1GoV1E (Lio/ktor/utils/io/core/Buffer;[BII)V + public static synthetic fun readFully-o1GoV1E$default (Lio/ktor/utils/io/core/Buffer;[BIIILjava/lang/Object;)V + public static final fun readFully-o2ZM2JE (Lio/ktor/utils/io/core/Buffer;[III)V + public static synthetic fun readFully-o2ZM2JE$default (Lio/ktor/utils/io/core/Buffer;[IIIILjava/lang/Object;)V + public static final fun readFully-pqYNikA (Lio/ktor/utils/io/core/Buffer;[JII)V + public static synthetic fun readFully-pqYNikA$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)V public static final fun readInt (Lio/ktor/utils/io/core/Buffer;)I public static final fun readInt (Lio/ktor/utils/io/core/internal/ChunkBuffer;)I public static final fun readLong (Lio/ktor/utils/io/core/Buffer;)J @@ -806,28 +804,28 @@ public final class io/ktor/utils/io/core/BufferPrimitivesKt { public static synthetic fun writeFully$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)V public static synthetic fun writeFully$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)V public static synthetic fun writeFully$default (Lio/ktor/utils/io/core/internal/ChunkBuffer;[BIIILjava/lang/Object;)V - public static final fun writeFully-d1ESLyo (Lio/ktor/utils/io/core/Buffer;[SII)V - public static synthetic fun writeFully-d1ESLyo$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)V - public static final fun writeFully-eOostTs (Lio/ktor/utils/io/core/Buffer;[JII)V - public static synthetic fun writeFully-eOostTs$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)V - public static final fun writeFully-mPGAOow (Lio/ktor/utils/io/core/Buffer;[BII)V - public static synthetic fun writeFully-mPGAOow$default (Lio/ktor/utils/io/core/Buffer;[BIIILjava/lang/Object;)V - public static final fun writeFully-uM_xt_c (Lio/ktor/utils/io/core/Buffer;[III)V - public static synthetic fun writeFully-uM_xt_c$default (Lio/ktor/utils/io/core/Buffer;[IIIILjava/lang/Object;)V + public static final fun writeFully-Wt3Bwxc (Lio/ktor/utils/io/core/Buffer;[SII)V + public static synthetic fun writeFully-Wt3Bwxc$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)V + public static final fun writeFully-o1GoV1E (Lio/ktor/utils/io/core/Buffer;[BII)V + public static synthetic fun writeFully-o1GoV1E$default (Lio/ktor/utils/io/core/Buffer;[BIIILjava/lang/Object;)V + public static final fun writeFully-o2ZM2JE (Lio/ktor/utils/io/core/Buffer;[III)V + public static synthetic fun writeFully-o2ZM2JE$default (Lio/ktor/utils/io/core/Buffer;[IIIILjava/lang/Object;)V + public static final fun writeFully-pqYNikA (Lio/ktor/utils/io/core/Buffer;[JII)V + public static synthetic fun writeFully-pqYNikA$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)V public static final fun writeInt (Lio/ktor/utils/io/core/Buffer;I)V public static final fun writeInt (Lio/ktor/utils/io/core/internal/ChunkBuffer;I)V public static final fun writeLong (Lio/ktor/utils/io/core/Buffer;J)V public static final fun writeLong (Lio/ktor/utils/io/core/internal/ChunkBuffer;J)V public static final fun writeShort (Lio/ktor/utils/io/core/Buffer;S)V public static final fun writeShort (Lio/ktor/utils/io/core/internal/ChunkBuffer;S)V - public static final fun writeUByte-Nf7JEWI (Lio/ktor/utils/io/core/Buffer;B)V - public static final fun writeUByte-ZYBa3AY (Lio/ktor/utils/io/core/internal/ChunkBuffer;B)V - public static final fun writeUInt-_mVlKAM (Lio/ktor/utils/io/core/Buffer;I)V - public static final fun writeUInt-e5fcjRE (Lio/ktor/utils/io/core/internal/ChunkBuffer;I)V - public static final fun writeULong-Zrk_yTk (Lio/ktor/utils/io/core/Buffer;J)V - public static final fun writeULong-pLKKpPU (Lio/ktor/utils/io/core/internal/ChunkBuffer;J)V - public static final fun writeUShort-SEn4WD4 (Lio/ktor/utils/io/core/internal/ChunkBuffer;S)V - public static final fun writeUShort-YTqlC3I (Lio/ktor/utils/io/core/Buffer;S)V + public static final fun writeUByte-EK-6454 (Lio/ktor/utils/io/core/Buffer;B)V + public static final fun writeUByte-EK-6454 (Lio/ktor/utils/io/core/internal/ChunkBuffer;B)V + public static final fun writeUInt-Qn1smSk (Lio/ktor/utils/io/core/Buffer;I)V + public static final fun writeUInt-Qn1smSk (Lio/ktor/utils/io/core/internal/ChunkBuffer;I)V + public static final fun writeULong-2TYgG_w (Lio/ktor/utils/io/core/Buffer;J)V + public static final fun writeULong-2TYgG_w (Lio/ktor/utils/io/core/internal/ChunkBuffer;J)V + public static final fun writeUShort-i8woANY (Lio/ktor/utils/io/core/Buffer;S)V + public static final fun writeUShort-i8woANY (Lio/ktor/utils/io/core/internal/ChunkBuffer;S)V } public final class io/ktor/utils/io/core/BufferUtilsJvmKt { @@ -838,7 +836,6 @@ public final class io/ktor/utils/io/core/BufferUtilsJvmKt { public static final fun readDirect (Lio/ktor/utils/io/core/Buffer;Lkotlin/jvm/functions/Function1;)I public static final fun readDirect (Lio/ktor/utils/io/core/internal/ChunkBuffer;Lkotlin/jvm/functions/Function1;)I public static final fun readFully (Lio/ktor/utils/io/core/Buffer;Ljava/nio/ByteBuffer;I)V - public static final fun resetFromContentToWrite (Lio/ktor/utils/io/core/internal/ChunkBuffer;Ljava/nio/ByteBuffer;)V public static final fun writeDirect (Lio/ktor/utils/io/core/Buffer;ILkotlin/jvm/functions/Function1;)I public static final fun writeDirect (Lio/ktor/utils/io/core/internal/ChunkBuffer;ILkotlin/jvm/functions/Function1;)I public static synthetic fun writeDirect$default (Lio/ktor/utils/io/core/Buffer;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)I @@ -847,7 +844,6 @@ public final class io/ktor/utils/io/core/BufferUtilsJvmKt { public final class io/ktor/utils/io/core/BuffersKt { public static final fun readBytes (Lio/ktor/utils/io/core/Buffer;I)[B public static synthetic fun readBytes$default (Lio/ktor/utils/io/core/Buffer;IILjava/lang/Object;)[B - public static final fun remainingAll (Lio/ktor/utils/io/core/internal/ChunkBuffer;)J } public final class io/ktor/utils/io/core/BuilderKt { @@ -948,21 +944,18 @@ public abstract class io/ktor/utils/io/core/Input : java/io/Closeable { public final fun discard (J)J public final fun discardExact (I)V public final fun ensureNext (Lio/ktor/utils/io/core/internal/ChunkBuffer;)Lio/ktor/utils/io/core/internal/ChunkBuffer; - public final fun ensureNextHead (Lio/ktor/utils/io/core/internal/ChunkBuffer;)Lio/ktor/utils/io/core/internal/ChunkBuffer; protected fun fill ()Lio/ktor/utils/io/core/internal/ChunkBuffer; - protected abstract fun fill-5Mw_xsg (Ljava/nio/ByteBuffer;II)I - public final fun fixGapAfterRead (Lio/ktor/utils/io/core/internal/ChunkBuffer;)V + protected abstract fun fill-62zg_DM (Ljava/nio/ByteBuffer;II)I public final fun getEndOfInput ()Z public final fun getPool ()Lio/ktor/utils/io/pool/ObjectPool; public final fun getRemaining ()J public final fun hasBytes (I)Z protected final fun markNoMoreChunksAvailable ()V public final fun peekTo (Lio/ktor/utils/io/core/internal/ChunkBuffer;)I - public final fun peekTo-1dgeIsk (Ljava/nio/ByteBuffer;JJJJ)J - public static synthetic fun peekTo-1dgeIsk$default (Lio/ktor/utils/io/core/Input;Ljava/nio/ByteBuffer;JJJJILjava/lang/Object;)J + public final fun peekTo-9zorpBc (Ljava/nio/ByteBuffer;JJJJ)J + public static synthetic fun peekTo-9zorpBc$default (Lio/ktor/utils/io/core/Input;Ljava/nio/ByteBuffer;JJJJILjava/lang/Object;)J public final fun prepareRead (I)Lio/ktor/utils/io/core/internal/ChunkBuffer; public final fun prepareRead (ILio/ktor/utils/io/core/internal/ChunkBuffer;)Lio/ktor/utils/io/core/internal/ChunkBuffer; - public final fun prepareReadHead (I)Lio/ktor/utils/io/core/internal/ChunkBuffer; public final fun readByte ()B public final fun readText (II)Ljava/lang/String; public final fun readText (Ljava/lang/Appendable;II)I @@ -999,8 +992,8 @@ public final class io/ktor/utils/io/core/InputArraysKt { public static synthetic fun readAvailable$default (Lio/ktor/utils/io/core/Input;[IIIILjava/lang/Object;)I public static synthetic fun readAvailable$default (Lio/ktor/utils/io/core/Input;[JIIILjava/lang/Object;)I public static synthetic fun readAvailable$default (Lio/ktor/utils/io/core/Input;[SIIILjava/lang/Object;)I - public static final fun readAvailable-9JA4kaw (Lio/ktor/utils/io/core/Input;Ljava/nio/ByteBuffer;II)I - public static final fun readAvailable-mCvI5oI (Lio/ktor/utils/io/core/Input;Ljava/nio/ByteBuffer;JJ)J + public static final fun readAvailable-UAd2zVI (Lio/ktor/utils/io/core/Input;Ljava/nio/ByteBuffer;II)I + public static final fun readAvailable-UAd2zVI (Lio/ktor/utils/io/core/Input;Ljava/nio/ByteBuffer;JJ)J public static final fun readFully (Lio/ktor/utils/io/core/Input;Lio/ktor/utils/io/core/Buffer;I)V public static final fun readFully (Lio/ktor/utils/io/core/Input;[BII)V public static final fun readFully (Lio/ktor/utils/io/core/Input;[DII)V @@ -1015,19 +1008,16 @@ public final class io/ktor/utils/io/core/InputArraysKt { public static synthetic fun readFully$default (Lio/ktor/utils/io/core/Input;[IIIILjava/lang/Object;)V public static synthetic fun readFully$default (Lio/ktor/utils/io/core/Input;[JIIILjava/lang/Object;)V public static synthetic fun readFully$default (Lio/ktor/utils/io/core/Input;[SIIILjava/lang/Object;)V - public static final fun readFully-9JA4kaw (Lio/ktor/utils/io/core/Input;Ljava/nio/ByteBuffer;II)V - public static final fun readFully-mCvI5oI (Lio/ktor/utils/io/core/Input;Ljava/nio/ByteBuffer;JJ)V + public static final fun readFully-UAd2zVI (Lio/ktor/utils/io/core/Input;Ljava/nio/ByteBuffer;II)V + public static final fun readFully-UAd2zVI (Lio/ktor/utils/io/core/Input;Ljava/nio/ByteBuffer;JJ)V } public final class io/ktor/utils/io/core/InputKt { public static final fun discard (Lio/ktor/utils/io/core/Input;)J public static final fun discardExact (Lio/ktor/utils/io/core/Input;I)V public static final fun discardExact (Lio/ktor/utils/io/core/Input;J)V - public static final fun forEach (Lio/ktor/utils/io/core/Input;Lkotlin/jvm/functions/Function1;)V public static final fun peekCharUtf8 (Lio/ktor/utils/io/core/Input;)C public static final fun takeWhile (Lio/ktor/utils/io/core/Input;Lkotlin/jvm/functions/Function1;)V - public static final fun takeWhileSize (Lio/ktor/utils/io/core/Input;ILkotlin/jvm/functions/Function1;)V - public static synthetic fun takeWhileSize$default (Lio/ktor/utils/io/core/Input;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V } public final class io/ktor/utils/io/core/InputLittleEndianKt { @@ -1051,18 +1041,18 @@ public final class io/ktor/utils/io/core/InputLittleEndianKt { public static synthetic fun readAvailableLittleEndian$default (Lio/ktor/utils/io/core/Input;[IIIILjava/lang/Object;)I public static synthetic fun readAvailableLittleEndian$default (Lio/ktor/utils/io/core/Input;[JIIILjava/lang/Object;)I public static synthetic fun readAvailableLittleEndian$default (Lio/ktor/utils/io/core/Input;[SIIILjava/lang/Object;)I - public static final fun readAvailableLittleEndian-Lv-FXd8 (Lio/ktor/utils/io/core/Input;[SII)I - public static synthetic fun readAvailableLittleEndian-Lv-FXd8$default (Lio/ktor/utils/io/core/Input;[SIIILjava/lang/Object;)I - public static final fun readAvailableLittleEndian-PIFet3Y (Lio/ktor/utils/io/core/Input;[III)I - public static synthetic fun readAvailableLittleEndian-PIFet3Y$default (Lio/ktor/utils/io/core/Input;[IIIILjava/lang/Object;)I - public static final fun readAvailableLittleEndian-d1ESLyo (Lio/ktor/utils/io/core/Buffer;[SII)I - public static synthetic fun readAvailableLittleEndian-d1ESLyo$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)I - public static final fun readAvailableLittleEndian-eOostTs (Lio/ktor/utils/io/core/Buffer;[JII)I - public static synthetic fun readAvailableLittleEndian-eOostTs$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)I - public static final fun readAvailableLittleEndian-r2sAqVg (Lio/ktor/utils/io/core/Input;[JII)I - public static synthetic fun readAvailableLittleEndian-r2sAqVg$default (Lio/ktor/utils/io/core/Input;[JIIILjava/lang/Object;)I - public static final fun readAvailableLittleEndian-uM_xt_c (Lio/ktor/utils/io/core/Buffer;[III)I - public static synthetic fun readAvailableLittleEndian-uM_xt_c$default (Lio/ktor/utils/io/core/Buffer;[IIIILjava/lang/Object;)I + public static final fun readAvailableLittleEndian-Wt3Bwxc (Lio/ktor/utils/io/core/Buffer;[SII)I + public static final fun readAvailableLittleEndian-Wt3Bwxc (Lio/ktor/utils/io/core/Input;[SII)I + public static synthetic fun readAvailableLittleEndian-Wt3Bwxc$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)I + public static synthetic fun readAvailableLittleEndian-Wt3Bwxc$default (Lio/ktor/utils/io/core/Input;[SIIILjava/lang/Object;)I + public static final fun readAvailableLittleEndian-o2ZM2JE (Lio/ktor/utils/io/core/Buffer;[III)I + public static final fun readAvailableLittleEndian-o2ZM2JE (Lio/ktor/utils/io/core/Input;[III)I + public static synthetic fun readAvailableLittleEndian-o2ZM2JE$default (Lio/ktor/utils/io/core/Buffer;[IIIILjava/lang/Object;)I + public static synthetic fun readAvailableLittleEndian-o2ZM2JE$default (Lio/ktor/utils/io/core/Input;[IIIILjava/lang/Object;)I + public static final fun readAvailableLittleEndian-pqYNikA (Lio/ktor/utils/io/core/Buffer;[JII)I + public static final fun readAvailableLittleEndian-pqYNikA (Lio/ktor/utils/io/core/Input;[JII)I + public static synthetic fun readAvailableLittleEndian-pqYNikA$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)I + public static synthetic fun readAvailableLittleEndian-pqYNikA$default (Lio/ktor/utils/io/core/Input;[JIIILjava/lang/Object;)I public static final fun readDouble (Lio/ktor/utils/io/core/Input;Lio/ktor/utils/io/core/ByteOrder;)D public static final fun readDoubleLittleEndian (Lio/ktor/utils/io/core/Buffer;)D public static final fun readDoubleLittleEndian (Lio/ktor/utils/io/core/Input;)D @@ -1089,18 +1079,18 @@ public final class io/ktor/utils/io/core/InputLittleEndianKt { public static synthetic fun readFullyLittleEndian$default (Lio/ktor/utils/io/core/Input;[IIIILjava/lang/Object;)V public static synthetic fun readFullyLittleEndian$default (Lio/ktor/utils/io/core/Input;[JIIILjava/lang/Object;)V public static synthetic fun readFullyLittleEndian$default (Lio/ktor/utils/io/core/Input;[SIIILjava/lang/Object;)V - public static final fun readFullyLittleEndian-Lv-FXd8 (Lio/ktor/utils/io/core/Input;[SII)V - public static synthetic fun readFullyLittleEndian-Lv-FXd8$default (Lio/ktor/utils/io/core/Input;[SIIILjava/lang/Object;)V - public static final fun readFullyLittleEndian-PIFet3Y (Lio/ktor/utils/io/core/Input;[III)V - public static synthetic fun readFullyLittleEndian-PIFet3Y$default (Lio/ktor/utils/io/core/Input;[IIIILjava/lang/Object;)V - public static final fun readFullyLittleEndian-d1ESLyo (Lio/ktor/utils/io/core/Buffer;[SII)V - public static synthetic fun readFullyLittleEndian-d1ESLyo$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)V - public static final fun readFullyLittleEndian-eOostTs (Lio/ktor/utils/io/core/Buffer;[JII)V - public static synthetic fun readFullyLittleEndian-eOostTs$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)V - public static final fun readFullyLittleEndian-r2sAqVg (Lio/ktor/utils/io/core/Input;[JII)V - public static synthetic fun readFullyLittleEndian-r2sAqVg$default (Lio/ktor/utils/io/core/Input;[JIIILjava/lang/Object;)V - public static final fun readFullyLittleEndian-uM_xt_c (Lio/ktor/utils/io/core/Buffer;[III)V - public static synthetic fun readFullyLittleEndian-uM_xt_c$default (Lio/ktor/utils/io/core/Buffer;[IIIILjava/lang/Object;)V + public static final fun readFullyLittleEndian-Wt3Bwxc (Lio/ktor/utils/io/core/Buffer;[SII)V + public static final fun readFullyLittleEndian-Wt3Bwxc (Lio/ktor/utils/io/core/Input;[SII)V + public static synthetic fun readFullyLittleEndian-Wt3Bwxc$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)V + public static synthetic fun readFullyLittleEndian-Wt3Bwxc$default (Lio/ktor/utils/io/core/Input;[SIIILjava/lang/Object;)V + public static final fun readFullyLittleEndian-o2ZM2JE (Lio/ktor/utils/io/core/Buffer;[III)V + public static final fun readFullyLittleEndian-o2ZM2JE (Lio/ktor/utils/io/core/Input;[III)V + public static synthetic fun readFullyLittleEndian-o2ZM2JE$default (Lio/ktor/utils/io/core/Buffer;[IIIILjava/lang/Object;)V + public static synthetic fun readFullyLittleEndian-o2ZM2JE$default (Lio/ktor/utils/io/core/Input;[IIIILjava/lang/Object;)V + public static final fun readFullyLittleEndian-pqYNikA (Lio/ktor/utils/io/core/Buffer;[JII)V + public static final fun readFullyLittleEndian-pqYNikA (Lio/ktor/utils/io/core/Input;[JII)V + public static synthetic fun readFullyLittleEndian-pqYNikA$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)V + public static synthetic fun readFullyLittleEndian-pqYNikA$default (Lio/ktor/utils/io/core/Input;[JIIILjava/lang/Object;)V public static final fun readInt (Lio/ktor/utils/io/core/Input;Lio/ktor/utils/io/core/ByteOrder;)I public static final fun readIntLittleEndian (Lio/ktor/utils/io/core/Buffer;)I public static final fun readIntLittleEndian (Lio/ktor/utils/io/core/Input;)I @@ -1145,7 +1135,7 @@ public abstract class io/ktor/utils/io/core/Output : java/io/Closeable, java/lan public final fun close ()V protected abstract fun closeDestination ()V public final fun flush ()V - protected abstract fun flush-5Mw_xsg (Ljava/nio/ByteBuffer;II)V + protected abstract fun flush-62zg_DM (Ljava/nio/ByteBuffer;II)V protected final fun getPool ()Lio/ktor/utils/io/pool/ObjectPool; protected final fun get_size ()I public final fun prepareWriteHead (I)Lio/ktor/utils/io/core/internal/ChunkBuffer; @@ -1182,11 +1172,8 @@ public final class io/ktor/utils/io/core/OutputKt { public static synthetic fun writeFully$default (Lio/ktor/utils/io/core/Output;[IIIILjava/lang/Object;)V public static synthetic fun writeFully$default (Lio/ktor/utils/io/core/Output;[JIIILjava/lang/Object;)V public static synthetic fun writeFully$default (Lio/ktor/utils/io/core/Output;[SIIILjava/lang/Object;)V - public static final fun writeFully-p0stHsI (Lio/ktor/utils/io/core/Output;Ljava/nio/ByteBuffer;II)V - public static final fun writeFully-sqKbz-I (Lio/ktor/utils/io/core/Output;Ljava/nio/ByteBuffer;JJ)V - public static final fun writeWhile (Lio/ktor/utils/io/core/Output;Lkotlin/jvm/functions/Function1;)V - public static final fun writeWhileSize (Lio/ktor/utils/io/core/Output;ILkotlin/jvm/functions/Function1;)V - public static synthetic fun writeWhileSize$default (Lio/ktor/utils/io/core/Output;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V + public static final fun writeFully-UAd2zVI (Lio/ktor/utils/io/core/Output;Ljava/nio/ByteBuffer;II)V + public static final fun writeFully-UAd2zVI (Lio/ktor/utils/io/core/Output;Ljava/nio/ByteBuffer;JJ)V } public final class io/ktor/utils/io/core/OutputLittleEndianKt { @@ -1216,18 +1203,18 @@ public final class io/ktor/utils/io/core/OutputLittleEndianKt { public static synthetic fun writeFullyLittleEndian$default (Lio/ktor/utils/io/core/Output;[IIIILjava/lang/Object;)V public static synthetic fun writeFullyLittleEndian$default (Lio/ktor/utils/io/core/Output;[JIIILjava/lang/Object;)V public static synthetic fun writeFullyLittleEndian$default (Lio/ktor/utils/io/core/Output;[SIIILjava/lang/Object;)V - public static final fun writeFullyLittleEndian-3GkuuDw (Lio/ktor/utils/io/core/Output;[JII)V - public static synthetic fun writeFullyLittleEndian-3GkuuDw$default (Lio/ktor/utils/io/core/Output;[JIIILjava/lang/Object;)V - public static final fun writeFullyLittleEndian-Hjr7jUQ (Lio/ktor/utils/io/core/Output;[SII)V - public static synthetic fun writeFullyLittleEndian-Hjr7jUQ$default (Lio/ktor/utils/io/core/Output;[SIIILjava/lang/Object;)V - public static final fun writeFullyLittleEndian-d1ESLyo (Lio/ktor/utils/io/core/Buffer;[SII)V - public static synthetic fun writeFullyLittleEndian-d1ESLyo$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)V - public static final fun writeFullyLittleEndian-eOostTs (Lio/ktor/utils/io/core/Buffer;[JII)V - public static synthetic fun writeFullyLittleEndian-eOostTs$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)V - public static final fun writeFullyLittleEndian-kYjf2rc (Lio/ktor/utils/io/core/Output;[III)V - public static synthetic fun writeFullyLittleEndian-kYjf2rc$default (Lio/ktor/utils/io/core/Output;[IIIILjava/lang/Object;)V - public static final fun writeFullyLittleEndian-uM_xt_c (Lio/ktor/utils/io/core/Buffer;[III)V - public static synthetic fun writeFullyLittleEndian-uM_xt_c$default (Lio/ktor/utils/io/core/Buffer;[IIIILjava/lang/Object;)V + public static final fun writeFullyLittleEndian-Wt3Bwxc (Lio/ktor/utils/io/core/Buffer;[SII)V + public static final fun writeFullyLittleEndian-Wt3Bwxc (Lio/ktor/utils/io/core/Output;[SII)V + public static synthetic fun writeFullyLittleEndian-Wt3Bwxc$default (Lio/ktor/utils/io/core/Buffer;[SIIILjava/lang/Object;)V + public static synthetic fun writeFullyLittleEndian-Wt3Bwxc$default (Lio/ktor/utils/io/core/Output;[SIIILjava/lang/Object;)V + public static final fun writeFullyLittleEndian-o2ZM2JE (Lio/ktor/utils/io/core/Buffer;[III)V + public static final fun writeFullyLittleEndian-o2ZM2JE (Lio/ktor/utils/io/core/Output;[III)V + public static synthetic fun writeFullyLittleEndian-o2ZM2JE$default (Lio/ktor/utils/io/core/Buffer;[IIIILjava/lang/Object;)V + public static synthetic fun writeFullyLittleEndian-o2ZM2JE$default (Lio/ktor/utils/io/core/Output;[IIIILjava/lang/Object;)V + public static final fun writeFullyLittleEndian-pqYNikA (Lio/ktor/utils/io/core/Buffer;[JII)V + public static final fun writeFullyLittleEndian-pqYNikA (Lio/ktor/utils/io/core/Output;[JII)V + public static synthetic fun writeFullyLittleEndian-pqYNikA$default (Lio/ktor/utils/io/core/Buffer;[JIIILjava/lang/Object;)V + public static synthetic fun writeFullyLittleEndian-pqYNikA$default (Lio/ktor/utils/io/core/Output;[JIIILjava/lang/Object;)V public static final fun writeInt (Lio/ktor/utils/io/core/Output;ILio/ktor/utils/io/core/ByteOrder;)V public static final fun writeIntLittleEndian (Lio/ktor/utils/io/core/Buffer;I)V public static final fun writeIntLittleEndian (Lio/ktor/utils/io/core/Output;I)V @@ -1335,30 +1322,30 @@ public final class io/ktor/utils/io/core/StringsKt { } public final class io/ktor/utils/io/core/UnsignedTypesKt { - public static final fun readFully-Lv-FXd8 (Lio/ktor/utils/io/core/Input;[SII)V - public static synthetic fun readFully-Lv-FXd8$default (Lio/ktor/utils/io/core/Input;[SIIILjava/lang/Object;)V - public static final fun readFully-PIFet3Y (Lio/ktor/utils/io/core/Input;[III)V - public static synthetic fun readFully-PIFet3Y$default (Lio/ktor/utils/io/core/Input;[IIIILjava/lang/Object;)V - public static final fun readFully-kDL3d6Y (Lio/ktor/utils/io/core/Input;[BII)V - public static synthetic fun readFully-kDL3d6Y$default (Lio/ktor/utils/io/core/Input;[BIIILjava/lang/Object;)V - public static final fun readFully-r2sAqVg (Lio/ktor/utils/io/core/Input;[JII)V - public static synthetic fun readFully-r2sAqVg$default (Lio/ktor/utils/io/core/Input;[JIIILjava/lang/Object;)V + public static final fun readFully-Wt3Bwxc (Lio/ktor/utils/io/core/Input;[SII)V + public static synthetic fun readFully-Wt3Bwxc$default (Lio/ktor/utils/io/core/Input;[SIIILjava/lang/Object;)V + public static final fun readFully-o1GoV1E (Lio/ktor/utils/io/core/Input;[BII)V + public static synthetic fun readFully-o1GoV1E$default (Lio/ktor/utils/io/core/Input;[BIIILjava/lang/Object;)V + public static final fun readFully-o2ZM2JE (Lio/ktor/utils/io/core/Input;[III)V + public static synthetic fun readFully-o2ZM2JE$default (Lio/ktor/utils/io/core/Input;[IIIILjava/lang/Object;)V + public static final fun readFully-pqYNikA (Lio/ktor/utils/io/core/Input;[JII)V + public static synthetic fun readFully-pqYNikA$default (Lio/ktor/utils/io/core/Input;[JIIILjava/lang/Object;)V public static final fun readUByte (Lio/ktor/utils/io/core/Input;)B public static final fun readUInt (Lio/ktor/utils/io/core/Input;)I public static final fun readULong (Lio/ktor/utils/io/core/Input;)J public static final fun readUShort (Lio/ktor/utils/io/core/Input;)S - public static final fun writeFully-3GkuuDw (Lio/ktor/utils/io/core/Output;[JII)V - public static synthetic fun writeFully-3GkuuDw$default (Lio/ktor/utils/io/core/Output;[JIIILjava/lang/Object;)V - public static final fun writeFully-Hjr7jUQ (Lio/ktor/utils/io/core/Output;[SII)V - public static synthetic fun writeFully-Hjr7jUQ$default (Lio/ktor/utils/io/core/Output;[SIIILjava/lang/Object;)V - public static final fun writeFully-kYjf2rc (Lio/ktor/utils/io/core/Output;[III)V - public static synthetic fun writeFully-kYjf2rc$default (Lio/ktor/utils/io/core/Output;[IIIILjava/lang/Object;)V - public static final fun writeFully-wDeirj4 (Lio/ktor/utils/io/core/Output;[BII)V - public static synthetic fun writeFully-wDeirj4$default (Lio/ktor/utils/io/core/Output;[BIIILjava/lang/Object;)V - public static final fun writeUByte-9EPp-TE (Lio/ktor/utils/io/core/Output;B)V - public static final fun writeUInt-fzK-hLo (Lio/ktor/utils/io/core/Output;I)V - public static final fun writeULong-O6EZHW0 (Lio/ktor/utils/io/core/Output;J)V - public static final fun writeUShort-SLr1GAc (Lio/ktor/utils/io/core/Output;S)V + public static final fun writeFully-Wt3Bwxc (Lio/ktor/utils/io/core/Output;[SII)V + public static synthetic fun writeFully-Wt3Bwxc$default (Lio/ktor/utils/io/core/Output;[SIIILjava/lang/Object;)V + public static final fun writeFully-o1GoV1E (Lio/ktor/utils/io/core/Output;[BII)V + public static synthetic fun writeFully-o1GoV1E$default (Lio/ktor/utils/io/core/Output;[BIIILjava/lang/Object;)V + public static final fun writeFully-o2ZM2JE (Lio/ktor/utils/io/core/Output;[III)V + public static synthetic fun writeFully-o2ZM2JE$default (Lio/ktor/utils/io/core/Output;[IIIILjava/lang/Object;)V + public static final fun writeFully-pqYNikA (Lio/ktor/utils/io/core/Output;[JII)V + public static synthetic fun writeFully-pqYNikA$default (Lio/ktor/utils/io/core/Output;[JIIILjava/lang/Object;)V + public static final fun writeUByte-EK-6454 (Lio/ktor/utils/io/core/Output;B)V + public static final fun writeUInt-Qn1smSk (Lio/ktor/utils/io/core/Output;I)V + public static final fun writeULong-2TYgG_w (Lio/ktor/utils/io/core/Output;J)V + public static final fun writeUShort-i8woANY (Lio/ktor/utils/io/core/Output;S)V } public class io/ktor/utils/io/core/internal/ChunkBuffer : io/ktor/utils/io/core/Buffer { @@ -1394,8 +1381,6 @@ public final class io/ktor/utils/io/core/internal/NumbersKt { } public final class io/ktor/utils/io/core/internal/UTF8Kt { - public static final fun decodeUTF8 (Lio/ktor/utils/io/core/Buffer;Lkotlin/jvm/functions/Function1;)I - public static final fun decodeUTF8LineLoopSuspend (Ljava/lang/Appendable;ILkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun highSurrogate (I)I public static final fun isBmpCodePoint (I)Z public static final fun isValidCodePoint (I)Z @@ -1409,7 +1394,6 @@ public final class io/ktor/utils/io/core/internal/UnsafeKt { public static final fun completeReadHead (Lio/ktor/utils/io/core/Input;Lio/ktor/utils/io/core/internal/ChunkBuffer;)V public static final fun prepareReadFirstHead (Lio/ktor/utils/io/core/Input;I)Lio/ktor/utils/io/core/internal/ChunkBuffer; public static final fun prepareReadNextHead (Lio/ktor/utils/io/core/Input;Lio/ktor/utils/io/core/internal/ChunkBuffer;)Lio/ktor/utils/io/core/internal/ChunkBuffer; - public static final fun prepareWriteHead (Lio/ktor/utils/io/core/Output;ILio/ktor/utils/io/core/internal/ChunkBuffer;)Lio/ktor/utils/io/core/internal/ChunkBuffer; } public final class io/ktor/utils/io/errors/ErrorsKt { @@ -1461,14 +1445,14 @@ public final class io/ktor/utils/io/jvm/nio/WritingKt { public final class io/ktor/utils/io/nio/ChannelsKt { public static final fun read (Ljava/nio/channels/ReadableByteChannel;Lio/ktor/utils/io/core/Buffer;)I - public static final fun read-r2lQqvc (Ljava/nio/channels/ReadableByteChannel;Ljava/nio/ByteBuffer;II)I - public static synthetic fun read-r2lQqvc$default (Ljava/nio/channels/ReadableByteChannel;Ljava/nio/ByteBuffer;IIILjava/lang/Object;)I + public static final fun read-UAd2zVI (Ljava/nio/channels/ReadableByteChannel;Ljava/nio/ByteBuffer;II)I + public static synthetic fun read-UAd2zVI$default (Ljava/nio/channels/ReadableByteChannel;Ljava/nio/ByteBuffer;IIILjava/lang/Object;)I public static final fun readPacketAtLeast (Ljava/nio/channels/ReadableByteChannel;J)Lio/ktor/utils/io/core/ByteReadPacket; public static final fun readPacketAtMost (Ljava/nio/channels/ReadableByteChannel;J)Lio/ktor/utils/io/core/ByteReadPacket; public static final fun readPacketExact (Ljava/nio/channels/ReadableByteChannel;J)Lio/ktor/utils/io/core/ByteReadPacket; public static final fun write (Ljava/nio/channels/WritableByteChannel;Lio/ktor/utils/io/core/Buffer;)I - public static final fun write-XQjEsr4 (Ljava/nio/channels/WritableByteChannel;Ljava/nio/ByteBuffer;II)I - public static synthetic fun write-XQjEsr4$default (Ljava/nio/channels/WritableByteChannel;Ljava/nio/ByteBuffer;IIILjava/lang/Object;)I + public static final fun write-UAd2zVI (Ljava/nio/channels/WritableByteChannel;Ljava/nio/ByteBuffer;II)I + public static synthetic fun write-UAd2zVI$default (Ljava/nio/channels/WritableByteChannel;Ljava/nio/ByteBuffer;IIILjava/lang/Object;)I public static final fun writePacket (Ljava/nio/channels/WritableByteChannel;Lio/ktor/utils/io/core/ByteReadPacket;)Z public static final fun writePacket (Ljava/nio/channels/WritableByteChannel;Lkotlin/jvm/functions/Function1;)Lio/ktor/utils/io/core/ByteReadPacket; } diff --git a/ktor-io/build.gradle.kts b/ktor-io/build.gradle.kts index 82b48e81b48..921ce1e8780 100644 --- a/ktor-io/build.gradle.kts +++ b/ktor-io/build.gradle.kts @@ -1,7 +1,5 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget -val ideaActive: Boolean by extra - val nativeTargets: List by extra kotlin { nativeTargets.forEach { @@ -37,7 +35,7 @@ kotlin { dependsOn(socketsMain) } - if (!ideaActive) { + if (!KtorBuildProperties.ideaActive) { apply(from = "$rootDir/gradle/interop-as-source-set-klib.gradle") val registerInteropAsSourceSetOutput: groovy.lang.Closure<*> by extra afterEvaluate { diff --git a/ktor-io/common/src/io/ktor/utils/io/ByteChannelSequential.kt b/ktor-io/common/src/io/ktor/utils/io/ByteChannelSequential.kt index de73a4c5fdd..3147febbdca 100644 --- a/ktor-io/common/src/io/ktor/utils/io/ByteChannelSequential.kt +++ b/ktor-io/common/src/io/ktor/utils/io/ByteChannelSequential.kt @@ -13,8 +13,7 @@ private const val EXPECTED_CAPACITY: Long = 4088L /** * Sequential (non-concurrent) byte channel implementation */ -@Suppress("OverridingDeprecatedMember") -@DangerousInternalIoApi +@Suppress("OverridingDeprecatedMember", "DEPRECATION") public abstract class ByteChannelSequentialBase( initial: ChunkBuffer, override val autoFlush: Boolean, @@ -248,7 +247,6 @@ public abstract class ByteChannelSequentialBase( } } - @ExperimentalIoApi @Suppress("DEPRECATION") override suspend fun writeSuspendSession(visitor: suspend WriterSuspendSession.() -> Unit) { val session = beginWriteSession() @@ -710,7 +708,6 @@ public abstract class ByteChannelSequentialBase( return false } - @OptIn(DangerousInternalIoApi::class) return decodeUTF8LineLoopSuspend(out, limit) { size -> afterRead(size) if (await(size)) readable diff --git a/ktor-io/common/src/io/ktor/utils/io/ByteWriteChannel.kt b/ktor-io/common/src/io/ktor/utils/io/ByteWriteChannel.kt index d1c71161a02..0c9b36bbc5f 100644 --- a/ktor-io/common/src/io/ktor/utils/io/ByteWriteChannel.kt +++ b/ktor-io/common/src/io/ktor/utils/io/ByteWriteChannel.kt @@ -105,7 +105,6 @@ public expect interface ByteWriteChannel { /** * Invokes [block] when at least 1 byte is available for write. */ - @ExperimentalIoApi public suspend fun awaitFreeSpace() /** @@ -189,7 +188,7 @@ public suspend fun ByteWriteChannel.writeBoolean(b: Boolean) { * Writes UTF16 character */ public suspend fun ByteWriteChannel.writeChar(ch: Char) { - return writeShort(ch.toInt()) + return writeShort(ch.code) } public suspend inline fun ByteWriteChannel.writePacket(headerSizeHint: Int = 0, builder: BytePacketBuilder.() -> Unit) { diff --git a/ktor-io/common/src/io/ktor/utils/io/Coroutines.kt b/ktor-io/common/src/io/ktor/utils/io/Coroutines.kt index de4e11eeba3..b51bd471168 100644 --- a/ktor-io/common/src/io/ktor/utils/io/Coroutines.kt +++ b/ktor-io/common/src/io/ktor/utils/io/Coroutines.kt @@ -43,6 +43,7 @@ public fun CoroutineScope.reader( block: suspend ReaderScope.() -> Unit ): ReaderJob = launchChannel(coroutineContext, ByteChannel(autoFlush), attachJob = true, block = block) +@OptIn(DelicateCoroutinesApi::class, ExperimentalCoroutinesApi::class) @Deprecated("Use scope.reader instead") public fun reader( coroutineContext: CoroutineContext, @@ -82,6 +83,7 @@ public fun CoroutineScope.writer( block: suspend WriterScope.() -> Unit ): WriterJob = launchChannel(coroutineContext, ByteChannel(autoFlush), attachJob = true, block = block) +@OptIn(DelicateCoroutinesApi::class, ExperimentalCoroutinesApi::class) @Deprecated("Use scope.writer instead") public fun writer( coroutineContext: CoroutineContext, diff --git a/ktor-io/common/src/io/ktor/utils/io/NativeUtils.kt b/ktor-io/common/src/io/ktor/utils/io/NativeUtils.kt index cbb01edc144..5880579be4c 100644 --- a/ktor-io/common/src/io/ktor/utils/io/NativeUtils.kt +++ b/ktor-io/common/src/io/ktor/utils/io/NativeUtils.kt @@ -4,10 +4,6 @@ package io.ktor.utils.io -import io.ktor.utils.io.core.internal.* - -@DangerousInternalIoApi public expect fun Any.preventFreeze() -@DangerousInternalIoApi public expect fun Any.makeShared() diff --git a/ktor-io/common/src/io/ktor/utils/io/ReadSession.kt b/ktor-io/common/src/io/ktor/utils/io/ReadSession.kt index d5660bead76..ca2db83c532 100644 --- a/ktor-io/common/src/io/ktor/utils/io/ReadSession.kt +++ b/ktor-io/common/src/io/ktor/utils/io/ReadSession.kt @@ -16,7 +16,6 @@ import io.ktor.utils.io.core.internal.* * * @return number of bytes consumed, possibly 0 */ -@ExperimentalIoApi public suspend inline fun ByteReadChannel.read( desiredSize: Int = 1, block: (source: Memory, start: Long, endExclusive: Long) -> Int diff --git a/ktor-io/common/src/io/ktor/utils/io/WriterSession.kt b/ktor-io/common/src/io/ktor/utils/io/WriterSession.kt index 75869d7cc11..f06c370b210 100644 --- a/ktor-io/common/src/io/ktor/utils/io/WriterSession.kt +++ b/ktor-io/common/src/io/ktor/utils/io/WriterSession.kt @@ -14,7 +14,6 @@ import io.ktor.utils.io.core.internal.ChunkBuffer * or when it is impossible to represent all [desiredSpace] bytes as a single memory range * due to internal implementation reasons. */ -@ExperimentalIoApi public suspend inline fun ByteWriteChannel.write( desiredSpace: Int = 1, block: (freeSpace: Memory, startOffset: Long, endExclusive: Long) -> Int diff --git a/ktor-io/common/src/io/ktor/utils/io/bits/ByteOrder.kt b/ktor-io/common/src/io/ktor/utils/io/bits/ByteOrder.kt index 5b17cee32e6..07c1b3a4204 100644 --- a/ktor-io/common/src/io/ktor/utils/io/bits/ByteOrder.kt +++ b/ktor-io/common/src/io/ktor/utils/io/bits/ByteOrder.kt @@ -1,7 +1,5 @@ package io.ktor.utils.io.bits -import io.ktor.utils.io.core.ExperimentalIoApi - /** * Reverse number's byte order */ @@ -30,35 +28,26 @@ public expect fun Double.reverseByteOrder(): Double /** * Reverse number's byte order */ -@ExperimentalUnsignedTypes public fun UShort.reverseByteOrder(): UShort = toShort().reverseByteOrder().toUShort() /** * Reverse number's byte order */ -@ExperimentalUnsignedTypes public fun UInt.reverseByteOrder(): UInt = toInt().reverseByteOrder().toUInt() /** * Reverse number's byte order */ -@ExperimentalUnsignedTypes public fun ULong.reverseByteOrder(): ULong = toLong().reverseByteOrder().toULong() -@ExperimentalIoApi public inline val Short.highByte: Byte get() = (toInt() ushr 8).toByte() -@ExperimentalIoApi public inline val Short.lowByte: Byte get() = (toInt() and 0xff).toByte() -@ExperimentalIoApi public inline val Int.highShort: Short get() = (this ushr 16).toShort() -@ExperimentalIoApi public inline val Int.lowShort: Short get() = (this and 0xffff).toShort() -@ExperimentalIoApi public inline val Long.highInt: Int get() = (this ushr 32).toInt() -@ExperimentalIoApi public inline val Long.lowInt: Int get() = (this and 0xffffffffL).toInt() diff --git a/ktor-io/common/src/io/ktor/utils/io/bits/Memory.kt b/ktor-io/common/src/io/ktor/utils/io/bits/Memory.kt index 484fe1f5d9c..c651806ba7d 100644 --- a/ktor-io/common/src/io/ktor/utils/io/bits/Memory.kt +++ b/ktor-io/common/src/io/ktor/utils/io/bits/Memory.kt @@ -2,8 +2,6 @@ package io.ktor.utils.io.bits -import io.ktor.utils.io.core.* - /** * Represents a linear range of bytes. * All operations are guarded by range-checks by default however at some platforms they could be disabled @@ -11,7 +9,6 @@ import io.ktor.utils.io.core.* * * Instance of this class has no additional state except the bytes themselves. */ -@ExperimentalIoApi public expect class Memory { /** * Size of memory range in bytes. diff --git a/ktor-io/common/src/io/ktor/utils/io/bits/MemoryFactory.kt b/ktor-io/common/src/io/ktor/utils/io/bits/MemoryFactory.kt index 08eb83b9d68..0fdaedcc728 100644 --- a/ktor-io/common/src/io/ktor/utils/io/bits/MemoryFactory.kt +++ b/ktor-io/common/src/io/ktor/utils/io/bits/MemoryFactory.kt @@ -2,8 +2,7 @@ package io.ktor.utils.io.bits import io.ktor.utils.io.core.* import io.ktor.utils.io.core.internal.* -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract +import kotlin.contracts.* // TODO: length default argument should be this.size - offset but it doesn't work due to KT-29920 /** @@ -17,7 +16,6 @@ import kotlin.contracts.contract * 1. length has no default (blocked by expect/actual with default value compiler bug (fixed in KT 1.4.3)) * 2. no inline -> can't suspend inside block (blocked by inline compiler bug) */ -@ExperimentalIoApi public expect fun ByteArray.useMemory(offset: Int = 0, length: Int, block: (Memory) -> R): R /** @@ -25,7 +23,7 @@ public expect fun ByteArray.useMemory(offset: Int = 0, length: Int, block: ( * The provided instance shouldn't be captured and used outside of the [block] otherwise an undefined behaviour * may occur including crash and/or data corruption. */ -@ExperimentalIoApi +@OptIn(ExperimentalContracts::class) public inline fun withMemory(size: Int, block: (Memory) -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -39,7 +37,7 @@ public inline fun withMemory(size: Int, block: (Memory) -> R): R { * The provided instance shouldn't be captured and used outside of the [block] otherwise an undefined behaviour * may occur including crash and/or data corruption. */ -@ExperimentalIoApi +@OptIn(ExperimentalContracts::class) public inline fun withMemory(size: Long, block: (Memory) -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -57,7 +55,6 @@ public inline fun withMemory(size: Long, block: (Memory) -> R): R { @PublishedApi internal expect object DefaultAllocator : Allocator -@DangerousInternalIoApi internal interface Allocator { fun alloc(size: Int): Memory diff --git a/ktor-io/common/src/io/ktor/utils/io/bits/PrimiteArrays.kt b/ktor-io/common/src/io/ktor/utils/io/bits/PrimiteArrays.kt index 909cd442f6e..f1f51e2bd4b 100644 --- a/ktor-io/common/src/io/ktor/utils/io/bits/PrimiteArrays.kt +++ b/ktor-io/common/src/io/ktor/utils/io/bits/PrimiteArrays.kt @@ -34,6 +34,7 @@ public inline fun Memory.loadByteArray( * to the [destination] at [destinationOffset] interpreting numbers in the network order (Big Endian). * @param destinationOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.loadUByteArray( offset: Int, destination: UByteArray, @@ -48,6 +49,7 @@ public inline fun Memory.loadUByteArray( * to the [destination] at [destinationOffset] interpreting numbers in the network order (Big Endian). * @param destinationOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.loadUByteArray( offset: Long, destination: UByteArray, @@ -86,6 +88,7 @@ public expect fun Memory.loadShortArray( * to the [destination] at [destinationOffset] interpreting numbers in the network order (Big Endian). * @param destinationOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.loadUShortArray( offset: Int, destination: UShortArray, @@ -100,6 +103,7 @@ public inline fun Memory.loadUShortArray( * to the [destination] at [destinationOffset] interpreting numbers in the network order (Big Endian). * @param destinationOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.loadUShortArray( offset: Long, destination: UShortArray, @@ -138,6 +142,7 @@ public expect fun Memory.loadIntArray( * to the [destination] at [destinationOffset] interpreting numbers in the network order (Big Endian). * @param destinationOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.loadUIntArray( offset: Int, destination: UIntArray, @@ -152,6 +157,7 @@ public inline fun Memory.loadUIntArray( * to the [destination] at [destinationOffset] interpreting numbers in the network order (Big Endian). * @param destinationOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.loadUIntArray( offset: Long, destination: UIntArray, @@ -190,6 +196,7 @@ public expect fun Memory.loadLongArray( * to the [destination] at [destinationOffset] interpreting numbers in the network order (Big Endian). * @param destinationOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.loadULongArray( offset: Int, destination: ULongArray, @@ -204,6 +211,7 @@ public inline fun Memory.loadULongArray( * to the [destination] at [destinationOffset] interpreting numbers in the network order (Big Endian). * @param destinationOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.loadULongArray( offset: Long, destination: ULongArray, @@ -295,6 +303,7 @@ public inline fun Memory.storeByteArray( * Copies unsigned shorts integers from the [source] array at [sourceOffset] to this memory at the specified [offset]. * @param sourceOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.storeUByteArray( offset: Int, source: UByteArray, @@ -308,6 +317,7 @@ public inline fun Memory.storeUByteArray( * Copies unsigned shorts integers from the [source] array at [sourceOffset] to this memory at the specified [offset]. * @param sourceOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.storeUByteArray( offset: Long, source: UByteArray, @@ -346,6 +356,7 @@ public expect fun Memory.storeShortArray( * interpreting numbers in the network order (Big Endian). * @param sourceOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.storeUShortArray( offset: Int, source: UShortArray, @@ -360,6 +371,7 @@ public inline fun Memory.storeUShortArray( * interpreting numbers in the network order (Big Endian). * @param sourceOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.storeUShortArray( offset: Long, source: UShortArray, @@ -398,6 +410,7 @@ public expect fun Memory.storeIntArray( * interpreting numbers in the network order (Big Endian). * @param sourceOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.storeUIntArray( offset: Int, source: UIntArray, @@ -412,6 +425,7 @@ public inline fun Memory.storeUIntArray( * interpreting numbers in the network order (Big Endian). * @param sourceOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.storeUIntArray( offset: Long, source: UIntArray, @@ -450,6 +464,7 @@ public expect fun Memory.storeLongArray( * interpreting numbers in the network order (Big Endian). * @param sourceOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.storeULongArray( offset: Int, source: ULongArray, @@ -464,6 +479,7 @@ public inline fun Memory.storeULongArray( * interpreting numbers in the network order (Big Endian). * @param sourceOffset items */ +@OptIn(ExperimentalUnsignedTypes::class) public inline fun Memory.storeULongArray( offset: Long, source: ULongArray, diff --git a/ktor-io/common/src/io/ktor/utils/io/charsets/Encoding.kt b/ktor-io/common/src/io/ktor/utils/io/charsets/Encoding.kt index 024b1bdeada..18f835d65fa 100644 --- a/ktor-io/common/src/io/ktor/utils/io/charsets/Encoding.kt +++ b/ktor-io/common/src/io/ktor/utils/io/charsets/Encoding.kt @@ -4,10 +4,8 @@ import io.ktor.utils.io.core.* import io.ktor.utils.io.core.internal.* public expect abstract class Charset { - @ExperimentalIoApi public abstract fun newEncoder(): CharsetEncoder - @ExperimentalIoApi public abstract fun newDecoder(): CharsetDecoder public companion object { @@ -19,7 +17,6 @@ public expect abstract class Charset { public expect val Charset.name: String // ----------------------------- ENCODER ------------------------------------------------------------------------------- -@ExperimentalIoApi public expect abstract class CharsetEncoder public expect val CharsetEncoder.charset: Charset @@ -36,7 +33,6 @@ public fun CharsetEncoder.encode(input: CharSequence, fromIndex: Int, toIndex: I encodeToImpl(dst, input, fromIndex, toIndex) } -@ExperimentalIoApi public expect fun CharsetEncoder.encodeToByteArray( input: CharSequence, fromIndex: Int = 0, @@ -56,10 +52,8 @@ public fun CharsetEncoder.encodeToByteArrayImpl( return encodeToByteArray(input, fromIndex, toIndex) } -@ExperimentalIoApi public expect fun CharsetEncoder.encodeUTF8(input: ByteReadPacket, dst: Output) -@ExperimentalIoApi public fun CharsetEncoder.encode( input: CharSequence, fromIndex: Int = 0, @@ -68,12 +62,10 @@ public fun CharsetEncoder.encode( encodeToImpl(this, input, fromIndex, toIndex) } -@ExperimentalIoApi public fun CharsetEncoder.encodeUTF8(input: ByteReadPacket): ByteReadPacket = buildPacket { encodeUTF8(input, this) } -@ExperimentalIoApi public fun CharsetEncoder.encode(input: CharArray, fromIndex: Int, toIndex: Int, dst: Output) { var start = fromIndex @@ -95,7 +87,6 @@ public fun CharsetEncoder.encode(input: CharArray, fromIndex: Int, toIndex: Int, // ----------------------------- DECODER ------------------------------------------------------------------------------- -@ExperimentalIoApi public expect abstract class CharsetDecoder /** @@ -103,16 +94,13 @@ public expect abstract class CharsetDecoder */ public expect val CharsetDecoder.charset: Charset -@ExperimentalIoApi public fun CharsetDecoder.decode(input: Input, max: Int = Int.MAX_VALUE): String = buildString(minOf(max.toLong(), input.sizeEstimate()).toInt()) { decode(input, this, max) } -@ExperimentalIoApi public expect fun CharsetDecoder.decode(input: Input, dst: Appendable, max: Int): Int -@ExperimentalIoApi public expect fun CharsetDecoder.decodeExactBytes(input: Input, inputLength: Int): String // ----------------------------- REGISTRY ------------------------------------------------------------------------------ diff --git a/ktor-io/common/src/io/ktor/utils/io/concurrent/Shared.kt b/ktor-io/common/src/io/ktor/utils/io/concurrent/Shared.kt index 0e6581ad492..8c3d501d2c0 100644 --- a/ktor-io/common/src/io/ktor/utils/io/concurrent/Shared.kt +++ b/ktor-io/common/src/io/ktor/utils/io/concurrent/Shared.kt @@ -16,7 +16,6 @@ import kotlin.properties.* * var myCounter by shared(0) * ``` */ -@DangerousInternalIoApi public expect inline fun shared(value: T): ReadWriteProperty /** @@ -25,5 +24,4 @@ public expect inline fun shared(value: T): ReadWriteProperty * * It will have value in creation thread and null otherwise. */ -@DangerousInternalIoApi public expect fun threadLocal(value: T): ReadOnlyProperty diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Buffer.kt b/ktor-io/common/src/io/ktor/utils/io/core/Buffer.kt index dff6741a3b8..408ae13136e 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Buffer.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Buffer.kt @@ -13,7 +13,6 @@ import kotlin.contracts.* * Concurrent unsafe: the same memory could be shared between different instances of [Buffer] however you can't * read/write using the same [Buffer] instance from different threads. */ -@DangerousInternalIoApi public open class Buffer(public val memory: Memory) { private val bufferState: BufferSharedState = BufferSharedState(memory.size32) @@ -87,8 +86,10 @@ public open class Buffer(public val memory: Memory) { /** * User data: could be a session, connection or anything useful */ - @Deprecated("Will be removed. Inherit Buffer and add required fields instead.") - @ExperimentalIoApi + @Deprecated( + "Will be removed. Inherit Buffer and add required fields instead.", + level = DeprecationLevel.ERROR + ) public var attachment: Any? get() = bufferState.attachment set(value) { @@ -110,7 +111,6 @@ public open class Buffer(public val memory: Memory) { readPosition = newReadPosition } - @DangerousInternalIoApi public fun commitWritten(count: Int) { val newWritePosition = writePosition + count if (count < 0 || newWritePosition > limit) { @@ -361,13 +361,11 @@ public open class Buffer(public val memory: Memory) { * when several instances of [io.ktor.utils.io.core.internal.ChunkBuffer] are connected into a chain (usually inside of [ByteReadPacket] * or [BytePacketBuilder]) */ - @DangerousInternalIoApi public const val ReservedSize: Int = 8 /** * The empty buffer singleton: it has zero capacity for read and write. */ - @Suppress("DEPRECATION") public val Empty: Buffer get() = ChunkBuffer.Empty } } @@ -388,7 +386,7 @@ public inline fun Buffer.canWrite(): Boolean = limit > writePosition * No read/write functions on this buffer should be called inside of [block] otherwise an undefined behaviour may occur * including data damage. */ -@DangerousInternalIoApi +@OptIn(ExperimentalContracts::class) public inline fun Buffer.read(block: (memory: Memory, start: Int, endExclusive: Int) -> Int): Int { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -405,7 +403,7 @@ public inline fun Buffer.read(block: (memory: Memory, start: Int, endExclusive: * o read/write functions on this buffer should be called inside of [block] otherwise an undefined behaviour may occur * including data damage. */ -@DangerousInternalIoApi +@OptIn(ExperimentalContracts::class) public inline fun Buffer.write(block: (memory: Memory, start: Int, endExclusive: Int) -> Int): Int { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -466,7 +464,6 @@ internal fun Buffer.restoreStartGap(size: Int) { releaseStartGap(readPosition - size) } -@ExperimentalIoApi public class InsufficientSpaceException(message: String = "Not enough free space") : Exception(message) { public constructor( size: Int, diff --git a/ktor-io/common/src/io/ktor/utils/io/core/BufferCompatibility.kt b/ktor-io/common/src/io/ktor/utils/io/core/BufferCompatibility.kt index d46d9d275d2..5b01f83c57d 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/BufferCompatibility.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/BufferCompatibility.kt @@ -1,4 +1,4 @@ -@file:Suppress("DeprecatedCallableAddReplaceWith") +@file:Suppress("unused", "UNUSED_PARAMETER") package io.ktor.utils.io.core @@ -38,24 +38,35 @@ public fun Buffer.fill(n: Long, v: Byte) { /** * Push back [n] bytes: only possible if there were at least [n] bytes read before this operation. */ -@Deprecated("Use rewind instead", ReplaceWith("rewind(n)")) +@Deprecated( + "Use rewind instead", + ReplaceWith("rewind(n)"), + level = DeprecationLevel.ERROR +) public fun Buffer.pushBack(n: Int): Unit = rewind(n) -@Deprecated("Use duplicate instead", ReplaceWith("duplicate()")) +@Deprecated( + "Use duplicate instead", + ReplaceWith("duplicate()"), + level = DeprecationLevel.ERROR +) public fun Buffer.makeView(): Buffer = duplicate() -@Deprecated("Use duplicate instead", ReplaceWith("duplicate()")) +@Deprecated( + "Use duplicate instead", + ReplaceWith("duplicate()"), + level = DeprecationLevel.ERROR +) public fun ChunkBuffer.makeView(): ChunkBuffer = duplicate() -@Deprecated("Does nothing.") +@Deprecated( + "Does nothing.", + level = DeprecationLevel.ERROR +) public fun Buffer.flush() { } -internal fun Buffer.appendChars(csq: CharArray, start: Int, end: Int): Int { - return appendChars(CharArraySequence(csq, 0, csq.size), start, end) -} - -internal fun Buffer.appendChars(csq: CharSequence, start: Int, end: Int): Int { +internal fun Buffer.appendChars(csq: CharSequence, start: Int = 0, end: Int = csq.length): Int { var charactersWritten: Int write { dst, dstStart, dstEndExclusive -> @@ -67,10 +78,13 @@ internal fun Buffer.appendChars(csq: CharSequence, start: Int, end: Int): Int { return start + charactersWritten } -@Deprecated("This is no longer supported. Use a packet builder to append characters instead.") +@Deprecated( + "This is no longer supported. Use a packet builder to append characters instead.", + level = DeprecationLevel.ERROR +) public fun Buffer.append(c: Char): Buffer { write { memory, start, endExclusive -> - val size = memory.putUtf8Char(start, c.toInt()) + val size = memory.putUtf8Char(start, c.code) when { size > endExclusive - start -> appendFailed(1) else -> size @@ -80,36 +94,38 @@ public fun Buffer.append(c: Char): Buffer { return this } -@Deprecated("This is no longer supported. Use a packet builder to append characters instead.") +@Deprecated( + "This is no longer supported. Use a packet builder to append characters instead.", + level = DeprecationLevel.ERROR +) public fun Buffer.append(csq: CharSequence?): Buffer { - if (csq == null) { - return append("null") - } - - return append(csq, 0, csq.length) + error("This is no longer supported. Use a packet builder to append characters instead.") } -@Deprecated("This is no longer supported. Use a packet builder to append characters instead.") +@Deprecated( + "This is no longer supported. Use a packet builder to append characters instead.", + level = DeprecationLevel.ERROR +) public fun Buffer.append(csq: CharSequence?, start: Int, end: Int): Buffer = apply { - if (csq == null) { - return append("null", start, end) - } - - if (appendChars(csq, start, end) != end) { - appendFailed(end - start) - } + error("This is no longer supported. Use a packet builder to append characters instead.") } private fun appendFailed(length: Int): Nothing { throw BufferLimitExceededException("Not enough free space available to write $length character(s).") } -@Deprecated("This is no longer supported. Use a packet builder to append characters instead.") +@Deprecated( + "This is no longer supported. Use a packet builder to append characters instead.", + level = DeprecationLevel.ERROR +) public fun Buffer.append(csq: CharArray, start: Int, end: Int): Buffer { - return append(CharArraySequence(csq, 0, csq.size), start, end) + error("This is no longer supported. Use a packet builder to append characters instead.") } -@Deprecated("This is no longer supported. Read from a packet instead.") +@Deprecated( + "This is no longer supported. Read from a packet instead.", + level = DeprecationLevel.ERROR +) public fun Buffer.readText( decoder: CharsetDecoder, out: Appendable, @@ -124,7 +140,11 @@ public fun Buffer.readText( * as consumed in any case. * @see [Buffer.tryPeekByte] */ -@Deprecated("Use tryPeekByte instead", replaceWith = ReplaceWith("tryPeekByte()")) +@Deprecated( + "Use tryPeekByte instead", + replaceWith = ReplaceWith("tryPeekByte()"), + level = DeprecationLevel.ERROR +) public fun Buffer.tryPeek(): Int = tryPeekByte() public fun Buffer.readFully(dst: Array, offset: Int = 0, length: Int = dst.size - offset) { diff --git a/ktor-io/common/src/io/ktor/utils/io/core/BufferFactory.kt b/ktor-io/common/src/io/ktor/utils/io/core/BufferFactory.kt index c4f000cb0d7..1eb5d67b09f 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/BufferFactory.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/BufferFactory.kt @@ -12,7 +12,6 @@ internal const val DEFAULT_BUFFER_SIZE: Int = 4096 * The provided instance shouldn't be captured and used outside of the [block] otherwise an undefined behaviour * may occur including crash and/or data corruption. */ -@ExperimentalIoApi public inline fun withBuffer(size: Int, block: Buffer.() -> R): R { return with(Buffer(DefaultAllocator.alloc(size)), block) } @@ -22,7 +21,6 @@ public inline fun withBuffer(size: Int, block: Buffer.() -> R): R { * Depending on the pool it may be safe or unsafe to capture and use the provided buffer outside of the [block]. * Usually it is always recommended to NOT capture an instance outside. */ -@ExperimentalIoApi public inline fun withBuffer(pool: ObjectPool, block: Buffer.() -> R): R { val instance = pool.borrow() return try { diff --git a/ktor-io/common/src/io/ktor/utils/io/core/BufferPrimitives.kt b/ktor-io/common/src/io/ktor/utils/io/core/BufferPrimitives.kt index c90dbb638d7..6d9c138d385 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/BufferPrimitives.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/BufferPrimitives.kt @@ -9,7 +9,6 @@ import kotlin.contracts.* /** * For every byte from this buffer invokes [block] function giving it as parameter. */ -@ExperimentalIoApi public inline fun Buffer.forEach(block: (Byte) -> Unit) { read { memory, start, endExclusive -> for (index in start until endExclusive) { @@ -226,6 +225,7 @@ public inline fun ChunkBuffer.readFully( /** * Read from this buffer to the [destination] array to [offset] and [length] bytes. */ +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readFully(destination: UByteArray, offset: Int = 0, length: Int = destination.size - offset) { readFully(destination.asByteArray(), offset, length) } @@ -264,6 +264,7 @@ public inline fun ChunkBuffer.readAvailable( * will be returned as result. * @return number of bytes copied to the [destination] or `-1` if the buffer is empty */ +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readAvailable( destination: UByteArray, offset: Int = 0, @@ -288,6 +289,7 @@ public inline fun ChunkBuffer.writeFully(source: ByteArray, offset: Int = 0, len /** * Write the whole [source] array range staring at [offset] and having the specified bytes [length]. */ +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.writeFully(source: UByteArray, offset: Int = 0, length: Int = source.size - offset) { writeFully(source.asByteArray(), offset, length) } @@ -306,6 +308,7 @@ public fun Buffer.readFully(destination: ShortArray, offset: Int = 0, length: In * Read from this buffer to the [destination] array to [offset] and [length] bytes. * Numeric values are interpreted in the network byte order (Big Endian). */ +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readFully(destination: UShortArray, offset: Int = 0, length: Int = destination.size - offset) { readFully(destination.asShortArray(), offset, length) } @@ -344,6 +347,7 @@ public fun Buffer.readAvailable( * @return number of elements copied to the [destination] or `-1` if the buffer is empty, * `0` - not enough bytes for at least an element */ +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readAvailable( destination: UShortArray, offset: Int = 0, @@ -366,6 +370,7 @@ public fun Buffer.writeFully(source: ShortArray, offset: Int = 0, length: Int = * Write the whole [source] array range staring at [offset] and having the specified items [length]. * Numeric values are interpreted in the network byte order (Big Endian). */ +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.writeFully(source: UShortArray, offset: Int = 0, length: Int = source.size - offset) { writeFully(source.asShortArray(), offset, length) } @@ -384,6 +389,7 @@ public fun Buffer.readFully(destination: IntArray, offset: Int = 0, length: Int * Read from this buffer to the [destination] array to [offset] and [length] bytes. * Numeric values are interpreted in the network byte order (Big Endian). */ +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readFully(destination: UIntArray, offset: Int = 0, length: Int = destination.size - offset) { readFully(destination.asIntArray(), offset, length) } @@ -418,6 +424,7 @@ public fun Buffer.readAvailable(destination: IntArray, offset: Int = 0, length: * @return number of elements copied to the [destination] or `-1` if the buffer is empty, * `0` - not enough bytes for at least an element */ +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readAvailable(destination: UIntArray, offset: Int = 0, length: Int = destination.size - offset): Int { return readAvailable(destination.asIntArray(), offset, length) } @@ -436,6 +443,7 @@ public fun Buffer.writeFully(source: IntArray, offset: Int = 0, length: Int = so * Write the whole [source] array range staring at [offset] and having the specified items [length]. * Numeric values are interpreted in the network byte order (Big Endian). */ +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.writeFully(source: UIntArray, offset: Int = 0, length: Int = source.size - offset) { writeFully(source.asIntArray(), offset, length) } @@ -454,6 +462,7 @@ public fun Buffer.readFully(destination: LongArray, offset: Int = 0, length: Int * Read from this buffer to the [destination] array to [offset] and [length] bytes. * Numeric values are interpreted in the network byte order (Big Endian). */ +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readFully(destination: ULongArray, offset: Int = 0, length: Int = destination.size - offset) { readFully(destination.asLongArray(), offset, length) } @@ -488,6 +497,7 @@ public fun Buffer.readAvailable(destination: LongArray, offset: Int = 0, length: * @return number of elements copied to the [destination] or `-1` if the buffer is empty, * `0` - not enough bytes for at least an element */ +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readAvailable( destination: ULongArray, offset: Int = 0, @@ -510,6 +520,7 @@ public fun Buffer.writeFully(source: LongArray, offset: Int = 0, length: Int = s * Write the whole [source] array range staring at [offset] and having the specified items [length]. * Numeric values are interpreted in the network byte order (Big Endian). */ +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.writeFully(source: ULongArray, offset: Int = 0, length: Int = source.size - offset) { writeFully(source.asLongArray(), offset, length) } @@ -670,6 +681,7 @@ public fun Buffer.writeFully(src: Buffer, length: Int) { } } +@OptIn(ExperimentalContracts::class) @PublishedApi internal inline fun Buffer.readExact(size: Int, name: String, block: (memory: Memory, offset: Int) -> R): R { contract { @@ -679,9 +691,10 @@ internal inline fun Buffer.readExact(size: Int, name: String, block: (memory var value: R read { memory, start, endExclusive -> - require(endExclusive - start >= size) { + if (endExclusive - start < size) { throw EOFException("Not enough bytes to read a $name of size $size.") } + value = block(memory, start) size } @@ -689,6 +702,7 @@ internal inline fun Buffer.readExact(size: Int, name: String, block: (memory return value } +@OptIn(ExperimentalContracts::class) @PublishedApi internal inline fun Buffer.writeExact(size: Int, name: String, block: (memory: Memory, offset: Int) -> Unit) { contract { diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Buffers.kt b/ktor-io/common/src/io/ktor/utils/io/core/Buffers.kt index 54ee6e6d82c..ee94a1ac3ef 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Buffers.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Buffers.kt @@ -27,6 +27,7 @@ internal fun ChunkBuffer?.releaseAll(pool: ObjectPool) { } } +@OptIn(ExperimentalContracts::class) internal inline fun ChunkBuffer.forEachChunk(block: (ChunkBuffer) -> Unit) { contract { callsInPlace(block, InvocationKind.AT_LEAST_ONCE) @@ -65,8 +66,7 @@ internal tailrec fun ChunkBuffer.findTail(): ChunkBuffer { /** * Summarize remainings of all elements of the chain */ -@DangerousInternalIoApi -public fun ChunkBuffer.remainingAll(): Long = remainingAll(0L) +internal fun ChunkBuffer.remainingAll(): Long = remainingAll(0L) private tailrec fun ChunkBuffer.remainingAll(n: Long): Long { val rem = readRemaining.toLong() + n @@ -90,7 +90,7 @@ internal inline fun Long.coerceAtMostMaxIntOrFail(message: String): Int { return this.toInt() } -internal fun Buffer.peekTo(destination: Memory, destinationOffset: Long, offset: Long, min: Long, max: Long): Long { +internal fun Buffer.peekTo(destination: Memory, destinationOffset: Long, offset: Long, max: Long): Long { val size = minOf( destination.size - destinationOffset, max, diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Builder.kt b/ktor-io/common/src/io/ktor/utils/io/core/Builder.kt index 1b47f66b27f..2448da330a1 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Builder.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Builder.kt @@ -7,6 +7,7 @@ public expect val PACKET_MAX_COPY_SIZE: Int /** * Build a byte packet in [block] lambda. Creates a temporary builder and releases it in case of failure */ +@OptIn(ExperimentalContracts::class) public inline fun buildPacket(headerSizeHint: Int = 0, block: BytePacketBuilder.() -> Unit): ByteReadPacket { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) diff --git a/ktor-io/common/src/io/ktor/utils/io/core/BytePacketBuilder.kt b/ktor-io/common/src/io/ktor/utils/io/core/BytePacketBuilder.kt index f8b97b15412..13dd537aec9 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/BytePacketBuilder.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/BytePacketBuilder.kt @@ -76,16 +76,16 @@ public class BytePacketBuilder( final override fun flush(source: Memory, offset: Int, length: Int) { } - override fun append(c: Char): BytePacketBuilder { - return super.append(c) as BytePacketBuilder + override fun append(value: Char): BytePacketBuilder { + return super.append(value) as BytePacketBuilder } - override fun append(csq: CharSequence?): BytePacketBuilder { - return super.append(csq) as BytePacketBuilder + override fun append(value: CharSequence?): BytePacketBuilder { + return super.append(value) as BytePacketBuilder } - override fun append(csq: CharSequence?, start: Int, end: Int): BytePacketBuilder { - return super.append(csq, start, end) as BytePacketBuilder + override fun append(value: CharSequence?, startIndex: Int, endIndex: Int): BytePacketBuilder { + return super.append(value, startIndex, endIndex) as BytePacketBuilder } /** @@ -93,9 +93,8 @@ public class BytePacketBuilder( */ public fun build(): ByteReadPacket { val size = size - val head = stealAll() - return when (head) { + return when (val head = stealAll()) { null -> ByteReadPacket.Empty else -> ByteReadPacket(head, size.toLong(), pool) } diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Input.kt b/ktor-io/common/src/io/ktor/utils/io/core/Input.kt index 06853f4450f..bc7c5de331c 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Input.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Input.kt @@ -560,11 +560,9 @@ public abstract class Input( throw EOFException("Not enough data in packet ($remaining) to read $n byte(s)") } - @DangerousInternalIoApi - public fun prepareReadHead(minSize: Int): ChunkBuffer? = prepareReadLoop(minSize, head) + internal fun prepareReadHead(minSize: Int): ChunkBuffer? = prepareReadLoop(minSize, head) - @DangerousInternalIoApi - public fun ensureNextHead(current: ChunkBuffer): ChunkBuffer? = ensureNext(current) + internal fun ensureNextHead(current: ChunkBuffer): ChunkBuffer? = ensureNext(current) @PublishedApi internal fun ensureNext(current: ChunkBuffer): ChunkBuffer? = ensureNext( @@ -572,8 +570,7 @@ public abstract class Input( ChunkBuffer.Empty ) - @DangerousInternalIoApi - public fun fixGapAfterRead(current: ChunkBuffer) { + internal fun fixGapAfterRead(current: ChunkBuffer) { val next = current.next ?: return fixGapAfterReadFallback(current) val remaining = current.readRemaining @@ -815,6 +812,7 @@ public fun Input.discardExact(n: Long) { /** * Discard exactly [n] bytes or fail if not enough bytes in the input to be discarded. */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public fun Input.discardExact(n: Int) { discardExact(n.toLong()) } @@ -827,7 +825,6 @@ public fun Input.discardExact(n: Int) { * [block] function should never release provided buffer and should not write to it otherwise an undefined behaviour * could be observed */ -@DangerousInternalIoApi public inline fun Input.takeWhile(block: (Buffer) -> Boolean) { var release = true var current = prepareReadFirstHead(1) ?: return @@ -857,8 +854,7 @@ public inline fun Input.takeWhile(block: (Buffer) -> Boolean) { * [block] function should never release provided buffer and should not write to it otherwise an undefined behaviour * could be observed */ -@DangerousInternalIoApi -public inline fun Input.takeWhileSize(initialSize: Int = 1, block: (Buffer) -> Int) { +internal inline fun Input.takeWhileSize(initialSize: Int = 1, block: (Buffer) -> Int) { var release = true var current = prepareReadFirstHead(initialSize) ?: return var size = initialSize @@ -887,11 +883,7 @@ public inline fun Input.takeWhileSize(initialSize: Int = 1, block: (Buffer) -> I prepareReadFirstHead(size) } else -> current - } - - if (next == null) { - break - } + } ?: break current = next release = true @@ -903,7 +895,6 @@ public inline fun Input.takeWhileSize(initialSize: Int = 1, block: (Buffer) -> I } } -@ExperimentalIoApi public fun Input.peekCharUtf8(): Char { val rc = tryPeek() if (rc and 0x80 == 0) return rc.toChar() @@ -915,8 +906,7 @@ public fun Input.peekCharUtf8(): Char { /** * For every byte from this input invokes [block] function giving it as parameter. */ -@ExperimentalIoApi -public inline fun Input.forEach(block: (Byte) -> Unit) { +internal inline fun Input.forEach(block: (Byte) -> Unit) { takeWhile { buffer -> buffer.forEach(block) true diff --git a/ktor-io/common/src/io/ktor/utils/io/core/InputLittleEndian.kt b/ktor-io/common/src/io/ktor/utils/io/core/InputLittleEndian.kt index 4928bf998c8..edb63eec898 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/InputLittleEndian.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/InputLittleEndian.kt @@ -39,6 +39,7 @@ public fun Buffer.readFloatLittleEndian(): Float = readPrimitiveTemplate({ readF public fun Buffer.readDoubleLittleEndian(): Double = readPrimitiveTemplate({ readDouble() }, { reverseByteOrder() }) +@OptIn(ExperimentalUnsignedTypes::class) public fun Input.readFullyLittleEndian(dst: UShortArray, offset: Int = 0, length: Int = dst.size - offset) { readFullyLittleEndian(dst.asShortArray(), offset, length) } @@ -51,6 +52,7 @@ public fun Input.readFullyLittleEndian(dst: ShortArray, offset: Int = 0, length: } } +@OptIn(ExperimentalUnsignedTypes::class) public fun Input.readFullyLittleEndian(dst: UIntArray, offset: Int = 0, length: Int = dst.size - offset) { readFullyLittleEndian(dst.asIntArray(), offset, length) } @@ -63,6 +65,7 @@ public fun Input.readFullyLittleEndian(dst: IntArray, offset: Int = 0, length: I } } +@OptIn(ExperimentalUnsignedTypes::class) public fun Input.readFullyLittleEndian(dst: ULongArray, offset: Int = 0, length: Int = dst.size - offset) { readFullyLittleEndian(dst.asLongArray(), offset, length) } @@ -91,6 +94,7 @@ public fun Input.readFullyLittleEndian(dst: DoubleArray, offset: Int = 0, length } } +@OptIn(ExperimentalUnsignedTypes::class) public fun Input.readAvailableLittleEndian(dst: UShortArray, offset: Int = 0, length: Int = dst.size - offset): Int { return readAvailableLittleEndian(dst.asShortArray(), offset, length) } @@ -106,6 +110,7 @@ public fun Input.readAvailableLittleEndian(dst: ShortArray, offset: Int = 0, len return result } +@OptIn(ExperimentalUnsignedTypes::class) public fun Input.readAvailableLittleEndian(dst: UIntArray, offset: Int = 0, length: Int = dst.size - offset): Int { return readAvailableLittleEndian(dst.asIntArray(), offset, length) } @@ -121,6 +126,7 @@ public fun Input.readAvailableLittleEndian(dst: IntArray, offset: Int = 0, lengt return result } +@OptIn(ExperimentalUnsignedTypes::class) public fun Input.readAvailableLittleEndian(dst: ULongArray, offset: Int = 0, length: Int = dst.size - offset): Int { return readAvailableLittleEndian(dst.asLongArray(), offset, length) } @@ -158,6 +164,7 @@ public fun Input.readAvailableLittleEndian(dst: DoubleArray, offset: Int = 0, le return result } +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readFullyLittleEndian(dst: UShortArray, offset: Int = 0, length: Int = dst.size - offset) { readFullyLittleEndian(dst.asShortArray(), offset, length) } @@ -170,6 +177,7 @@ public fun Buffer.readFullyLittleEndian(dst: ShortArray, offset: Int = 0, length } } +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readFullyLittleEndian(dst: UIntArray, offset: Int = 0, length: Int = dst.size - offset) { readFullyLittleEndian(dst.asIntArray(), offset, length) } @@ -182,6 +190,7 @@ public fun Buffer.readFullyLittleEndian(dst: IntArray, offset: Int = 0, length: } } +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readFullyLittleEndian(dst: ULongArray, offset: Int = 0, length: Int = dst.size - offset) { readFullyLittleEndian(dst.asLongArray(), offset, length) } @@ -210,6 +219,7 @@ public fun Buffer.readFullyLittleEndian(dst: DoubleArray, offset: Int = 0, lengt } } +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readAvailableLittleEndian(dst: UShortArray, offset: Int = 0, length: Int = dst.size - offset): Int { return readAvailableLittleEndian(dst.asShortArray(), offset, length) } @@ -223,6 +233,7 @@ public fun Buffer.readAvailableLittleEndian(dst: ShortArray, offset: Int = 0, le return result } +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readAvailableLittleEndian(dst: UIntArray, offset: Int = 0, length: Int = dst.size - offset): Int { return readAvailableLittleEndian(dst.asIntArray(), offset, length) } @@ -236,6 +247,7 @@ public fun Buffer.readAvailableLittleEndian(dst: IntArray, offset: Int = 0, leng return result } +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.readAvailableLittleEndian(dst: ULongArray, offset: Int = 0, length: Int = dst.size - offset): Int { return readAvailableLittleEndian(dst.asLongArray(), offset, length) } diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Output.kt b/ktor-io/common/src/io/ktor/utils/io/core/Output.kt index 3259d17928e..8fa79c0c49c 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Output.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Output.kt @@ -192,7 +192,7 @@ public abstract class Output internal constructor( override fun append(value: Char): Output { val tailPosition = tailPosition if (tailEndExclusive - tailPosition >= 3) { - val size = tailMemory.putUtf8Char(tailPosition, value.toInt()) + val size = tailMemory.putUtf8Char(tailPosition, value.code) this.tailPosition = tailPosition + size return this } @@ -203,7 +203,7 @@ public abstract class Output internal constructor( private fun appendCharFallback(c: Char) { write(3) { buffer -> - val size = buffer.memory.putUtf8Char(buffer.writePosition, c.toInt()) + val size = buffer.memory.putUtf8Char(buffer.writePosition, c.code) buffer.commitWritten(size) size } @@ -238,13 +238,13 @@ public abstract class Output internal constructor( return } - val _tail = _tail - if (_tail == null) { + val tail = _tail + if (tail == null) { appendChain(foreignStolen) return } - writePacketMerging(_tail, foreignStolen, packet.pool) + writePacketMerging(tail, foreignStolen, packet.pool) } /** @@ -375,8 +375,8 @@ public abstract class Output internal constructor( close() } - @DangerousInternalIoApi - public fun prepareWriteHead(n: Int): ChunkBuffer { + @PublishedApi + internal fun prepareWriteHead(n: Int): ChunkBuffer { if (tailRemaining >= n) { _tail?.let { it.commitWrittenUntilIndex(tailPosition) @@ -386,8 +386,8 @@ public abstract class Output internal constructor( return appendNewChunk() } - @DangerousInternalIoApi - public fun afterHeadWrite() { + @PublishedApi + internal fun afterHeadWrite() { _tail?.let { tailPosition = it.writePosition } } @@ -422,10 +422,12 @@ public abstract class Output internal constructor( } } +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public fun Output.append(csq: CharSequence, start: Int = 0, end: Int = csq.length): Appendable { return append(csq, start, end) } +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public fun Output.append(csq: CharArray, start: Int = 0, end: Int = csq.size): Appendable { return append(csq, start, end) } @@ -497,8 +499,7 @@ public fun Output.fill(times: Long, value: Byte = 0) { * Depending on the output underlying implementation it could invoke [block] function with the same buffer several times * however it is guaranteed that it is always non-empty. */ -@DangerousInternalIoApi -public inline fun Output.writeWhile(block: (Buffer) -> Boolean) { +internal inline fun Output.writeWhile(block: (Buffer) -> Boolean) { var tail: ChunkBuffer = prepareWriteHead(1, null) try { while (true) { @@ -516,8 +517,7 @@ public inline fun Output.writeWhile(block: (Buffer) -> Boolean) { * bytes space (could be the same buffer as before if it complies to the restriction). * @param initialSize for the first buffer passed to [block] function */ -@DangerousInternalIoApi -public inline fun Output.writeWhileSize(initialSize: Int = 1, block: (Buffer) -> Int) { +internal inline fun Output.writeWhileSize(initialSize: Int = 1, block: (Buffer) -> Int) { var tail = prepareWriteHead(initialSize, null) try { diff --git a/ktor-io/common/src/io/ktor/utils/io/core/OutputLittleEndian.kt b/ktor-io/common/src/io/ktor/utils/io/core/OutputLittleEndian.kt index 64c0640d2b7..862da2498cf 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/OutputLittleEndian.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/OutputLittleEndian.kt @@ -44,6 +44,7 @@ public fun Output.writeDoubleLittleEndian(value: Double) { writePrimitiveTemplate(value, { writeDouble(it) }, { reverseByteOrder() }) } +@OptIn(ExperimentalUnsignedTypes::class) public fun Output.writeFullyLittleEndian(source: UShortArray, offset: Int = 0, length: Int = source.size - offset) { writeFullyLittleEndian(source.asShortArray(), offset, length) } @@ -68,6 +69,7 @@ public fun Buffer.writeDoubleLittleEndian(value: Double) { writePrimitiveTemplate(value, { writeDouble(it) }, { reverseByteOrder() }) } +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.writeFullyLittleEndian(source: UShortArray, offset: Int = 0, length: Int = source.size - offset) { writeFullyLittleEndian(source.asShortArray(), offset, length) } @@ -81,6 +83,7 @@ public fun Output.writeFullyLittleEndian(source: ShortArray, offset: Int = 0, le ) } +@OptIn(ExperimentalUnsignedTypes::class) public fun Output.writeFullyLittleEndian(source: UIntArray, offset: Int = 0, length: Int = source.size - offset) { writeFullyLittleEndian(source.asIntArray(), offset, length) } @@ -94,6 +97,7 @@ public fun Output.writeFullyLittleEndian(source: IntArray, offset: Int = 0, leng ) } +@OptIn(ExperimentalUnsignedTypes::class) public fun Output.writeFullyLittleEndian(source: ULongArray, offset: Int = 0, length: Int = source.size - offset) { writeFullyLittleEndian(source.asLongArray(), offset, length) } @@ -134,6 +138,7 @@ public fun Buffer.writeFullyLittleEndian(source: ShortArray, offset: Int = 0, le ) } +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.writeFullyLittleEndian(source: UIntArray, offset: Int = 0, length: Int = source.size - offset) { writeFullyLittleEndian(source.asIntArray(), offset, length) } @@ -147,6 +152,7 @@ public fun Buffer.writeFullyLittleEndian(source: IntArray, offset: Int = 0, leng ) } +@OptIn(ExperimentalUnsignedTypes::class) public fun Buffer.writeFullyLittleEndian(source: ULongArray, offset: Int = 0, length: Int = source.size - offset) { writeFullyLittleEndian(source.asLongArray(), offset, length) } diff --git a/ktor-io/common/src/io/ktor/utils/io/core/PacketDirect.kt b/ktor-io/common/src/io/ktor/utils/io/core/PacketDirect.kt index 59ef412b2aa..0361f1c0502 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/PacketDirect.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/PacketDirect.kt @@ -2,6 +2,7 @@ package io.ktor.utils.io.core import kotlin.contracts.* +@OptIn(ExperimentalContracts::class) @PublishedApi internal inline fun Input.read(n: Int = 1, block: (Buffer) -> Unit) { contract { diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Preview.kt b/ktor-io/common/src/io/ktor/utils/io/core/Preview.kt index ae4989ecff6..54a43128f3a 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Preview.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Preview.kt @@ -9,7 +9,7 @@ import kotlin.contracts.* * A temporary view packet is passed as argument to [block] function and it shouldn't leak outside of this block * otherwise an unexpected behaviour may occur. */ -@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +@OptIn(ExperimentalContracts::class) public inline fun BytePacketBuilder.preview(block: (tmp: ByteReadPacket) -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) diff --git a/ktor-io/common/src/io/ktor/utils/io/core/Strings.kt b/ktor-io/common/src/io/ktor/utils/io/core/Strings.kt index 0bc8042ce62..8de93d8a516 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/Strings.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/Strings.kt @@ -98,6 +98,7 @@ public fun Input.readUTF8LineTo(out: Appendable, limit: Int): Boolean { * @throws BufferLimitExceededException * @returns a string of characters read before delimiter */ +@Suppress("unused") public fun Input.readUTF8UntilDelimiter(delimiters: String, limit: Int = Int.MAX_VALUE): String { return buildString { readUTF8UntilDelimiterTo(this, delimiters, limit) @@ -146,9 +147,9 @@ public fun Input.readUTF8UntilDelimiterTo(out: Appendable, delimiters: String, l public fun Input.readUTF8UntilDelimiterTo(out: Output, delimiters: String, limit: Int = Int.MAX_VALUE): Int { val delimitersCount = delimiters.length if (delimitersCount == 1 && delimiters[0].isAsciiChar()) { - return readUntilDelimiter(delimiters[0].toByte(), out).toInt() + return readUntilDelimiter(delimiters[0].code.toByte(), out).toInt() } else if (delimitersCount == 2 && delimiters[0].isAsciiChar() && delimiters[1].isAsciiChar()) { - return readUntilDelimiters(delimiters[0].toByte(), delimiters[1].toByte(), out).toInt() + return readUntilDelimiters(delimiters[0].code.toByte(), delimiters[1].code.toByte(), out).toInt() } return readUTFUntilDelimiterToSlowAscii(delimiters, limit, out) @@ -333,7 +334,7 @@ private fun Output.writeTextUtf8(text: CharSequence, fromIndex: Int, toIndex: In internal expect fun String.getCharsInternal(dst: CharArray, dstOffset: Int) @Suppress("NOTHING_TO_INLINE") -private inline fun Char.isAsciiChar() = toInt() <= 0x7f +private inline fun Char.isAsciiChar() = code <= 0x7f private fun Input.readUTFUntilDelimiterToSlowAscii(delimiters: String, limit: Int, out: Output): Int { var decoded = 0 diff --git a/ktor-io/common/src/io/ktor/utils/io/core/internal/ChunkBuffer.kt b/ktor-io/common/src/io/ktor/utils/io/core/internal/ChunkBuffer.kt index 06937bf8523..aac426eb090 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/internal/ChunkBuffer.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/internal/ChunkBuffer.kt @@ -121,8 +121,6 @@ public open class ChunkBuffer( require(origin == null) { "Unable to reset buffer with origin" } super.reset() - @Suppress("DEPRECATION") - attachment = null nextRef.value = null } diff --git a/ktor-io/common/src/io/ktor/utils/io/core/internal/UTF8.kt b/ktor-io/common/src/io/ktor/utils/io/core/internal/UTF8.kt index b0a4d93bfdb..61e31f8c959 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/internal/UTF8.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/internal/UTF8.kt @@ -3,6 +3,7 @@ package io.ktor.utils.io.core.internal import io.ktor.utils.io.bits.* import io.ktor.utils.io.charsets.* import io.ktor.utils.io.core.* +import kotlin.jvm.* internal inline fun Buffer.decodeASCII(consumer: (Char) -> Boolean): Boolean { read { memory, start, endExclusive -> @@ -20,8 +21,7 @@ internal inline fun Buffer.decodeASCII(consumer: (Char) -> Boolean): Boolean { return true } -@DangerousInternalIoApi -public suspend fun decodeUTF8LineLoopSuspend( +internal suspend fun decodeUTF8LineLoopSuspend( out: Appendable, limit: Int, nextChunk: suspend (Int) -> Input? @@ -87,7 +87,6 @@ public suspend fun decodeUTF8LineLoopSuspend( private fun prematureEndOfStreamUtf(size: Int): Nothing = throw EOFException("Premature end of stream: expected $size bytes to decode UTF-8 char") -@DangerousInternalIoApi internal fun byteCountUtf8(firstByte: Int): Int { var byteCount = 0 var mask = 0x80 @@ -113,8 +112,7 @@ internal fun byteCountUtf8(firstByte: Int): Int { * @return number of bytes required to decode incomplete utf8 character or 0 if all bytes were processed * or -1 if consumer rejected loop */ -@DangerousInternalIoApi -public inline fun Buffer.decodeUTF8(consumer: (Char) -> Boolean): Int { +internal inline fun Buffer.decodeUTF8(consumer: (Char) -> Boolean): Int { var byteCount = 0 var value = 0 var lastByteCount = 0 @@ -215,8 +213,9 @@ internal class CharArraySequence( } } -@Suppress("NOTHING_TO_INLINE", "EXPERIMENTAL_FEATURE_WARNING") -internal inline class EncodeResult(val value: Int) { +@Suppress("NOTHING_TO_INLINE") +@JvmInline +internal value class EncodeResult(val value: Int) { constructor(characters: UShort, bytes: UShort) : this(characters.toInt() shl 16 or bytes.toInt()) inline val characters: UShort get() = value.highShort.toUShort() @@ -238,7 +237,7 @@ internal fun Memory.encodeUTF8(text: CharSequence, from: Int, to: Int, dstOffset return EncodeResult((index - from).toUShort(), (resultPosition - dstOffset).toUShort()) } - val character = text[index++].toInt() and 0xffff + val character = text[index++].code and 0xffff if (character and 0xff80 == 0) { storeAt(resultPosition++, character.toByte()) } else { @@ -281,7 +280,7 @@ private fun Memory.encodeUTF8Stage1( codePoint(character, text[index++]) } } - else -> character.toInt() + else -> character.code } val size = putUtf8Char(resultPosition, codepoint) @@ -315,7 +314,7 @@ private fun Memory.encodeUTF8Stage2( val character = text[index++] val codepoint = when { - !character.isHighSurrogate() -> character.toInt() + !character.isHighSurrogate() -> character.code else -> { if (index == lastCharIndex || !text[index].isLowSurrogate()) { 63 @@ -336,33 +335,33 @@ private fun Memory.encodeUTF8Stage2( } @Suppress("NOTHING_TO_INLINE") -private inline fun charactersSize(v: Int) = when { - v in 1..0x7f -> 1 - v in 0x80..0x7ff -> 2 - v in 0x800..0xffff -> 3 - v in 0x10000..0x10ffff -> 4 +private inline fun charactersSize(v: Int) = when (v) { + in 1..0x7f -> 1 + in 0x80..0x7ff -> 2 + in 0x800..0xffff -> 3 + in 0x10000..0x10ffff -> 4 else -> malformedCodePoint(v) } // TODO optimize it, now we are simply do naive encoding here @Suppress("NOTHING_TO_INLINE") -internal inline fun Memory.putUtf8Char(offset: Int, v: Int): Int = when { - v in 0..0x7f -> { +internal inline fun Memory.putUtf8Char(offset: Int, v: Int): Int = when (v) { + in 0..0x7f -> { storeAt(offset, v.toByte()) 1 } - v in 0x80..0x7ff -> { + in 0x80..0x7ff -> { this[offset] = (0xc0 or ((v shr 6) and 0x1f)).toByte() this[offset + 1] = (0x80 or (v and 0x3f)).toByte() 2 } - v in 0x800..0xffff -> { + in 0x800..0xffff -> { this[offset] = (0xe0 or ((v shr 12) and 0x0f)).toByte() this[offset + 1] = (0x80 or ((v shr 6) and 0x3f)).toByte() this[offset + 2] = (0x80 or (v and 0x3f)).toByte() 3 } - v in 0x10000..0x10ffff -> { + in 0x10000..0x10ffff -> { this[offset] = (0xf0 or ((v shr 18) and 0x07)).toByte() // 3 bits this[offset + 1] = (0x80 or ((v shr 12) and 0x3f)).toByte() // 6 bits this[offset + 2] = (0x80 or ((v shr 6) and 0x3f)).toByte() // 6 bits @@ -399,11 +398,8 @@ internal fun lowSurrogate(cp: Int): Int = (cp and 0x3ff) + MinLowSurrogate internal fun highSurrogate(cp: Int): Int = (cp ushr 10) + HighSurrogateMagic internal fun codePoint(high: Char, low: Char): Int { -// check(high.isHighSurrogate()) -// check(low.isLowSurrogate()) - - val highValue = high.toInt() - HighSurrogateMagic - val lowValue = low.toInt() - MinLowSurrogate + val highValue = high.code - HighSurrogateMagic + val lowValue = low.code - MinLowSurrogate return highValue shl 10 or lowValue } diff --git a/ktor-io/common/src/io/ktor/utils/io/core/internal/Unsafe.kt b/ktor-io/common/src/io/ktor/utils/io/core/internal/Unsafe.kt index ee1971b5159..88d3d4d9949 100644 --- a/ktor-io/common/src/io/ktor/utils/io/core/internal/Unsafe.kt +++ b/ktor-io/common/src/io/ktor/utils/io/core/internal/Unsafe.kt @@ -42,11 +42,11 @@ internal fun ByteReadPacket.unsafeAppend(builder: BytePacketBuilder): Int { return builderSize } -@DangerousInternalIoApi -public fun Input.prepareReadFirstHead(minSize: Int): ChunkBuffer? = prepareReadHead(minSize) +@PublishedApi +internal fun Input.prepareReadFirstHead(minSize: Int): ChunkBuffer? = prepareReadHead(minSize) -@DangerousInternalIoApi -public fun Input.completeReadHead(current: ChunkBuffer) { +@PublishedApi +internal fun Input.completeReadHead(current: ChunkBuffer) { when { current === this -> return !current.canRead() -> ensureNext(current) @@ -55,8 +55,8 @@ public fun Input.completeReadHead(current: ChunkBuffer) { } } -@DangerousInternalIoApi -public fun Input.prepareReadNextHead(current: ChunkBuffer): ChunkBuffer? { +@PublishedApi +internal fun Input.prepareReadNextHead(current: ChunkBuffer): ChunkBuffer? { if (current === this) { return if (canRead()) this else null } @@ -64,8 +64,7 @@ public fun Input.prepareReadNextHead(current: ChunkBuffer): ChunkBuffer? { return ensureNextHead(current) } -@DangerousInternalIoApi -public fun Output.prepareWriteHead(capacity: Int, current: ChunkBuffer?): ChunkBuffer { +internal fun Output.prepareWriteHead(capacity: Int, current: ChunkBuffer?): ChunkBuffer { if (current != null) { afterHeadWrite() } diff --git a/ktor-io/common/test/io/ktor/utils/io/ByteBufferChannelScenarioTest.kt b/ktor-io/common/test/io/ktor/utils/io/ByteBufferChannelScenarioTest.kt index 1c0db48e29d..34af68cd104 100644 --- a/ktor-io/common/test/io/ktor/utils/io/ByteBufferChannelScenarioTest.kt +++ b/ktor-io/common/test/io/ktor/utils/io/ByteBufferChannelScenarioTest.kt @@ -5,6 +5,7 @@ import io.ktor.utils.io.core.* import io.ktor.utils.io.core.internal.* import kotlin.test.* +@Suppress("DEPRECATION") open class ByteBufferChannelScenarioTest : ByteChannelTestBase(true) { @Test diff --git a/ktor-io/common/test/io/ktor/utils/io/ByteChannelSessionsTest.kt b/ktor-io/common/test/io/ktor/utils/io/ByteChannelSessionsTest.kt index c3f3657a285..2339a8f3314 100644 --- a/ktor-io/common/test/io/ktor/utils/io/ByteChannelSessionsTest.kt +++ b/ktor-io/common/test/io/ktor/utils/io/ByteChannelSessionsTest.kt @@ -32,7 +32,7 @@ class ByteChannelSessionsTest : ByteChannelTestBase() { 1, ch.read { buffer, start, endExclusive -> assertEquals(3, endExclusive - start) - assertEquals('A'.toByte(), buffer[start]) + assertEquals('A'.code.toByte(), buffer[start]) 1 } ) @@ -41,8 +41,8 @@ class ByteChannelSessionsTest : ByteChannelTestBase() { 2, ch.read { buffer, start, endExclusive -> assertEquals(2, endExclusive - start) - assertEquals('B'.toByte(), buffer[start]) - assertEquals('C'.toByte(), buffer[start + 1]) + assertEquals('B'.code.toByte(), buffer[start]) + assertEquals('C'.code.toByte(), buffer[start + 1]) 2 } ) @@ -93,10 +93,10 @@ class ByteChannelSessionsTest : ByteChannelTestBase() { var textOffset = bytesRead for (index in start until endIndex) { assertEquals( - text[textOffset].toByte(), + text[textOffset].code.toByte(), source[index], "Expected character '${text[textOffset]}', " + - "got '${source[index].toChar()}', index $bytesRead + $index" + "got '${source[index].toInt().toChar()}', index $bytesRead + $index" ) textOffset++ } diff --git a/ktor-io/common/test/io/ktor/utils/io/ByteChannelSmokeTest.kt b/ktor-io/common/test/io/ktor/utils/io/ByteChannelSmokeTest.kt index 404ab5436dc..d042589ef91 100644 --- a/ktor-io/common/test/io/ktor/utils/io/ByteChannelSmokeTest.kt +++ b/ktor-io/common/test/io/ktor/utils/io/ByteChannelSmokeTest.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.* import kotlin.math.* import kotlin.test.* +@Suppress("DEPRECATION") open class ByteChannelSmokeTest : ByteChannelTestBase() { @Test diff --git a/ktor-io/common/test/io/ktor/utils/io/ByteChannelTest.kt b/ktor-io/common/test/io/ktor/utils/io/ByteChannelTest.kt index e70007763ea..aa16a1572b5 100644 --- a/ktor-io/common/test/io/ktor/utils/io/ByteChannelTest.kt +++ b/ktor-io/common/test/io/ktor/utils/io/ByteChannelTest.kt @@ -6,7 +6,6 @@ package io.ktor.utils.io import io.ktor.test.dispatcher.* import io.ktor.utils.io.bits.* -import io.ktor.utils.io.core.* import kotlinx.coroutines.* import kotlin.test.* @@ -121,7 +120,7 @@ class ByteChannelTest { val total = withMemory(1024) { channel.peekTo(it, destinationOffset = 16, min = 1, max = Long.MAX_VALUE) } - assertEquals(1024 - 16, total) + assertEquals(1008L, total) } @Test @@ -137,7 +136,7 @@ class ByteChannelTest { val total = withMemory(1024) { channel.peekTo(it, destinationOffset = 0, offset = 16, min = 1, max = Long.MAX_VALUE) } - assertEquals(1024 - 16, total) + assertEquals(1008L, total) } @Test @@ -153,7 +152,7 @@ class ByteChannelTest { val total = withMemory(1024) { channel.peekTo(it, destinationOffset = 16, offset = 16, min = 1, max = Long.MAX_VALUE) } - assertEquals(1024 - 16, total) + assertEquals(1008L, total) } @Test diff --git a/ktor-io/common/test/io/ktor/utils/io/BytePacketBuildTest.kt b/ktor-io/common/test/io/ktor/utils/io/BytePacketBuildTest.kt index 14d8f187bbf..e854199d27c 100644 --- a/ktor-io/common/test/io/ktor/utils/io/BytePacketBuildTest.kt +++ b/ktor-io/common/test/io/ktor/utils/io/BytePacketBuildTest.kt @@ -37,7 +37,7 @@ open class BytePacketBuildTest { listOf(1, 2, 3).joinTo(this, separator = "|") } - assertEquals(2 + 1 + 2 + 4 + 8 + 4 + 8 + 8 + 3 + 5, p.remaining) + assertEquals(45L, p.remaining) val ba = ByteArray(2) p.readFully(ba) @@ -75,7 +75,7 @@ open class BytePacketBuildTest { listOf(1, 2, 3).joinTo(this, separator = "|") } - assertEquals(9999 + 1 + 2 + 4 + 8 + 4 + 8 + 3 + 5, p.remaining) + assertEquals(10034L, p.remaining) p.readFully(ByteArray(9999)) assertEquals(0x12, p.readByte()) @@ -299,7 +299,7 @@ open class BytePacketBuildTest { val result = ByteArray(length) for (i in 0 until length) { - val v = this[i].toInt() and 0xff + val v = this[i].code and 0xff if (v > 0x7f) fail() result[i] = v.toByte() } @@ -308,6 +308,6 @@ open class BytePacketBuildTest { } companion object { - public const val PACKET_BUFFER_SIZE: Int = 4096 + const val PACKET_BUFFER_SIZE: Int = 4096 } } diff --git a/ktor-io/common/test/io/ktor/utils/io/BytePacketStringTest.kt b/ktor-io/common/test/io/ktor/utils/io/BytePacketStringTest.kt index 497f173f01b..cc8df95e664 100644 --- a/ktor-io/common/test/io/ktor/utils/io/BytePacketStringTest.kt +++ b/ktor-io/common/test/io/ktor/utils/io/BytePacketStringTest.kt @@ -6,7 +6,6 @@ package io.ktor.utils.io import io.ktor.utils.io.charsets.* import io.ktor.utils.io.core.* -import io.ktor.utils.io.core.internal.* import kotlin.test.* open class BytePacketStringTest { @@ -70,7 +69,7 @@ open class BytePacketStringTest { fun testMultiBufferReadText() { val size = 100000 val ba = ByteArray(size) { - 'x'.toByte() + 'x'.code.toByte() } val s = CharArray(size) { 'x' @@ -419,7 +418,7 @@ open class BytePacketStringTest { } try { - assertEquals("\u0422", packet.readTextExactBytes(bytes = 2)) + assertEquals("\u0422", packet.readTextExactBytes(bytesCount = 2)) } finally { packet.release() } @@ -429,7 +428,7 @@ open class BytePacketStringTest { } try { - assertEquals("\u0422e", packet.readTextExactBytes(bytes = 3)) + assertEquals("\u0422e", packet.readTextExactBytes(bytesCount = 3)) } finally { packet.release() } @@ -440,7 +439,7 @@ open class BytePacketStringTest { try { assertFails { - assertEquals("\u0422", packet.readTextExactBytes(bytes = 4)) + assertEquals("\u0422", packet.readTextExactBytes(bytesCount = 4)) } } finally { packet.release() @@ -451,7 +450,7 @@ open class BytePacketStringTest { } try { - val text = packet.readTextExactBytes(bytes = 5) + val text = packet.readTextExactBytes(bytesCount = 5) assertEquals(3, text.length) assertEquals("\u0422e\u0438", text) } finally { @@ -472,7 +471,7 @@ open class BytePacketStringTest { val copied = big.copy() try { - val actual = copied.readTextExactBytes(bytes = i) + val actual = copied.readTextExactBytes(bytesCount = i) assertEquals(i, actual.length) assertTrue { longLine.substring(0, i) == actual } } finally { diff --git a/ktor-io/common/test/io/ktor/utils/io/InputTest.kt b/ktor-io/common/test/io/ktor/utils/io/InputTest.kt index d7129dbf01d..ba711fa09df 100644 --- a/ktor-io/common/test/io/ktor/utils/io/InputTest.kt +++ b/ktor-io/common/test/io/ktor/utils/io/InputTest.kt @@ -60,7 +60,7 @@ class InputTest { if (items.isEmpty()) return 0 val next = items.removeAt(0) for (index in 0 until next.length) { - destination[offset + index] = next[index].toByte() + destination[offset + index] = next[index].code.toByte() } return next.length } diff --git a/ktor-io/common/test/io/ktor/utils/io/OutputTest.kt b/ktor-io/common/test/io/ktor/utils/io/OutputTest.kt index 5118707b33d..337a6a65947 100644 --- a/ktor-io/common/test/io/ktor/utils/io/OutputTest.kt +++ b/ktor-io/common/test/io/ktor/utils/io/OutputTest.kt @@ -43,13 +43,13 @@ class OutputTest { val fromHead = ChunkBuffer.Pool.borrow() var current = fromHead repeat(3) { - current.append("test $it. ") + current.appendChars("test $it. ") val next = ChunkBuffer.Pool.borrow() current.next = next current = next } - current.append("end.") + current.appendChars("end.") val from = ByteReadPacket(fromHead, ChunkBuffer.Pool) diff --git a/ktor-io/common/test/io/ktor/utils/io/PrimitiveArraysTest.kt b/ktor-io/common/test/io/ktor/utils/io/PrimitiveArraysTest.kt index 14e692fb827..5f62238c727 100644 --- a/ktor-io/common/test/io/ktor/utils/io/PrimitiveArraysTest.kt +++ b/ktor-io/common/test/io/ktor/utils/io/PrimitiveArraysTest.kt @@ -5,6 +5,7 @@ import io.ktor.utils.io.core.internal.* import kotlin.require import kotlin.test.* +@Suppress("EXPERIMENTAL_API_USAGE") class PrimitiveArraysTest { private val pool = VerifyingChunkBufferPool() private val view = pool.borrow() diff --git a/ktor-io/common/test/io/ktor/utils/io/PrimitiveCodecTest.kt b/ktor-io/common/test/io/ktor/utils/io/PrimitiveCodecTest.kt index a70a65a5c4c..62cb4aa2ff8 100644 --- a/ktor-io/common/test/io/ktor/utils/io/PrimitiveCodecTest.kt +++ b/ktor-io/common/test/io/ktor/utils/io/PrimitiveCodecTest.kt @@ -5,6 +5,7 @@ import io.ktor.utils.io.core.internal.* import kotlin.math.* import kotlin.test.* +@Suppress("EXPERIMENTAL_API_USAGE") class PrimitiveCodecTest { val pool = VerifyingChunkBufferPool() val builder = BytePacketBuilder(0, pool) diff --git a/ktor-io/common/test/io/ktor/utils/io/ReadBufferTest.kt b/ktor-io/common/test/io/ktor/utils/io/ReadBufferTest.kt index e00bf2c5e29..d065376d62f 100644 --- a/ktor-io/common/test/io/ktor/utils/io/ReadBufferTest.kt +++ b/ktor-io/common/test/io/ktor/utils/io/ReadBufferTest.kt @@ -17,7 +17,7 @@ class ReadBufferTest { reserveEndGap(8) repeat(writeRemaining) { index -> - append(charForIndex(index)) + writeByte(charForIndex(index).code.toByte()) } } private val initialBufferSize = buffer.readRemaining @@ -51,7 +51,7 @@ class ReadBufferTest { val expected = byteArrayOf(0x7f) + (offset until offset + size).map { - charForIndex(it).toByte() + charForIndex(it).code.toByte() }.toByteArray() + byteArrayOf(0x7f) assertEquals(expected.hexdump(), dst.hexdump()) @@ -75,7 +75,7 @@ class ReadBufferTest { val expected = byteArrayOf(0x7f) + (offset until offset + size).map { - charForIndex(it).toByte() + charForIndex(it).code.toByte() }.toByteArray() + byteArrayOf(0x7f) assertEquals(expected.hexdump(), dst.hexdump()) @@ -99,7 +99,7 @@ class ReadBufferTest { val rc = buffer.readAvailable(dst, size) assertEquals(size, rc) - val expected = (offset until offset + size).map { charForIndex(it).toByte() }.toByteArray() + val expected = (offset until offset + size).map { charForIndex(it).code.toByte() }.toByteArray() assertEquals(expected.hexdump(), dst.readBytes().hexdump()) } finally { @@ -124,7 +124,7 @@ class ReadBufferTest { assertEquals(initialBufferSize - offset, buffer.readRemaining) buffer.readFully(dst, size) - val expected = (offset until offset + size).map { charForIndex(it).toByte() }.toByteArray() + val expected = (offset until offset + size).map { charForIndex(it).code.toByte() }.toByteArray() assertEquals(expected.hexdump(), dst.readBytes().hexdump()) } finally { @@ -151,7 +151,7 @@ class ReadBufferTest { val expected = byteArrayOf(0x7f) + (offset until offset + size).map { - charForIndex(it).toByte() + charForIndex(it).code.toByte() }.toByteArray() + byteArrayOf(0x7f) assertEquals(expected.hexdump(), dst.hexdump()) @@ -175,7 +175,7 @@ class ReadBufferTest { val expected = byteArrayOf(0x7f) + (offset until offset + size).map { - charForIndex(it).toByte() + charForIndex(it).code.toByte() }.toByteArray() + byteArrayOf(0x7f) assertEquals(expected.hexdump(), dst.hexdump()) @@ -199,7 +199,7 @@ class ReadBufferTest { val rc = packet.readAvailable(dst, size) assertEquals(size, rc) - val expected = (offset until offset + size).map { charForIndex(it).toByte() }.toByteArray() + val expected = (offset until offset + size).map { charForIndex(it).code.toByte() }.toByteArray() assertEquals(expected.hexdump(), dst.readBytes().hexdump()) } finally { @@ -224,7 +224,7 @@ class ReadBufferTest { assertEquals(initialPacketSize - offset, packet.remaining) packet.readFully(dst, size) - val expected = (offset until offset + size).map { charForIndex(it).toByte() }.toByteArray() + val expected = (offset until offset + size).map { charForIndex(it).code.toByte() }.toByteArray() assertEquals(expected.hexdump(), dst.readBytes().hexdump()) } finally { diff --git a/ktor-io/common/test/io/ktor/utils/io/ReaderTest.kt b/ktor-io/common/test/io/ktor/utils/io/ReaderTest.kt index 1bf186a797b..389e482fa89 100644 --- a/ktor-io/common/test/io/ktor/utils/io/ReaderTest.kt +++ b/ktor-io/common/test/io/ktor/utils/io/ReaderTest.kt @@ -10,10 +10,11 @@ import kotlin.test.* class ReaderTest { + @OptIn(DelicateCoroutinesApi::class) @Test fun testCancelExceptionLoggedOnce() = testSuspend { var failInHandler = false - val handler = CoroutineExceptionHandler { coroutineContext, throwable -> + val handler = CoroutineExceptionHandler { _, _ -> failInHandler = true } diff --git a/ktor-io/common/test/io/ktor/utils/io/UnconfinedTests.kt b/ktor-io/common/test/io/ktor/utils/io/UnconfinedTests.kt index ed5eb9d6d3a..fef7ea0c203 100644 --- a/ktor-io/common/test/io/ktor/utils/io/UnconfinedTests.kt +++ b/ktor-io/common/test/io/ktor/utils/io/UnconfinedTests.kt @@ -9,8 +9,10 @@ import kotlinx.coroutines.* import kotlin.coroutines.* import kotlin.test.* +@Suppress("DEPRECATION") class UnconfinedTests { + @OptIn(DelicateCoroutinesApi::class) @Test fun testReaderPropagation() { var resumed = false diff --git a/ktor-io/js/src/io/ktor/utils/io/ByteWriteChannelJs.kt b/ktor-io/js/src/io/ktor/utils/io/ByteWriteChannelJs.kt index 1257e3afa20..68b60bea9ce 100644 --- a/ktor-io/js/src/io/ktor/utils/io/ByteWriteChannelJs.kt +++ b/ktor-io/js/src/io/ktor/utils/io/ByteWriteChannelJs.kt @@ -104,7 +104,6 @@ public actual interface ByteWriteChannel { */ public actual suspend fun writeFloat(f: Float) - @ExperimentalIoApi public actual suspend fun awaitFreeSpace() /** diff --git a/ktor-io/js/src/io/ktor/utils/io/NativeUtilsJs.kt b/ktor-io/js/src/io/ktor/utils/io/NativeUtilsJs.kt index a67c5a656a0..8851c5b9533 100644 --- a/ktor-io/js/src/io/ktor/utils/io/NativeUtilsJs.kt +++ b/ktor-io/js/src/io/ktor/utils/io/NativeUtilsJs.kt @@ -4,12 +4,8 @@ package io.ktor.utils.io -import io.ktor.utils.io.core.internal.* - -@DangerousInternalIoApi public actual fun Any.preventFreeze() { } -@DangerousInternalIoApi public actual fun Any.makeShared() { } diff --git a/ktor-io/js/src/io/ktor/utils/io/bits/MemoryFactoryJs.kt b/ktor-io/js/src/io/ktor/utils/io/bits/MemoryFactoryJs.kt index 0e56e051264..d39d3318d82 100644 --- a/ktor-io/js/src/io/ktor/utils/io/bits/MemoryFactoryJs.kt +++ b/ktor-io/js/src/io/ktor/utils/io/bits/MemoryFactoryJs.kt @@ -10,6 +10,7 @@ import kotlin.contracts.* * By default, if neither [offset] nor [length] specified, the whole array is used. * An instance of [Memory] provided into the [block] should be never captured and used outside of lambda. */ +@OptIn(ExperimentalContracts::class) public actual inline fun ByteArray.useMemory(offset: Int, length: Int, block: (Memory) -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) diff --git a/ktor-io/js/src/io/ktor/utils/io/bits/MemoryJs.kt b/ktor-io/js/src/io/ktor/utils/io/bits/MemoryJs.kt index 15dca0f882a..8666e342151 100644 --- a/ktor-io/js/src/io/ktor/utils/io/bits/MemoryJs.kt +++ b/ktor-io/js/src/io/ktor/utils/io/bits/MemoryJs.kt @@ -9,7 +9,7 @@ import kotlin.require /** * Represents a linear range of bytes. */ -public actual class Memory @DangerousInternalIoApi constructor(public val view: DataView) { +public actual class Memory constructor(public val view: DataView) { /** * Size of memory range in bytes. */ diff --git a/ktor-io/js/src/io/ktor/utils/io/charsets/CharsetJS.kt b/ktor-io/js/src/io/ktor/utils/io/charsets/CharsetJS.kt index 685286aeba9..7301f42fd91 100644 --- a/ktor-io/js/src/io/ktor/utils/io/charsets/CharsetJS.kt +++ b/ktor-io/js/src/io/ktor/utils/io/charsets/CharsetJS.kt @@ -9,6 +9,7 @@ public actual abstract class Charset(internal val _name: String) { public actual abstract fun newDecoder(): CharsetDecoder public actual companion object { + @Suppress("LocalVariableName") public actual fun forName(name: String): Charset { if (name == "UTF-8" || name == "utf-8" || name == "UTF8" || name == "utf8") return Charsets.UTF_8 if (name == "ISO-8859-1" || name == "iso-8859-1" || @@ -25,7 +26,7 @@ public actual abstract class Charset(internal val _name: String) { public actual fun isSupported(charset: String): Boolean = when { charset == "UTF-8" || charset == "utf-8" || charset == "UTF8" || charset == "utf8" -> true charset == "ISO-8859-1" || charset == "iso-8859-1" || charset.replace('_', '-').let { - it == "iso-8859-1" || it.toLowerCase() == "iso-8859-1" + it == "iso-8859-1" || it.lowercase() == "iso-8859-1" } || charset == "latin1" -> true else -> false } diff --git a/ktor-io/js/src/io/ktor/utils/io/charsets/ISO88591.kt b/ktor-io/js/src/io/ktor/utils/io/charsets/ISO88591.kt index 832a60bfbcc..bef05a2a458 100644 --- a/ktor-io/js/src/io/ktor/utils/io/charsets/ISO88591.kt +++ b/ktor-io/js/src/io/ktor/utils/io/charsets/ISO88591.kt @@ -10,7 +10,7 @@ internal fun encodeISO88591(input: CharSequence, fromIndex: Int, toIndex: Int, d val i8 = Int8Array(view.buffer, view.byteOffset, view.byteLength) var writeIndex = 0 for (index in fromIndex until toIndex) { - val character = input[index].toInt() + val character = input[index].code if (character > 0xff) { failedToMapError(character) } diff --git a/ktor-io/js/src/io/ktor/utils/io/concurrent/SharedJs.kt b/ktor-io/js/src/io/ktor/utils/io/concurrent/SharedJs.kt index 0cd03a948a3..7a817f10106 100644 --- a/ktor-io/js/src/io/ktor/utils/io/concurrent/SharedJs.kt +++ b/ktor-io/js/src/io/ktor/utils/io/concurrent/SharedJs.kt @@ -4,7 +4,6 @@ package io.ktor.utils.io.concurrent -import io.ktor.utils.io.core.internal.* import kotlin.properties.* import kotlin.reflect.* @@ -18,7 +17,6 @@ import kotlin.reflect.* * ``` */ @Suppress("NOTHING_TO_INLINE") -@DangerousInternalIoApi public actual inline fun shared(value: T): ReadWriteProperty = object : ReadWriteProperty { private var value: T = value @@ -37,6 +35,5 @@ public actual inline fun shared(value: T): ReadWriteProperty = objec * * This reference is allowed to use only from creation thread. Otherwise it will return null. */ -@DangerousInternalIoApi public actual fun threadLocal(value: T): ReadOnlyProperty = - ReadOnlyProperty { thisRef, property -> value } + ReadOnlyProperty { _, _ -> value } diff --git a/ktor-io/js/src/io/ktor/utils/io/core/BufferUtilsJs.kt b/ktor-io/js/src/io/ktor/utils/io/core/BufferUtilsJs.kt index 522bd7449f2..6722e58322a 100644 --- a/ktor-io/js/src/io/ktor/utils/io/core/BufferUtilsJs.kt +++ b/ktor-io/js/src/io/ktor/utils/io/core/BufferUtilsJs.kt @@ -64,6 +64,7 @@ public fun Buffer.writeFully(src: ArrayBufferView, offset: Int = 0, length: Int } } +@OptIn(ExperimentalContracts::class) public inline fun Buffer.writeDirect(block: (DataView) -> Int): Int { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -74,6 +75,7 @@ public inline fun Buffer.writeDirect(block: (DataView) -> Int): Int { } } +@OptIn(ExperimentalContracts::class) public inline fun Buffer.readDirect(block: (DataView) -> Int): Int { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -84,6 +86,7 @@ public inline fun Buffer.readDirect(block: (DataView) -> Int): Int { } } +@OptIn(ExperimentalContracts::class) public inline fun Buffer.writeDirectInt8Array(block: (Int8Array) -> Int): Int { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -94,6 +97,7 @@ public inline fun Buffer.writeDirectInt8Array(block: (Int8Array) -> Int): Int { } } +@OptIn(ExperimentalContracts::class) public inline fun Buffer.readDirectInt8Array(block: (Int8Array) -> Int): Int { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) diff --git a/ktor-io/js/src/io/ktor/utils/io/core/InputArraysJS.kt b/ktor-io/js/src/io/ktor/utils/io/core/InputArraysJS.kt index 9b6542d855a..383b683d8fe 100644 --- a/ktor-io/js/src/io/ktor/utils/io/core/InputArraysJS.kt +++ b/ktor-io/js/src/io/ktor/utils/io/core/InputArraysJS.kt @@ -1,8 +1,8 @@ package io.ktor.utils.io.core -import io.ktor.utils.io.core.internal.* import org.khronos.webgl.* +@Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE") public fun Input.readFully(dst: Int8Array, offset: Int = 0, length: Int = dst.length - offset) { readFully(dst as ArrayBufferView, offset, length) } @@ -28,6 +28,7 @@ public fun Input.readFully(dst: ArrayBufferView, byteOffset: Int = 0, byteLength return readFully(dst.buffer, dst.byteOffset + byteOffset, byteLength) } +@Suppress("unused") public fun Input.readAvailable(dst: Int8Array, offset: Int = 0, length: Int = dst.length - offset): Int { val remaining = remaining if (remaining == 0L) return -1 @@ -44,6 +45,7 @@ public fun Input.readAvailable(dst: ArrayBuffer, offset: Int = 0, length: Int = return size } +@Suppress("unused") public fun Input.readAvailable( dst: ArrayBufferView, byteOffset: Int = 0, diff --git a/ktor-io/js/src/io/ktor/utils/io/js/Decoder.kt b/ktor-io/js/src/io/ktor/utils/io/js/Decoder.kt index 341128fbe58..b9910ec66f8 100644 --- a/ktor-io/js/src/io/ktor/utils/io/js/Decoder.kt +++ b/ktor-io/js/src/io/ktor/utils/io/js/Decoder.kt @@ -18,6 +18,7 @@ internal interface Decoder { fun decode(buffer: ArrayBufferView, options: dynamic): String } +@Suppress("NOTHING_TO_INLINE") internal inline fun Decoder.decodeStream(buffer: ArrayBufferView, stream: Boolean): String { decodeWrap { return decode(buffer, decodeOptions(stream)) diff --git a/ktor-io/js/src/io/ktor/utils/io/js/TextDecoderFallback.kt b/ktor-io/js/src/io/ktor/utils/io/js/TextDecoderFallback.kt index 5aaaa6afa1a..d50452f4651 100644 --- a/ktor-io/js/src/io/ktor/utils/io/js/TextDecoderFallback.kt +++ b/ktor-io/js/src/io/ktor/utils/io/js/TextDecoderFallback.kt @@ -40,7 +40,7 @@ internal class TextDecoderFallback( ) : Decoder { init { - val requestedEncoding = encoding.trim().toLowerCase() + val requestedEncoding = encoding.trim().lowercase() check(ENCODING_ALIASES.contains(requestedEncoding)) { "$encoding is not supported." } } diff --git a/ktor-io/js/test/io/ktor/utils/io/TextDecoderFallbackTest.kt b/ktor-io/js/test/io/ktor/utils/io/TextDecoderFallbackTest.kt index 2f7f55a297c..3a405fb3fc5 100644 --- a/ktor-io/js/test/io/ktor/utils/io/TextDecoderFallbackTest.kt +++ b/ktor-io/js/test/io/ktor/utils/io/TextDecoderFallbackTest.kt @@ -13,7 +13,7 @@ class TextDecoderFallbackTest { @Test fun testReplacement() { val origin = byteArrayOf(0x81.toByte(), 0x8F.toByte(), 0x90.toByte()) - val jsArray = origin as Int8Array + val jsArray = origin.unsafeCast() val fatalDecoder = TextDecoderFallback("ISO-8859-1", fatal = true) val decoder = TextDecoderFallback("ISO-8859-1", fatal = false) @@ -31,7 +31,7 @@ class TextDecoderFallbackTest { val asciiArray = (0x20..0x7E).toList().map { it.toByte() }.toByteArray() val decoder = TextDecoderFallback("ISO-8859-1", fatal = false) - val decoded = decoder.decode(asciiArray as Int8Array) + val decoded = decoder.decode(asciiArray.unsafeCast()) assertEquals( " !\"#\$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", diff --git a/ktor-io/jvm/src/io/ktor/utils/io/ByteBufferChannel.kt b/ktor-io/jvm/src/io/ktor/utils/io/ByteBufferChannel.kt index ac5c95ff6a9..3f82ee663d8 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/ByteBufferChannel.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/ByteBufferChannel.kt @@ -22,6 +22,7 @@ internal const val DEFAULT_CLOSE_MESSAGE: String = "Byte channel was closed" private const val BYTE_BUFFER_CAPACITY: Int = 4088 // implementation for ByteChannel +@Suppress("DEPRECATION", "OverridingDeprecatedMember") internal open class ByteBufferChannel( override val autoFlush: Boolean, private val pool: ObjectPool = BufferObjectPool, @@ -286,8 +287,11 @@ internal open class ByteBufferChannel( private fun setupStateForRead(): ByteBuffer? { val newState = _state.updateAndGet { state -> when (state) { - ReadWriteBufferState.Terminated -> closed?.cause?.let { rethrowClosed(it) } ?: return null - ReadWriteBufferState.IdleEmpty -> closed?.cause?.let { rethrowClosed(it) } ?: return null + ReadWriteBufferState.Terminated, + ReadWriteBufferState.IdleEmpty -> { + val cause = closed?.cause ?: return null + rethrowClosed(cause) + } else -> { closed?.cause?.let { rethrowClosed(it) } if (state.capacity.availableForRead == 0) return null @@ -1022,7 +1026,6 @@ internal open class ByteBufferChannel( } } - @ExperimentalIoApi override suspend fun awaitFreeSpace() { writeSuspend(1) } @@ -1593,7 +1596,6 @@ internal open class ByteBufferChannel( writeSession.complete() } - @ExperimentalIoApi override fun readSession(consumer: ReadSession.() -> Unit) { lookAhead { try { @@ -1604,7 +1606,6 @@ internal open class ByteBufferChannel( } } - @ExperimentalIoApi override suspend fun readSuspendableSession(consumer: suspend SuspendableReadSession.() -> Unit) { lookAheadSuspend { try { @@ -1805,7 +1806,6 @@ internal open class ByteBufferChannel( private val writeSession = WriteSessionImpl(this) - @ExperimentalIoApi override suspend fun writeSuspendSession(visitor: suspend WriterSuspendSession.() -> Unit) { val session = writeSession @@ -2037,7 +2037,7 @@ internal open class ByteBufferChannel( val buffer = request(0, 1) when { buffer != null -> { - if (buffer.get() != '\r'.toByte()) { + if (buffer.get() != '\r'.code.toByte()) { buffer.position(buffer.position() - 1) throw TooLongLineException("Line is longer than limit") } diff --git a/ktor-io/jvm/src/io/ktor/utils/io/ByteChannel.kt b/ktor-io/jvm/src/io/ktor/utils/io/ByteChannel.kt index 7634937da67..47112ba1861 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/ByteChannel.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/ByteChannel.kt @@ -23,7 +23,6 @@ public actual fun ByteReadChannel(content: ByteArray, offset: Int, length: Int): * Creates buffered channel for asynchronous reading and writing of sequences of bytes using [close] function to close * channel. */ -@ExperimentalIoApi public fun ByteChannel(autoFlush: Boolean = false, exceptionMapper: (Throwable?) -> Throwable?): ByteChannel = object : ByteBufferChannel(autoFlush = autoFlush) { diff --git a/ktor-io/jvm/src/io/ktor/utils/io/ByteChannelSequentialJVM.kt b/ktor-io/jvm/src/io/ktor/utils/io/ByteChannelSequentialJVM.kt index d60bc747ba3..2570b3809b3 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/ByteChannelSequentialJVM.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/ByteChannelSequentialJVM.kt @@ -6,8 +6,7 @@ import kotlinx.coroutines.* import kotlinx.coroutines.channels.* import java.nio.* -@Suppress("EXPERIMENTAL_FEATURE_WARNING") -@ExperimentalIoApi +@Suppress("DEPRECATION", "OverridingDeprecatedMember") public class ByteChannelSequentialJVM( initial: ChunkBuffer, autoFlush: Boolean @@ -97,7 +96,7 @@ public class ByteChannelSequentialJVM( prepareFlushedBytes() - var result = 0 + var result: Int readable.readDirect(min) { val position = it.position() block(it) @@ -210,7 +209,7 @@ public class ByteChannelSequentialJVM( return 0 } - var result = 0 + var result: Int writable.writeDirect(min) { val position = it.position() block(it) @@ -236,7 +235,7 @@ public class ByteChannelSequentialJVM( throw closedCause ?: ClosedSendChannelException("Channel closed for write") } - var shouldContinue: Boolean = false + var shouldContinue: Boolean awaitAtLeastNBytesAvailableForWrite(1) val result = writable.writeByteBufferDirect(1) { shouldContinue = block(it) diff --git a/ktor-io/jvm/src/io/ktor/utils/io/ByteWriteChannel.kt b/ktor-io/jvm/src/io/ktor/utils/io/ByteWriteChannel.kt index cf267097c59..fd16b460d56 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/ByteWriteChannel.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/ByteWriteChannel.kt @@ -169,7 +169,6 @@ public actual interface ByteWriteChannel { */ public actual fun flush() - @ExperimentalIoApi public actual suspend fun awaitFreeSpace() public actual suspend fun writeFully(src: Buffer) diff --git a/ktor-io/jvm/src/io/ktor/utils/io/Delimited.kt b/ktor-io/jvm/src/io/ktor/utils/io/Delimited.kt index 9f5c646ef25..7f93e345d84 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/Delimited.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/Delimited.kt @@ -14,6 +14,7 @@ import java.nio.* * * @return non-negative number of copied bytes, possibly 0 */ +@Suppress("DEPRECATION") public suspend fun ByteReadChannel.readUntilDelimiter(delimiter: ByteBuffer, dst: ByteBuffer): Int { require(delimiter.hasRemaining()) require(delimiter !== dst) @@ -38,6 +39,7 @@ public suspend fun ByteReadChannel.readUntilDelimiter(delimiter: ByteBuffer, dst else readUntilDelimiterSuspend(delimiter, dst, copied) } +@Suppress("DEPRECATION") public suspend fun ByteReadChannel.skipDelimiter(delimiter: ByteBuffer) { require(delimiter.hasRemaining()) @@ -52,6 +54,7 @@ public suspend fun ByteReadChannel.skipDelimiter(delimiter: ByteBuffer) { } } +@Suppress("DEPRECATION") private suspend fun ByteReadChannel.skipDelimiterSuspend(delimiter: ByteBuffer) { lookAheadSuspend { awaitAtLeast(delimiter.remaining()) @@ -59,6 +62,7 @@ private suspend fun ByteReadChannel.skipDelimiterSuspend(delimiter: ByteBuffer) } } +@Suppress("DEPRECATION") private suspend fun ByteReadChannel.readUntilDelimiterSuspend( delimiter: ByteBuffer, dst: ByteBuffer, @@ -108,6 +112,7 @@ private suspend fun ByteReadChannel.readUntilDelimiterSuspend( * @return a positive number of bytes copied if no [delimiter] found yet or a negated number of bytes copied if * the delimited has been found, or 0 if no buffer available (not yet ready or EOF) */ +@Suppress("DEPRECATION") private fun LookAheadSession.tryCopyUntilDelimiter(delimiter: ByteBuffer, dst: ByteBuffer): Int { var endFound = false val buffer = request(0, 1) ?: return 0 @@ -143,6 +148,7 @@ private fun LookAheadSession.tryCopyUntilDelimiter(delimiter: ByteBuffer, dst: B return if (endFound) -size else size } +@Suppress("DEPRECATION") private fun LookAheadSession.tryEnsureDelimiter(delimiter: ByteBuffer): Int { val found = startsWithDelimiter(delimiter) if (found == -1) throw IOException("Failed to skip delimiter: actual bytes differ from delimiter bytes") @@ -155,6 +161,7 @@ private fun LookAheadSession.tryEnsureDelimiter(delimiter: ByteBuffer): Int { /** * @return Number of bytes of the delimiter found (possibly 0 if no bytes available yet) or -1 if it doesn't start */ +@Suppress("DEPRECATION") private fun LookAheadSession.startsWithDelimiter(delimiter: ByteBuffer): Int { val buffer = request(0, 1) ?: return 0 val index = buffer.indexOfPartial(delimiter) diff --git a/ktor-io/jvm/src/io/ktor/utils/io/ExceptionUtilsJvm.kt b/ktor-io/jvm/src/io/ktor/utils/io/ExceptionUtilsJvm.kt index f2ffcd71612..b0c9c720624 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/ExceptionUtilsJvm.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/ExceptionUtilsJvm.kt @@ -33,7 +33,7 @@ private val exceptionCtors: WeakHashMap, Ctor> = WeakHashMa /** * Try copy [exception] using [cause] as cause. */ -@DangerousInternalIoApi +@Suppress("UNCHECKED_CAST") @OptIn(ExperimentalCoroutinesApi::class) public fun tryCopyException(exception: E, cause: Throwable): E? { // Fast path for CopyableThrowable diff --git a/ktor-io/jvm/src/io/ktor/utils/io/LookAheadSession.kt b/ktor-io/jvm/src/io/ktor/utils/io/LookAheadSession.kt index 48437322fc6..9c8fe3c44cc 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/LookAheadSession.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/LookAheadSession.kt @@ -23,6 +23,7 @@ public interface LookAheadSession { public fun request(skip: Int, atLeast: Int): ByteBuffer? } +@Suppress("DEPRECATION") @Deprecated("Use read { } instead.") public interface LookAheadSuspendSession : LookAheadSession { /** @@ -32,7 +33,7 @@ public interface LookAheadSuspendSession : LookAheadSession { public suspend fun awaitAtLeast(n: Int): Boolean } -@ExperimentalIoApi +@Suppress("DEPRECATION") public inline fun LookAheadSession.consumeEachRemaining(visitor: (ByteBuffer) -> Boolean) { do { val cont = request(0, 1)?.let { @@ -46,8 +47,7 @@ public inline fun LookAheadSession.consumeEachRemaining(visitor: (ByteBuffer) -> } while (true) } -@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE") -@ExperimentalIoApi +@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE", "DEPRECATION") public suspend inline fun LookAheadSuspendSession.consumeEachRemaining(visitor: suspend (ByteBuffer) -> Boolean) { do { val buffer = request(0, 1) diff --git a/ktor-io/jvm/src/io/ktor/utils/io/NativeUtilsJvm.kt b/ktor-io/jvm/src/io/ktor/utils/io/NativeUtilsJvm.kt index a67c5a656a0..4e3ff0f2552 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/NativeUtilsJvm.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/NativeUtilsJvm.kt @@ -6,10 +6,8 @@ package io.ktor.utils.io import io.ktor.utils.io.core.internal.* -@DangerousInternalIoApi public actual fun Any.preventFreeze() { } -@DangerousInternalIoApi public actual fun Any.makeShared() { } diff --git a/ktor-io/jvm/src/io/ktor/utils/io/bits/MemoryFactoryJvm.kt b/ktor-io/jvm/src/io/ktor/utils/io/bits/MemoryFactoryJvm.kt index 60b03b7ac21..9f318326437 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/bits/MemoryFactoryJvm.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/bits/MemoryFactoryJvm.kt @@ -12,6 +12,7 @@ import kotlin.contracts.* * By default, if neither [offset] nor [length] specified, the whole array is used. * An instance of [Memory] provided into the [block] should be never captured and used outside of lambda. */ +@OptIn(ExperimentalContracts::class) public actual inline fun ByteArray.useMemory(offset: Int, length: Int, block: (Memory) -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) diff --git a/ktor-io/jvm/src/io/ktor/utils/io/bits/MemoryJvm.kt b/ktor-io/jvm/src/io/ktor/utils/io/bits/MemoryJvm.kt index 95d6043bc7f..ee0b034965f 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/bits/MemoryJvm.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/bits/MemoryJvm.kt @@ -6,7 +6,8 @@ import io.ktor.utils.io.core.internal.* import java.nio.* @Suppress("ACTUAL_WITHOUT_EXPECT", "EXPERIMENTAL_FEATURE_WARNING") -public actual inline class Memory @DangerousInternalIoApi constructor(public val buffer: ByteBuffer) { +@JvmInline +public actual value class Memory constructor(public val buffer: ByteBuffer) { /** * Size of memory range in bytes. diff --git a/ktor-io/jvm/src/io/ktor/utils/io/charsets/Strings.kt b/ktor-io/jvm/src/io/ktor/utils/io/charsets/Strings.kt index 8164ba3db32..9ce64f6fe66 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/charsets/Strings.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/charsets/Strings.kt @@ -31,7 +31,7 @@ private fun ByteBuffer.decodeASCII3_array(out: CharArray, offset: Int, length: I val b = array[srcPos] if (b < 0) break - out[pos] = b.toChar() + out[pos] = b.toInt().toChar() pos++ srcPos++ @@ -60,7 +60,7 @@ private fun ByteBuffer.decodeASCII3_buffer(out: CharArray, offset: Int, length: pushBack = true break } - out[pos] = b.toChar() + out[pos] = b.toInt().toChar() pos++ } } @@ -89,7 +89,7 @@ private inline fun ByteBuffer.decodeASCII3_array( val b = array[srcPos] if (b < 0) break - val ch = b.toChar() + val ch = b.toInt().toChar() if (!predicate(ch)) { srcPos-- break @@ -128,7 +128,7 @@ private inline fun ByteBuffer.decodeASCII3_buffer( pushBack = true break } - val ch = b.toChar() + val ch = b.toInt().toChar() if (!predicate(ch)) { pushBack = true break diff --git a/ktor-io/jvm/src/io/ktor/utils/io/charsets/UTF.kt b/ktor-io/jvm/src/io/ktor/utils/io/charsets/UTF.kt index 1698e5853f1..7b79fc0e2e7 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/charsets/UTF.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/charsets/UTF.kt @@ -1,21 +1,13 @@ package io.ktor.utils.io.charsets -import io.ktor.utils.io.core.* -import io.ktor.utils.io.core.internal.* import java.nio.* -@DangerousInternalIoApi -public fun decodeUtf8Result(numberOfChars: Int, requireBytes: Int): Long = +internal fun decodeUtf8Result(numberOfChars: Int, requireBytes: Int): Long = numberOfChars.toLong() shl 32 or (requireBytes.toLong() and 0xffffffffL) -internal fun decodeUtf8ResultAcc(predecoded: Int, result: Long): Long = - decodeUtf8Result(predecoded + (result shr 32).toInt(), (result and 0xffffffffL).toInt()) +internal fun decodeUtf8ResultAcc(preDecoded: Int, result: Long): Long = + decodeUtf8Result(preDecoded + (result shr 32).toInt(), (result and 0xffffffffL).toInt()) -@DangerousInternalIoApi -public fun decodeUtf8ResultCombine(prev: Long, next: Long): Long = - ((prev and 0xffffffffL.inv()) + (next and 0xffffffffL.inv())) or (next and 0xffffffffL) - -@ExperimentalIoApi public fun ByteBuffer.decodeUTF(out: CharArray, offset: Int, length: Int): Long { val decoded = decodeASCII(out, offset, length) @@ -30,7 +22,6 @@ public fun ByteBuffer.decodeUTF(out: CharArray, offset: Int, length: Int): Long * @return packed number of decoded characters to [out] buffer (highest 32 bits) and number of bytes required * to decode the next character, or 0 if buffer has been decoded completely or -1 if end of line has been encountered */ -@ExperimentalIoApi public fun ByteBuffer.decodeUTF8Line(out: CharArray, offset: Int = 0, length: Int = out.size): Long { return when { hasArray() -> decodeUTF8Line_array(out, offset, length) @@ -129,7 +120,7 @@ private fun ByteBuffer.decodeUTF8Line_buffer(out: CharArray, offset: Int, length * @see [decodeUtf8Result] */ private fun ByteBuffer.decodeUTF8_array(out: CharArray, offset: Int, length: Int): Long { - val array = array()!! + val array = array() var srcPos = arrayOffset() + position() val srcEnd = srcPos + remaining() @@ -147,7 +138,7 @@ private fun ByteBuffer.decodeUTF8_array(out: CharArray, offset: Int, length: Int when { v >= 0 -> { - val ch = v.toChar() + val ch = v.toInt().toChar() out[outPos++] = ch } vi and 0xe0 == 0xc0 -> { @@ -233,7 +224,7 @@ private fun ByteBuffer.decodeUTF8_buffer(out: CharArray, offset: Int, length: In when { v >= 0 -> { - val ch = v.toChar() + val ch = v.toInt().toChar() out[outPos++] = ch } vi and 0xe0 == 0xc0 -> { @@ -311,7 +302,7 @@ private inline fun ByteBuffer.decodeUTF8_array( length: Int, predicate: (Char) -> Boolean ): Long { - val array = array()!! + val array = array() var srcPos = arrayOffset() + position() val srcEnd = srcPos + remaining() @@ -329,7 +320,7 @@ private inline fun ByteBuffer.decodeUTF8_array( when { v >= 0 -> { - val ch = v.toChar() + val ch = v.toInt().toChar() if (!predicate(ch)) { position(srcPos - 1 - arrayOffset()) return decodeUtf8Result(outPos - offset, -1) @@ -443,7 +434,7 @@ private inline fun ByteBuffer.decodeUTF8_buffer( when { v >= 0 -> { - val ch = v.toChar() + val ch = v.toInt().toChar() if (!predicate(ch)) { position(position() - 1) return decodeUtf8Result(outPos - offset, -1) diff --git a/ktor-io/jvm/src/io/ktor/utils/io/concurrent/SharedJvm.kt b/ktor-io/jvm/src/io/ktor/utils/io/concurrent/SharedJvm.kt index 0cd03a948a3..620208d93e5 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/concurrent/SharedJvm.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/concurrent/SharedJvm.kt @@ -18,7 +18,6 @@ import kotlin.reflect.* * ``` */ @Suppress("NOTHING_TO_INLINE") -@DangerousInternalIoApi public actual inline fun shared(value: T): ReadWriteProperty = object : ReadWriteProperty { private var value: T = value @@ -37,6 +36,5 @@ public actual inline fun shared(value: T): ReadWriteProperty = objec * * This reference is allowed to use only from creation thread. Otherwise it will return null. */ -@DangerousInternalIoApi public actual fun threadLocal(value: T): ReadOnlyProperty = - ReadOnlyProperty { thisRef, property -> value } + ReadOnlyProperty { _, _ -> value } diff --git a/ktor-io/jvm/src/io/ktor/utils/io/core/BufferUtilsJvm.kt b/ktor-io/jvm/src/io/ktor/utils/io/core/BufferUtilsJvm.kt index 18deb07f5e6..f484fc2326c 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/core/BufferUtilsJvm.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/core/BufferUtilsJvm.kt @@ -1,5 +1,3 @@ -@file:Suppress("RedundantModalityModifier") - package io.ktor.utils.io.core import io.ktor.utils.io.bits.* @@ -61,8 +59,7 @@ public inline fun ChunkBuffer.writeDirect(size: Int, block: (ByteBuffer) -> Unit /** * Reset read/write position to original's content pos/limit. May not work due to slicing. */ -@DangerousInternalIoApi -public fun ChunkBuffer.resetFromContentToWrite(child: ByteBuffer) { +internal fun ChunkBuffer.resetFromContentToWrite(child: ByteBuffer) { resetForWrite(child.limit()) commitWrittenUntilIndex(child.position()) } @@ -86,6 +83,7 @@ public fun Buffer.readAvailable(dst: ByteBuffer, length: Int = dst.remaining()): return size } +@OptIn(ExperimentalContracts::class) public inline fun Buffer.readDirect(block: (ByteBuffer) -> Unit): Int { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -100,6 +98,8 @@ public inline fun Buffer.readDirect(block: (ByteBuffer) -> Unit): Int { } } +@Suppress("UNUSED_PARAMETER") +@OptIn(ExperimentalContracts::class) public inline fun Buffer.writeDirect(size: Int = 1, block: (ByteBuffer) -> Unit): Int { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) diff --git a/ktor-io/jvm/src/io/ktor/utils/io/core/ByteBuffers.kt b/ktor-io/jvm/src/io/ktor/utils/io/core/ByteBuffers.kt index 746fd46fe26..142d4049049 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/core/ByteBuffers.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/core/ByteBuffers.kt @@ -2,8 +2,7 @@ package io.ktor.utils.io.core import io.ktor.utils.io.core.internal.* import java.nio.* -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract +import kotlin.contracts.* /** * Read at most `dst.remaining()` bytes to the specified [dst] byte buffer and change it's position accordingly @@ -54,6 +53,7 @@ private tailrec fun ByteReadPacket.readAsMuchAsPossible(bb: ByteBuffer, copied: * and not guaranteed that is will be big enough to keep [size] bytes. However it is guaranteed that the segment size * is at least 8 bytes long (long integer bytes length) */ +@OptIn(ExperimentalContracts::class) public inline fun BytePacketBuilder.writeDirect(size: Int, block: (ByteBuffer) -> Unit) { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -74,6 +74,7 @@ public inline fun BytePacketBuilder.writeDirect(size: Int, block: (ByteBuffer) - * and not guaranteed that is will be big enough to keep [size] bytes. However it is guaranteed that the segment size * is at least 8 bytes long (long integer bytes length) */ +@OptIn(ExperimentalContracts::class) public inline fun BytePacketBuilder.writeByteBufferDirect(size: Int, block: (ByteBuffer) -> Unit): Int { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -84,6 +85,7 @@ public inline fun BytePacketBuilder.writeByteBufferDirect(size: Int, block: (Byt } } +@OptIn(ExperimentalContracts::class) public inline fun ByteReadPacket.readDirect(size: Int, block: (ByteBuffer) -> Unit) { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -94,6 +96,7 @@ public inline fun ByteReadPacket.readDirect(size: Int, block: (ByteBuffer) -> Un } } +@OptIn(ExperimentalContracts::class) @Deprecated("Use read {} instead.") public inline fun Input.readDirect(size: Int, block: (ByteBuffer) -> Unit) { contract { @@ -107,8 +110,4 @@ public inline fun Input.readDirect(size: Int, block: (ByteBuffer) -> Unit) { } } -internal fun Buffer.writeBuffer(): ByteBuffer { - return memory.slice(writePosition, writeRemaining).buffer -} - internal fun Buffer.hasArray(): Boolean = memory.buffer.let { it.hasArray() && !it.isReadOnly } diff --git a/ktor-io/jvm/src/io/ktor/utils/io/internal/ReadSessionImpl.kt b/ktor-io/jvm/src/io/ktor/utils/io/internal/ReadSessionImpl.kt index ac9d7724c0a..798b782f6d6 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/internal/ReadSessionImpl.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/internal/ReadSessionImpl.kt @@ -4,6 +4,7 @@ import io.ktor.utils.io.* import io.ktor.utils.io.core.* import io.ktor.utils.io.core.internal.* +@Suppress("DEPRECATION") internal class ReadSessionImpl(private val channel: ByteBufferChannel) : SuspendableReadSession { private var lastAvailable = 0 private var lastView: ChunkBuffer = ChunkBuffer.Empty diff --git a/ktor-io/jvm/src/io/ktor/utils/io/internal/Strings.kt b/ktor-io/jvm/src/io/ktor/utils/io/internal/Strings.kt index c8b09730e92..00ca3153bca 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/internal/Strings.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/internal/Strings.kt @@ -114,7 +114,7 @@ private fun ByteBuffer.decodeASCII3_array(out: CharArray, offset: Int, length: I val b = array[srcPos] if (b < 0) break - out[pos] = b.toChar() + out[pos] = b.toInt().toChar() pos++ srcPos++ @@ -143,7 +143,7 @@ private fun ByteBuffer.decodeASCII3_buffer(out: CharArray, offset: Int, length: pushBack = true break } - out[pos] = b.toChar() + out[pos] = b.toInt().toChar() pos++ } } @@ -172,7 +172,7 @@ private inline fun ByteBuffer.decodeASCII3_array( val b = array[srcPos] if (b < 0) break - val ch = b.toChar() + val ch = b.toInt().toChar() if (!predicate(ch)) { position(srcPos - arrayOffset()) return decodeUtf8Result(pos - offset, -1) @@ -213,7 +213,7 @@ private inline fun ByteBuffer.decodeASCII3_buffer( break } - val ch = b.toChar() + val ch = b.toInt().toChar() if (!predicate(ch)) { pushBack = true predicateFailed = true diff --git a/ktor-io/jvm/src/io/ktor/utils/io/internal/WriteSessionImpl.kt b/ktor-io/jvm/src/io/ktor/utils/io/internal/WriteSessionImpl.kt index ae4704303aa..aa634d7d854 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/internal/WriteSessionImpl.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/internal/WriteSessionImpl.kt @@ -1,11 +1,10 @@ -@file:Suppress("DEPRECATION") - package io.ktor.utils.io.internal import io.ktor.utils.io.* import io.ktor.utils.io.core.* import io.ktor.utils.io.core.internal.* +@Suppress("DEPRECATION") internal class WriteSessionImpl(channel: ByteBufferChannel) : WriterSuspendSession { private var locked = 0 diff --git a/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Reading.kt b/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Reading.kt index d9f614e7857..8a65733d200 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Reading.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/jvm/javaio/Reading.kt @@ -41,7 +41,7 @@ public suspend fun InputStream.copyTo(channel: ByteWriteChannel, limit: Long = L * Please note that it may block your async code when started on [Dispatchers.Unconfined] * since [InputStream] is blocking on it's nature */ -@ExperimentalIoApi +@OptIn(DelicateCoroutinesApi::class) @Suppress("BlockingMethodInNonBlockingContext") public fun InputStream.toByteReadChannel( context: CoroutineContext = Dispatchers.IO, @@ -72,7 +72,7 @@ public fun InputStream.toByteReadChannel( * Please note that it may block your async code when started on [Dispatchers.Unconfined] * since [InputStream] is blocking on it's nature */ -@ExperimentalIoApi +@OptIn(DelicateCoroutinesApi::class) @Suppress("BlockingMethodInNonBlockingContext") @JvmName("toByteReadChannelWithArrayPool") public fun InputStream.toByteReadChannel( diff --git a/ktor-io/jvm/src/io/ktor/utils/io/nio/Channels.kt b/ktor-io/jvm/src/io/ktor/utils/io/nio/Channels.kt index e6de1e4e982..ec85714b50c 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/nio/Channels.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/nio/Channels.kt @@ -30,7 +30,7 @@ public fun WritableByteChannel.writePacket(builder: BytePacketBuilder.() -> Unit public fun WritableByteChannel.writePacket(p: ByteReadPacket): Boolean { try { while (true) { - var rc = 0 + var rc: Int p.read { node: Buffer -> node.readDirect { diff --git a/ktor-io/jvm/src/io/ktor/utils/io/pool/ByteBufferPools.kt b/ktor-io/jvm/src/io/ktor/utils/io/pool/ByteBufferPools.kt index 043480d6c72..eef569c4d21 100644 --- a/ktor-io/jvm/src/io/ktor/utils/io/pool/ByteBufferPools.kt +++ b/ktor-io/jvm/src/io/ktor/utils/io/pool/ByteBufferPools.kt @@ -12,7 +12,6 @@ private const val DEFAULT_POOL_CAPACITY: Int = 2000 private const val DEFAULT_BUFFER_SIZE: Int = 4096 -@ExperimentalIoApi public class ByteBufferPool( capacity: Int = DEFAULT_POOL_CAPACITY, public val bufferSize: Int = DEFAULT_BUFFER_SIZE @@ -31,7 +30,6 @@ public class ByteBufferPool( } } -@ExperimentalIoApi public class DirectByteBufferPool( capacity: Int = DEFAULT_POOL_CAPACITY, public val bufferSize: Int = DEFAULT_BUFFER_SIZE diff --git a/ktor-io/jvm/test/io/ktor/utils/io/BlockingAdaptersOnProhibitedThreadTest.kt b/ktor-io/jvm/test/io/ktor/utils/io/BlockingAdaptersOnProhibitedThreadTest.kt index b92c7210f9d..ff6f0f2c848 100644 --- a/ktor-io/jvm/test/io/ktor/utils/io/BlockingAdaptersOnProhibitedThreadTest.kt +++ b/ktor-io/jvm/test/io/ktor/utils/io/BlockingAdaptersOnProhibitedThreadTest.kt @@ -9,6 +9,7 @@ import kotlinx.coroutines.* import kotlin.test.* class BlockingAdaptersOnProhibitedThreadTest { + @OptIn(ExperimentalCoroutinesApi::class) private val dispatcher = newSingleThreadContext("BlockingAdaptersOnProhibitedThreadTest") @AfterTest diff --git a/ktor-io/jvm/test/io/ktor/utils/io/ByteBufferChannelLookAheadTest.kt b/ktor-io/jvm/test/io/ktor/utils/io/ByteBufferChannelLookAheadTest.kt index 267a2d3dcad..4473bb7cda7 100644 --- a/ktor-io/jvm/test/io/ktor/utils/io/ByteBufferChannelLookAheadTest.kt +++ b/ktor-io/jvm/test/io/ktor/utils/io/ByteBufferChannelLookAheadTest.kt @@ -4,6 +4,7 @@ import io.ktor.utils.io.* import io.ktor.utils.io.core.writeInt import kotlin.test.* +@Suppress("DEPRECATION") class ByteBufferChannelLookAheadTest : ByteChannelTestBase() { @Test fun testDoNothing() = runTest { diff --git a/ktor-io/jvm/test/io/ktor/utils/io/ByteBufferChannelTest.kt b/ktor-io/jvm/test/io/ktor/utils/io/ByteBufferChannelTest.kt index 86d298d4202..8d33f79477d 100644 --- a/ktor-io/jvm/test/io/ktor/utils/io/ByteBufferChannelTest.kt +++ b/ktor-io/jvm/test/io/ktor/utils/io/ByteBufferChannelTest.kt @@ -61,6 +61,7 @@ class ByteBufferChannelTest { testWriteXRaceCondition { it.writeLong(1) } } + @OptIn(DelicateCoroutinesApi::class) private fun testWriteXRaceCondition(writer: suspend (ByteChannel) -> Unit): Unit = runBlocking { val channel = ByteBufferChannel(false) diff --git a/ktor-io/jvm/test/io/ktor/utils/io/BytePacketBuildTestExtended.kt b/ktor-io/jvm/test/io/ktor/utils/io/BytePacketBuildTestExtended.kt index 44ecbb07848..5da4259c07d 100644 --- a/ktor-io/jvm/test/io/ktor/utils/io/BytePacketBuildTestExtended.kt +++ b/ktor-io/jvm/test/io/ktor/utils/io/BytePacketBuildTestExtended.kt @@ -5,11 +5,8 @@ package io.ktor.utils.io import io.ktor.utils.io.core.* -import io.ktor.utils.io.core.internal.* -import org.junit.* import java.nio.* import kotlin.test.* -import kotlin.test.Test class BytePacketBuildTestExtended : BytePacketBuildTest() { override val pool: VerifyingChunkBufferPool = VerifyingChunkBufferPool() @@ -17,7 +14,7 @@ class BytePacketBuildTestExtended : BytePacketBuildTest() { @Test fun smokeSingleBufferTestExtended() { val p = buildPacket { - writeFully(kotlin.ByteArray(2)) + writeFully(ByteArray(2)) writeFully(ByteBuffer.allocate(3)) writeByte(0x12) @@ -31,7 +28,7 @@ class BytePacketBuildTestExtended : BytePacketBuildTest() { listOf(1, 2, 3).joinTo(this, separator = "|") } - assertEquals(2 + 3 + 1 + 2 + 4 + 8 + 4 + 8 + 3 + 5, p.remaining) + assertEquals(40L, p.remaining) p.readFully(ByteArray(2)) p.readFully(ByteBuffer.allocate(3)) @@ -63,7 +60,7 @@ class BytePacketBuildTestExtended : BytePacketBuildTest() { listOf(1, 2, 3).joinTo(this, separator = "|") } - assertEquals(9999 + 8888 + 1 + 2 + 4 + 8 + 4 + 8 + 3 + 5, p.remaining) + assertEquals(18922L, p.remaining) p.readFully(ByteArray(9999)) p.readFully(ByteBuffer.allocate(8888)) diff --git a/ktor-io/jvm/test/io/ktor/utils/io/ChannelsTest.kt b/ktor-io/jvm/test/io/ktor/utils/io/ChannelsTest.kt index f5f87521dc0..8124ea3c33b 100644 --- a/ktor-io/jvm/test/io/ktor/utils/io/ChannelsTest.kt +++ b/ktor-io/jvm/test/io/ktor/utils/io/ChannelsTest.kt @@ -17,7 +17,7 @@ class ChannelsTest { @Test fun testInputBig() { - val array = ByteArray(16384) { ((it and 0x0f) + 'a'.toInt()).toByte() } + val array = ByteArray(16384) { ((it and 0x0f) + 'a'.code).toByte() } val content = ByteArrayInputStream(array) val input = Channels.newChannel(content).asInput() diff --git a/ktor-io/posix/src/io/ktor/utils/io/ByteWriteChannelNative.kt b/ktor-io/posix/src/io/ktor/utils/io/ByteWriteChannelNative.kt index c23b68a314f..1d4a1866a06 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/ByteWriteChannelNative.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/ByteWriteChannelNative.kt @@ -127,7 +127,6 @@ public actual interface ByteWriteChannel { */ public actual suspend fun writeFloat(f: Float) - @ExperimentalIoApi public actual suspend fun awaitFreeSpace() /** diff --git a/ktor-io/posix/src/io/ktor/utils/io/NativeUtilsNative.kt b/ktor-io/posix/src/io/ktor/utils/io/NativeUtilsNative.kt index c420dcf9640..e261a410e2c 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/NativeUtilsNative.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/NativeUtilsNative.kt @@ -4,15 +4,12 @@ package io.ktor.utils.io -import io.ktor.utils.io.core.internal.* import kotlin.native.concurrent.* -@DangerousInternalIoApi public actual fun Any.preventFreeze() { ensureNeverFrozen() } -@DangerousInternalIoApi public actual fun Any.makeShared() { freeze() } diff --git a/ktor-io/posix/src/io/ktor/utils/io/bits/MemoryFactoryNative.kt b/ktor-io/posix/src/io/ktor/utils/io/bits/MemoryFactoryNative.kt index 4ba891d4081..ce472e5d6e0 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/bits/MemoryFactoryNative.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/bits/MemoryFactoryNative.kt @@ -12,6 +12,7 @@ import kotlin.contracts.* * By default, if neither [offset] nor [length] specified, the whole array is used. * An instance of [Memory] provided into the [block] should be never captured and used outside of lambda. */ +@OptIn(ExperimentalContracts::class) public actual inline fun ByteArray.useMemory(offset: Int, length: Int, block: (Memory) -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -88,7 +89,7 @@ public fun NativeFreeablePlacement.free(memory: Memory) { free(memory.pointer) } -internal inline class PlacementAllocator(private val placement: NativeFreeablePlacement) : Allocator { +internal value class PlacementAllocator(private val placement: NativeFreeablePlacement) : Allocator { override fun alloc(size: Int): Memory = alloc(size.toLong()) override fun alloc(size: Long): Memory = Memory(placement.allocArray(size), size) diff --git a/ktor-io/posix/src/io/ktor/utils/io/bits/MemoryNative.kt b/ktor-io/posix/src/io/ktor/utils/io/bits/MemoryNative.kt index 0fef5b520cb..51d58bafef8 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/bits/MemoryNative.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/bits/MemoryNative.kt @@ -8,7 +8,7 @@ import kotlinx.cinterop.* import platform.posix.* import kotlin.require -public actual class Memory @DangerousInternalIoApi constructor( +public actual class Memory constructor( public val pointer: CPointer, public actual inline val size: Long ) { diff --git a/ktor-io/posix/src/io/ktor/utils/io/charsets/CharsetNative.kt b/ktor-io/posix/src/io/ktor/utils/io/charsets/CharsetNative.kt index 54964eb1b38..f06dc110a96 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/charsets/CharsetNative.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/charsets/CharsetNative.kt @@ -122,7 +122,7 @@ public actual fun CharsetEncoder.encodeUTF8(input: ByteReadPacket, dst: Output) } dst.writeWhileSize(writeSize) { dstBuffer -> - var written: Int = 0 + var written = 0 dstBuffer.writeDirect { buffer -> var read = 0 @@ -214,8 +214,8 @@ public actual fun CharsetDecoder.decode(input: Input, dst: Appendable, max: Int) val rem = max - copied if (rem == 0) return@takeWhileSize 0 - var written: Int = 0 - var read = 0 + var written: Int + var read: Int srcView.readDirect { src -> val length = srcView.readRemaining.convert() @@ -337,8 +337,8 @@ public actual fun CharsetDecoder.decodeExactBytes(input: Input, inputLength: Int val rem = inputLength - charsCopied if (rem == 0) return@takeWhileSize 0 - var written: Int = 0 - var read = 0 + var written: Int + var read: Int srcView.readDirect { src -> val length = minOf(srcView.readRemaining, inputLength - bytesConsumed).convert() diff --git a/ktor-io/posix/src/io/ktor/utils/io/concurrent/SharedNative.kt b/ktor-io/posix/src/io/ktor/utils/io/concurrent/SharedNative.kt index d2b88ee3c51..7cd665879a6 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/concurrent/SharedNative.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/concurrent/SharedNative.kt @@ -42,7 +42,6 @@ public actual inline fun shared(value: T): ReadWriteProperty = objec * * This reference is allowed to use only from creation thread. Otherwise it will return null. */ -@DangerousInternalIoApi public actual fun threadLocal(value: T): ReadOnlyProperty { val threadLocal = ThreadLocalValue(value) diff --git a/ktor-io/posix/src/io/ktor/utils/io/core/BufferUtilsNative.kt b/ktor-io/posix/src/io/ktor/utils/io/core/BufferUtilsNative.kt index e8051a6ca58..feb8f73548b 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/core/BufferUtilsNative.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/core/BufferUtilsNative.kt @@ -92,6 +92,7 @@ public fun Buffer.writeFully(pointer: CPointer, offset: Long, length: I } } +@OptIn(ExperimentalContracts::class) public inline fun Buffer.readDirect(block: (CPointer) -> Int): Int { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -102,6 +103,7 @@ public inline fun Buffer.readDirect(block: (CPointer) -> Int): Int { } } +@OptIn(ExperimentalContracts::class) public inline fun Buffer.writeDirect(block: (CPointer) -> Int): Int { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) diff --git a/ktor-io/posix/src/io/ktor/utils/io/errors/PosixErrors.kt b/ktor-io/posix/src/io/ktor/utils/io/errors/PosixErrors.kt index 83db822e72b..46b21c8b29e 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/errors/PosixErrors.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/errors/PosixErrors.kt @@ -36,54 +36,37 @@ private val KnownPosixErrors = mapOf( * @property errno error code that caused this exception * @property message error text */ -@ExperimentalIoApi public sealed class PosixException(public val errno: Int, message: String) : Exception(message) { - @ExperimentalIoApi public class BadFileDescriptorException(message: String) : PosixException(EBADF, message) - @ExperimentalIoApi public class TryAgainException(errno: Int = EAGAIN, message: String) : PosixException(errno, message) - @ExperimentalIoApi public class BadMessageException(message: String) : PosixException(EBADMSG, message) - @ExperimentalIoApi public class InterruptedException(message: String) : PosixException(EINTR, message) - @ExperimentalIoApi public class InvalidArgumentException(message: String) : PosixException(EINVAL, message) - @ExperimentalIoApi public class ConnectionResetException(message: String) : PosixException(ECONNRESET, message) - @ExperimentalIoApi public class ConnectionRefusedException(message: String) : PosixException(ECONNREFUSED, message) - @ExperimentalIoApi public class ConnectionAbortedException(message: String) : PosixException(ECONNABORTED, message) - @ExperimentalIoApi public class NotConnectedException(message: String) : PosixException(ENOTCONN, message) - @ExperimentalIoApi public class TimeoutIOException(message: String) : PosixException(ETIMEDOUT, message) - @ExperimentalIoApi public class NotSocketException(message: String) : PosixException(ENOTSOCK, message) - @ExperimentalIoApi public class AddressAlreadyInUseException(message: String) : PosixException(EADDRINUSE, message) - @ExperimentalIoApi public class NoSuchFileException(message: String) : PosixException(ENOENT, message) - @ExperimentalIoApi public class OverflowException(message: String) : PosixException(EOVERFLOW, message) - @ExperimentalIoApi public class NoMemoryException(message: String) : PosixException(ENOMEM, message) - @ExperimentalIoApi public class PosixErrnoException(errno: Int, message: String) : PosixException(errno, "$message ($errno)") public companion object { @@ -95,7 +78,6 @@ public sealed class PosixException(public val errno: Int, message: String) : Exc * @param posixFunctionName optional function name to be included to the exception message * @return an instance of [PosixException] or it's subtype */ - @ExperimentalIoApi public fun forErrno( errno: Int = platform.posix.errno, posixFunctionName: String? = null diff --git a/ktor-io/posix/src/io/ktor/utils/io/streams/PosixInput.kt b/ktor-io/posix/src/io/ktor/utils/io/streams/PosixInput.kt index a40117d8540..d5228537d74 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/streams/PosixInput.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/streams/PosixInput.kt @@ -11,14 +11,12 @@ import platform.posix.* * Create a blocking [Input] reading from the specified [fileDescriptor] using [read]. */ @Suppress("FunctionName") -@ExperimentalIoApi public fun Input(fileDescriptor: Int): Input = PosixInputForFileDescriptor(fileDescriptor) /** * Create a blocking [Input] reading from the specified [file] instance using [fread]. */ @Suppress("FunctionName") -@ExperimentalIoApi public fun Input(file: CPointer): Input = PosixInputForFile(file) private class PosixInputForFileDescriptor(val fileDescriptor: Int) : Input() { diff --git a/ktor-io/posix/src/io/ktor/utils/io/streams/PosixIo.kt b/ktor-io/posix/src/io/ktor/utils/io/streams/PosixIo.kt index 851e0d6b303..5d0bc01af9b 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/streams/PosixIo.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/streams/PosixIo.kt @@ -8,7 +8,6 @@ import io.ktor.utils.io.internal.utils.* import kotlinx.cinterop.* import platform.posix.* -@ExperimentalIoApi public inline fun CPointer.use(block: (CPointer) -> R): R { return try { block(this) @@ -17,7 +16,6 @@ public inline fun CPointer.use(block: (CPointer) -> R): R { } } -@Deprecated("Use fwrite(Memory) instead.") public fun fwrite(buffer: Buffer, stream: CPointer): size_t { var written: size_t @@ -32,18 +30,15 @@ public fun fwrite(buffer: Buffer, stream: CPointer): size_t { return written } -@ExperimentalIoApi public fun fwrite(source: Memory, offset: Int, length: Int, stream: CPointer): Int { return fwrite(source, offset.toLong(), length.toLong(), stream).toInt() } -@ExperimentalIoApi public fun fwrite(source: Memory, offset: Long, length: Long, stream: CPointer): Long { val maxLength = minOf(length, ssize_t.MAX_VALUE.convert()) return fwrite(source.pointer + offset, 1.convert(), maxLength.convert(), stream).convert() } -@Deprecated("Use write(Memory) instead.") public fun write(fildes: Int, buffer: Buffer): ssize_t { var written: ssize_t @@ -59,18 +54,15 @@ public fun write(fildes: Int, buffer: Buffer): ssize_t { return written } -@ExperimentalIoApi public fun write(fildes: Int, source: Memory, offset: Int, length: Int): Int { return write(fildes, source, offset.toLong(), length.toLong()).toInt() } -@ExperimentalIoApi public fun write(fildes: Int, source: Memory, offset: Long, length: Long): Long { val maxLength = minOf(length, ssize_t.MAX_VALUE.convert()) return write(fildes, source.pointer + offset, maxLength.convert()).convert() } -@Deprecated("Use send(Memory) instead.") public fun send(socket: KX_SOCKET, buffer: Buffer, flags: Int): ssize_t { var written: ssize_t @@ -86,19 +78,16 @@ public fun send(socket: KX_SOCKET, buffer: Buffer, flags: Int): ssize_t { return written } -@ExperimentalIoApi public fun send(socket: KX_SOCKET, source: Memory, sourceOffset: Long, maxLength: Long, flags: Int): Long { val pointer = source.pointer + sourceOffset return send(socket, pointer, maxLength.coerceAtMost(size_t.MAX_VALUE.toLong()).convert(), flags).convert() } -@ExperimentalIoApi public fun send(socket: KX_SOCKET, source: Memory, sourceOffset: Int, maxLength: Int, flags: Int): Int { return send(socket, source, sourceOffset.toLong(), maxLength.toLong(), flags).toInt() } -@Deprecated("Use fread(Memory) instead.") public fun fread(buffer: Buffer, stream: CPointer): size_t { var bytesRead: size_t @@ -113,12 +102,10 @@ public fun fread(buffer: Buffer, stream: CPointer): size_t { return bytesRead } -@ExperimentalIoApi public fun fread(destination: Memory, offset: Int, length: Int, stream: CPointer): Int { return fread(destination, offset.toLong(), length.toLong(), stream).toInt() } -@ExperimentalIoApi public fun fread(destination: Memory, offset: Long, length: Long, stream: CPointer): Long { val maxLength = minOf(length, Int.MAX_VALUE.toLong(), ssize_t.MAX_VALUE.toLong()) val pointer = destination.pointer + offset @@ -129,7 +116,6 @@ public fun fread(destination: Memory, offset: Long, length: Long, stream: CPoint return result.convert() } -@Deprecated("Use read(Memory) instead.") public fun read(fildes: Int, buffer: Buffer): ssize_t { var bytesRead: ssize_t @@ -151,12 +137,10 @@ public fun read(fildes: Int, buffer: Buffer): ssize_t { return bytesRead } -@ExperimentalIoApi public fun read(fildes: Int, destination: Memory, offset: Int, length: Int): Int { return read(fildes, destination, offset.toLong(), length.toLong()).toInt() } -@ExperimentalIoApi public fun read(fildes: Int, destination: Memory, offset: Long, length: Long): Long { val maxLength = minOf( ssize_t.MAX_VALUE.convert(), @@ -166,7 +150,6 @@ public fun read(fildes: Int, destination: Memory, offset: Long, length: Long): L return read(fildes, destination.pointer + offset, maxLength.convert()).convert().coerceAtLeast(0) } -@Deprecated("Use fread(Memory) instead.") public fun recv(socket: KX_SOCKET, buffer: Buffer, flags: Int): ssize_t { var bytesRead: ssize_t @@ -182,7 +165,6 @@ public fun recv(socket: KX_SOCKET, buffer: Buffer, flags: Int): ssize_t { return bytesRead } -@ExperimentalIoApi public fun recvfrom( socket: KX_SOCKET, buffer: Buffer, @@ -204,7 +186,6 @@ public fun recvfrom( return bytesRead } -@ExperimentalIoApi public fun sendto( socket: KX_SOCKET, buffer: Buffer, diff --git a/ktor-io/posix/src/io/ktor/utils/io/streams/PosixOutput.kt b/ktor-io/posix/src/io/ktor/utils/io/streams/PosixOutput.kt index c6f4b00c39b..c1fc3482148 100644 --- a/ktor-io/posix/src/io/ktor/utils/io/streams/PosixOutput.kt +++ b/ktor-io/posix/src/io/ktor/utils/io/streams/PosixOutput.kt @@ -11,14 +11,12 @@ import platform.posix.* * Create a blocking [Output] writing to the specified [fileDescriptor] using [write]. */ @Suppress("FunctionName") -@ExperimentalIoApi public fun Output(fileDescriptor: Int): Output = PosixFileDescriptorOutput(fileDescriptor) /** * Create a blocking [Output] writing to the specified [file] instance using [fwrite]. */ @Suppress("FunctionName") -@ExperimentalIoApi public fun Output(file: CPointer): Output = PosixFileInstanceOutput(file) private class PosixFileDescriptorOutput(val fileDescriptor: Int) : Output() { diff --git a/ktor-io/posix/test/io/ktor/utils/io/ByteChannelNativeConcurrentTest.kt b/ktor-io/posix/test/io/ktor/utils/io/ByteChannelNativeConcurrentTest.kt index e9b8f31e75a..f4e4d0d973d 100644 --- a/ktor-io/posix/test/io/ktor/utils/io/ByteChannelNativeConcurrentTest.kt +++ b/ktor-io/posix/test/io/ktor/utils/io/ByteChannelNativeConcurrentTest.kt @@ -11,6 +11,7 @@ import kotlin.test.* class ByteChannelNativeConcurrentTest { private val TEST_SIZE = 10 * 1024 + @OptIn(DelicateCoroutinesApi::class) @Test fun testReadWriteByte() { val channel = ByteChannel() @@ -29,6 +30,7 @@ class ByteChannelNativeConcurrentTest { } } + @OptIn(DelicateCoroutinesApi::class) @Test fun testReadWriteBlock() { val channel = ByteChannel() diff --git a/ktor-io/posix/test/io/ktor/utils/io/BytePacketBuilderExtendedTest.kt b/ktor-io/posix/test/io/ktor/utils/io/BytePacketBuilderExtendedTest.kt index 1f5a0a5fef0..292f51222d6 100644 --- a/ktor-io/posix/test/io/ktor/utils/io/BytePacketBuilderExtendedTest.kt +++ b/ktor-io/posix/test/io/ktor/utils/io/BytePacketBuilderExtendedTest.kt @@ -5,10 +5,8 @@ package io.ktor.utils.io import io.ktor.utils.io.core.* -import io.ktor.utils.io.core.internal.* import kotlinx.cinterop.* import kotlin.test.* -import kotlin.test.Test class BytePacketBuilderExtendedTest : BytePacketBuildTest() { override val pool = VerifyingChunkBufferPool() @@ -18,7 +16,7 @@ class BytePacketBuilderExtendedTest : BytePacketBuildTest() { @Test fun smokeSingleBufferTestExtended() { val p = buildPacket { - writeFully(kotlin.ByteArray(2)) + writeFully(ByteArray(2)) writeFully(buffer, 3) writeByte(0x12) @@ -32,7 +30,7 @@ class BytePacketBuilderExtendedTest : BytePacketBuildTest() { listOf(1, 2, 3).joinTo(this, separator = "|") } - assertEquals(2 + 3 + 1 + 2 + 4 + 8 + 4 + 8 + 3 + 5, p.remaining) + assertEquals(40L, p.remaining) p.readFully(ByteArray(2)) p.readFully(buffer, 3) @@ -64,7 +62,7 @@ class BytePacketBuilderExtendedTest : BytePacketBuildTest() { listOf(1, 2, 3).joinTo(this, separator = "|") } - assertEquals(9999 + 8888 + 1 + 2 + 4 + 8 + 4 + 8 + 3 + 5, p.remaining) + assertEquals(18922L, p.remaining) p.readFully(ByteArray(9999)) p.readFully(buffer, 8888) @@ -91,6 +89,5 @@ class BytePacketBuilderExtendedTest : BytePacketBuildTest() { } companion object { - val PACKET_BUFFER_SIZE = 4096 } } diff --git a/ktor-io/posix/test/io/ktor/utils/io/ChunkBufferNativeTest.kt b/ktor-io/posix/test/io/ktor/utils/io/ChunkBufferNativeTest.kt index 84b868ecef6..a0e5d8923ac 100644 --- a/ktor-io/posix/test/io/ktor/utils/io/ChunkBufferNativeTest.kt +++ b/ktor-io/posix/test/io/ktor/utils/io/ChunkBufferNativeTest.kt @@ -16,8 +16,8 @@ class ChunkBufferNativeTest { @Test fun testReadDirectOnEmpty() { - var invoked = false - buffer.readDirect { ptr -> + var invoked: Boolean + buffer.readDirect { invoked = true 0 }.also { @@ -28,9 +28,8 @@ class ChunkBufferNativeTest { @Test fun testReadDirectNegativeResult() { - var invoked = false assertFails { - buffer.readDirect { ptr -> + buffer.readDirect { -1 } } @@ -38,9 +37,8 @@ class ChunkBufferNativeTest { @Test fun testReadDirectTooManyBytesResult() { - var invoked = false assertFails { - buffer.readDirect { ptr -> + buffer.readDirect { 1 } } @@ -48,7 +46,7 @@ class ChunkBufferNativeTest { @Test fun testReadDirect() { - var result = 0 + var result: Int buffer.writeByte(7) buffer.writeByte(8) buffer.readDirect { ptr -> @@ -68,7 +66,7 @@ class ChunkBufferNativeTest { } val size = buffer.readRemaining - buffer.readDirect { ptr -> + buffer.readDirect { buffer.readRemaining }.also { assertEquals(size, it) diff --git a/ktor-io/posix/test/io/ktor/utils/io/PosixIoTest.kt b/ktor-io/posix/test/io/ktor/utils/io/PosixIoTest.kt index 520a4d140c2..84989bd51d4 100644 --- a/ktor-io/posix/test/io/ktor/utils/io/PosixIoTest.kt +++ b/ktor-io/posix/test/io/ktor/utils/io/PosixIoTest.kt @@ -18,7 +18,7 @@ class PosixIoTest { fun setup() { buffer = Buffer(DefaultAllocator.alloc(4096)) buffer.resetForWrite() - buffer.append("test") + buffer.writeFully("test".encodeToByteArray()) unlink(filename) } @@ -31,9 +31,9 @@ class PosixIoTest { @Test fun testFFunctions() { - val file = fopen(filename, "w") ?: return + val descriptor = fopen(filename, "w") ?: return - file.use { file -> + descriptor.use { file -> assertEquals(4, fwrite(buffer, file).convert(), "Expected all bytes to be written") } buffer.resetForWrite() @@ -46,12 +46,12 @@ class PosixIoTest { @Test fun testFunctions() { - val file = open(filename, O_WRONLY or O_CREAT, 420) - if (file < 0) { + val descriptor = open(filename, O_WRONLY or O_CREAT, 420) + if (descriptor < 0) { return } - file.use { file -> + descriptor.use { file -> assertEquals(4, write(file, buffer).toInt(), "Expected all bytes to be written") } buffer.resetForWrite() @@ -104,13 +104,13 @@ class PosixIoTest { val clientAddr = alloc() with(serverAddr) { - memset(this.ptr, 0, sockaddr_in.size.convert()) + memset(this.ptr, 0, sizeOf().convert()) sin_family = AF_INET.convert() sin_port = 0u // my_htons(port) } with(clientAddr) { - memset(this.ptr, 0, sockaddr_in.size.convert()) + memset(this.ptr, 0, sizeOf().convert()) sin_family = AF_INET.convert() sin_port = my_htons(port) set_loopback(ptr) @@ -118,7 +118,7 @@ class PosixIoTest { val acceptor = socket(AF_INET, SOCK_STREAM, 0).checkError("socket()") acceptor.makeNonBlocking() - bind(acceptor, serverAddr.ptr.reinterpret(), sockaddr_in.size.convert()).let { rc -> + bind(acceptor, serverAddr.ptr.reinterpret(), sizeOf().convert()).let { rc -> if (rc != 0) { val error = socket_get_error() throw PosixException.forErrno(errno = error, posixFunctionName = "bind()") @@ -127,7 +127,7 @@ class PosixIoTest { listen(acceptor, 10).checkError("listen()") val addrSizeResult = alloc() - addrSizeResult.value = sockaddr_in.size.convert() + addrSizeResult.value = sizeOf().convert() getsockname( acceptor, serverAddr.ptr.reinterpret(), @@ -166,19 +166,23 @@ class PosixIoTest { } } - if (!connectedFlag) { - val result = connect(connected, clientAddr.ptr.reinterpret(), sockaddr_in.size.convert()) - if (result != 0) { - val error = socket_get_error() - if (error == EINPROGRESS || error == EISCONN) { - } else if (error != EAGAIN && error != EWOULDBLOCK) { + if (connectedFlag) { + continue + } + + val result = connect(connected, clientAddr.ptr.reinterpret(), sizeOf().convert()) + if (result != 0) { + val error = socket_get_error() + if (error != EINPROGRESS && error != EISCONN) { + if (error != EAGAIN && error != EWOULDBLOCK) { throw PosixException.forErrno(error, "connect()") - } else { - continue } + + continue } - connectedFlag = true } + + connectedFlag = true } // send diff --git a/ktor-network/build.gradle.kts b/ktor-network/build.gradle.kts index 608c2c12f43..0ffa22fcf48 100644 --- a/ktor-network/build.gradle.kts +++ b/ktor-network/build.gradle.kts @@ -3,7 +3,6 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.* description = "Ktor network utilities" -val ideaActive: Boolean by project.extra val nativeCompilations: List by project.extra val mockk_version: String by project.extra @@ -29,7 +28,7 @@ kotlin { } } - if (!ideaActive && findByName("posixMain") != null) { + if (!KtorBuildProperties.ideaActive && findByName("posixMain") != null) { val networkInterop by creating getByName("posixMain").dependsOn(networkInterop) apply(from = "$rootDir/gradle/interop-as-source-set-klib.gradle") diff --git a/ktor-network/common/src/io/ktor/network/selector/SelectorManagerCommon.kt b/ktor-network/common/src/io/ktor/network/selector/SelectorManagerCommon.kt index c254ed1606c..14a39468019 100644 --- a/ktor-network/common/src/io/ktor/network/selector/SelectorManagerCommon.kt +++ b/ktor-network/common/src/io/ktor/network/selector/SelectorManagerCommon.kt @@ -1,6 +1,5 @@ package io.ktor.network.selector -import io.ktor.util.* import io.ktor.utils.io.core.* import kotlinx.coroutines.* import kotlin.coroutines.* @@ -9,7 +8,6 @@ import kotlin.coroutines.* * Creates the selector manager for current platform. */ @Suppress("FunctionName") -@InternalAPI public expect fun SelectorManager( dispatcher: CoroutineContext = EmptyCoroutineContext ): SelectorManager @@ -41,7 +39,6 @@ public expect interface SelectorManager : CoroutineScope, Closeable { * Select interest kind */ @Suppress("KDocMissingDocumentation", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING") -@InternalAPI public expect enum class SelectInterest { READ, WRITE, ACCEPT, CONNECT; diff --git a/ktor-network/common/src/io/ktor/network/sockets/TypeOfService.kt b/ktor-network/common/src/io/ktor/network/sockets/TypeOfService.kt index 62b5afceb7f..ae5fc0f314c 100644 --- a/ktor-network/common/src/io/ktor/network/sockets/TypeOfService.kt +++ b/ktor-network/common/src/io/ktor/network/sockets/TypeOfService.kt @@ -4,12 +4,14 @@ package io.ktor.network.sockets +import kotlin.jvm.* + /** * An inline class to hold a IP ToS value * @property value an unsigned byte IP_TOS value */ -@OptIn(ExperimentalUnsignedTypes::class) -public inline class TypeOfService(public val value: UByte) { +@JvmInline +public value class TypeOfService(public val value: UByte) { /** * Creates ToS by integer value discarding extra high bits */ diff --git a/ktor-network/js/src/io/ktor/network/selector/SelectorManagerJs.kt b/ktor-network/js/src/io/ktor/network/selector/SelectorManagerJs.kt index 441f2df8fa8..b5ab31ba5a8 100644 --- a/ktor-network/js/src/io/ktor/network/selector/SelectorManagerJs.kt +++ b/ktor-network/js/src/io/ktor/network/selector/SelectorManagerJs.kt @@ -4,12 +4,10 @@ package io.ktor.network.selector -import io.ktor.util.* import io.ktor.utils.io.core.* import kotlinx.coroutines.* import kotlin.coroutines.* -@InternalAPI public actual fun SelectorManager(dispatcher: CoroutineContext): SelectorManager { error("Selector manager is unsupported on JS platform") } @@ -41,7 +39,6 @@ public actual interface SelectorManager : CoroutineScope, Closeable { * Select interest kind */ @Suppress("KDocMissingDocumentation", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING") -@InternalAPI public actual enum class SelectInterest { READ, WRITE, ACCEPT, CONNECT; diff --git a/ktor-network/jvm/src/io/ktor/network/selector/InterestSuspensionsMap.kt b/ktor-network/jvm/src/io/ktor/network/selector/InterestSuspensionsMap.kt index afcf33d1e0d..3089cc95e81 100644 --- a/ktor-network/jvm/src/io/ktor/network/selector/InterestSuspensionsMap.kt +++ b/ktor-network/jvm/src/io/ktor/network/selector/InterestSuspensionsMap.kt @@ -4,12 +4,10 @@ package io.ktor.network.selector -import io.ktor.util.* import kotlinx.coroutines.* import java.util.concurrent.atomic.* @Suppress("KDocMissingDocumentation") -@InternalAPI public class InterestSuspensionsMap { @Volatile @Suppress("unused") @@ -54,6 +52,7 @@ public class InterestSuspensionsMap { public fun removeSuspension(interest: SelectInterest): CancellableContinuation? = updater(interest).getAndSet(this, null) + public fun removeSuspension(interestOrdinal: Int): CancellableContinuation? = updaters[interestOrdinal].getAndSet(this, null) @@ -77,8 +76,9 @@ public class InterestSuspensionsMap { ) as AtomicReferenceFieldUpdater?> }.toTypedArray() - private fun updater(interest: SelectInterest): - AtomicReferenceFieldUpdater?> = - updaters[interest.ordinal] + private fun updater( + interest: SelectInterest + ): AtomicReferenceFieldUpdater?> = + updaters[interest.ordinal] } } diff --git a/ktor-network/jvm/src/io/ktor/network/selector/JvmSelector.kt b/ktor-network/jvm/src/io/ktor/network/selector/JvmSelector.kt index 32a887eeb7d..6f122996796 100644 --- a/ktor-network/jvm/src/io/ktor/network/selector/JvmSelector.kt +++ b/ktor-network/jvm/src/io/ktor/network/selector/JvmSelector.kt @@ -1,17 +1,14 @@ // ktlint-disable filename package io.ktor.network.selector -import io.ktor.util.* import kotlinx.coroutines.* import java.io.* import java.nio.channels.* -@InternalAPI public actual interface Selectable : Closeable, DisposableHandle { /** * Current selectable suspensions map */ - @InternalAPI public val suspensions: InterestSuspensionsMap /** diff --git a/ktor-network/jvm/src/io/ktor/network/selector/LockFreeMPSCQueue.kt b/ktor-network/jvm/src/io/ktor/network/selector/LockFreeMPSCQueue.kt index 2a2bbf40470..a50aa0103d9 100644 --- a/ktor-network/jvm/src/io/ktor/network/selector/LockFreeMPSCQueue.kt +++ b/ktor-network/jvm/src/io/ktor/network/selector/LockFreeMPSCQueue.kt @@ -20,7 +20,6 @@ private typealias Core = LockFreeMPSCQueueCore * Thread 2: addLast(2) = 2 // this operation is concurrent with both operations in the first thread * ``` */ -@InternalAPI internal class LockFreeMPSCQueue { private val _cur = atomic(Core(Core.INITIAL_CAPACITY)) diff --git a/ktor-network/jvm/src/io/ktor/network/selector/SelectorManager.kt b/ktor-network/jvm/src/io/ktor/network/selector/SelectorManager.kt index 767b60ba3f8..ca629849646 100644 --- a/ktor-network/jvm/src/io/ktor/network/selector/SelectorManager.kt +++ b/ktor-network/jvm/src/io/ktor/network/selector/SelectorManager.kt @@ -11,7 +11,6 @@ import java.nio.channels.* import java.nio.channels.spi.* import kotlin.coroutines.* -@InternalAPI public actual fun SelectorManager(dispatcher: CoroutineContext): SelectorManager = ActorSelectorManager(dispatcher) /** @@ -66,8 +65,7 @@ public inline fun SelectorManager.buildOrClose( * Select interest kind * @property [flag] to be set in NIO selector */ -@Suppress("KDocMissingDocumentation", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING") -@InternalAPI +@Suppress("KDocMissingDocumentation") public actual enum class SelectInterest(public val flag: Int) { READ(SelectionKey.OP_READ), WRITE(SelectionKey.OP_WRITE), diff --git a/ktor-network/jvm/src/io/ktor/network/sockets/CIOReader.kt b/ktor-network/jvm/src/io/ktor/network/sockets/CIOReader.kt index 12c9e633389..3cb1215f64c 100644 --- a/ktor-network/jvm/src/io/ktor/network/sockets/CIOReader.kt +++ b/ktor-network/jvm/src/io/ktor/network/sockets/CIOReader.kt @@ -71,7 +71,6 @@ internal fun CoroutineScope.attachForReadingImpl( } } -@OptIn(ExperimentalIoApi::class) internal fun CoroutineScope.attachForReadingDirectImpl( channel: ByteChannel, nioChannel: ReadableByteChannel, diff --git a/ktor-network/jvm/src/io/ktor/network/sockets/CIOWriter.kt b/ktor-network/jvm/src/io/ktor/network/sockets/CIOWriter.kt index b9c7f8b1d08..de95b3003ba 100644 --- a/ktor-network/jvm/src/io/ktor/network/sockets/CIOWriter.kt +++ b/ktor-network/jvm/src/io/ktor/network/sockets/CIOWriter.kt @@ -42,7 +42,7 @@ internal fun CoroutineScope.attachForWritingImpl( buffer.flip() while (buffer.hasRemaining()) { - var rc = 0 + var rc: Int timeout.withTimeout { do { @@ -80,6 +80,7 @@ internal fun CoroutineScope.attachForWritingDirectImpl( ): ReaderJob = reader(Dispatchers.Unconfined + CoroutineName("cio-to-nio-writer"), channel) { selectable.interestOp(SelectInterest.WRITE, false) try { + @Suppress("DEPRECATION") channel.lookAheadSuspend { val timeout = if (socketOptions?.socketTimeout != null) { createTimeout("writing-direct", socketOptions.socketTimeout) { diff --git a/ktor-network/jvm/src/io/ktor/network/sockets/DatagramSendChannel.kt b/ktor-network/jvm/src/io/ktor/network/sockets/DatagramSendChannel.kt index 59214e74d4a..37f34f34ba9 100644 --- a/ktor-network/jvm/src/io/ktor/network/sockets/DatagramSendChannel.kt +++ b/ktor-network/jvm/src/io/ktor/network/sockets/DatagramSendChannel.kt @@ -16,7 +16,6 @@ import kotlinx.coroutines.sync.* import java.net.* import java.nio.* import java.nio.channels.* -import kotlin.coroutines.* private val CLOSED: (Throwable?) -> Unit = {} private val CLOSED_INVOKED: (Throwable?) -> Unit = {} diff --git a/ktor-network/jvm/src/io/ktor/network/sockets/SocketImpl.kt b/ktor-network/jvm/src/io/ktor/network/sockets/SocketImpl.kt index 6e331cdcb2d..07ed39dce96 100644 --- a/ktor-network/jvm/src/io/ktor/network/sockets/SocketImpl.kt +++ b/ktor-network/jvm/src/io/ktor/network/sockets/SocketImpl.kt @@ -59,10 +59,6 @@ internal class SocketImpl( } private fun selfConnect(): Boolean { - if (this.localAddress == null || this.remoteAddress == null) { - throw IllegalStateException("localAddress and remoteAddress should not be null.") - } - val localHostAddress = (this.localAddress as? InetSocketAddress)?.address?.hostAddress ?: "" val remoteHostAddress = (this.remoteAddress as? InetSocketAddress)?.address?.hostAddress ?: "" val isRemoteAnyLocalAddress = (this.remoteAddress as? InetSocketAddress)?.address?.isAnyLocalAddress ?: false diff --git a/ktor-network/jvm/src/io/ktor/network/sockets/TCPSocketBuilderJvm.kt b/ktor-network/jvm/src/io/ktor/network/sockets/TCPSocketBuilderJvm.kt index 72552e0028c..7b25e98c89b 100644 --- a/ktor-network/jvm/src/io/ktor/network/sockets/TCPSocketBuilderJvm.kt +++ b/ktor-network/jvm/src/io/ktor/network/sockets/TCPSocketBuilderJvm.kt @@ -6,6 +6,7 @@ package io.ktor.network.sockets import java.net.* +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public suspend fun TcpSocketBuilder.connect( remoteAddress: SocketAddress, configure: SocketOptions.TCPClientSocketOptions.() -> Unit = {} diff --git a/ktor-network/jvm/src/io/ktor/network/util/Pools.kt b/ktor-network/jvm/src/io/ktor/network/util/Pools.kt index 18bdbe5eef5..3651cef5242 100644 --- a/ktor-network/jvm/src/io/ktor/network/util/Pools.kt +++ b/ktor-network/jvm/src/io/ktor/network/util/Pools.kt @@ -8,28 +8,23 @@ import io.ktor.network.sockets.* import io.ktor.util.* import io.ktor.utils.io.pool.* import io.ktor.utils.io.pool.DirectByteBufferPool -import kotlinx.coroutines.* import java.nio.* @Suppress("KDocMissingDocumentation") -@InternalAPI internal val DEFAULT_BYTE_BUFFER_POOL_SIZE: Int = 4096 @Suppress("KDocMissingDocumentation") -@InternalAPI internal const val DEFAULT_BYTE_BUFFER_BUFFER_SIZE: Int = 4096 /** * Byte buffer pool for general-purpose buffers. */ -@InternalAPI public val DefaultByteBufferPool: ObjectPool = DirectByteBufferPool(DEFAULT_BYTE_BUFFER_POOL_SIZE, DEFAULT_BYTE_BUFFER_BUFFER_SIZE) /** * Byte buffer pool for UDP datagrams */ -@InternalAPI public val DefaultDatagramByteBufferPool: ObjectPool = DirectByteBufferPool(2048, MAX_DATAGRAM_SIZE) diff --git a/ktor-network/jvm/test/io/ktor/network/sockets/tests/UDPSocketTest.kt b/ktor-network/jvm/test/io/ktor/network/sockets/tests/UDPSocketTest.kt index 13bc1e92113..277f4572eda 100644 --- a/ktor-network/jvm/test/io/ktor/network/sockets/tests/UDPSocketTest.kt +++ b/ktor-network/jvm/test/io/ktor/network/sockets/tests/UDPSocketTest.kt @@ -12,6 +12,7 @@ import kotlinx.coroutines.* import kotlinx.coroutines.debug.junit4.* import org.junit.* import java.net.* +import java.util.* import kotlin.coroutines.* import kotlin.io.use import kotlin.test.* @@ -118,6 +119,7 @@ class UDPSocketTest : CoroutineScope { assertTrue(socket.isClosed) } + @OptIn(ExperimentalCoroutinesApi::class) @Test fun testInvokeOnClose() = runBlocking { val socket: BoundDatagramSocket = aSocket(selector) @@ -143,6 +145,7 @@ class UDPSocketTest : CoroutineScope { assertEquals(1, done) } + @OptIn(ExperimentalCoroutinesApi::class) @Test fun testOutgoingInvokeOnClose() = runBlocking { val socket: BoundDatagramSocket = aSocket(selector) @@ -162,6 +165,7 @@ class UDPSocketTest : CoroutineScope { assertTrue(socket.isClosed) } + @OptIn(ExperimentalCoroutinesApi::class) @Test fun testOutgoingInvokeOnCloseWithSocketClose() = runBlocking { val socket: BoundDatagramSocket = aSocket(selector) @@ -181,6 +185,7 @@ class UDPSocketTest : CoroutineScope { assertTrue(socket.isClosed) } + @OptIn(ExperimentalCoroutinesApi::class) @Test fun testOutgoingInvokeOnClosed() = runBlocking { val socket: BoundDatagramSocket = aSocket(selector) @@ -222,7 +227,7 @@ class UDPSocketTest : CoroutineScope { private val OS_NAME: String get() { - val os = System.getProperty("os.name", "unknown").toLowerCase() + val os = System.getProperty("os.name", "unknown").lowercase(Locale.getDefault()) return when { os.contains("win") -> "win" os.contains("mac") -> "mac" diff --git a/ktor-network/jvm/test/io/ktor/network/util/StartTimeoutTest.kt b/ktor-network/jvm/test/io/ktor/network/util/StartTimeoutTest.kt index b2b7f0cdca1..b360be574f4 100644 --- a/ktor-network/jvm/test/io/ktor/network/util/StartTimeoutTest.kt +++ b/ktor-network/jvm/test/io/ktor/network/util/StartTimeoutTest.kt @@ -99,6 +99,7 @@ class StartTimeoutTest { assertTrue(timeoutInvoked) } + @OptIn(DelicateCoroutinesApi::class) @Test fun testTimeoutCancelsWhenParentScopeCancels() = runBlocking { var timeoutInvoked = false diff --git a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/OID.kt b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/OID.kt index 60ae7f5dbc3..8645044f00c 100644 --- a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/OID.kt +++ b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/OID.kt @@ -6,7 +6,6 @@ package io.ktor.network.tls import io.ktor.util.* -@InternalAPI public data class OID(public val identifier: String) { public val asArray: IntArray = identifier.split(".", " ").map { it.trim().toInt() }.toIntArray() @@ -50,7 +49,6 @@ public data class OID(public val identifier: String) { } } -@InternalAPI public fun keysGenerationAlgorithm(algorithm: String): String = when { algorithm.endsWith("ecdsa", ignoreCase = true) -> "EC" algorithm.endsWith("dsa", ignoreCase = true) -> "DSA" diff --git a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/SignatureAlgorithm.kt b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/SignatureAlgorithm.kt index ea28df8df83..a1394f32602 100644 --- a/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/SignatureAlgorithm.kt +++ b/ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/SignatureAlgorithm.kt @@ -122,7 +122,6 @@ internal fun ByteReadPacket.readHashAndSign(): HashAndSign? { return HashAndSign.byCode(hash, sign) } -@InternalAPI public fun HashAndSign.Companion.byCode(hash: Byte, sign: Byte): HashAndSign? { check(sign != SignatureAlgorithm.ANON.code) { "Anonymous signature not allowed." } diff --git a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/Headers.kt b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/Headers.kt index 5cc38fffaf8..bd791c32ece 100644 --- a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/Headers.kt +++ b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/Headers.kt @@ -8,7 +8,6 @@ import io.ktor.util.* import io.ktor.utils.io.core.* @Suppress("KDocMissingDocumentation") -@InternalAPI internal class TLSRecord( val type: TLSRecordType = TLSRecordType.Handshake, val version: TLSVersion = TLSVersion.TLS12, @@ -16,7 +15,6 @@ internal class TLSRecord( ) @Suppress("KDocMissingDocumentation") -@InternalAPI internal class TLSHandshake { var type: TLSHandshakeType = TLSHandshakeType.HelloRequest var packet = ByteReadPacket.Empty diff --git a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/Render.kt b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/Render.kt index 8fe08de4dc4..6ab8dd8e6f6 100644 --- a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/Render.kt +++ b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/Render.kt @@ -64,7 +64,7 @@ internal fun BytePacketBuilder.writeTLSClientHello( extensions += buildServerNameExtension(name) } - writeShort(extensions.sumBy { it.remaining.toInt() }.toShort()) + writeShort(extensions.sumOf { it.remaining.toInt() }.toShort()) for (e in extensions) { writePacket(e) } diff --git a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSClientSessionJvm.kt b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSClientSessionJvm.kt index 96e83469114..c8184355f0b 100644 --- a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSClientSessionJvm.kt +++ b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/TLSClientSessionJvm.kt @@ -33,7 +33,7 @@ internal actual suspend fun openTLSSession( private class TLSSocket( private val input: ReceiveChannel, private val output: SendChannel, - socket: Socket, + private val socket: Socket, override val coroutineContext: CoroutineContext ) : CoroutineScope, Socket by socket { @@ -83,4 +83,8 @@ private class TLSSocket( output.close() } } + + override fun dispose() { + socket.dispose() + } } diff --git a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/Utils.kt b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/Utils.kt index 94cd7bd1e49..3325fc6f0ba 100644 --- a/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/Utils.kt +++ b/ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/Utils.kt @@ -10,14 +10,15 @@ import java.security.* internal fun Digest(): Digest = Digest(BytePacketBuilder()) -internal inline class Digest(val state: BytePacketBuilder) : Closeable { +@JvmInline +internal value class Digest(val state: BytePacketBuilder) : Closeable { - public fun update(packet: ByteReadPacket) = synchronized(this) { + fun update(packet: ByteReadPacket) = synchronized(this) { if (packet.isEmpty) return state.writePacket(packet.copy()) } - public fun doHash(hashName: String): ByteArray = synchronized(this) { + fun doHash(hashName: String): ByteArray = synchronized(this) { state.preview { handshakes: ByteReadPacket -> val digest = MessageDigest.getInstance(hashName)!! diff --git a/ktor-network/ktor-network-tls/jvm/test/io/ktor/network/tls/tests/ConnectionTests.kt b/ktor-network/ktor-network-tls/jvm/test/io/ktor/network/tls/tests/ConnectionTests.kt index 7d9a79edf2a..b4af25a677e 100644 --- a/ktor-network/ktor-network-tls/jvm/test/io/ktor/network/tls/tests/ConnectionTests.kt +++ b/ktor-network/ktor-network-tls/jvm/test/io/ktor/network/tls/tests/ConnectionTests.kt @@ -29,6 +29,7 @@ import java.security.cert.* import javax.net.ssl.* import kotlin.test.* +@Suppress("UNCHECKED_CAST") class ConnectionTests { @get:Rule @@ -72,7 +73,7 @@ class ConnectionTests { addKeyStore(keyStore, "changeit".toCharArray()) } - val input = socket.openReadChannel() + socket.openReadChannel() val output = socket.openWriteChannel(autoFlush = true) output.close() socket.close() diff --git a/ktor-network/ktor-network-tls/jvm/test/io/ktor/network/tls/tests/TLSConfigBuilderTest.kt b/ktor-network/ktor-network-tls/jvm/test/io/ktor/network/tls/tests/TLSConfigBuilderTest.kt index 3cb215a6e27..e73154e8d93 100644 --- a/ktor-network/ktor-network-tls/jvm/test/io/ktor/network/tls/tests/TLSConfigBuilderTest.kt +++ b/ktor-network/ktor-network-tls/jvm/test/io/ktor/network/tls/tests/TLSConfigBuilderTest.kt @@ -119,6 +119,7 @@ internal class TLSConfigBuilderTest { } } + @Suppress("DEPRECATION") @Test fun useNullAsPassword() { val customProvider = object : Provider("InMemorySPI", 0.0, "") { diff --git a/ktor-network/posix/src/io/ktor/network/selector/SelectUtils.kt b/ktor-network/posix/src/io/ktor/network/selector/SelectUtils.kt index bab88277950..ea015391aa3 100644 --- a/ktor-network/posix/src/io/ktor/network/selector/SelectUtils.kt +++ b/ktor-network/posix/src/io/ktor/network/selector/SelectUtils.kt @@ -5,6 +5,7 @@ package io.ktor.network.selector import io.ktor.network.interop.* import io.ktor.network.util.* +import io.ktor.util.* import io.ktor.util.collections.* import io.ktor.utils.io.* import kotlinx.cinterop.* @@ -15,6 +16,7 @@ import kotlin.coroutines.* import kotlin.math.* import kotlin.native.concurrent.* +@OptIn(InternalAPI::class) internal class SelectorHelper { private val wakeupSignal = SignalPoint() private val interestQueue = LockFreeMPSCQueue() diff --git a/ktor-network/posix/src/io/ktor/network/selector/SelectorManager.kt b/ktor-network/posix/src/io/ktor/network/selector/SelectorManager.kt index cf5f723f10e..3c705727695 100644 --- a/ktor-network/posix/src/io/ktor/network/selector/SelectorManager.kt +++ b/ktor-network/posix/src/io/ktor/network/selector/SelectorManager.kt @@ -4,12 +4,10 @@ package io.ktor.network.selector -import io.ktor.util.* import io.ktor.utils.io.core.* import kotlinx.coroutines.* import kotlin.coroutines.* -@InternalAPI public actual fun SelectorManager( dispatcher: CoroutineContext ): SelectorManager = WorkerSelectorManager() @@ -41,7 +39,6 @@ public actual interface SelectorManager : CoroutineScope, Closeable { * Select interest kind */ @Suppress("KDocMissingDocumentation", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING") -@InternalAPI public actual enum class SelectInterest { READ, WRITE, ACCEPT, CONNECT; diff --git a/ktor-network/posix/src/io/ktor/network/sockets/ConnectUtilsNative.kt b/ktor-network/posix/src/io/ktor/network/sockets/ConnectUtilsNative.kt index a4224b596ce..8a93b7d1990 100644 --- a/ktor-network/posix/src/io/ktor/network/sockets/ConnectUtilsNative.kt +++ b/ktor-network/posix/src/io/ktor/network/sockets/ConnectUtilsNative.kt @@ -56,8 +56,8 @@ internal actual fun bind( fcntl(descriptor, F_SETFL, O_NONBLOCK).check { it == 0 } - address.nativeAddress { address, size -> - bind(descriptor, address, size).check() + address.nativeAddress { pointer, size -> + bind(descriptor, pointer, size).check() } listen(descriptor, DEFAULT_BACKLOG_SIZE).check() diff --git a/ktor-network/posix/src/io/ktor/network/sockets/TCPServerSocketNative.kt b/ktor-network/posix/src/io/ktor/network/sockets/TCPServerSocketNative.kt index ad7f7238a89..52b04f7b91e 100644 --- a/ktor-network/posix/src/io/ktor/network/sockets/TCPServerSocketNative.kt +++ b/ktor-network/posix/src/io/ktor/network/sockets/TCPServerSocketNative.kt @@ -26,10 +26,11 @@ internal class TCPServerSocketNative( override val socketContext: Job get() = _socketContext + @Suppress("DUPLICATE_LABEL_IN_WHEN") override suspend fun accept(): Socket = memScoped { val clientAddress = alloc() val clientAddressLength: UIntVarOf = alloc() - clientAddressLength.value = sockaddr_storage.size.convert() + clientAddressLength.value = sizeOf().convert() var clientDescriptor: Int while (true) { diff --git a/ktor-network/posix/src/io/ktor/network/sockets/TCPSocketNative.kt b/ktor-network/posix/src/io/ktor/network/sockets/TCPSocketNative.kt index 185a60641d8..a2150b6cc94 100644 --- a/ktor-network/posix/src/io/ktor/network/sockets/TCPSocketNative.kt +++ b/ktor-network/posix/src/io/ktor/network/sockets/TCPSocketNative.kt @@ -5,7 +5,6 @@ package io.ktor.network.sockets import io.ktor.network.selector.* -import io.ktor.util.* import io.ktor.util.network.NetworkAddress import io.ktor.utils.io.* import io.ktor.utils.io.errors.* @@ -34,15 +33,15 @@ internal class TCPSocketNative( makeShared() } - override fun attachForReading(userChannel: ByteChannel): WriterJob = writer(Dispatchers.Unconfined, userChannel) { - while (!channel.isClosedForWrite) { - val count = channel.write { memory, startIndex, endIndex -> + override fun attachForReading(channel: ByteChannel): WriterJob = writer(Dispatchers.Unconfined, channel) { + while (!this.channel.isClosedForWrite) { + val count = this.channel.write { memory, startIndex, endIndex -> val bufferStart = memory.pointer + startIndex val size = endIndex - startIndex val result = recv(descriptor, bufferStart, size.convert(), 0).toInt() if (result == 0) { - channel.close() + this.channel.close() } if (result == -1) { if (errno == EAGAIN) { @@ -55,22 +54,22 @@ internal class TCPSocketNative( result.convert() } - if (count == 0 && !channel.isClosedForWrite) { + if (count == 0 && !this.channel.isClosedForWrite) { selector.select(selectable, SelectInterest.READ) } - channel.flush() + this.channel.flush() } - channel.closedCause?.let { throw it } + this.channel.closedCause?.let { throw it } }.apply { invokeOnCompletion { shutdown(descriptor, SHUT_RD) } } - override fun attachForWriting(userChannel: ByteChannel): ReaderJob = reader(Dispatchers.Unconfined, userChannel) { - val source = channel + override fun attachForWriting(channel: ByteChannel): ReaderJob = reader(Dispatchers.Unconfined, channel) { + val source = this.channel var sockedClosed = false var needSelect = false var total = 0 diff --git a/ktor-network/posix/src/io/ktor/network/util/SocketAddress.kt b/ktor-network/posix/src/io/ktor/network/util/SocketAddress.kt index e3b53fce3a2..7a313e57aab 100644 --- a/ktor-network/posix/src/io/ktor/network/util/SocketAddress.kt +++ b/ktor-network/posix/src/io/ktor/network/util/SocketAddress.kt @@ -35,7 +35,7 @@ internal class IPv4Address( sin_port = port.convert() sin_family = family - block(ptr.reinterpret(), sockaddr_in.size.convert()) + block(ptr.reinterpret(), sizeOf().convert()) } } @@ -43,6 +43,7 @@ internal class IPv4Address( get() = error("String address representation is unsupported on Native.") } +@Suppress("UNUSED_PARAMETER") internal class IPv6Address( family: sa_family_t, rawAddress: in6_addr, @@ -62,7 +63,7 @@ internal class IPv6Address( sin6_port = port.convert() sin6_scope_id = scopeId - block(ptr.reinterpret(), sockaddr_in6.size.convert()) + block(ptr.reinterpret(), sizeOf().convert()) } } diff --git a/ktor-network/posix/src/io/ktor/network/util/SocketAddressUtils.kt b/ktor-network/posix/src/io/ktor/network/util/SocketAddressUtils.kt index 8dd4ebe745f..abf772de658 100644 --- a/ktor-network/posix/src/io/ktor/network/util/SocketAddressUtils.kt +++ b/ktor-network/posix/src/io/ktor/network/util/SocketAddressUtils.kt @@ -4,8 +4,10 @@ package io.ktor.network.util +import io.ktor.util.* import io.ktor.util.network.* +@OptIn(InternalAPI::class) public val NetworkAddress.address: SocketAddress get() { if (explicitAddress.value == null) { explicitAddress.value = resolve().first() diff --git a/ktor-network/posix/src/io/ktor/network/util/SocketUtils.kt b/ktor-network/posix/src/io/ktor/network/util/SocketUtils.kt index 541c9b99e48..06743a78b38 100644 --- a/ktor-network/posix/src/io/ktor/network/util/SocketUtils.kt +++ b/ktor-network/posix/src/io/ktor/network/util/SocketUtils.kt @@ -46,7 +46,7 @@ internal fun getAddressInfo( internal fun getLocalAddress(descriptor: Int): SocketAddress = memScoped { val address = alloc() val length: UIntVarOf = alloc() - length.value = sockaddr_storage.size.convert() + length.value = sizeOf().convert() getsockname(descriptor, address.ptr.reinterpret(), length.ptr).check() @@ -56,7 +56,7 @@ internal fun getLocalAddress(descriptor: Int): SocketAddress = memScoped { internal fun getRemoteAddress(descriptor: Int): SocketAddress = memScoped { val address = alloc() val length: UIntVarOf = alloc() - length.value = sockaddr_storage.size.convert() + length.value = sizeOf().convert() getpeername(descriptor, address.ptr.reinterpret(), length.ptr).check() diff --git a/ktor-network/posix/test/SocketTest.kt b/ktor-network/posix/test/SocketTest.kt index bb7f0e64d55..e4bdf11f5d5 100644 --- a/ktor-network/posix/test/SocketTest.kt +++ b/ktor-network/posix/test/SocketTest.kt @@ -2,6 +2,7 @@ package io.ktor.network.tests import io.ktor.network.selector.* import io.ktor.network.sockets.* +import io.ktor.util.* import io.ktor.utils.io.* import io.ktor.utils.io.core.* import kotlinx.coroutines.* @@ -9,6 +10,7 @@ import kotlin.test.* class SocketTest { + @OptIn(InternalAPI::class) @Test fun testEcho() = runBlocking { SelectorManager().use { selector -> diff --git a/ktor-server/api/ktor-server.api b/ktor-server/api/ktor-server.api index 2bcfefd496a..86285fc8d7f 100644 --- a/ktor-server/api/ktor-server.api +++ b/ktor-server/api/ktor-server.api @@ -1083,7 +1083,6 @@ public final class io/ktor/server/util/DispatcherWithShutdown : kotlinx/coroutin public final class io/ktor/server/util/ParametersKt { public static final fun getOrFail (Lio/ktor/http/Parameters;Ljava/lang/String;)Ljava/lang/String; public static final fun getOrFailImpl (Lio/ktor/http/Parameters;Ljava/lang/String;Lio/ktor/util/reflect/TypeInfo;)Ljava/lang/Object; - public static final fun getOrFailImpl (Lio/ktor/http/Parameters;Ljava/lang/String;Lkotlin/reflect/KClass;Ljava/lang/reflect/Type;)Ljava/lang/Object; } public final class io/ktor/server/util/PathsKt { diff --git a/ktor-server/jvm/src/io/ktor/server/application/Application.kt b/ktor-server/jvm/src/io/ktor/server/application/Application.kt index ed923d4b7f8..d46967d1d44 100644 --- a/ktor-server/jvm/src/io/ktor/server/application/Application.kt +++ b/ktor-server/jvm/src/io/ktor/server/application/Application.kt @@ -26,6 +26,7 @@ public class Application( /** * Called by [ApplicationEngine] when [Application] is terminated */ + @Suppress("DEPRECATION") public fun dispose() { applicationJob.cancel() uninstallAllPlugins() diff --git a/ktor-server/jvm/src/io/ktor/server/application/ApplicationPlugin.kt b/ktor-server/jvm/src/io/ktor/server/application/ApplicationPlugin.kt index 9ca1a5f5815..7cb6961cc34 100644 --- a/ktor-server/jvm/src/io/ktor/server/application/ApplicationPlugin.kt +++ b/ktor-server/jvm/src/io/ktor/server/application/ApplicationPlugin.kt @@ -94,7 +94,7 @@ public fun

, B : Any, F : Any> P.install( public fun > A.uninstallAllPlugins() { val registry = attributes.computeIfAbsent(pluginRegistryKey) { Attributes(true) } registry.allKeys.forEach { - @Suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST", "DEPRECATION") uninstallPlugin(it as AttributeKey) } } @@ -102,6 +102,7 @@ public fun > A.uninstallAllPlugins() { /** * Uninstalls [plugin] from the pipeline */ +@Suppress("DEPRECATION") @Deprecated( "This method is misleading and will be removed. " + "If you have use case that requires this functionaity, please add it in KTOR-2696" diff --git a/ktor-server/jvm/src/io/ktor/server/config/MapApplicationConfig.kt b/ktor-server/jvm/src/io/ktor/server/config/MapApplicationConfig.kt index 9ee8c36f613..519a1a9391d 100644 --- a/ktor-server/jvm/src/io/ktor/server/config/MapApplicationConfig.kt +++ b/ktor-server/jvm/src/io/ktor/server/config/MapApplicationConfig.kt @@ -75,14 +75,14 @@ public open class MapApplicationConfig : ApplicationConfig { val keys = if (isTopLevel) map.keys else map.keys.filter { it.startsWith("$path.") } val listEntries = keys.filter { it.contains(".size") }.map { it.substringBefore(".size") } val addedListKeys = mutableSetOf() - return keys.mapNotNull { key -> - val listKey = listEntries.firstOrNull { key.startsWith(it) } + return keys.mapNotNull { candidate -> + val listKey = listEntries.firstOrNull { candidate.startsWith(it) } val key = when { listKey != null && !addedListKeys.contains(listKey) -> { addedListKeys.add(listKey) listKey } - listKey == null -> key + listKey == null -> candidate else -> null } if (isTopLevel) key else key?.substringAfter("$path.") diff --git a/ktor-server/jvm/src/io/ktor/server/http/Push.kt b/ktor-server/jvm/src/io/ktor/server/http/Push.kt index c7ee6e9b41d..a28ddfb484c 100644 --- a/ktor-server/jvm/src/io/ktor/server/http/Push.kt +++ b/ktor-server/jvm/src/io/ktor/server/http/Push.kt @@ -39,6 +39,7 @@ public fun ApplicationCall.push(encodedPath: String, encodedParameters: Paramete * or does nothing (may call or not call [block]). * Exact behaviour is up to engine implementation. */ +@OptIn(InternalAPI::class) @UseHttp2Push public fun ApplicationCall.push(block: ResponsePushBuilder.() -> Unit) { response.push(DefaultResponsePushBuilder(this).apply(block)) diff --git a/ktor-server/jvm/src/io/ktor/server/http/content/StaticContentResolution.kt b/ktor-server/jvm/src/io/ktor/server/http/content/StaticContentResolution.kt index 3381d1c4f1a..ba58d366c64 100644 --- a/ktor-server/jvm/src/io/ktor/server/http/content/StaticContentResolution.kt +++ b/ktor-server/jvm/src/io/ktor/server/http/content/StaticContentResolution.kt @@ -19,6 +19,7 @@ import java.net.* * * @return [LocalFileContent] or [JarFileContent] or `null` */ +@OptIn(InternalAPI::class) public fun ApplicationCall.resolveResource( path: String, resourcePackage: String? = null, diff --git a/ktor-server/jvm/src/io/ktor/server/plugins/OriginConnectionPoint.kt b/ktor-server/jvm/src/io/ktor/server/plugins/OriginConnectionPoint.kt index 6bbf6659ae3..9fb5e9c6ab9 100644 --- a/ktor-server/jvm/src/io/ktor/server/plugins/OriginConnectionPoint.kt +++ b/ktor-server/jvm/src/io/ktor/server/plugins/OriginConnectionPoint.kt @@ -14,6 +14,7 @@ import kotlin.reflect.* * Represents request and connection parameters possibly overridden via https headers. * By default it fallbacks to [ApplicationRequest.local] */ +@Suppress("DEPRECATION") public val ApplicationRequest.origin: RequestConnectionPoint get() = call.attributes.getOrNull(MutableOriginConnectionPointKey) ?: local @@ -89,6 +90,7 @@ internal class OriginConnectionPoint( /** * Returns [MutableOriginConnectionPoint] associated with this call */ +@Suppress("DEPRECATION") public val ApplicationCall.mutableOriginConnectionPoint: MutableOriginConnectionPoint get() = attributes.computeIfAbsent(MutableOriginConnectionPointKey) { MutableOriginConnectionPoint( diff --git a/ktor-server/jvm/src/io/ktor/server/response/ApplicationResponseFunctions.kt b/ktor-server/jvm/src/io/ktor/server/response/ApplicationResponseFunctions.kt index 65b7cf5bea9..47ce72e8fa7 100644 --- a/ktor-server/jvm/src/io/ktor/server/response/ApplicationResponseFunctions.kt +++ b/ktor-server/jvm/src/io/ktor/server/response/ApplicationResponseFunctions.kt @@ -11,6 +11,7 @@ import io.ktor.http.content.* import io.ktor.server.application.* import io.ktor.server.http.content.* import io.ktor.server.util.* +import io.ktor.util.* import io.ktor.util.reflect.* import io.ktor.utils.io.* import java.io.* @@ -18,7 +19,7 @@ import java.io.* /** * Sends a [message] as a response */ -@OptIn(ExperimentalStdlibApi::class) +@OptIn(ExperimentalStdlibApi::class, InternalAPI::class) @JvmName("respondWithType") public suspend inline fun ApplicationCall.respond(message: T) { if (message !is OutgoingContent && message !is String && message !is ByteArray) { diff --git a/ktor-server/jvm/src/io/ktor/server/routing/RouteSelector.kt b/ktor-server/jvm/src/io/ktor/server/routing/RouteSelector.kt index 8e33385e5c4..f6dc0dc993c 100644 --- a/ktor-server/jvm/src/io/ktor/server/routing/RouteSelector.kt +++ b/ktor-server/jvm/src/io/ktor/server/routing/RouteSelector.kt @@ -83,6 +83,7 @@ public sealed class RouteSelectorEvaluation( /** * Quality of [RouteSelectorEvaluation] when a HTTP method parameter has matched */ + @Suppress("unused") public const val qualityMethodParameter: Double = qualityParameter /** @@ -193,7 +194,6 @@ constructor(@Deprecated("This property is not used anymore and will be removed") /** * The selector for routing root. */ -@InternalAPI public class RootRouteSelector(rootPath: String = "") : RouteSelector() { private val parts = RoutingPath.parse(rootPath).parts.map { @@ -304,6 +304,7 @@ public data class PathSegmentConstantRouteSelector( val value: String ) : RouteSelector() { + @Suppress("UNUSED_PARAMETER") @Deprecated( "hasTrailingSlash is not used anymore. This is going to be removed", level = DeprecationLevel.ERROR, @@ -350,6 +351,7 @@ public data class PathSegmentParameterRouteSelector( val suffix: String? = null ) : RouteSelector() { + @Suppress("UNUSED_PARAMETER") @Deprecated( "hasTrailingSlash is not used anymore. This is going to be removed", level = DeprecationLevel.ERROR, @@ -384,6 +386,7 @@ public data class PathSegmentOptionalParameterRouteSelector( val suffix: String? = null ) : RouteSelector() { + @Suppress("UNUSED_PARAMETER") @Deprecated( "hasTrailingSlash is not used anymore. This is going to be removed", level = DeprecationLevel.ERROR, @@ -430,6 +433,7 @@ public data class PathSegmentTailcardRouteSelector( val prefix: String = "" ) : RouteSelector() { + @Suppress("UNUSED_PARAMETER") @Deprecated( "hasTrailingSlash is not used anymore. This is going to be removed", level = DeprecationLevel.ERROR, @@ -479,6 +483,7 @@ public data class PathSegmentTailcardRouteSelector( * @param first is a first selector * @param second is a second selector */ +@Suppress("unused") public data class OrRouteSelector( val first: RouteSelector, val second: RouteSelector @@ -501,6 +506,7 @@ public data class OrRouteSelector( * @param first is a first selector * @param second is a second selector */ +@Suppress("unused") public data class AndRouteSelector( val first: RouteSelector, val second: RouteSelector diff --git a/ktor-server/jvm/src/io/ktor/server/routing/Routing.kt b/ktor-server/jvm/src/io/ktor/server/routing/Routing.kt index 8dc6badf325..4cccc66e51c 100644 --- a/ktor-server/jvm/src/io/ktor/server/routing/Routing.kt +++ b/ktor-server/jvm/src/io/ktor/server/routing/Routing.kt @@ -19,6 +19,7 @@ public val RoutingFailureStatusCode: AttributeKey = AttributeKey * Root routing node for an [Application] * @param application is an instance of [Application] for this routing */ +@OptIn(InternalAPI::class) public class Routing( public val application: Application ) : Route( diff --git a/ktor-server/jvm/src/io/ktor/server/routing/RoutingBuilder.kt b/ktor-server/jvm/src/io/ktor/server/routing/RoutingBuilder.kt index 7154a349565..62b84f56278 100644 --- a/ktor-server/jvm/src/io/ktor/server/routing/RoutingBuilder.kt +++ b/ktor-server/jvm/src/io/ktor/server/routing/RoutingBuilder.kt @@ -325,6 +325,7 @@ public object PathSegmentSelectorBuilder { level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("parseParameter(value)") ) + @Suppress("UNUSED_PARAMETER") public fun parseParameter(value: String, hasTrailingSlash: Boolean): RouteSelector = parseParameter(value) /** @@ -343,6 +344,7 @@ public object PathSegmentSelectorBuilder { level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("parseConstant(value)") ) + @Suppress("UNUSED_PARAMETER") public fun parseConstant(value: String, hasTrailingSlash: Boolean): RouteSelector = parseConstant(value) /** diff --git a/ktor-server/jvm/src/io/ktor/server/util/CopyOnWriteHashMap.kt b/ktor-server/jvm/src/io/ktor/server/util/CopyOnWriteHashMap.kt index 525bbd2d20d..d6cc91fe3fc 100644 --- a/ktor-server/jvm/src/io/ktor/server/util/CopyOnWriteHashMap.kt +++ b/ktor-server/jvm/src/io/ktor/server/util/CopyOnWriteHashMap.kt @@ -4,4 +4,7 @@ package io.ktor.server.util +import io.ktor.util.* + +@OptIn(InternalAPI::class) public typealias CopyOnWriteHashMap = io.ktor.util.collections.CopyOnWriteHashMap diff --git a/ktor-server/jvm/src/io/ktor/server/util/Parameters.kt b/ktor-server/jvm/src/io/ktor/server/util/Parameters.kt index 77355901a26..44e7faf85e4 100644 --- a/ktor-server/jvm/src/io/ktor/server/util/Parameters.kt +++ b/ktor-server/jvm/src/io/ktor/server/util/Parameters.kt @@ -8,7 +8,6 @@ import io.ktor.http.* import io.ktor.server.plugins.* import io.ktor.util.converters.* import io.ktor.util.reflect.* -import java.lang.reflect.Type import kotlin.reflect.* import kotlin.reflect.jvm.* @@ -53,12 +52,6 @@ public inline fun Parameters.getOrFail(name: String): R { return getOrFailImpl(name, typeInfo()) } -@PublishedApi -@Deprecated("Please use overload with typeInfo parameter", level = DeprecationLevel.ERROR) -internal fun Parameters.getOrFailImpl(name: String, type: KClass, javaType: Type): R { - error("Please use overload with typeInfo parameter") -} - @PublishedApi internal fun Parameters.getOrFailImpl(name: String, typeInfo: TypeInfo): R { val values = getAll(name) ?: throw MissingRequestParameterException(name) diff --git a/ktor-server/jvm/src/io/ktor/server/util/Paths.kt b/ktor-server/jvm/src/io/ktor/server/util/Paths.kt index 1715a82f305..6725134275b 100644 --- a/ktor-server/jvm/src/io/ktor/server/util/Paths.kt +++ b/ktor-server/jvm/src/io/ktor/server/util/Paths.kt @@ -10,7 +10,6 @@ import io.ktor.util.* * Process path components such as `.` and `..`, replacing redundant path components including all leading. * It also discards all reserved characters and component names that are reserved (such as `CON`, `NUL`). */ -@InternalAPI public fun List.normalizePathComponents(): List { for (index in indices) { val component = get(index) @@ -105,6 +104,6 @@ private fun String.shouldBeReplaced(): Boolean { private fun CharArray.toASCIITable(): BooleanArray = BooleanArray(0x100) { it.toChar() in this@toASCIITable } private operator fun BooleanArray.contains(char: Char): Boolean { - val codepoint = char.toInt() + val codepoint = char.code return codepoint < size && this[codepoint] } diff --git a/ktor-server/jvm/test/io/ktor/tests/http/PathNormalizationTest.kt b/ktor-server/jvm/test/io/ktor/tests/http/PathNormalizationTest.kt index 469fadf4557..92f9895e2c2 100644 --- a/ktor-server/jvm/test/io/ktor/tests/http/PathNormalizationTest.kt +++ b/ktor-server/jvm/test/io/ktor/tests/http/PathNormalizationTest.kt @@ -5,6 +5,7 @@ package io.ktor.tests.http import io.ktor.server.util.* +import java.util.* import kotlin.test.* class PathNormalizationTest { @@ -116,7 +117,20 @@ class PathNormalizationTest { "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" ) - for (name in names + names.map { it.toLowerCase() } + names.map { it.toLowerCase().capitalize() }) { + val allNames = names + + names.map { it.lowercase(Locale.getDefault()) } + + names.map { name -> + name.lowercase(Locale.getDefault()) + .replaceFirstChar { char -> + if (char.isLowerCase()) { + char.titlecase(Locale.getDefault()) + } else { + char.toString() + } + } + } + + for (name in allNames) { assertEquals(listOf(), listOf(name).normalizePathComponents()) assertEquals(listOf(), listOf(name, name).normalizePathComponents()) assertEquals(listOf("a"), listOf(name, "a", name).normalizePathComponents()) diff --git a/ktor-server/jvm/test/io/ktor/tests/http/content/StaticContentResolutionTest.kt b/ktor-server/jvm/test/io/ktor/tests/http/content/StaticContentResolutionTest.kt index 23e94fe1260..0712b40777d 100644 --- a/ktor-server/jvm/test/io/ktor/tests/http/content/StaticContentResolutionTest.kt +++ b/ktor-server/jvm/test/io/ktor/tests/http/content/StaticContentResolutionTest.kt @@ -16,6 +16,7 @@ class StaticContentResolutionTest { private val baseUrl = StaticContentResolutionTest::class.java.classLoader.getResource("testjar.jar") + @OptIn(InternalAPI::class) @Test fun testResourceClasspathResourceWithDirectoryInsideJar() { val content = resourceClasspathResource(URL("jar:$baseUrl!/testdir"), "testdir") { @@ -25,6 +26,7 @@ class StaticContentResolutionTest { assertNull(content) } + @OptIn(InternalAPI::class) @Test fun testResourceClasspathResourceWithFileInsideJar() { val content = resourceClasspathResource(URL("jar:$baseUrl!/testdir/testfile"), "testdir/testfile") { diff --git a/ktor-server/jvm/test/io/ktor/tests/utils/CopyOnWriteHashMapTest.kt b/ktor-server/jvm/test/io/ktor/tests/utils/CopyOnWriteHashMapTest.kt index c06911609eb..89f2c22b7a8 100644 --- a/ktor-server/jvm/test/io/ktor/tests/utils/CopyOnWriteHashMapTest.kt +++ b/ktor-server/jvm/test/io/ktor/tests/utils/CopyOnWriteHashMapTest.kt @@ -5,8 +5,10 @@ package io.ktor.tests.utils import io.ktor.server.util.* +import io.ktor.util.* import kotlin.test.* +@OptIn(InternalAPI::class) class CopyOnWriteHashMapTest { private val map = CopyOnWriteHashMap() diff --git a/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/CIOApplicationCall.kt b/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/CIOApplicationCall.kt index e966fdc817a..af6a2666b4f 100644 --- a/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/CIOApplicationCall.kt +++ b/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/CIOApplicationCall.kt @@ -12,6 +12,7 @@ import kotlinx.coroutines.* import java.net.* import kotlin.coroutines.* +@OptIn(EngineAPI::class) internal class CIOApplicationCall( application: Application, _request: Request, diff --git a/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/CIOApplicationEngine.kt b/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/CIOApplicationEngine.kt index 350ad56414b..ef5f80bf008 100644 --- a/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/CIOApplicationEngine.kt +++ b/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/CIOApplicationEngine.kt @@ -9,6 +9,7 @@ import io.ktor.server.application.* import io.ktor.server.cio.backend.* import io.ktor.server.engine.* import io.ktor.server.util.* +import io.ktor.util.* import io.ktor.util.pipeline.* import kotlinx.coroutines.* import kotlinx.coroutines.scheduling.* @@ -16,6 +17,7 @@ import kotlinx.coroutines.scheduling.* /** * Engine that based on CIO backend */ +@OptIn(EngineAPI::class, InternalAPI::class) public class CIOApplicationEngine( environment: ApplicationEngineEnvironment, configure: Configuration.() -> Unit @@ -42,7 +44,7 @@ public class CIOApplicationEngine( @OptIn(InternalCoroutinesApi::class) private val engineDispatcher = ExperimentalCoroutineDispatcher(corePoolSize) - @OptIn(InternalCoroutinesApi::class) + @OptIn(InternalCoroutinesApi::class, InternalAPI::class) private val userDispatcher = DispatcherWithShutdown(engineDispatcher.blocking(configuration.callGroupSize)) private val startupJob: CompletableDeferred = CompletableDeferred() @@ -119,6 +121,7 @@ public class CIOApplicationEngine( return this } + @OptIn(DelicateCoroutinesApi::class) override fun stop(gracePeriodMillis: Long, timeoutMillis: Long) { try { shutdownServer(gracePeriodMillis, timeoutMillis) diff --git a/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/CIOApplicationRequest.kt b/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/CIOApplicationRequest.kt index 9495f3a056d..0d3fedaa72a 100644 --- a/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/CIOApplicationRequest.kt +++ b/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/CIOApplicationRequest.kt @@ -9,6 +9,7 @@ import io.ktor.http.cio.* import io.ktor.server.application.* import io.ktor.server.engine.* import io.ktor.server.request.* +import io.ktor.util.* import io.ktor.utils.io.* import java.net.* @@ -22,6 +23,8 @@ internal class CIOApplicationRequest( override val cookies: RequestCookies by lazy(LazyThreadSafetyMode.NONE) { RequestCookies(this) } override fun receiveChannel() = input + + @OptIn(InternalAPI::class) override val headers: Headers = CIOHeaders(request.headers) override val queryParameters: Parameters by lazy(LazyThreadSafetyMode.NONE) { diff --git a/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/backend/HttpServer.kt b/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/backend/HttpServer.kt index 708f86c4a77..217cea1868e 100644 --- a/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/backend/HttpServer.kt +++ b/ktor-server/ktor-server-cio/jvm/src/io/ktor/server/cio/backend/HttpServer.kt @@ -18,7 +18,7 @@ import java.nio.channels.* /** * Start an http server with [settings] invoking [handler] for every request */ -@OptIn(InternalAPI::class) +@OptIn(InternalAPI::class, EngineAPI::class) public fun CoroutineScope.httpServer( settings: HttpServerSettings, handler: HttpRequestHandler diff --git a/ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/RAWExample.kt b/ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/RAWExample.kt index 8607d5c4889..880e8f3261f 100644 --- a/ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/RAWExample.kt +++ b/ktor-server/ktor-server-cio/jvm/test/io/ktor/tests/server/cio/RAWExample.kt @@ -27,6 +27,7 @@ private val notFound404_11 = RequestResponseBuilder().apply { /** * This is just an example demonstrating how to create CIO low-level http server */ +@OptIn(DelicateCoroutinesApi::class) fun main() { val settings = HttpServerSettings() diff --git a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/ApplicationEngineEnvironment.kt b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/ApplicationEngineEnvironment.kt index 3b690ed96be..9cc40232b71 100644 --- a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/ApplicationEngineEnvironment.kt +++ b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/ApplicationEngineEnvironment.kt @@ -108,6 +108,7 @@ public class ApplicationEngineEnvironmentBuilder { /** * Build an application engine environment */ + @OptIn(EngineAPI::class) public fun build(builder: ApplicationEngineEnvironmentBuilder.() -> Unit): ApplicationEngineEnvironment { builder(this) return ApplicationEngineEnvironmentReloading( diff --git a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/BaseApplicationEngine.kt b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/BaseApplicationEngine.kt index 3caeb423772..4cbc9c98bab 100644 --- a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/BaseApplicationEngine.kt +++ b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/BaseApplicationEngine.kt @@ -68,6 +68,7 @@ public abstract class BaseApplicationEngine( } } + @OptIn(InternalAPI::class) private fun Application.installDefaultInterceptors() { intercept(ApplicationCallPipeline.Setup) { call.response.pipeline.intercept(ApplicationSendPipeline.Before) { diff --git a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/CommandLine.kt b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/CommandLine.kt index a0d4914f445..060ea074712 100644 --- a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/CommandLine.kt +++ b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/CommandLine.kt @@ -163,6 +163,7 @@ private fun String.splitPair(ch: Char): Pair? = indexOf(ch).let /** * Load engine's configuration suitable for all engines from [deploymentConfig] */ +@OptIn(EngineAPI::class) public fun BaseApplicationEngine.Configuration.loadCommonConfiguration(deploymentConfig: ApplicationConfig) { deploymentConfig.propertyOrNull("callGroupSize")?.getString()?.toInt()?.let { callGroupSize = it diff --git a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/DefaultEnginePipeline.kt b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/DefaultEnginePipeline.kt index 82fdcaa0147..d0d302c5f2f 100644 --- a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/DefaultEnginePipeline.kt +++ b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/DefaultEnginePipeline.kt @@ -22,6 +22,7 @@ import java.util.concurrent.* /** * Default engine pipeline for all engines. Use it only if you are writing your own application engine implementation. */ +@OptIn(InternalAPI::class) @EngineAPI public fun defaultEnginePipeline(environment: ApplicationEnvironment): EnginePipeline { val pipeline = EnginePipeline(environment.developmentMode) @@ -58,6 +59,7 @@ public suspend fun handleFailure(call: ApplicationCall, error: Throwable) { tryRespondError(call, defaultExceptionStatusCode(error) ?: HttpStatusCode.InternalServerError) } +@OptIn(InternalAPI::class) @EngineAPI public suspend fun logError(call: ApplicationCall, error: Throwable) { call.application.mdcProvider.withMDCBlock(call) { diff --git a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/DefaultTransform.kt b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/DefaultTransform.kt index bfe4a958bce..5dbb458db4a 100644 --- a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/DefaultTransform.kt +++ b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/DefaultTransform.kt @@ -12,7 +12,9 @@ import io.ktor.server.http.content.* import io.ktor.server.plugins.* import io.ktor.server.request.* import io.ktor.server.response.* +import io.ktor.util.* import io.ktor.util.cio.* +import io.ktor.util.cio.toByteArray import io.ktor.util.pipeline.* import io.ktor.utils.io.* import io.ktor.utils.io.charsets.* @@ -114,6 +116,7 @@ private inline fun withContentType(call: ApplicationCall, block: () -> R): R ) } +@OptIn(InternalAPI::class) private fun PipelineContext<*, ApplicationCall>.multiPartData(rc: ByteReadChannel): MultiPartData { val contentType = call.request.header(HttpHeaders.ContentType) ?: throw IllegalStateException("Content-Type header is required for multipart processing") diff --git a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/EmbeddedServer.kt b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/EmbeddedServer.kt index 469856d85c7..506d72297f5 100644 --- a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/EmbeddedServer.kt +++ b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/EmbeddedServer.kt @@ -26,6 +26,7 @@ public interface ApplicationEngineFactory embeddedServer( factory: ApplicationEngineFactory, diff --git a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/EngineContextCancellationHelper.kt b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/EngineContextCancellationHelper.kt index 34aca78dc24..cc4964d4e8c 100644 --- a/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/EngineContextCancellationHelper.kt +++ b/ktor-server/ktor-server-host-common/jvm/src/io/ktor/server/engine/EngineContextCancellationHelper.kt @@ -10,6 +10,7 @@ import kotlinx.coroutines.* /** * Stop server on job cancellation. The returned deferred need to be completed or cancelled. */ +@OptIn(InternalAPI::class) @EngineAPI public fun ApplicationEngine.stopServerOnCancellation(): CompletableJob = environment.parentCoroutineContext[Job]?.launchOnCancellation { @@ -21,6 +22,7 @@ public fun ApplicationEngine.stopServerOnCancellation(): CompletableJob = * It is important to complete or cancel returned deferred * otherwise the parent job will be unable to complete successfully. */ +@OptIn(DelicateCoroutinesApi::class) @InternalAPI public fun Job.launchOnCancellation(block: suspend () -> Unit): CompletableJob { val deferred: CompletableJob = Job(parent = this) diff --git a/ktor-server/ktor-server-host-common/jvm/test/io/ktor/tests/hosts/ApplicationEngineEnvironmentReloadingTests.kt b/ktor-server/ktor-server-host-common/jvm/test/io/ktor/tests/hosts/ApplicationEngineEnvironmentReloadingTests.kt index 216714a7844..355e22de34a 100644 --- a/ktor-server/ktor-server-host-common/jvm/test/io/ktor/tests/hosts/ApplicationEngineEnvironmentReloadingTests.kt +++ b/ktor-server/ktor-server-host-common/jvm/test/io/ktor/tests/hosts/ApplicationEngineEnvironmentReloadingTests.kt @@ -2,6 +2,8 @@ * Copyright 2014-2019 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +@file:Suppress("unused", "UNUSED_PARAMETER") + package io.ktor.tests.hosts import com.typesafe.config.* @@ -19,6 +21,7 @@ import kotlin.reflect.* import kotlin.reflect.jvm.* import kotlin.test.* +@OptIn(EngineAPI::class) class ApplicationEngineEnvironmentReloadingTests { @Test diff --git a/ktor-server/ktor-server-host-common/jvm/test/io/ktor/tests/hosts/ReceiveBlockingPrimitiveTest.kt b/ktor-server/ktor-server-host-common/jvm/test/io/ktor/tests/hosts/ReceiveBlockingPrimitiveTest.kt index 772e9f738de..fe669e0e954 100644 --- a/ktor-server/ktor-server-host-common/jvm/test/io/ktor/tests/hosts/ReceiveBlockingPrimitiveTest.kt +++ b/ktor-server/ktor-server-host-common/jvm/test/io/ktor/tests/hosts/ReceiveBlockingPrimitiveTest.kt @@ -15,7 +15,7 @@ import java.lang.reflect.* import kotlin.concurrent.* import kotlin.test.* -@OptIn(ExperimentalStdlibApi::class) +@OptIn(ExperimentalStdlibApi::class, EngineAPI::class) class ReceiveBlockingPrimitiveTest { private val pipeline = ApplicationReceivePipeline() diff --git a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationCall.kt b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationCall.kt index 56995854d4f..859af16cd17 100644 --- a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationCall.kt +++ b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationCall.kt @@ -5,6 +5,7 @@ package io.ktor.server.jetty import io.ktor.server.application.* +import io.ktor.server.engine.* import io.ktor.server.jetty.internal.* import io.ktor.server.servlet.* import io.ktor.util.* @@ -12,6 +13,7 @@ import org.eclipse.jetty.server.* import javax.servlet.http.* import kotlin.coroutines.* +@OptIn(EngineAPI::class) @Suppress("KDocMissingDocumentation") @InternalAPI public class JettyApplicationCall( diff --git a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngine.kt b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngine.kt index 020a3dd78ce..c9a187289ca 100644 --- a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngine.kt +++ b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngine.kt @@ -6,11 +6,13 @@ package io.ktor.server.jetty import io.ktor.server.engine.* import io.ktor.server.util.* +import io.ktor.util.* import kotlinx.coroutines.* /** * [ApplicationEngine] implementation for running in a standalone Jetty */ +@OptIn(EngineAPI::class, InternalAPI::class) public class JettyApplicationEngine( environment: ApplicationEngineEnvironment, configure: Configuration.() -> Unit diff --git a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngineBase.kt b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngineBase.kt index 18244b948af..6decd096b85 100644 --- a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngineBase.kt +++ b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationEngineBase.kt @@ -14,6 +14,7 @@ import java.util.concurrent.* /** * [ApplicationEngine] base type for running in a standalone Jetty */ +@OptIn(EngineAPI::class) public open class JettyApplicationEngineBase @EngineAPI constructor( environment: ApplicationEngineEnvironment, configure: Configuration.() -> Unit diff --git a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationResponse.kt b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationResponse.kt index b14d61ba7a9..d16384ae378 100644 --- a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationResponse.kt +++ b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyApplicationResponse.kt @@ -5,6 +5,7 @@ package io.ktor.server.jetty import io.ktor.http.* +import io.ktor.server.engine.* import io.ktor.server.jetty.internal.* import io.ktor.server.response.* import io.ktor.server.servlet.* @@ -15,7 +16,8 @@ import kotlin.coroutines.* @Suppress("KDocMissingDocumentation") @InternalAPI -public class JettyApplicationResponse( +@OptIn(EngineAPI::class) +public class JettyApplicationResponse constructor( call: AsyncServletApplicationCall, servletRequest: HttpServletRequest, servletResponse: HttpServletResponse, diff --git a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyKtorHandler.kt b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyKtorHandler.kt index 7d476a5bf65..9e2b79cab3f 100644 --- a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyKtorHandler.kt +++ b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/JettyKtorHandler.kt @@ -27,6 +27,7 @@ private val JettyKtorCounter = AtomicLong() private const val THREAD_KEEP_ALIVE_TIME = 1L +@OptIn(InternalAPI::class, EngineAPI::class) internal class JettyKtorHandler( val environment: ApplicationEngineEnvironment, private val pipeline: () -> EnginePipeline, @@ -50,9 +51,7 @@ internal class JettyKtorHandler( private val handlerJob = SupervisorJob(environment.parentCoroutineContext[Job]) override val coroutineContext: CoroutineContext = - environment.parentCoroutineContext + - handlerJob + - DefaultUncaughtExceptionHandler(environment.log) + environment.parentCoroutineContext + handlerJob + DefaultUncaughtExceptionHandler(environment.log) override fun destroy() { dispatcher.prepareShutdown() diff --git a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/internal/JettyUpgradeImpl.kt b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/internal/JettyUpgradeImpl.kt index 4c8635be26e..b873cd4b90b 100644 --- a/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/internal/JettyUpgradeImpl.kt +++ b/ktor-server/ktor-server-jetty/jvm/src/io/ktor/server/jetty/internal/JettyUpgradeImpl.kt @@ -5,6 +5,7 @@ package io.ktor.server.jetty.internal import io.ktor.http.content.* +import io.ktor.server.engine.* import io.ktor.server.servlet.* import io.ktor.util.* import io.ktor.utils.io.* @@ -15,6 +16,7 @@ import java.util.concurrent.* import javax.servlet.http.* import kotlin.coroutines.* +@OptIn(EngineAPI::class) @Suppress("KDocMissingDocumentation") @InternalAPI public object JettyUpgradeImpl : ServletUpgrade { diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationCall.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationCall.kt index 88ba5aa75e3..8d5702a2fa6 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationCall.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationCall.kt @@ -6,6 +6,7 @@ package io.ktor.server.netty import io.ktor.server.application.* import io.ktor.server.engine.* +import io.ktor.util.* import io.netty.channel.* import io.netty.util.* import kotlinx.atomicfu.* @@ -13,6 +14,7 @@ import kotlinx.coroutines.* @Suppress("KDocMissingDocumentation") @EngineAPI +@OptIn(InternalAPI::class) public abstract class NettyApplicationCall( application: Application, public val context: ChannelHandlerContext, @@ -29,9 +31,9 @@ public abstract class NettyApplicationCall( internal suspend fun finish() { try { response.ensureResponseSent() - } catch (t: Throwable) { + } catch (cause: Throwable) { finishComplete() - throw t + throw cause } if (responseWriteJob.isCompleted) { diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationCallHandler.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationCallHandler.kt index c6a35c6e318..5353fdf4546 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationCallHandler.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationCallHandler.kt @@ -24,9 +24,9 @@ internal class NettyApplicationCallHandler( private val enginePipeline: EnginePipeline, logger: Logger ) : ChannelInboundHandlerAdapter(), CoroutineScope { + @OptIn(EngineAPI::class) override val coroutineContext: CoroutineContext = userCoroutineContext + - CallHandlerCoroutineName + - DefaultUncaughtExceptionHandler(logger) + CallHandlerCoroutineName + DefaultUncaughtExceptionHandler(logger) override fun channelRead(ctx: ChannelHandlerContext, msg: Any) { when (msg) { @@ -35,7 +35,7 @@ internal class NettyApplicationCallHandler( } } - @OptIn(ExperimentalCoroutinesApi::class) + @OptIn(ExperimentalCoroutinesApi::class, EngineAPI::class) private fun handleRequest(context: ChannelHandlerContext, call: ApplicationCall) { val callContext = CallHandlerCoroutineName + NettyDispatcher.CurrentContext(context) diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationEngine.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationEngine.kt index 7bfc6d148f3..0a1a2ed7a1f 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationEngine.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationEngine.kt @@ -27,6 +27,7 @@ import kotlin.reflect.* /** * [ApplicationEngine] implementation for running in a standalone Netty */ +@OptIn(EngineAPI::class, InternalAPI::class) public class NettyApplicationEngine( environment: ApplicationEngineEnvironment, configure: Configuration.() -> Unit = {} diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationResponse.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationResponse.kt index 645edbb32f5..cf9ff674eea 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationResponse.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyApplicationResponse.kt @@ -17,6 +17,7 @@ import kotlin.coroutines.* @Suppress("KDocMissingDocumentation") @InternalAPI +@OptIn(EngineAPI::class) public abstract class NettyApplicationResponse( call: NettyApplicationCall, protected val context: ChannelHandlerContext, @@ -24,7 +25,7 @@ public abstract class NettyApplicationResponse( protected val userContext: CoroutineContext ) : BaseApplicationResponse(call) { - public val responseMessage: CompletableDeferred = CompletableDeferred() + public val responseMessage: CompletableDeferred = CompletableDeferred() @Volatile protected var responseMessageSent: Boolean = false diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyChannelInitializer.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyChannelInitializer.kt index c680ebb5c70..7ec5b3e27f8 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyChannelInitializer.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/NettyChannelInitializer.kt @@ -123,6 +123,7 @@ public class NettyChannelInitializer( when (protocol) { ApplicationProtocolNames.HTTP_2 -> { val handler = NettyHttp2Handler(enginePipeline, environment.application, callEventGroup, userContext) + @Suppress("DEPRECATION") pipeline.addLast(Http2MultiplexCodecBuilder.forServer(handler).build()) pipeline.channel().closeFuture().addListener { handler.cancel() @@ -188,7 +189,7 @@ public class NettyChannelInitializer( } try { - if (OpenSsl.isAlpnSupported()) { + if (SslProvider.isAlpnSupported(SslProvider.OPENSSL)) { return SslProvider.OPENSSL } } catch (ignore: Throwable) { diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/cio/NettyRequestQueue.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/cio/NettyRequestQueue.kt index 7e432112658..18732b525f4 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/cio/NettyRequestQueue.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/cio/NettyRequestQueue.kt @@ -4,7 +4,9 @@ package io.ktor.server.netty.cio +import io.ktor.server.engine.* import io.ktor.server.netty.* +import io.ktor.util.* import io.ktor.util.internal.* import kotlinx.atomicfu.* import kotlinx.coroutines.* @@ -20,38 +22,41 @@ internal class NettyRequestQueue(internal val readLimit: Int, internal val runni val elements: ReceiveChannel = incomingQueue - public fun schedule(call: NettyApplicationCall) { + @OptIn(EngineAPI::class) + fun schedule(call: NettyApplicationCall) { val element = CallElement(call) try { - incomingQueue.offer(element) + incomingQueue.trySend(element).isSuccess } catch (t: Throwable) { element.tryDispose() } } - public fun close() { + fun close() { incomingQueue.close() } - public fun cancel() { + fun cancel() { incomingQueue.close() while (true) { - incomingQueue.poll()?.tryDispose() ?: break + incomingQueue.tryReceive().getOrNull()?.tryDispose() ?: break } } @OptIn(ExperimentalCoroutinesApi::class) - public fun canRequestMoreEvents(): Boolean = incomingQueue.isEmpty + fun canRequestMoreEvents(): Boolean = incomingQueue.isEmpty + @OptIn(EngineAPI::class) internal class CallElement(val call: NettyApplicationCall) : LockFreeLinkedListNode() { private val scheduled = atomic(0) + @OptIn(InternalAPI::class) private val message: Job = call.response.responseMessage val isCompleted: Boolean get() = message.isCompleted - public fun ensureRunning(): Boolean { + fun ensureRunning(): Boolean { scheduled.update { value -> when (value) { 0 -> 1 @@ -64,7 +69,7 @@ internal class NettyRequestQueue(internal val readLimit: Int, internal val runni return true } - public fun tryDispose() { + fun tryDispose() { if (scheduled.compareAndSet(0, 2)) { call.dispose() } diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/cio/NettyResponsePipeline.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/cio/NettyResponsePipeline.kt index f171530742a..0abdbc10ba7 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/cio/NettyResponsePipeline.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/cio/NettyResponsePipeline.kt @@ -5,6 +5,7 @@ package io.ktor.server.netty.cio import io.ktor.http.* +import io.ktor.server.engine.* import io.ktor.server.netty.* import io.ktor.server.netty.http2.* import io.ktor.server.netty.http2.NettyHttp2ApplicationResponse @@ -25,7 +26,8 @@ import kotlin.coroutines.* private const val UNFLUSHED_LIMIT = 65536 -internal class NettyResponsePipeline( +@OptIn(InternalAPI::class, EngineAPI::class) +internal class NettyResponsePipeline constructor( private val dst: ChannelHandlerContext, initialEncapsulation: WriterEncapsulation, private val requestQueue: NettyRequestQueue, @@ -56,7 +58,7 @@ internal class NettyResponsePipeline( private var encapsulation: WriterEncapsulation = initialEncapsulation - public fun ensureRunning() { + fun ensureRunning() { responses.start() } @@ -94,7 +96,7 @@ internal class NettyResponsePipeline( private suspend fun fillSuspend() { if (running.isEmpty()) { @OptIn(ExperimentalCoroutinesApi::class) - val e = incoming.receiveOrNull() + val e = incoming.receiveCatching().getOrNull() if (e != null && e.ensureRunning()) { running.addLast(e) @@ -105,7 +107,7 @@ internal class NettyResponsePipeline( private fun pollReady(): Boolean { for (index in 1..(readyQueueSize - ready.size)) { - val e = incoming.poll() ?: return false + val e = incoming.tryReceive().getOrNull() ?: return false ready.addLast(e) } return true @@ -266,6 +268,7 @@ internal class NettyResponsePipeline( var unflushedBytes = 0 var lastFuture: ChannelFuture = requestMessageFuture + @Suppress("DEPRECATION") channel.lookAheadSuspend { while (true) { val buffer = request(0, 1) @@ -313,6 +316,7 @@ internal class NettyResponsePipeline( var unflushedBytes = 0 var lastFuture: ChannelFuture = requestMessageFuture + @Suppress("DEPRECATION") channel.lookAheadSuspend { while (true) { val buffer = request(0, 1) @@ -349,6 +353,7 @@ internal class NettyResponsePipeline( } } +@OptIn(InternalAPI::class) private fun NettyApplicationResponse.isUpgradeResponse() = status()?.value == HttpStatusCode.SwitchingProtocols.value diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/cio/RequestBodyHandler.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/cio/RequestBodyHandler.kt index 0f96b556b30..a009ba1ac13 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/cio/RequestBodyHandler.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/cio/RequestBodyHandler.kt @@ -33,8 +33,8 @@ internal class RequestBodyHandler( try { while (true) { @OptIn(ExperimentalCoroutinesApi::class) - val event = queue.poll() - ?: run { current?.flush(); queue.receiveOrNull() } + val event = queue.tryReceive().getOrNull() + ?: run { current?.flush(); queue.receiveCatching().getOrNull() } ?: break if (event is ByteBufHolder) { @@ -66,12 +66,12 @@ internal class RequestBodyHandler( } } - public fun upgrade(): ByteReadChannel { + fun upgrade(): ByteReadChannel { tryOfferChannelOrToken(Upgrade) return newChannel() } - public fun newChannel(): ByteReadChannel { + fun newChannel(): ByteReadChannel { val bc = ByteChannel() tryOfferChannelOrToken(bc) return bc @@ -79,7 +79,7 @@ internal class RequestBodyHandler( private fun tryOfferChannelOrToken(token: Any) { try { - if (!queue.offer(token)) { + if (!queue.trySend(token).isSuccess) { throw IllegalStateException( "Unable to start request processing: failed to offer $token to the HTTP pipeline queue" ) @@ -89,17 +89,15 @@ internal class RequestBodyHandler( } } - public fun close() { + fun close() { queue.close() } override fun channelRead(ctx: ChannelHandlerContext, msg: Any?) { - if (msg is ByteBufHolder) { - handleBytesRead(msg) - } else if (msg is ByteBuf) { - handleBytesRead(msg) - } else { - ctx.fireChannelRead(msg) + when (msg) { + is ByteBufHolder -> handleBytesRead(msg) + is ByteBuf -> handleBytesRead(msg) + else -> ctx.fireChannelRead(msg) } } @@ -132,7 +130,7 @@ internal class RequestBodyHandler( private fun consumeAndReleaseQueue() { while (!queue.isEmpty) { val e = try { - queue.poll() + queue.tryReceive().getOrNull() } catch (t: Throwable) { null } ?: break @@ -155,7 +153,7 @@ internal class RequestBodyHandler( } private fun handleBytesRead(content: ReferenceCounted) { - if (!queue.offer(content)) { + if (!queue.trySend(content).isSuccess) { content.release() throw IllegalStateException("Unable to process received buffer: queue offer failed") } diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1ApplicationCall.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1ApplicationCall.kt index bb4c755e381..8a90b18ca37 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1ApplicationCall.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1ApplicationCall.kt @@ -5,12 +5,14 @@ package io.ktor.server.netty.http1 import io.ktor.server.application.* +import io.ktor.server.engine.* import io.ktor.server.netty.* import io.ktor.utils.io.* import io.netty.channel.* import io.netty.handler.codec.http.* import kotlin.coroutines.* +@OptIn(EngineAPI::class) internal class NettyHttp1ApplicationCall( application: Application, context: ChannelHandlerContext, diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1ApplicationRequest.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1ApplicationRequest.kt index d61f09bfe10..4e68b2ea062 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1ApplicationRequest.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1ApplicationRequest.kt @@ -7,12 +7,14 @@ package io.ktor.server.netty.http1 import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.netty.* +import io.ktor.util.* import io.ktor.utils.io.* import io.netty.channel.* import io.netty.handler.codec.http.* import io.netty.handler.codec.http.multipart.* import kotlin.coroutines.* +@OptIn(InternalAPI::class) internal class NettyHttp1ApplicationRequest( call: ApplicationCall, coroutineContext: CoroutineContext, diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1ApplicationResponse.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1ApplicationResponse.kt index 6fc2060600e..015234ecd67 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1ApplicationResponse.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1ApplicationResponse.kt @@ -6,9 +6,11 @@ package io.ktor.server.netty.http1 import io.ktor.http.* import io.ktor.http.content.* +import io.ktor.server.engine.* import io.ktor.server.netty.* import io.ktor.server.netty.cio.* import io.ktor.server.response.* +import io.ktor.util.* import io.ktor.utils.io.* import io.netty.buffer.* import io.netty.channel.* @@ -16,7 +18,8 @@ import io.netty.handler.codec.http.* import kotlinx.coroutines.CancellationException import kotlin.coroutines.* -internal class NettyHttp1ApplicationResponse( +@OptIn(EngineAPI::class, InternalAPI::class) +internal class NettyHttp1ApplicationResponse constructor( call: NettyApplicationCall, context: ChannelHandlerContext, engineContext: CoroutineContext, diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1Handler.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1Handler.kt index facc428cdd9..1be19ea4729 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1Handler.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http1/NettyHttp1Handler.kt @@ -8,6 +8,7 @@ import io.ktor.server.application.* import io.ktor.server.engine.* import io.ktor.server.netty.* import io.ktor.server.netty.cio.* +import io.ktor.util.* import io.ktor.util.cio.* import io.ktor.utils.io.* import io.netty.channel.* @@ -82,6 +83,7 @@ internal class NettyHttp1Handler( } } + @OptIn(InternalAPI::class) override fun channelActive(ctx: ChannelHandlerContext) { if (!configured) { configured = true diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2ApplicationCall.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2ApplicationCall.kt index 1fdb8b2927d..3d13e4b0e64 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2ApplicationCall.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2ApplicationCall.kt @@ -5,11 +5,13 @@ package io.ktor.server.netty.http2 import io.ktor.server.application.* +import io.ktor.server.engine.* import io.ktor.server.netty.* import io.netty.channel.* import io.netty.handler.codec.http2.* import kotlin.coroutines.* +@OptIn(EngineAPI::class) internal class NettyHttp2ApplicationCall( application: Application, context: ChannelHandlerContext, diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2ApplicationRequest.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2ApplicationRequest.kt index ad2873b331c..425f1cc9d9e 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2ApplicationRequest.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2ApplicationRequest.kt @@ -8,6 +8,7 @@ import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.netty.* import io.ktor.server.request.* +import io.ktor.util.* import io.ktor.utils.io.* import io.netty.channel.* import io.netty.handler.codec.http.* @@ -19,6 +20,7 @@ import kotlinx.coroutines.channels.* import java.net.* import kotlin.coroutines.* +@OptIn(InternalAPI::class) internal class NettyHttp2ApplicationRequest( call: ApplicationCall, coroutineContext: CoroutineContext, diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2ApplicationResponse.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2ApplicationResponse.kt index c41557edeb1..fed855cd9c4 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2ApplicationResponse.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2ApplicationResponse.kt @@ -6,6 +6,7 @@ package io.ktor.server.netty.http2 import io.ktor.http.* import io.ktor.http.content.* +import io.ktor.server.engine.* import io.ktor.server.netty.* import io.ktor.server.response.* import io.ktor.util.* @@ -13,7 +14,8 @@ import io.netty.channel.* import io.netty.handler.codec.http2.* import kotlin.coroutines.* -internal class NettyHttp2ApplicationResponse( +@OptIn(EngineAPI::class, InternalAPI::class) +internal class NettyHttp2ApplicationResponse constructor( call: NettyApplicationCall, val handler: NettyHttp2Handler, context: ChannelHandlerContext, diff --git a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2Handler.kt b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2Handler.kt index a0b21253a04..38335009eec 100644 --- a/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2Handler.kt +++ b/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/http2/NettyHttp2Handler.kt @@ -10,9 +10,10 @@ import io.ktor.server.engine.* import io.ktor.server.netty.* import io.ktor.server.netty.cio.* import io.ktor.server.response.* +import io.ktor.util.* import io.netty.channel.* import io.netty.handler.codec.http2.* -import io.netty.util.* +import io.netty.util.AttributeKey import io.netty.util.concurrent.* import kotlinx.coroutines.* import java.lang.reflect.* @@ -39,7 +40,7 @@ internal class NettyHttp2Handler( is Http2DataFrame -> { context.applicationCall?.request?.apply { val eof = message.isEndStream - contentActor.offer(message) + contentActor.trySend(message).isSuccess if (eof) { contentActor.close() } @@ -68,6 +69,7 @@ internal class NettyHttp2Handler( ctx.close() } + @OptIn(InternalAPI::class) private fun startHttp2(context: ChannelHandlerContext, headers: Http2Headers) { val requestQueue = NettyRequestQueue(1, 1) val responseWriter = NettyResponsePipeline(context, WriterEncapsulation.Http2, requestQueue, handlerJob) @@ -88,6 +90,7 @@ internal class NettyHttp2Handler( responseWriter.ensureRunning() } + @Suppress("DEPRECATION") @UseHttp2Push internal fun startHttp2PushPromise(context: ChannelHandlerContext, builder: ResponsePushBuilder) { val channel = context.channel() as Http2StreamChannel @@ -193,12 +196,12 @@ internal class NettyHttp2Handler( override val message: String get() = "Got close frame with code $errorCode" - override fun createCopy(): Http2ClosedChannelException? = Http2ClosedChannelException(errorCode).also { + override fun createCopy(): Http2ClosedChannelException = Http2ClosedChannelException(errorCode).also { it.initCause(this) } } - public companion object { + companion object { private val ApplicationCallKey = AttributeKey.newInstance("ktor.ApplicationCall") private var ChannelHandlerContext.applicationCall: NettyHttp2ApplicationCall? diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuthSchemes.kt b/ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuthSchemes.kt index 6f0df6b1c8b..9020c8d8e87 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuthSchemes.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuthSchemes.kt @@ -4,9 +4,11 @@ package io.ktor.server.auth.jwt +import java.util.* + internal class JWTAuthSchemes(val defaultScheme: String, vararg additionalSchemes: String) { val schemes = (arrayOf(defaultScheme) + additionalSchemes).toSet() - val schemesLowerCase = schemes.map { it.toLowerCase() }.toSet() + val schemesLowerCase = schemes.map { it.lowercase(Locale.getDefault()) }.toSet() - operator fun contains(scheme: String): Boolean = scheme.toLowerCase() in schemesLowerCase + operator fun contains(scheme: String): Boolean = scheme.lowercase(Locale.getDefault()) in schemesLowerCase } diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/src/io/ktor/server/auth/ldap/Ldap.kt b/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/src/io/ktor/server/auth/ldap/Ldap.kt index fbd95f4fe25..a2d060e2dd1 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/src/io/ktor/server/auth/ldap/Ldap.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/src/io/ktor/server/auth/ldap/Ldap.kt @@ -108,7 +108,7 @@ private fun ldapEscapeImpl(string: String, firstIndex: Int): String = buildStrin private val ESCAPE_CHARACTERS = charArrayOf(' ', '"', '#', '+', ',', ';', '<', '=', '>', '\\') -private fun Char.shouldEscape(): Boolean = this.toInt().let { codepoint -> +private fun Char.shouldEscape(): Boolean = this.code.let { codepoint -> when (codepoint) { in 0x3f..0x7e -> codepoint == 0x5c // the only forbidden character is backslash in 0x2d..0x3a -> false // minus, point, slash (allowed), digits + colon : diff --git a/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/test/io/ktor/tests/auth/ldap/LdapAuthTest.kt b/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/test/io/ktor/tests/auth/ldap/LdapAuthTest.kt index d659113b9f1..ddfe1b9346f 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/test/io/ktor/tests/auth/ldap/LdapAuthTest.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-auth-ldap/jvm/test/io/ktor/tests/auth/ldap/LdapAuthTest.kt @@ -24,6 +24,7 @@ import javax.naming.directory.* import javax.naming.ldap.* import kotlin.test.* +@Suppress("DEPRECATION") @RunWith(FrameworkRunner::class) @CreateLdapServer(transports = arrayOf(CreateTransport(protocol = "LDAP"))) @Ignore("LdapAuthTest is ignored because it is very slow. Run it explicitly when you need.") diff --git a/ktor-server/ktor-server-plugins/ktor-server-cors/api/ktor-server-cors.api b/ktor-server/ktor-server-plugins/ktor-server-cors/api/ktor-server-cors.api index 5e3d74dae3e..b539ef74f4f 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-cors/api/ktor-server-cors.api +++ b/ktor-server/ktor-server-plugins/ktor-server-cors/api/ktor-server-cors.api @@ -54,6 +54,6 @@ public final class io/ktor/server/plugins/CORS$Plugin : io/ktor/server/applicati public final class io/ktor/server/plugins/KotlinTimeJvmKt { public static final fun getMaxAgeDuration (Lio/ktor/server/plugins/CORS$Configuration;)J - public static final fun setMaxAgeDuration-Kw8x68k (Lio/ktor/server/plugins/CORS$Configuration;J)V + public static final fun setMaxAgeDuration-HG0u8IE (Lio/ktor/server/plugins/CORS$Configuration;J)V } diff --git a/ktor-server/ktor-server-plugins/ktor-server-cors/jvm/src/io/ktor/server/plugins/CORS.kt b/ktor-server/ktor-server-plugins/ktor-server-cors/jvm/src/io/ktor/server/plugins/CORS.kt index 18b06c4d799..54a7324a82a 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-cors/jvm/src/io/ktor/server/plugins/CORS.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-cors/jvm/src/io/ktor/server/plugins/CORS.kt @@ -342,6 +342,7 @@ public class CORS(configuration: Configuration) { /** * Allowed CORS headers */ + @OptIn(InternalAPI::class) public val headers: MutableSet = CaseInsensitiveSet() /** @@ -352,6 +353,7 @@ public class CORS(configuration: Configuration) { /** * Exposed HTTP headers that could be accessed by a client */ + @OptIn(InternalAPI::class) public val exposedHeaders: MutableSet = CaseInsensitiveSet() /** @@ -486,6 +488,7 @@ public class CORS(configuration: Configuration) { return cors } + @OptIn(InternalAPI::class) private fun caseInsensitiveSet(vararg elements: String): Set = CaseInsensitiveSet(elements.asList()) } diff --git a/ktor-server/ktor-server-plugins/ktor-server-cors/jvm/src/io/ktor/server/plugins/KotlinTimeJvm.kt b/ktor-server/ktor-server-plugins/ktor-server-cors/jvm/src/io/ktor/server/plugins/KotlinTimeJvm.kt index b2476738f41..f7c8d5be37f 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-cors/jvm/src/io/ktor/server/plugins/KotlinTimeJvm.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-cors/jvm/src/io/ktor/server/plugins/KotlinTimeJvm.kt @@ -12,8 +12,8 @@ import kotlin.time.* */ @ExperimentalTime public var CORS.Configuration.maxAgeDuration: Duration - get() = maxAgeInSeconds.seconds + get() = Duration.seconds(maxAgeInSeconds) set(newMaxAge) { require(!newMaxAge.isNegative()) { "Only non-negative durations can be specified" } - maxAgeInSeconds = newMaxAge.inSeconds.roundToLong() + maxAgeInSeconds = newMaxAge.toDouble(DurationUnit.SECONDS).roundToLong() } diff --git a/ktor-server/ktor-server-plugins/ktor-server-default-headers/jvm/src/io/ktor/server/plugins/DefaultHeaders.kt b/ktor-server/ktor-server-plugins/ktor-server-default-headers/jvm/src/io/ktor/server/plugins/DefaultHeaders.kt index aa69a277d34..3ce6ee3af9f 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-default-headers/jvm/src/io/ktor/server/plugins/DefaultHeaders.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-default-headers/jvm/src/io/ktor/server/plugins/DefaultHeaders.kt @@ -18,6 +18,7 @@ import java.util.* */ public class DefaultHeaders(config: Configuration) { private val headers = config.headers.build() + @OptIn(InternalAPI::class) private val clock = config.clock private var cachedDateTimeStamp: Long = 0L @@ -40,7 +41,6 @@ public class DefaultHeaders(config: Configuration) { /** * Provides time source. Useful for testing. */ - @InternalAPI public var clock: () -> Long = { System.currentTimeMillis() } } diff --git a/ktor-server/ktor-server-plugins/ktor-server-forwarded-header/jvm/src/io/ktor/server/plugins/ForwardHeaderSupport.kt b/ktor-server/ktor-server-plugins/ktor-server-forwarded-header/jvm/src/io/ktor/server/plugins/ForwardHeaderSupport.kt index f1ffbca270e..33f89ecbb22 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-forwarded-header/jvm/src/io/ktor/server/plugins/ForwardHeaderSupport.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-forwarded-header/jvm/src/io/ktor/server/plugins/ForwardHeaderSupport.kt @@ -8,6 +8,7 @@ import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.request.* import io.ktor.util.* +import kotlin.reflect.KProperty /** * `X-Forwarded-*` headers support @@ -104,6 +105,7 @@ public object XForwardedHeaderSupport : /** * Port X-header names. Default is `X-Forwarded-Port` */ + @OptIn(InternalAPI::class) @PublicAPICandidate("2.0.0") internal val portHeaders: ArrayList = arrayListOf("X-Forwarded-Port") } diff --git a/ktor-server/ktor-server-plugins/ktor-server-hsts/api/ktor-server-hsts.api b/ktor-server/ktor-server-plugins/ktor-server-hsts/api/ktor-server-hsts.api index a77367e6543..c325d0a57da 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-hsts/api/ktor-server-hsts.api +++ b/ktor-server/ktor-server-plugins/ktor-server-hsts/api/ktor-server-hsts.api @@ -25,6 +25,6 @@ public final class io/ktor/server/plugins/HSTS$Plugin : io/ktor/server/applicati public final class io/ktor/server/plugins/KotlinTimeJvmKt { public static final fun getMaxAgeDuration (Lio/ktor/server/plugins/HSTS$Configuration;)J - public static final fun setMaxAgeDuration-x3IzF7w (Lio/ktor/server/plugins/HSTS$Configuration;J)V + public static final fun setMaxAgeDuration-HG0u8IE (Lio/ktor/server/plugins/HSTS$Configuration;J)V } diff --git a/ktor-server/ktor-server-plugins/ktor-server-hsts/jvm/src/io/ktor/server/plugins/KotlinTimeJvm.kt b/ktor-server/ktor-server-plugins/ktor-server-hsts/jvm/src/io/ktor/server/plugins/KotlinTimeJvm.kt index 0e578412da1..30cd87b0f32 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-hsts/jvm/src/io/ktor/server/plugins/KotlinTimeJvm.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-hsts/jvm/src/io/ktor/server/plugins/KotlinTimeJvm.kt @@ -9,8 +9,8 @@ import kotlin.time.* @ExperimentalTime public var HSTS.Configuration.maxAgeDuration: Duration - get() = maxAgeInSeconds.seconds + get() = Duration.seconds(maxAgeInSeconds) set(newMaxAge) { require(!newMaxAge.isNegative()) { "Only non-negative durations can be specified" } - maxAgeInSeconds = newMaxAge.inSeconds.roundToLong() + maxAgeInSeconds = newMaxAge.toDouble(DurationUnit.SECONDS).roundToLong() } diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/api/ktor-server-sessions.api b/ktor-server/ktor-server-plugins/ktor-server-sessions/api/ktor-server-sessions.api index 1cada747214..87b3a1e37e0 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/api/ktor-server-sessions.api +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/api/ktor-server-sessions.api @@ -82,7 +82,7 @@ public class io/ktor/server/sessions/HeaderSessionBuilder { public final class io/ktor/server/sessions/KotlinTimeJvmKt { public static final fun getMaxAge (Lio/ktor/server/sessions/CookieConfiguration;)Lkotlin/time/Duration; - public static final fun setMaxAge-YQjt_ts (Lio/ktor/server/sessions/CookieConfiguration;Lkotlin/time/Duration;)V + public static final fun setMaxAge-6Au4x4Y (Lio/ktor/server/sessions/CookieConfiguration;Lkotlin/time/Duration;)V } public final class io/ktor/server/sessions/SessionIdProviderKt { diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/Cache.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/Cache.kt index cbea859d3b9..c1a0fe7c4e4 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/Cache.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/Cache.kt @@ -27,7 +27,7 @@ internal interface CacheReference { val key: K } -@OptIn(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class, InternalAPI::class) internal class BaseCache(val calc: suspend (K) -> V) : Cache { private val container = ConcurrentHashMap>() @@ -77,6 +77,7 @@ internal class BaseCache(val calc: suspend (K) -> V) : Cach } } +@OptIn(InternalAPI::class) internal open class ReferenceCache( val calc: suspend (K) -> V, val wrapFunction: (K, V, ReferenceQueue) -> R @@ -124,7 +125,8 @@ internal open class ReferenceCache( } } -private class ReferenceWorker>( +@OptIn(InternalAPI::class) +private class ReferenceWorker> constructor( owner: Cache, val queue: ReferenceQueue<*> ) : Runnable { @@ -146,15 +148,18 @@ private class ReferenceWorker>( internal class CacheSoftReference(override val key: K, value: V, queue: ReferenceQueue) : SoftReference(value, queue), CacheReference + internal class CacheWeakReference(override val key: K, value: V, queue: ReferenceQueue) : WeakReference(value, queue), CacheReference internal class SoftReferenceCache(calc: suspend (K) -> V) : ReferenceCache>(calc, { k, v, q -> CacheSoftReference(k, v, q) }) + internal class WeakReferenceCache(calc: suspend (K) -> V) : ReferenceCache>(calc, { k, v, q -> CacheWeakReference(k, v, q) }) -internal class BaseTimeoutCache( +@OptIn(InternalAPI::class) +internal class BaseTimeoutCache constructor( val timeoutValue: Long, val touchOnGet: Boolean, val delegate: Cache @@ -237,11 +242,11 @@ private class KeyState(key: K, val timeout: Long) : ListElement>( val key: WeakReference = WeakReference(key) var lastAccess = System.currentTimeMillis() - public fun touch() { + fun touch() { lastAccess = System.currentTimeMillis() } - public fun timeToWait() = Math.max(0L, lastAccess + timeout - System.currentTimeMillis()) + fun timeToWait() = Math.max(0L, lastAccess + timeout - System.currentTimeMillis()) } private class TimeoutWorker( @@ -292,11 +297,11 @@ private class PullableLinkedList> { private var head: E? = null private var tail: E? = null - public fun isEmpty() = head == null - public fun take(): E = head().apply { remove(this) } - public fun head(): E = head ?: throw NoSuchElementException() + fun isEmpty() = head == null + fun take(): E = head().apply { remove(this) } + fun head(): E = head ?: throw NoSuchElementException() - public fun add(element: E) { + fun add(element: E) { require(element.next == null) require(element.prev == null) @@ -311,7 +316,7 @@ private class PullableLinkedList> { } } - public fun remove(element: E) { + fun remove(element: E) { if (element == head) { head = null } @@ -324,12 +329,12 @@ private class PullableLinkedList> { element.prev = null } - public fun clear() { + fun clear() { head = null tail = null } - public fun pull(element: E) { + fun pull(element: E) { if (element !== head) { remove(element) add(element) diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/CacheStorage.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/CacheStorage.kt index 533c70b97ad..3c9f20c7475 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/CacheStorage.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/CacheStorage.kt @@ -4,12 +4,10 @@ package io.ktor.server.sessions -import io.ktor.util.* import io.ktor.utils.io.* import io.ktor.utils.io.core.* @Suppress("KDocMissingDocumentation") -@InternalAPI public class CacheStorage(public val delegate: SessionStorage, idleTimeout: Long) : SessionStorage { private val referenceCache = SoftReferenceCache { id -> delegate.read(id) { input -> input.readRemaining().readBytes() } diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/DirectoryStorage.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/DirectoryStorage.kt index 322ffc595d2..6ef76b69331 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/DirectoryStorage.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/DirectoryStorage.kt @@ -4,6 +4,7 @@ package io.ktor.server.sessions +import io.ktor.util.* import io.ktor.util.cio.* import io.ktor.utils.io.* import kotlinx.coroutines.* @@ -12,6 +13,7 @@ import java.io.* /** * Creates a session storage that serializes them into regular files under the specified [rootDir] */ +@OptIn(InternalAPI::class) public fun directorySessionStorage(rootDir: File, cached: Boolean = true): SessionStorage = when (cached) { true -> CacheStorage(DirectoryStorage(rootDir), 60000) false -> DirectoryStorage(rootDir) diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/KotlinTimeJvm.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/KotlinTimeJvm.kt index 4d844007282..91b156f32d3 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/KotlinTimeJvm.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/KotlinTimeJvm.kt @@ -14,8 +14,8 @@ import kotlin.time.* */ @ExperimentalTime public var CookieConfiguration.maxAge: Duration? - get() = maxAgeInSeconds.seconds + get() = Duration.seconds(maxAgeInSeconds) set(newMaxAge) { require(newMaxAge == null || !newMaxAge.isNegative()) { "Only non-negative durations can be specified" } - maxAgeInSeconds = newMaxAge?.inSeconds?.roundToLong() ?: 0L + maxAgeInSeconds = newMaxAge?.toDouble(DurationUnit.SECONDS)?.roundToLong() ?: 0L } diff --git a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/Sessions.kt b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/Sessions.kt index 63fe3fb1a09..37582491416 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/Sessions.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-sessions/jvm/src/io/ktor/server/sessions/Sessions.kt @@ -95,6 +95,7 @@ public class Sessions(public val providers: List>) { public val ApplicationCall.sessions: CurrentSession get() = attributes.getOrNull(SessionKey) ?: reportMissingSession() +@OptIn(InternalAPI::class) private fun ApplicationCall.reportMissingSession(): Nothing { application.plugin(Sessions) // ensure the plugin is installed throw SessionNotYetConfiguredException() @@ -180,6 +181,7 @@ private data class SessionData( return entry.value.provider.name } + @OptIn(InternalAPI::class) override fun set(name: String, value: Any?) { if (committed) { throw TooLateSessionSetException() @@ -239,7 +241,6 @@ private val SessionKey = AttributeKey("SessionKey") /** * This exception is thrown when HTTP response has already been sent but an attempt to modify session is made */ -@InternalAPI public class TooLateSessionSetException : IllegalStateException("It's too late to set session: response most likely already has been sent") @@ -248,6 +249,5 @@ public class TooLateSessionSetException : * For example, in a phase before [ApplicationCallPipeline.Plugins] or in a plugin installed before [Sessions] into * the same phase. */ -@InternalAPI public class SessionNotYetConfiguredException : IllegalStateException("Sessions are not yet ready: you are asking it to early before the Sessions plugin.") diff --git a/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/VelocityTools.kt b/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/VelocityTools.kt index d48bbea9695..ff520c37e26 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/VelocityTools.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/src/io/ktor/server/velocity/VelocityTools.kt @@ -21,6 +21,7 @@ public fun EasyFactoryConfiguration.engine(configure: VelocityEngine.() -> Unit) /** * VelocityTools ktor plugin. Populates model with standard Velocity tools. */ +@Suppress("UNCHECKED_CAST") public class VelocityTools private constructor(private val toolManager: ToolManager) { /** @@ -33,15 +34,15 @@ public class VelocityTools private constructor(private val toolManager: ToolMana override fun install( pipeline: ApplicationCallPipeline, - config: EasyFactoryConfiguration.() -> Unit + configure: EasyFactoryConfiguration.() -> Unit ): VelocityTools { - val factoryConfig = EasyFactoryConfiguration().apply(config) + val factoryConfig = EasyFactoryConfiguration().apply(configure) val engineConfig = factoryConfig.getData(ENGINE_CONFIG_KEY) ?.also { factoryConfig.removeData(it) } ?.value as (VelocityEngine.() -> Unit)? ?: {} val engine = VelocityEngine().apply(engineConfig) val toolManager = ToolManager().apply { - configure(factoryConfig) + this.configure(factoryConfig) velocityEngine = engine } val plugin = VelocityTools(toolManager) diff --git a/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/test/io/ktor/tests/velocity/VelocityToolsTest.kt b/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/test/io/ktor/tests/velocity/VelocityToolsTest.kt index 7c98ffe36ca..f9d4f0508e1 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/test/io/ktor/tests/velocity/VelocityToolsTest.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-velocity/jvm/test/io/ktor/tests/velocity/VelocityToolsTest.kt @@ -2,6 +2,8 @@ * Copyright 2014-2019 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +@file:Suppress("unused", "UNUSED_PARAMETER") + package io.ktor.tests.velocity import io.ktor.http.* diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/api/ktor-server-websockets.api b/ktor-server/ktor-server-plugins/ktor-server-websockets/api/ktor-server-websockets.api index 25e3d1ef7a5..856b9a1f78e 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/api/ktor-server-websockets.api +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/api/ktor-server-websockets.api @@ -22,9 +22,9 @@ public final class io/ktor/server/websocket/DefaultWebSocketServerSession$Defaul } public final class io/ktor/server/websocket/KotlinDurationsKt { - public static final fun WebSockets-v29k7_A (Lkotlin/time/Duration;JJZ)Lio/ktor/server/websocket/WebSockets; - public static final fun pinger-1WGW0hc (Lkotlinx/coroutines/CoroutineScope;Lkotlinx/coroutines/channels/SendChannel;JJLio/ktor/utils/io/pool/ObjectPool;)Lkotlinx/coroutines/channels/SendChannel; - public static synthetic fun pinger-1WGW0hc$default (Lkotlinx/coroutines/CoroutineScope;Lkotlinx/coroutines/channels/SendChannel;JJLio/ktor/utils/io/pool/ObjectPool;ILjava/lang/Object;)Lkotlinx/coroutines/channels/SendChannel; + public static final fun WebSockets-EBYhdyk (Lkotlin/time/Duration;JJZ)Lio/ktor/server/websocket/WebSockets; + public static final fun pinger-ck1zr5g (Lkotlinx/coroutines/CoroutineScope;Lkotlinx/coroutines/channels/SendChannel;JJLio/ktor/utils/io/pool/ObjectPool;)Lkotlinx/coroutines/channels/SendChannel; + public static synthetic fun pinger-ck1zr5g$default (Lkotlinx/coroutines/CoroutineScope;Lkotlinx/coroutines/channels/SendChannel;JJLio/ktor/utils/io/pool/ObjectPool;ILjava/lang/Object;)Lkotlinx/coroutines/channels/SendChannel; } public final class io/ktor/server/websocket/RoutingKt { diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/src/io/ktor/server/websocket/KotlinDurations.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/src/io/ktor/server/websocket/KotlinDurations.kt index ac8825843aa..2a1162bf989 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/src/io/ktor/server/websocket/KotlinDurations.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/src/io/ktor/server/websocket/KotlinDurations.kt @@ -21,8 +21,8 @@ public fun WebSockets( maxFrameSize: Long, masking: Boolean ): WebSockets = WebSockets( - pingInterval?.toLongMilliseconds() ?: 0L, - timeout.toLongMilliseconds(), + pingInterval?.inWholeMilliseconds ?: 0L, + timeout.inWholeMilliseconds, maxFrameSize, masking ) @@ -37,4 +37,4 @@ public fun CoroutineScope.pinger( period: Duration, timeout: Duration, pool: ObjectPool = KtorDefaultPool -): SendChannel = pinger(outgoing, period.toLongMilliseconds(), timeout.toLongMilliseconds(), pool) +): SendChannel = pinger(outgoing, period.inWholeMilliseconds, timeout.inWholeMilliseconds, pool) diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/src/io/ktor/server/websocket/Routing.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/src/io/ktor/server/websocket/Routing.kt index f72be591e9c..3d98b9e5dc1 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/src/io/ktor/server/websocket/Routing.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/src/io/ktor/server/websocket/Routing.kt @@ -126,6 +126,7 @@ public fun Route.webSocketRaw( ReplaceWith("webSocketRaw(protocol = webSocketProtocol, handler = webSocketHandler)"), DeprecationLevel.ERROR ) +@Suppress("UNUSED_PARAMETER") public fun Route.webSocketRaw( webSocketProtocol: String, webSocketHandler: suspend WebSocketServerSession.() -> Unit, diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/src/io/ktor/server/websocket/WebSocketUpgrade.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/src/io/ktor/server/websocket/WebSocketUpgrade.kt index 53371ce2dfc..f3c51f50966 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/src/io/ktor/server/websocket/WebSocketUpgrade.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/src/io/ktor/server/websocket/WebSocketUpgrade.kt @@ -10,6 +10,7 @@ import io.ktor.http.content.* import io.ktor.http.websocket.* import io.ktor.server.application.* import io.ktor.server.request.* +import io.ktor.util.* import io.ktor.utils.io.* import kotlinx.coroutines.* import kotlin.coroutines.* @@ -79,6 +80,7 @@ public class WebSocketUpgrade( } } + @OptIn(InternalAPI::class) override suspend fun upgrade( input: ByteReadChannel, output: ByteWriteChannel, diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/DefaultWebSocketTest.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/DefaultWebSocketTest.kt index 11fe72da90f..0065c361ec9 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/DefaultWebSocketTest.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/DefaultWebSocketTest.kt @@ -5,6 +5,7 @@ package io.ktor.tests.websocket import io.ktor.http.cio.websocket.* +import io.ktor.util.* import io.ktor.utils.io.* import kotlinx.coroutines.* import kotlinx.coroutines.CancellationException @@ -26,7 +27,7 @@ class DefaultWebSocketTest { private lateinit var client: RawWebSocket - @OptIn(ExperimentalWebSocketExtensionApi::class) + @OptIn(InternalAPI::class) @BeforeTest fun prepare() { parent = Job() @@ -89,7 +90,7 @@ class DefaultWebSocketTest { fun testCancellation(): Unit = runBlocking { server.cancel() - client.incoming.receiveOrNull() + client.incoming.receiveCatching().getOrNull() client.close() ensureCompletion() diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/ParserTest.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/ParserTest.kt index a823cf8e2f7..f18fbf87a2f 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/ParserTest.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/ParserTest.kt @@ -78,7 +78,7 @@ class ParserTest { assertEquals(1, parser.length) assertTrue { parser.bodyReady } - assertEquals('1', buffer.get().toChar()) + assertEquals('1', buffer.get().toInt().toChar()) parser.bodyComplete() parser.frame(buffer) @@ -89,7 +89,7 @@ class ParserTest { assertEquals(1, parser.length) assertTrue { parser.bodyReady } - assertEquals('2', buffer.get().toChar()) + assertEquals('2', buffer.get().toInt().toChar()) parser.bodyComplete() parser.frame(buffer) @@ -100,7 +100,7 @@ class ParserTest { assertEquals(1, parser.length) assertTrue { parser.bodyReady } - assertEquals('3', buffer.get().toChar()) + assertEquals('3', buffer.get().toInt().toChar()) parser.bodyComplete() assertFalse { buffer.hasRemaining() } diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/RawWebSocketTest.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/RawWebSocketTest.kt index 28fe8426e5f..cd6e6e6ec0f 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/RawWebSocketTest.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/RawWebSocketTest.kt @@ -83,10 +83,10 @@ class RawWebSocketTest { @Test fun testServerIncomingDisconnected(): Unit = runTest { client2server.close() - assertNull(server.incoming.receiveOrNull()) + assertNull(server.incoming.receiveCatching().getOrNull()) server.outgoing.send(Frame.Close()) - client.incoming.receiveOrNull() as Frame.Close + client.incoming.receiveCatching().getOrNull() as Frame.Close client.cancel() ensureCompletion() diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/WebSocketEngineSuite.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/WebSocketEngineSuite.kt index ca70cca210a..eb3900ad2d6 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/WebSocketEngineSuite.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/WebSocketEngineSuite.kt @@ -278,7 +278,7 @@ abstract class WebSocketEngineSuite() - val engine = createAndStartServer { + createAndStartServer { webSocket("/") { try { incoming.consumeEach { frame -> @@ -604,7 +604,7 @@ abstract class WebSocketEngineSuite("Outgoing channel should be closed properly") { repeat(10) { // we need this loop because the outgoing is not closed immediately diff --git a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/WebSocketTest.kt b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/WebSocketTest.kt index f41129739f4..310109de248 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/WebSocketTest.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-websockets/jvm/test/io/ktor/tests/websocket/WebSocketTest.kt @@ -518,9 +518,9 @@ class WebSocketTest { } } - handleWebSocketConversation("/close/me") { incoming, outgoing -> + handleWebSocketConversation("/close/me") { incoming, _ -> assertTrue(incoming.receive() is Frame.Close) - assertNull(incoming.receiveOrNull()) + assertNull(incoming.receiveCatching().getOrNull()) } runBlocking { session.await() diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/BlockingServlet.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/BlockingServlet.kt index 6b1d2c0058d..465df5d943e 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/BlockingServlet.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/BlockingServlet.kt @@ -15,6 +15,7 @@ import javax.servlet.* import javax.servlet.http.* import kotlin.coroutines.* +@OptIn(EngineAPI::class) internal class BlockingServletApplicationCall( application: Application, servletRequest: HttpServletRequest, @@ -31,6 +32,7 @@ internal class BlockingServletApplicationCall( } } +@OptIn(EngineAPI::class) private class BlockingServletApplicationRequest( call: ApplicationCall, servletRequest: HttpServletRequest @@ -43,6 +45,7 @@ private class BlockingServletApplicationRequest( override fun receiveChannel() = inputStreamChannel } +@OptIn(EngineAPI::class) internal class BlockingServletApplicationResponse( call: ApplicationCall, servletResponse: HttpServletResponse, diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/JAASBridge.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/JAASBridge.kt index d1d22af4ad7..d2eced2f191 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/JAASBridge.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/JAASBridge.kt @@ -4,12 +4,15 @@ package io.ktor.server.servlet +import io.ktor.server.engine.* import io.ktor.server.request.* import java.security.* /** * Returns Java's JAAS Principal */ +@Suppress("unused") +@OptIn(EngineAPI::class) public val ApplicationRequest.javaSecurityPrincipal: Principal? get() = when (this) { is ServletApplicationRequest -> servletRequest.userPrincipal diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/KtorServlet.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/KtorServlet.kt index 2cde6d717f7..9897991a454 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/KtorServlet.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/KtorServlet.kt @@ -148,9 +148,9 @@ public abstract class KtorServlet : HttpServlet(), CoroutineScope { /** * Attribute that is added by ktor servlet to application attributes to hold [ServletContext] instance. */ -@InternalAPI public val ServletContextAttribute: AttributeKey = AttributeKey("servlet-context") +@OptIn(InternalAPI::class) private class AsyncDispatchers { val engineExecutor = ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors()) val engineDispatcher = DispatcherWithShutdown(engineExecutor.asCoroutineDispatcher()) @@ -158,7 +158,7 @@ private class AsyncDispatchers { val executor = ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 8) val dispatcher = DispatcherWithShutdown(executor.asCoroutineDispatcher()) - public fun destroy() { + fun destroy() { engineDispatcher.prepareShutdown() dispatcher.prepareShutdown() try { diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletApplicationEngine.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletApplicationEngine.kt index 455e41cb8bd..a8c1c7442f9 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletApplicationEngine.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletApplicationEngine.kt @@ -17,6 +17,7 @@ import kotlin.coroutines.* /** * This servlet need to be installed into a servlet container */ +@OptIn(EngineAPI::class) @MultipartConfig public open class ServletApplicationEngine : KtorServlet() { private val environment: ApplicationEngineEnvironment by lazy { diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletReader.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletReader.kt index f8c22f70993..6192c307692 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletReader.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletReader.kt @@ -24,7 +24,7 @@ private class ServletReader(val input: ServletInputStream) : ReadListener { val channel = ByteChannel() private val events = Channel(2) - public suspend fun run() { + suspend fun run() { val buffer = ArrayPool.borrow() try { input.setReadListener(this) @@ -36,8 +36,7 @@ private class ServletReader(val input: ServletInputStream) : ReadListener { events.close() return } - @OptIn(ExperimentalCoroutinesApi::class) - events.receiveOrNull() ?: return + events.receiveCatching().getOrNull() ?: return loop(buffer) events.close() @@ -64,8 +63,7 @@ private class ServletReader(val input: ServletInputStream) : ReadListener { channel.writeFully(buffer, 0, rc) } else { channel.flush() - @OptIn(ExperimentalCoroutinesApi::class) - events.receiveOrNull() ?: break + events.receiveCatching().getOrNull() ?: break } } } @@ -83,8 +81,8 @@ private class ServletReader(val input: ServletInputStream) : ReadListener { override fun onDataAvailable() { try { - if (!events.offer(Unit)) { - events.sendBlocking(Unit) + if (!events.trySend(Unit).isSuccess) { + events.trySendBlocking(Unit) } } catch (ignore: Throwable) { } diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletUpgrade.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletUpgrade.kt index 0695bbb8c37..1f55fcf07b5 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletUpgrade.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletUpgrade.kt @@ -38,6 +38,7 @@ public interface ServletUpgrade { */ @EngineAPI public object DefaultServletUpgrade : ServletUpgrade { + @OptIn(InternalAPI::class) override suspend fun performUpgrade( upgrade: OutgoingContent.ProtocolUpgrade, servletRequest: HttpServletRequest, diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletWriter.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletWriter.kt index 237ae115ab7..df068a9b27d 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletWriter.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/ServletWriter.kt @@ -105,8 +105,8 @@ private class ServletWriter(val output: ServletOutputStream) : WriteListener { override fun onWritePossible() { try { - if (!events.offer(Unit)) { - events.sendBlocking(Unit) + if (!events.trySend(Unit).isSuccess) { + events.trySendBlocking(Unit) } } catch (ignore: Throwable) { } diff --git a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/WebResources.kt b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/WebResources.kt index 4e500229f67..c1826b5dee4 100644 --- a/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/WebResources.kt +++ b/ktor-server/ktor-server-servlet/jvm/src/io/ktor/server/servlet/WebResources.kt @@ -10,6 +10,7 @@ import io.ktor.server.http.content.* import io.ktor.server.response.* import io.ktor.server.routing.* import io.ktor.server.util.* +import io.ktor.util.* import kotlin.random.* /** @@ -66,6 +67,7 @@ constructor() { * itself is not served by default. * @param subPath slash-delimited web resources root path (relative to webapp directory) */ +@OptIn(InternalAPI::class) public fun Route.webResources(subPath: String = "/", configure: WebResourcesConfig.() -> Unit = {}) { @Suppress("DEPRECATION_ERROR") val config = WebResourcesConfig().apply(configure) diff --git a/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/EngineTestBase.kt b/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/EngineTestBase.kt index 23f5c2e7d7e..841d68de761 100644 --- a/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/EngineTestBase.kt +++ b/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/EngineTestBase.kt @@ -32,8 +32,8 @@ import kotlin.concurrent.* import kotlin.coroutines.* @Suppress("KDocMissingDocumentation") -public abstract class EngineTestBase( - public val applicationEngineFactory: ApplicationEngineFactory +abstract class EngineTestBase( + val applicationEngineFactory: ApplicationEngineFactory ) : CoroutineScope { private val testJob = Job() @@ -57,7 +57,7 @@ public abstract class EngineTestBase() - public val testLog: Logger = LoggerFactory.getLogger("EngineTestBase") + val testLog: Logger = LoggerFactory.getLogger("EngineTestBase") @Target(AnnotationTarget.FUNCTION) @Retention @@ -71,21 +71,21 @@ public abstract class EngineTestBase { this.server = server @@ -327,15 +328,15 @@ public abstract class EngineTestBase("RequestHandledAttributeKey") - /** * Represents a test application call that is used in [withTestApplication] and [handleRequest] */ -public class TestApplicationCall( +@OptIn(EngineAPI::class) +class TestApplicationCall( application: Application, readResponse: Boolean = false, closeRequest: Boolean = true, @@ -25,7 +23,7 @@ public class TestApplicationCall( /** * Set to `true` when the request has been handled and a response has been produced */ - @Suppress("DeprecatedCallableAddReplaceWith") + @Suppress("DeprecatedCallableAddReplaceWith", "unused") @Deprecated( "This property may have unpredictable behaviour. " + "Please use asserts on response status, headers or content", diff --git a/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/TestApplicationEngine.kt b/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/TestApplicationEngine.kt index d3942f54efc..5904e0fd5ac 100644 --- a/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/TestApplicationEngine.kt +++ b/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/TestApplicationEngine.kt @@ -26,7 +26,8 @@ import kotlin.coroutines.* * ktor test engine that provides way to simulate application calls to existing application module(s) * without actual HTTP connection */ -public class TestApplicationEngine( +@OptIn(EngineAPI::class) +class TestApplicationEngine( environment: ApplicationEngineEnvironment = createTestEnvironment(), configure: Configuration.() -> Unit = {} ) : BaseApplicationEngine(environment, EnginePipeline(environment.developmentMode)), CoroutineScope { @@ -41,7 +42,7 @@ public class TestApplicationEngine( * Test application engine configuration * @property dispatcher to run handlers and interceptors on */ - public class Configuration : BaseApplicationEngine.Configuration() { + class Configuration : BaseApplicationEngine.Configuration() { var dispatcher: CoroutineContext = Dispatchers.IO } @@ -115,7 +116,7 @@ public class TestApplicationEngine( /** * Install a hook for test requests */ - public fun hookRequests( + fun hookRequests( processRequest: TestApplicationRequest.(setup: TestApplicationRequest.() -> Unit) -> Unit, processResponse: TestApplicationCall.() -> Unit, block: () -> Unit @@ -142,8 +143,8 @@ public class TestApplicationEngine( /** * Make a test request */ - @OptIn(InternalAPI::class) - public fun handleRequest( + @OptIn(InternalAPI::class, kotlinx.coroutines.DelicateCoroutinesApi::class) + fun handleRequest( closeRequest: Boolean = true, setup: TestApplicationRequest.() -> Unit ): TestApplicationCall { @@ -177,7 +178,7 @@ public class TestApplicationEngine( /** * Make a test request that setup a websocket session and wait for completion */ - public fun handleWebSocket(uri: String, setup: TestApplicationRequest.() -> Unit): TestApplicationCall { + fun handleWebSocket(uri: String, setup: TestApplicationRequest.() -> Unit): TestApplicationCall { val call = createWebSocketCall(uri, setup) // we can't simply do runBlocking here because runBlocking is not completing @@ -203,7 +204,7 @@ public class TestApplicationEngine( * that does conversation with server */ @OptIn(WebSocketInternalAPI::class) - public fun handleWebSocketConversation( + fun handleWebSocketConversation( uri: String, setup: TestApplicationRequest.() -> Unit = {}, callback: suspend TestApplicationCall.(incoming: ReceiveChannel, outgoing: SendChannel) -> Unit @@ -263,7 +264,7 @@ public class TestApplicationEngine( /** * Creates an instance of test call but doesn't start request processing */ - public fun createCall( + fun createCall( readResponse: Boolean = false, closeRequest: Boolean = true, setup: TestApplicationRequest.() -> Unit @@ -276,8 +277,8 @@ public class TestApplicationEngine( * * This processes [HttpHeaders.SetCookie] from the responses and produce [HttpHeaders.Cookie] in subsequent requests. */ -public fun TestApplicationEngine.cookiesSession(callback: () -> Unit) { - var trackedCookies: List = listOf() +fun TestApplicationEngine.cookiesSession(callback: () -> Unit) { + val trackedCookies: MutableList = mutableListOf() hookRequests( processRequest = { setup -> diff --git a/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/TestApplicationResponse.kt b/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/TestApplicationResponse.kt index 0fd0f8595c8..e45515a2616 100644 --- a/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/TestApplicationResponse.kt +++ b/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/TestApplicationResponse.kt @@ -69,6 +69,7 @@ public class TestApplicationResponse( override fun getEngineHeaderValues(name: String): List = builder.getAll(name).orEmpty() } + @OptIn(DelicateCoroutinesApi::class) override suspend fun responseChannel(): ByteWriteChannel { val result = ByteChannel(autoFlush = true) diff --git a/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/client/TestHttpClientEngine.kt b/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/client/TestHttpClientEngine.kt index 0c7820769da..a04f8bb671a 100644 --- a/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/client/TestHttpClientEngine.kt +++ b/ktor-server/ktor-server-test-host/jvm/src/io/ktor/server/testing/client/TestHttpClientEngine.kt @@ -17,7 +17,7 @@ import kotlinx.coroutines.* import kotlin.coroutines.* @Suppress("KDocMissingDocumentation") -public class TestHttpClientEngine(override val config: TestHttpClientConfig) : HttpClientEngineBase("ktor-test") { +class TestHttpClientEngine(override val config: TestHttpClientConfig) : HttpClientEngineBase("ktor-test") { override val dispatcher = Dispatchers.IO @@ -29,6 +29,7 @@ public class TestHttpClientEngine(override val config: TestHttpClientConfig) : H override val coroutineContext: CoroutineContext = dispatcher + clientJob + @OptIn(InternalAPI::class) override suspend fun execute(data: HttpRequestData): HttpResponseData { val testServerCall = with(data) { runRequest(method, url.fullPath, headers, body) } diff --git a/ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/Utils.kt b/ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/Utils.kt index b794b901d5c..fdde7240422 100644 --- a/ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/Utils.kt +++ b/ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/Utils.kt @@ -6,6 +6,7 @@ package io.ktor.server.testing import org.junit.Assert.* import java.io.* +import java.util.* import java.util.zip.* internal suspend fun assertFailsSuspend(block: suspend () -> Unit): Throwable { @@ -61,13 +62,9 @@ internal fun BufferedReader.parseHeadersAndGetContentLength(): Int { break } - when (line.split(" ", ":")[0].toLowerCase()) { - "content-length" -> { - contentLength = line.drop(16).trim().toInt() - } - "transfer-encoding" -> { - error("We don't support chunked for 400 in this test") - } + when (line.split(" ", ":")[0].lowercase(Locale.getDefault())) { + "content-length" -> contentLength = line.drop(16).trim().toInt() + "transfer-encoding" -> error("We don't support chunked for 400 in this test") } } while (true) return contentLength diff --git a/ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/CompressionTestSuite.kt b/ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/CompressionTestSuite.kt index ccd619bbf3b..6b5ad12698e 100644 --- a/ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/CompressionTestSuite.kt +++ b/ktor-server/ktor-server-test-suites/jvm/src/io/ktor/server/testing/suites/CompressionTestSuite.kt @@ -16,6 +16,7 @@ import io.ktor.server.plugins.* import io.ktor.server.response.* import io.ktor.server.routing.* import io.ktor.server.testing.* +import io.ktor.util.* import io.ktor.utils.io.* import io.ktor.utils.io.jvm.javaio.* import org.junit.* @@ -27,6 +28,7 @@ abstract class CompressionTestSuite ) : EngineTestBase(hostFactory) { + @OptIn(InternalAPI::class) @Test fun testLocalFileContentWithCompression() { val file = loadTestFile() @@ -46,6 +48,7 @@ abstract class CompressionTestSuite var intercepted = false val server = createServer(log = logger) { - intercept(ApplicationCallPipeline.Setup) { + intercept(ApplicationCallPipeline.Setup) setup@{ call.response.pipeline.intercept(phase) { if (intercepted) return@intercept intercepted = true @@ -739,7 +743,7 @@ abstract class SustainabilityTestSuite() + body() assertEquals("Failed in phase $phase", InternalServerError, status) assertEquals("Failed in phase $phase", exceptions.size, 1) assertEquals("Failed in phase $phase", exceptions[0].message) @@ -750,6 +754,7 @@ abstract class SustainabilityTestSuite + handleRequest(HttpMethod.Get, "/uri1").let { _ -> assertTrue { "INFO: test message [mdc-call-id=generated-call-id-0, mdc-uri=/uri1]" in messages } assertTrue { "INFO: ${green("200 OK")}: ${cyan("GET")} - " + @@ -248,7 +248,7 @@ class CallLoggingTest { } } - handleRequest(HttpMethod.Get, "/uri1").let { call -> + handleRequest(HttpMethod.Get, "/uri1").let { assertTrue { "INFO: test message [mdc-call-id=generated-call-id-0, mdc-uri=/uri1]" in messages } assertTrue { "INFO: ${green("200 OK")}: ${cyan("GET")} - " + diff --git a/ktor-server/ktor-server-tests/jvm/test/io/ktor/tests/server/plugins/StatusPageTest.kt b/ktor-server/ktor-server-tests/jvm/test/io/ktor/tests/server/plugins/StatusPageTest.kt index ff123eeca77..b3b0352c2ff 100644 --- a/ktor-server/ktor-server-tests/jvm/test/io/ktor/tests/server/plugins/StatusPageTest.kt +++ b/ktor-server/ktor-server-tests/jvm/test/io/ktor/tests/server/plugins/StatusPageTest.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.* import kotlinx.coroutines.CancellationException import kotlin.test.* +@Suppress("IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION") class StatusPageTest { private val textPlainUtf8 = ContentType.Text.Plain.withCharset(Charsets.UTF_8) private val textHtmlUtf8 = ContentType.Text.Html.withCharset(Charsets.UTF_8) @@ -288,7 +289,7 @@ class StatusPageTest { @Test @Suppress("RedundantAsync", "IMPLICIT_NOTHING_AS_TYPE_PARAMETER", "ReplaceSingleLineLet") - fun testErrorInAsync(): Unit = withTestApplication { + fun testErrorInAsync(): Unit = withTestApplication { class AsyncFailedException : Exception() application.install(StatusPages) { diff --git a/ktor-server/ktor-server-tests/jvm/test/io/ktor/tests/server/routing/RoutingResolveTest.kt b/ktor-server/ktor-server-tests/jvm/test/io/ktor/tests/server/routing/RoutingResolveTest.kt index c733549f953..2197b067754 100644 --- a/ktor-server/ktor-server-tests/jvm/test/io/ktor/tests/server/routing/RoutingResolveTest.kt +++ b/ktor-server/ktor-server-tests/jvm/test/io/ktor/tests/server/routing/RoutingResolveTest.kt @@ -13,7 +13,9 @@ import io.ktor.server.testing.* import io.ktor.util.* import kotlin.test.* -fun routing(rootPath: String = "") = Route(parent = null, selector = RootRouteSelector(rootPath)) +fun routing(rootPath: String = ""): Route = + Route(parent = null, selector = RootRouteSelector(rootPath)) + fun resolve( routing: Route, path: String, diff --git a/ktor-server/ktor-server-tests/jvm/test/io/ktor/tests/server/sessions/SessionTest.kt b/ktor-server/ktor-server-tests/jvm/test/io/ktor/tests/server/sessions/SessionTest.kt index e6456f3eb45..32c630b17c0 100644 --- a/ktor-server/ktor-server-tests/jvm/test/io/ktor/tests/server/sessions/SessionTest.kt +++ b/ktor-server/ktor-server-tests/jvm/test/io/ktor/tests/server/sessions/SessionTest.kt @@ -37,12 +37,10 @@ class SessionTest { call.respondText("No session") } } - handleRequest(HttpMethod.Get, "/0").let { call -> - assertNull( - call.response.cookies[cookieName], - "There should be no session data after setting and clearing" - ) - } + assertNull( + handleRequest(HttpMethod.Get, "/0").response.cookies[cookieName], + "There should be no session data after setting and clearing" + ) } } @@ -52,7 +50,7 @@ class SessionTest { application.install(Sessions) { cookie(cookieName) { cookie.domain = "foo.bar" - cookie.maxAge = 1.hours + cookie.maxAge = Duration.hours(1) } } @@ -82,9 +80,10 @@ class SessionTest { } } - handleRequest(HttpMethod.Get, "/0").let { call -> - assertNull(call.response.cookies[cookieName], "There should be no session set by default") - } + assertNull( + handleRequest(HttpMethod.Get, "/0").response.cookies[cookieName], + "There should be no session set by default" + ) var sessionParam: String handleRequest(HttpMethod.Get, "/1").let { call -> @@ -373,9 +372,10 @@ class SessionTest { } } - handleRequest(HttpMethod.Get, "/0").let { response -> - assertNull(response.response.cookies[cookieName], "There should be no session set by default") - } + assertNull( + handleRequest(HttpMethod.Get, "/0").response.cookies[cookieName], + "There should be no session set by default" + ) var sessionId: String handleRequest(HttpMethod.Get, "/1").let { response -> @@ -422,9 +422,7 @@ class SessionTest { } } - handleRequest(HttpMethod.Get, "/0").let { call -> - assertEquals("There should be no session started", call.response.content) - } + assertEquals("There should be no session started", handleRequest(HttpMethod.Get, "/0").response.content) } } @@ -450,9 +448,10 @@ class SessionTest { } } - handleRequest(HttpMethod.Get, "/0").let { response -> - assertNull(response.response.cookies[cookieName], "There should be no session set by default") - } + assertNull( + handleRequest(HttpMethod.Get, "/0").response.cookies[cookieName], + "There should be no session set by default" + ) handleRequest(HttpMethod.Get, "/1").let { response -> val sessionCookie = response.response.cookies[cookieName] @@ -478,7 +477,7 @@ class SessionTest { withTestApplication { application.install(Sessions) { cookie(cookieName, sessionStorage) { - cookie.maxAge = durationSeconds.seconds + cookie.maxAge = Duration.seconds(durationSeconds) identity { (id++).toString() } } } @@ -594,9 +593,7 @@ class SessionTest { assertFailsWith { runBlocking { - handleRequest(HttpMethod.Get, "/after-response").let { call -> - call.response.content - } + handleRequest(HttpMethod.Get, "/after-response").response.content } } } @@ -606,7 +603,7 @@ class SessionTest { val transport = SessionTransportCookie( "test", CookieConfiguration().apply { - maxAge = (365 * 100).days + maxAge = Duration.days((365 * 100)) }, emptyList() ) @@ -624,7 +621,7 @@ class SessionTest { val transport = SessionTransportCookie( "test", CookieConfiguration().apply { - maxAge = Long.MAX_VALUE.seconds + maxAge = Duration.seconds(Long.MAX_VALUE) }, emptyList() ) @@ -670,9 +667,7 @@ class SessionTest { call.respondText(cause.key.name) } } - handleRequest(HttpMethod.Get, "/").let { call -> - assertEquals(Sessions.key.name, call.response.content) - } + assertEquals(Sessions.key.name, handleRequest(HttpMethod.Get, "/").response.content) } @Test @@ -692,9 +687,7 @@ class SessionTest { cookie("name1") } - handleRequest(HttpMethod.Get, "/").let { call -> - assertEquals("OK", call.response.content) - } + assertEquals("OK", handleRequest(HttpMethod.Get, "/").response.content) } private fun flipLastHexDigit(sessionId: String) = sessionId.mapIndexed { index, letter -> diff --git a/ktor-server/ktor-server-tomcat/jvm/src/io/ktor/server/tomcat/TomcatApplicationEngine.kt b/ktor-server/ktor-server-tomcat/jvm/src/io/ktor/server/tomcat/TomcatApplicationEngine.kt index f392cf2b0fe..8e9452df550 100644 --- a/ktor-server/ktor-server-tomcat/jvm/src/io/ktor/server/tomcat/TomcatApplicationEngine.kt +++ b/ktor-server/ktor-server-tomcat/jvm/src/io/ktor/server/tomcat/TomcatApplicationEngine.kt @@ -26,8 +26,11 @@ import kotlin.coroutines.* /** * Tomcat application engine that runs it in embedded mode */ -public class TomcatApplicationEngine(environment: ApplicationEngineEnvironment, configure: Configuration.() -> Unit) : - BaseApplicationEngine(environment) { +@OptIn(EngineAPI::class) +public class TomcatApplicationEngine( + environment: ApplicationEngineEnvironment, + configure: Configuration.() -> Unit +) : BaseApplicationEngine(environment) { /** * Tomcat engine specific configuration builder */ @@ -81,17 +84,17 @@ public class TomcatApplicationEngine(environment: ApplicationEngineEnvironment, ) } - setAttribute("keyAlias", ktorConnector.keyAlias) - setAttribute("keystorePass", String(ktorConnector.keyStorePassword())) - setAttribute("keyPass", String(ktorConnector.privateKeyPassword())) - setAttribute("keystoreFile", ktorConnector.keyStorePath!!.absolutePath) - setAttribute("clientAuth", false) - setAttribute("sslProtocol", "TLS") - setAttribute("SSLEnabled", true) + setProperty("keyAlias", ktorConnector.keyAlias) + setProperty("keystorePass", String(ktorConnector.keyStorePassword())) + setProperty("keyPass", String(ktorConnector.privateKeyPassword())) + setProperty("keystoreFile", ktorConnector.keyStorePath!!.absolutePath) + setProperty("clientAuth", "false") + setProperty("sslProtocol", "TLS") + setProperty("SSLEnabled", "true") val sslImpl = chooseSSLImplementation() - setAttribute("sslImplementationName", sslImpl.name) + setProperty("sslImplementationName", sslImpl.name) if (sslImpl.simpleName == "OpenSSLImplementation") { addUpgradeProtocol(Http2Protocol()) @@ -138,14 +141,14 @@ public class TomcatApplicationEngine(environment: ApplicationEngineEnvironment, } override fun stop(gracePeriodMillis: Long, timeoutMillis: Long) { - if (stopped.compareAndSet(false, true)) { - cancellationDeferred?.complete() - environment.monitor.raise(ApplicationStopPreparing, environment) - server.stop() - environment.stop() - server.destroy() - tempDirectory.toFile().deleteRecursively() - } + if (!stopped.compareAndSet(expect = false, update = true)) return + + cancellationDeferred?.complete() + environment.monitor.raise(ApplicationStopPreparing, environment) + server.stop() + environment.stop() + server.destroy() + tempDirectory.toFile().deleteRecursively() } public companion object { diff --git a/ktor-server/ktor-server/jvm/test/io/ktor/tests/http/PathNormalizationTest.kt b/ktor-server/ktor-server/jvm/test/io/ktor/tests/http/PathNormalizationTest.kt index 469fadf4557..93459195773 100644 --- a/ktor-server/ktor-server/jvm/test/io/ktor/tests/http/PathNormalizationTest.kt +++ b/ktor-server/ktor-server/jvm/test/io/ktor/tests/http/PathNormalizationTest.kt @@ -5,6 +5,7 @@ package io.ktor.tests.http import io.ktor.server.util.* +import java.util.* import kotlin.test.* class PathNormalizationTest { @@ -116,7 +117,13 @@ class PathNormalizationTest { "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" ) - for (name in names + names.map { it.toLowerCase() } + names.map { it.toLowerCase().capitalize() }) { + val allNames = names + names.map { it.lowercase(Locale.getDefault()) } + names.map { current -> + current.lowercase(Locale.getDefault()).replaceFirstChar { + if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() + } + } + + for (name in allNames) { assertEquals(listOf(), listOf(name).normalizePathComponents()) assertEquals(listOf(), listOf(name, name).normalizePathComponents()) assertEquals(listOf("a"), listOf(name, "a", name).normalizePathComponents()) diff --git a/ktor-server/ktor-server/jvm/test/io/ktor/tests/http/content/StaticContentResolutionTest.kt b/ktor-server/ktor-server/jvm/test/io/ktor/tests/http/content/StaticContentResolutionTest.kt index 23e94fe1260..23ad7ba14c2 100644 --- a/ktor-server/ktor-server/jvm/test/io/ktor/tests/http/content/StaticContentResolutionTest.kt +++ b/ktor-server/ktor-server/jvm/test/io/ktor/tests/http/content/StaticContentResolutionTest.kt @@ -12,6 +12,7 @@ import kotlinx.coroutines.* import java.net.* import kotlin.test.* +@OptIn(InternalAPI::class) class StaticContentResolutionTest { private val baseUrl = StaticContentResolutionTest::class.java.classLoader.getResource("testjar.jar") diff --git a/ktor-server/ktor-server/jvm/test/io/ktor/tests/utils/CopyOnWriteHashMapTest.kt b/ktor-server/ktor-server/jvm/test/io/ktor/tests/utils/CopyOnWriteHashMapTest.kt index c06911609eb..08d62d0a470 100644 --- a/ktor-server/ktor-server/jvm/test/io/ktor/tests/utils/CopyOnWriteHashMapTest.kt +++ b/ktor-server/ktor-server/jvm/test/io/ktor/tests/utils/CopyOnWriteHashMapTest.kt @@ -7,6 +7,7 @@ package io.ktor.tests.utils import io.ktor.server.util.* import kotlin.test.* +@OptIn(InternalAPI::class) class CopyOnWriteHashMapTest { private val map = CopyOnWriteHashMap() diff --git a/ktor-shared/ktor-shared-events/common/src/io/ktor/events/Events.kt b/ktor-shared/ktor-shared-events/common/src/io/ktor/events/Events.kt index a1a93068bf2..9c31a3cb090 100644 --- a/ktor-shared/ktor-shared-events/common/src/io/ktor/events/Events.kt +++ b/ktor-shared/ktor-shared-events/common/src/io/ktor/events/Events.kt @@ -4,10 +4,12 @@ package io.ktor.events +import io.ktor.util.* import io.ktor.util.collections.* import kotlinx.coroutines.* import kotlinx.coroutines.internal.* +@OptIn(InternalAPI::class) public class Events { @OptIn(InternalCoroutinesApi::class) private val handlers = CopyOnWriteHashMap, LockFreeLinkedListHead>() diff --git a/ktor-shared/ktor-shared-serialization-gson/jvm/src/GsonConverter.kt b/ktor-shared/ktor-shared-serialization-gson/jvm/src/GsonConverter.kt index 9214e6650aa..7e09040e603 100644 --- a/ktor-shared/ktor-shared-serialization-gson/jvm/src/GsonConverter.kt +++ b/ktor-shared/ktor-shared-serialization-gson/jvm/src/GsonConverter.kt @@ -28,7 +28,7 @@ public class GsonConverter(private val gson: Gson = Gson()) : ContentConverter { charset: Charset, typeInfo: TypeInfo, value: Any - ): OutgoingContent? { + ): OutgoingContent { return TextContent(gson.toJson(value), contentType.withCharset(charset)) } diff --git a/ktor-shared/ktor-shared-serialization-jackson/build.gradle.kts b/ktor-shared/ktor-shared-serialization-jackson/build.gradle.kts index a679515b3f7..e1d02f5bb9f 100644 --- a/ktor-shared/ktor-shared-serialization-jackson/build.gradle.kts +++ b/ktor-shared/ktor-shared-serialization-jackson/build.gradle.kts @@ -1,5 +1,6 @@ description = "" +val kotlin_version: String by project.extra val jackson_version: String by project.extra val jackson_kotlin_version: String by project.extra @@ -10,6 +11,7 @@ kotlin { api(project(":ktor-shared:ktor-shared-serialization")) api("com.fasterxml.jackson.core:jackson-databind:$jackson_version") api("com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_kotlin_version") + implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version") } } jvmTest { diff --git a/ktor-test-dispatcher/build.gradle.kts b/ktor-test-dispatcher/build.gradle.kts index 5c86f504e3f..89136722e65 100644 --- a/ktor-test-dispatcher/build.gradle.kts +++ b/ktor-test-dispatcher/build.gradle.kts @@ -1,9 +1,8 @@ -val ideaActive: Boolean by project.extra val isMacosHost: Boolean by project.extra kotlin { sourceSets { - if (ideaActive) { + if (KtorBuildProperties.ideaActive) { val srcDir = when { isMacosHost -> "macosX64/src" else -> "linuxX64/src" diff --git a/ktor-test-dispatcher/js/src/TestJs.kt b/ktor-test-dispatcher/js/src/TestJs.kt index 607aab27019..cd7ac5fb033 100644 --- a/ktor-test-dispatcher/js/src/TestJs.kt +++ b/ktor-test-dispatcher/js/src/TestJs.kt @@ -10,6 +10,7 @@ import kotlin.coroutines.* /** * Test runner for js suspend tests. */ +@OptIn(DelicateCoroutinesApi::class) public actual fun testSuspend( context: CoroutineContext, block: suspend CoroutineScope.() -> Unit diff --git a/ktor-utils/api/ktor-utils.api b/ktor-utils/api/ktor-utils.api index 8998465e8f2..57ec11aed44 100644 --- a/ktor-utils/api/ktor-utils.api +++ b/ktor-utils/api/ktor-utils.api @@ -649,9 +649,9 @@ public final class io/ktor/util/date/DateJvmKt { public final class io/ktor/util/date/DateKt { public static final fun minus (Lio/ktor/util/date/GMTDate;J)Lio/ktor/util/date/GMTDate; - public static final fun minus-DXA3NOw (Lio/ktor/util/date/GMTDate;J)Lio/ktor/util/date/GMTDate; + public static final fun minus-HG0u8IE (Lio/ktor/util/date/GMTDate;J)Lio/ktor/util/date/GMTDate; public static final fun plus (Lio/ktor/util/date/GMTDate;J)Lio/ktor/util/date/GMTDate; - public static final fun plus-DXA3NOw (Lio/ktor/util/date/GMTDate;J)Lio/ktor/util/date/GMTDate; + public static final fun plus-HG0u8IE (Lio/ktor/util/date/GMTDate;J)Lio/ktor/util/date/GMTDate; public static final fun truncateToSeconds (Lio/ktor/util/date/GMTDate;)Lio/ktor/util/date/GMTDate; } diff --git a/ktor-utils/build.gradle.kts b/ktor-utils/build.gradle.kts index 681e27a706d..cbdc09bc455 100644 --- a/ktor-utils/build.gradle.kts +++ b/ktor-utils/build.gradle.kts @@ -1,7 +1,6 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.* val nativeCompilations: List by project.extra -val ideaActive: Boolean by project.extra kotlin { configure(nativeCompilations) { @@ -31,7 +30,7 @@ kotlin { } // Hack: register the Native interop klibs as outputs of Kotlin source sets: - if (!ideaActive && rootProject.ext.get("native_targets_enabled") as Boolean) { + if (!KtorBuildProperties.ideaActive && rootProject.ext.get("native_targets_enabled") as Boolean) { val utilsInterop by creating getByName("posixMain").dependsOn(utilsInterop) apply(from = "$rootDir/gradle/interop-as-source-set-klib.gradle") diff --git a/ktor-utils/common/src/io/ktor/util/Base64.kt b/ktor-utils/common/src/io/ktor/util/Base64.kt index 9f2258dfd30..8e6c1d5b74b 100644 --- a/ktor-utils/common/src/io/ktor/util/Base64.kt +++ b/ktor-utils/common/src/io/ktor/util/Base64.kt @@ -21,7 +21,6 @@ private val BASE64_INVERSE_ALPHABET = IntArray(256) { /** * Encode [String] in base64 format and UTF-8 character encoding. */ -@InternalAPI public fun String.encodeBase64(): String = buildPacket { writeText(this@encodeBase64) }.encodeBase64() @@ -29,7 +28,6 @@ public fun String.encodeBase64(): String = buildPacket { /** * Encode [ByteArray] in base64 format */ -@InternalAPI public fun ByteArray.encodeBase64(): String = buildPacket { writeFully(this@encodeBase64) }.encodeBase64() @@ -37,7 +35,6 @@ public fun ByteArray.encodeBase64(): String = buildPacket { /** * Encode [ByteReadPacket] in base64 format */ -@InternalAPI public fun ByteReadPacket.encodeBase64(): String = buildString { val data = ByteArray(3) while (remaining > 0) { @@ -61,13 +58,11 @@ public fun ByteReadPacket.encodeBase64(): String = buildString { /** * Decode [String] from base64 format encoded in UTF-8. */ -@InternalAPI public fun String.decodeBase64String(): String = String(decodeBase64Bytes(), charset = Charsets.UTF_8) /** * Decode [String] from base64 format */ -@InternalAPI public fun String.decodeBase64Bytes(): ByteArray = buildPacket { writeText(dropLastWhile { it == BASE64_PAD }) }.decodeBase64Bytes().readBytes() @@ -75,7 +70,6 @@ public fun String.decodeBase64Bytes(): ByteArray = buildPacket { /** * Decode [ByteReadPacket] from base64 format */ -@InternalAPI public fun ByteReadPacket.decodeBase64Bytes(): Input = buildPacket { val data = ByteArray(4) diff --git a/ktor-utils/common/src/io/ktor/util/ByteChannels.kt b/ktor-utils/common/src/io/ktor/util/ByteChannels.kt index f3e715f2681..243dbf7453c 100644 --- a/ktor-utils/common/src/io/ktor/util/ByteChannels.kt +++ b/ktor-utils/common/src/io/ktor/util/ByteChannels.kt @@ -53,7 +53,7 @@ public fun ByteReadChannel.split(coroutineScope: CoroutineScope): Pair : MutableMap { private val delegate = mutableMapOf() diff --git a/ktor-utils/common/src/io/ktor/util/Charset.kt b/ktor-utils/common/src/io/ktor/util/Charset.kt index 7c06a533262..644a40863e0 100644 --- a/ktor-utils/common/src/io/ktor/util/Charset.kt +++ b/ktor-utils/common/src/io/ktor/util/Charset.kt @@ -7,11 +7,9 @@ package io.ktor.util /** * Check if [Char] is in lower case */ -@InternalAPI -public fun Char.isLowerCase(): Boolean = toLowerCase() == this +public fun Char.isLowerCase(): Boolean = lowercaseChar() == this /** * Convert [String] to [CharArray] */ -@InternalAPI public fun String.toCharArray(): CharArray = CharArray(length) { get(it) } diff --git a/ktor-utils/common/src/io/ktor/util/Collections.kt b/ktor-utils/common/src/io/ktor/util/Collections.kt index aa3a89a4caa..45649e3e8bb 100644 --- a/ktor-utils/common/src/io/ktor/util/Collections.kt +++ b/ktor-utils/common/src/io/ktor/util/Collections.kt @@ -7,11 +7,9 @@ package io.ktor.util /** * Create an instance of case insensitive mutable map. For internal use only. */ -@InternalAPI public fun caseInsensitiveMap(): MutableMap = CaseInsensitiveMap() /** * Freeze selected set. May do nothing on some platforms. */ -@InternalAPI public expect fun Set.unmodifiable(): Set diff --git a/ktor-utils/common/src/io/ktor/util/CoroutinesUtils.kt b/ktor-utils/common/src/io/ktor/util/CoroutinesUtils.kt index 935cd655398..0794dbada4f 100644 --- a/ktor-utils/common/src/io/ktor/util/CoroutinesUtils.kt +++ b/ktor-utils/common/src/io/ktor/util/CoroutinesUtils.kt @@ -10,7 +10,6 @@ import kotlin.coroutines.* /** * Print [Job] children tree. */ -@InternalAPI public fun Job.printDebugTree(offset: Int = 0) { println(" ".repeat(offset) + this) @@ -21,7 +20,6 @@ public fun Job.printDebugTree(offset: Int = 0) { if (offset == 0) println() } -@InternalAPI @Suppress("NOTHING_TO_INLINE") internal expect inline fun (suspend R.(A) -> Unit).startCoroutineUninterceptedOrReturn3( receiver: R, @@ -32,6 +30,5 @@ internal expect inline fun (suspend R.(A) -> Unit).startCoroutineUninterc /** * Supervisor with empty coroutine exception handler ignoring all exceptions. */ -@InternalAPI public fun SilentSupervisor(parent: Job? = null): CoroutineContext = SupervisorJob(parent) + CoroutineExceptionHandler { _, _ -> } diff --git a/ktor-utils/common/src/io/ktor/util/Crypto.kt b/ktor-utils/common/src/io/ktor/util/Crypto.kt index d006344b67f..03c13bb3482 100644 --- a/ktor-utils/common/src/io/ktor/util/Crypto.kt +++ b/ktor-utils/common/src/io/ktor/util/Crypto.kt @@ -49,13 +49,11 @@ public fun hex(s: String): ByteArray { /** * Generates a nonce string. Could block if the system's entropy source is empty */ -@InternalAPI public expect fun generateNonce(): String /** * Generates a nonce bytes of [size]. Could block if the system's entropy source is empty */ -@InternalAPI public fun generateNonce(size: Int): ByteArray = buildPacket { while (this.size < size) { writeText(generateNonce()) @@ -71,13 +69,11 @@ public expect fun sha1(bytes: ByteArray): ByteArray * Create [Digest] from specified hash [name]. */ @Suppress("FunctionName") -@InternalAPI public expect fun Digest(name: String): Digest /** * Stateful digest class specified to calculate digest. */ -@InternalAPI public interface Digest { /** * Add [bytes] to digest value. diff --git a/ktor-utils/common/src/io/ktor/util/Lock.kt b/ktor-utils/common/src/io/ktor/util/Lock.kt index 305c2d1d93f..2256e332298 100644 --- a/ktor-utils/common/src/io/ktor/util/Lock.kt +++ b/ktor-utils/common/src/io/ktor/util/Lock.kt @@ -6,7 +6,6 @@ package io.ktor.util -@InternalAPI public expect class Lock() { public fun lock() public fun unlock() @@ -14,7 +13,6 @@ public expect class Lock() { public fun close() } -@InternalAPI public inline fun Lock.withLock(crossinline block: () -> R): R { try { lock() diff --git a/ktor-utils/common/src/io/ktor/util/PlatformUtils.kt b/ktor-utils/common/src/io/ktor/util/PlatformUtils.kt index d1e4e7fb577..6b7df6e953a 100644 --- a/ktor-utils/common/src/io/ktor/util/PlatformUtils.kt +++ b/ktor-utils/common/src/io/ktor/util/PlatformUtils.kt @@ -4,7 +4,6 @@ package io.ktor.util -@InternalAPI public expect object PlatformUtils { public val IS_BROWSER: Boolean public val IS_NODE: Boolean diff --git a/ktor-utils/common/src/io/ktor/util/Ranges.kt b/ktor-utils/common/src/io/ktor/util/Ranges.kt index fa4755755d5..8edbb35b921 100644 --- a/ktor-utils/common/src/io/ktor/util/Ranges.kt +++ b/ktor-utils/common/src/io/ktor/util/Ranges.kt @@ -14,6 +14,5 @@ public val LongRange.length: Long /** * Returns `true` if [other] range is fully contained inside [this] range */ -@InternalAPI public operator fun LongRange.contains(other: LongRange): Boolean = other.start >= start && other.endInclusive <= endInclusive diff --git a/ktor-utils/common/src/io/ktor/util/StringValues.kt b/ktor-utils/common/src/io/ktor/util/StringValues.kt index 70230969cfa..73cd1d3ad05 100644 --- a/ktor-utils/common/src/io/ktor/util/StringValues.kt +++ b/ktor-utils/common/src/io/ktor/util/StringValues.kt @@ -100,7 +100,6 @@ public interface StringValuesBuilder { public fun build(): StringValues } -@InternalAPI @Suppress("KDocMissingDocumentation") public open class StringValuesSingleImpl( override val caseInsensitiveName: Boolean, @@ -144,7 +143,6 @@ public open class StringValuesSingleImpl( name.equals(this.name, caseInsensitiveName) && values.contains(value) } -@InternalAPI @Suppress("KDocMissingDocumentation") public open class StringValuesImpl( override val caseInsensitiveName: Boolean = false, @@ -187,7 +185,6 @@ public open class StringValuesImpl( override fun hashCode(): Int = entriesHashCode(entries(), 31 * caseInsensitiveName.hashCode()) } -@InternalAPI @Suppress("KDocMissingDocumentation") public open class StringValuesBuilderImpl( final override val caseInsensitiveName: Boolean = false, diff --git a/ktor-utils/common/src/io/ktor/util/Text.kt b/ktor-utils/common/src/io/ktor/util/Text.kt index 3e7c72c2107..687f0a5a25e 100644 --- a/ktor-utils/common/src/io/ktor/util/Text.kt +++ b/ktor-utils/common/src/io/ktor/util/Text.kt @@ -46,7 +46,6 @@ public inline fun String.chomp( * Does the same as the regular [toLowerCase] except that locale-specific rules are not applied to ASCII characters * so latin characters are converted by the original english rules. */ -@InternalAPI public fun String.toLowerCasePreservingASCIIRules(): String { val firstIndex = indexOfFirst { toLowerCasePreservingASCII(it) != it @@ -70,7 +69,6 @@ public fun String.toLowerCasePreservingASCIIRules(): String { * Does the same as the regular [toUpperCase] except that locale-specific rules are not applied to ASCII characters * so latin characters are converted by the original english rules. */ -@InternalAPI public fun String.toUpperCasePreservingASCIIRules(): String { val firstIndex = indexOfFirst { toUpperCasePreservingASCII(it) != it @@ -93,19 +91,19 @@ public fun String.toUpperCasePreservingASCIIRules(): String { private fun toLowerCasePreservingASCII(ch: Char): Char = when (ch) { in 'A'..'Z' -> ch + 32 in '\u0000'..'\u007f' -> ch - else -> ch.toLowerCase() + else -> ch.lowercaseChar() } private fun toUpperCasePreservingASCII(ch: Char): Char = when (ch) { in 'a'..'z' -> ch - 32 in '\u0000'..'\u007f' -> ch - else -> ch.toLowerCase() + else -> ch.lowercaseChar() } internal fun String.caseInsensitive(): CaseInsensitiveString = CaseInsensitiveString(this) internal class CaseInsensitiveString(val content: String) { - private val hash = content.toLowerCase().hashCode() + private val hash = content.lowercase().hashCode() override fun equals(other: Any?): Boolean = (other as? CaseInsensitiveString)?.content?.equals(content, ignoreCase = true) == true diff --git a/ktor-utils/common/src/io/ktor/util/cio/Readers.kt b/ktor-utils/common/src/io/ktor/util/cio/Readers.kt index 2c0d23697cd..7aeb58ee08f 100644 --- a/ktor-utils/common/src/io/ktor/util/cio/Readers.kt +++ b/ktor-utils/common/src/io/ktor/util/cio/Readers.kt @@ -17,6 +17,7 @@ public suspend fun ByteReadChannel.toByteArray(limit: Int = Int.MAX_VALUE): Byte /** * Executes [block] on [ByteWriteChannel] and close it down correctly whether an exception */ +@OptIn(ExperimentalContracts::class) public inline fun ByteWriteChannel.use(block: ByteWriteChannel.() -> Unit) { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) diff --git a/ktor-utils/common/src/io/ktor/util/collections/ConcurrentMap.kt b/ktor-utils/common/src/io/ktor/util/collections/ConcurrentMap.kt index cd392ca84d5..86c18fb0df5 100644 --- a/ktor-utils/common/src/io/ktor/util/collections/ConcurrentMap.kt +++ b/ktor-utils/common/src/io/ktor/util/collections/ConcurrentMap.kt @@ -17,7 +17,6 @@ private const val UPSIZE_RATIO = 2 /** * Ktor concurrent map implementation. Please do not use it. */ -@InternalAPI public class ConcurrentMap( private val lock: Lock = Lock(), initialCapacity: Int = INITIAL_CAPACITY diff --git a/ktor-utils/common/src/io/ktor/util/collections/ConcurrentSet.kt b/ktor-utils/common/src/io/ktor/util/collections/ConcurrentSet.kt index 8c83326cdbf..08b0421e765 100644 --- a/ktor-utils/common/src/io/ktor/util/collections/ConcurrentSet.kt +++ b/ktor-utils/common/src/io/ktor/util/collections/ConcurrentSet.kt @@ -10,7 +10,6 @@ import io.ktor.utils.io.* /** * Concurrent set implemented on top of [ConcurrentMap] */ -@InternalAPI public class ConcurrentSet constructor( private val lock: Lock = Lock(), private val delegate: ConcurrentMap = ConcurrentMap(lock) diff --git a/ktor-utils/common/src/io/ktor/util/collections/internal/SharedList.kt b/ktor-utils/common/src/io/ktor/util/collections/internal/SharedList.kt index 723f03393df..d4037109d5e 100644 --- a/ktor-utils/common/src/io/ktor/util/collections/internal/SharedList.kt +++ b/ktor-utils/common/src/io/ktor/util/collections/internal/SharedList.kt @@ -4,11 +4,9 @@ package io.ktor.util.collections.internal -import io.ktor.util.* import io.ktor.utils.io.* import kotlinx.atomicfu.* -@InternalAPI internal class SharedList(override val size: Int) : List { private val data: AtomicArray = atomicArrayOfNulls(size) diff --git a/ktor-utils/common/src/io/ktor/util/converters/DataConversion.kt b/ktor-utils/common/src/io/ktor/util/converters/DataConversion.kt index 8bc9244824e..e8d3a444b62 100644 --- a/ktor-utils/common/src/io/ktor/util/converters/DataConversion.kt +++ b/ktor-utils/common/src/io/ktor/util/converters/DataConversion.kt @@ -77,13 +77,13 @@ public class DelegatingConversionService( ) : ConversionService { override fun fromValues(values: List, type: TypeInfo): Any? { - if (decoder == null) throw IllegalStateException("Decoder was not specified for type '$klass'") - return decoder!!(values) + val currentDecoder = decoder ?: throw IllegalStateException("Decoder was not specified for type '$klass'") + return currentDecoder(values) } override fun toValues(value: Any?): List { - if (encoder == null) throw IllegalStateException("Encoder was not specified for type '$klass'") - return encoder!!(value) + val currentDecoder = encoder ?: throw IllegalStateException("Encoder was not specified for type '$klass'") + return currentDecoder(value) } /** diff --git a/ktor-utils/common/src/io/ktor/util/date/Date.kt b/ktor-utils/common/src/io/ktor/util/date/Date.kt index 1616b12c917..664d3ac64bd 100644 --- a/ktor-utils/common/src/io/ktor/util/date/Date.kt +++ b/ktor-utils/common/src/io/ktor/util/date/Date.kt @@ -138,13 +138,13 @@ public operator fun GMTDate.minus(milliseconds: Long): GMTDate = GMTDate(timesta * Adds the specified [duration] */ @ExperimentalTime -public operator fun GMTDate.plus(duration: Duration): GMTDate = GMTDate(timestamp + duration.toLongMilliseconds()) +public operator fun GMTDate.plus(duration: Duration): GMTDate = GMTDate(timestamp + duration.inWholeMilliseconds) /** * Subtracts the specified [duration] */ @ExperimentalTime -public operator fun GMTDate.minus(duration: Duration): GMTDate = GMTDate(timestamp - duration.toLongMilliseconds()) +public operator fun GMTDate.minus(duration: Duration): GMTDate = GMTDate(timestamp - duration.inWholeMilliseconds) /** * Truncate to seconds by discarding sub-second part diff --git a/ktor-utils/common/src/io/ktor/util/date/GMTDateParser.kt b/ktor-utils/common/src/io/ktor/util/date/GMTDateParser.kt index 63db2936888..d055d3b836c 100644 --- a/ktor-utils/common/src/io/ktor/util/date/GMTDateParser.kt +++ b/ktor-utils/common/src/io/ktor/util/date/GMTDateParser.kt @@ -19,7 +19,6 @@ import io.ktor.util.* * | Year | Y | parse year | * | Any char | * | Match any character | */ -@InternalAPI public class GMTDateParser(private val pattern: String) { init { check(pattern.isNotEmpty()) { "Date parser pattern shouldn't be empty." } diff --git a/ktor-utils/common/src/io/ktor/util/network/NetworkAddress.kt b/ktor-utils/common/src/io/ktor/util/network/NetworkAddress.kt index 61822a3c813..597a26e7066 100644 --- a/ktor-utils/common/src/io/ktor/util/network/NetworkAddress.kt +++ b/ktor-utils/common/src/io/ktor/util/network/NetworkAddress.kt @@ -25,11 +25,13 @@ public expect fun NetworkAddress(hostname: String, port: Int): NetworkAddress /** * Network address hostname. */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public expect val NetworkAddress.hostname: String /** * Network address port. */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public expect val NetworkAddress.port: Int @Suppress("KDocMissingDocumentation") diff --git a/ktor-utils/common/src/io/ktor/util/pipeline/Pipeline.kt b/ktor-utils/common/src/io/ktor/util/pipeline/Pipeline.kt index ffa3e5e204d..f30dc611ee6 100644 --- a/ktor-utils/common/src/io/ktor/util/pipeline/Pipeline.kt +++ b/ktor-utils/common/src/io/ktor/util/pipeline/Pipeline.kt @@ -41,7 +41,6 @@ public open class Pipeline( /** * @return `true` if there are no interceptors installed regardless number of phases */ - @InternalAPI public val isEmpty: Boolean get() = interceptorsQuantity == 0 diff --git a/ktor-utils/common/test/io/ktor/util/ChannelTest.kt b/ktor-utils/common/test/io/ktor/util/ChannelTest.kt index c1c1acb66db..a340c672199 100644 --- a/ktor-utils/common/test/io/ktor/util/ChannelTest.kt +++ b/ktor-utils/common/test/io/ktor/util/ChannelTest.kt @@ -38,6 +38,7 @@ class ChannelTest { assertArrayEquals(data, results[1]) } + @OptIn(DelicateCoroutinesApi::class) @Test fun testCopyToBothCancelSource() = testSuspend { val source = ByteChannel() @@ -67,6 +68,7 @@ class ChannelTest { } } + @OptIn(DelicateCoroutinesApi::class) @Test fun testCopyToBothCancelFirstReader() = testSuspend { val data = ByteArray(16 * 1024) { it.toByte() } @@ -97,6 +99,7 @@ class ChannelTest { } } + @OptIn(DelicateCoroutinesApi::class) @Test fun testCopyToBothCancelSecondReader() = testSuspend { val data = ByteArray(16 * 1024) { it.toByte() } diff --git a/ktor-utils/common/test/io/ktor/util/GMTDateTest.kt b/ktor-utils/common/test/io/ktor/util/GMTDateTest.kt index fed158231c0..57fd66a56d6 100644 --- a/ktor-utils/common/test/io/ktor/util/GMTDateTest.kt +++ b/ktor-utils/common/test/io/ktor/util/GMTDateTest.kt @@ -50,9 +50,9 @@ class GMTDateTest { @Test fun testDurationArithmetic() { val now = GMTDate() - val plus10Secs = now + 10.seconds + val plus10Secs = now + Duration.seconds(10) assertTrue { now < plus10Secs } assertEquals(now.plus(10_000), plus10Secs) - assertEquals(now, plus10Secs - 10.seconds) + assertEquals(now, plus10Secs - Duration.seconds(10)) } } diff --git a/ktor-utils/js/src/io/ktor/util/CoroutinesUtilsJs.kt b/ktor-utils/js/src/io/ktor/util/CoroutinesUtilsJs.kt index 114603acd5a..70bec312d7d 100644 --- a/ktor-utils/js/src/io/ktor/util/CoroutinesUtilsJs.kt +++ b/ktor-utils/js/src/io/ktor/util/CoroutinesUtilsJs.kt @@ -7,7 +7,6 @@ package io.ktor.util import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* -@InternalAPI @Suppress("NOTHING_TO_INLINE") internal actual inline fun (suspend R.(A) -> Unit).startCoroutineUninterceptedOrReturn3( receiver: R, diff --git a/ktor-utils/js/src/io/ktor/util/CryptoJs.kt b/ktor-utils/js/src/io/ktor/util/CryptoJs.kt index 2c063a8d727..570c3770044 100644 --- a/ktor-utils/js/src/io/ktor/util/CryptoJs.kt +++ b/ktor-utils/js/src/io/ktor/util/CryptoJs.kt @@ -13,7 +13,6 @@ private const val NONCE_SIZE_IN_BYTES = 8 /** * Generates a nonce string. */ -@InternalAPI public actual fun generateNonce(): String { val buffer = ByteArray(NONCE_SIZE_IN_BYTES) if (PlatformUtils.IS_NODE) { @@ -27,7 +26,6 @@ public actual fun generateNonce(): String { /** * Create [Digest] from specified hash [name]. */ -@InternalAPI public actual fun Digest(name: String): Digest = object : Digest { private val state = mutableListOf() override fun plusAssign(bytes: ByteArray) { @@ -59,13 +57,13 @@ private val _crypto: Crypto by lazy { // lazy because otherwise it's untestable private external class Crypto { val subtle: SubtleCrypto - public fun getRandomValues(array: ByteArray) + fun getRandomValues(array: ByteArray) - public fun randomFillSync(array: ByteArray) + fun randomFillSync(array: ByteArray) } private external class SubtleCrypto { - public fun digest(algoName: String, buffer: ByteArray): Promise + fun digest(algoName: String, buffer: ByteArray): Promise } /** diff --git a/ktor-utils/js/src/io/ktor/util/LockJs.kt b/ktor-utils/js/src/io/ktor/util/LockJs.kt index d4083ef37e2..50c83217c4b 100644 --- a/ktor-utils/js/src/io/ktor/util/LockJs.kt +++ b/ktor-utils/js/src/io/ktor/util/LockJs.kt @@ -5,7 +5,6 @@ package io.ktor.util -@InternalAPI public actual class Lock { public actual fun lock() {} public actual fun unlock() {} diff --git a/ktor-utils/jvm/src/io/ktor/util/BufferViewJvm.kt b/ktor-utils/jvm/src/io/ktor/util/BufferViewJvm.kt index 4859ec02ea3..968dc5c446c 100644 --- a/ktor-utils/jvm/src/io/ktor/util/BufferViewJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/BufferViewJvm.kt @@ -13,7 +13,6 @@ import java.nio.channels.* * Could return `0` if the channel is non-blocking or [buffer] has no free space * @return number of bytes read (possibly 0) or -1 if EOF */ -@InternalAPI public fun ReadableByteChannel.read(buffer: ChunkBuffer): Int { if (buffer.writeRemaining == 0) return 0 var count = 0 diff --git a/ktor-utils/jvm/src/io/ktor/util/CollectionsJvm.kt b/ktor-utils/jvm/src/io/ktor/util/CollectionsJvm.kt index 894775b4139..f174cd44daf 100644 --- a/ktor-utils/jvm/src/io/ktor/util/CollectionsJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/CollectionsJvm.kt @@ -9,5 +9,4 @@ import java.util.* /** * Wraps into an unmodifiable set */ -@InternalAPI public actual fun Set.unmodifiable(): Set = Collections.unmodifiableSet(this) diff --git a/ktor-utils/jvm/src/io/ktor/util/CoroutinesUtilsJvm.kt b/ktor-utils/jvm/src/io/ktor/util/CoroutinesUtilsJvm.kt index 3c91c1579bf..1880e1a1da1 100644 --- a/ktor-utils/jvm/src/io/ktor/util/CoroutinesUtilsJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/CoroutinesUtilsJvm.kt @@ -6,7 +6,6 @@ package io.ktor.util import kotlin.coroutines.* -@InternalAPI @Suppress("NOTHING_TO_INLINE") internal actual inline fun (suspend R.(A) -> Unit).startCoroutineUninterceptedOrReturn3( receiver: R, diff --git a/ktor-utils/jvm/src/io/ktor/util/CryptoJvm.kt b/ktor-utils/jvm/src/io/ktor/util/CryptoJvm.kt index 81fac7db2f4..28124c73d22 100644 --- a/ktor-utils/jvm/src/io/ktor/util/CryptoJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/CryptoJvm.kt @@ -38,7 +38,8 @@ public actual fun sha1(bytes: ByteArray): ByteArray = runBlocking { */ public actual fun Digest(name: String): Digest = DigestImpl(MessageDigest.getInstance(name)) -private inline class DigestImpl(val delegate: MessageDigest) : Digest { +@JvmInline +private value class DigestImpl(val delegate: MessageDigest) : Digest { override fun plusAssign(bytes: ByteArray) { delegate.update(bytes) } @@ -54,7 +55,7 @@ private inline class DigestImpl(val delegate: MessageDigest) : Digest { * Generates a nonce string 16 characters long. Could block if the system's entropy source is empty */ public actual fun generateNonce(): String { - val nonce = seedChannel.poll() + val nonce = seedChannel.tryReceive().getOrNull() if (nonce != null) return nonce return generateNonceBlocking() diff --git a/ktor-utils/jvm/src/io/ktor/util/Deflater.kt b/ktor-utils/jvm/src/io/ktor/util/Deflater.kt index 5250ab58fa5..0df83acdb7f 100644 --- a/ktor-utils/jvm/src/io/ktor/util/Deflater.kt +++ b/ktor-utils/jvm/src/io/ktor/util/Deflater.kt @@ -57,6 +57,7 @@ private suspend fun ByteWriteChannel.deflateWhile(deflater: Deflater, buffer: By * Launch a coroutine on [coroutineContext] that does deflate compression * optionally doing CRC and writing GZIP header and trailer if [gzip] = `true` */ +@OptIn(DelicateCoroutinesApi::class) public fun ByteReadChannel.deflated( gzip: Boolean = true, pool: ObjectPool = KtorDefaultPool, @@ -103,6 +104,7 @@ public fun ByteReadChannel.deflated( * Launch a coroutine on [coroutineContext] that does deflate compression * optionally doing CRC and writing GZIP header and trailer if [gzip] = `true` */ +@OptIn(DelicateCoroutinesApi::class) public fun ByteWriteChannel.deflated( gzip: Boolean = true, pool: ObjectPool = KtorDefaultPool, diff --git a/ktor-utils/jvm/src/io/ktor/util/LockJvm.kt b/ktor-utils/jvm/src/io/ktor/util/LockJvm.kt index f56a6f77984..31dbc957576 100644 --- a/ktor-utils/jvm/src/io/ktor/util/LockJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/LockJvm.kt @@ -9,7 +9,6 @@ package io.ktor.util import java.util.concurrent.locks.* -@InternalAPI public actual class Lock { private val lock = ReentrantLock() diff --git a/ktor-utils/jvm/src/io/ktor/util/NIO.kt b/ktor-utils/jvm/src/io/ktor/util/NIO.kt index e581ffa81a6..75d21ea8f09 100644 --- a/ktor-utils/jvm/src/io/ktor/util/NIO.kt +++ b/ktor-utils/jvm/src/io/ktor/util/NIO.kt @@ -15,7 +15,6 @@ import java.nio.charset.* * @param limit is an optional parameter specifying maximum number of bytes to be moved * @return number of bytes moved */ -@InternalAPI public fun ByteBuffer.moveTo(destination: ByteBuffer, limit: Int = Int.MAX_VALUE): Int { val size = minOf(limit, remaining(), destination.remaining()) if (size == remaining()) { @@ -32,7 +31,6 @@ public fun ByteBuffer.moveTo(destination: ByteBuffer, limit: Int = Int.MAX_VALUE /** * Moves bytes from `this` buffer into newly created [ByteArray] and returns it */ -@InternalAPI public fun ByteBuffer.moveToByteArray(): ByteArray { val array = ByteArray(remaining()) get(array) @@ -42,7 +40,6 @@ public fun ByteBuffer.moveToByteArray(): ByteArray { /** * Decodes a string from `this` buffer with the specified [charset] */ -@InternalAPI public fun ByteBuffer.decodeString(charset: Charset = Charsets.UTF_8): String { return charset.decode(this).toString() } @@ -50,7 +47,6 @@ public fun ByteBuffer.decodeString(charset: Charset = Charsets.UTF_8): String { /** * Moves all bytes in `this` buffer to a newly created buffer with the optionally specified [size] */ -@InternalAPI public fun ByteBuffer.copy(size: Int = remaining()): ByteBuffer { return ByteBuffer.allocate(size).apply { this@copy.slice().moveTo(this@apply) @@ -61,7 +57,6 @@ public fun ByteBuffer.copy(size: Int = remaining()): ByteBuffer { /** * Moves all bytes in `this` buffer to a newly created buffer with the optionally specified [size] by allocating it from the given [pool] */ -@InternalAPI public fun ByteBuffer.copy(pool: ObjectPool, size: Int = remaining()): ByteBuffer = pool.borrow().apply { limit(size) this@copy.slice().moveTo(this) diff --git a/ktor-utils/jvm/src/io/ktor/util/Nonce.kt b/ktor-utils/jvm/src/io/ktor/util/Nonce.kt index 901c3e6dcf5..15963bd598f 100644 --- a/ktor-utils/jvm/src/io/ktor/util/Nonce.kt +++ b/ktor-utils/jvm/src/io/ktor/util/Nonce.kt @@ -26,67 +26,67 @@ internal val seedChannel: Channel = Channel(1024) private val NonceGeneratorCoroutineName = CoroutineName("nonce-generator") -private val nonceGeneratorJob = - GlobalScope.launch( - context = Dispatchers.IO + NonCancellable + NonceGeneratorCoroutineName, - start = CoroutineStart.LAZY - ) { - val seedChannel = seedChannel - var lastReseed = 0L - val previousRoundNonceList = ArrayList() - val secureInstance = lookupSecureRandom() - val weakRandom = SecureRandom.getInstance(SHA1PRNG) - - val secureBytes = ByteArray(SECURE_NONCE_COUNT * NONCE_SIZE_IN_BYTES) - val weakBytes = ByteArray(secureBytes.size * INSECURE_NONCE_COUNT_FACTOR) - - weakRandom.setSeed(secureInstance.generateSeed(secureBytes.size)) - - try { - while (true) { - // fill both - secureInstance.nextBytes(secureBytes) - weakRandom.nextBytes(weakBytes) - - // mix secure and weak - for (i in 0 until secureBytes.size) { - weakBytes[i * INSECURE_NONCE_COUNT_FACTOR] = secureBytes[i] - } - - // reseed weak bytes - // if too much time then reseed completely - // otherwise simply reseed with mixed - val currentTime = System.currentTimeMillis() - - if (currentTime - lastReseed > SECURE_RESEED_PERIOD) { - weakRandom.setSeed(lastReseed - currentTime) - weakRandom.setSeed(secureInstance.generateSeed(secureBytes.size)) - lastReseed = currentTime - } else { - weakRandom.setSeed(secureBytes) - } - - // concat entries with entries from the previous round - // and shuffle with weak random (reseeded) - val randomNonceList = (hex(weakBytes).chunked(16) + previousRoundNonceList).shuffled(weakRandom) - - // send first part to the channel - for (index in 0 until randomNonceList.size / 2) { - seedChannel.send(randomNonceList[index]) - } - - // stash the second part for the next round - previousRoundNonceList.clear() - for (index in randomNonceList.size / 2 until randomNonceList.size) { - previousRoundNonceList.add(randomNonceList[index]) - } +@OptIn(DelicateCoroutinesApi::class) +private val nonceGeneratorJob = GlobalScope.launch( + context = Dispatchers.IO + NonCancellable + NonceGeneratorCoroutineName, + start = CoroutineStart.LAZY +) { + val seedChannel = seedChannel + var lastReseed = 0L + val previousRoundNonceList = ArrayList() + val secureInstance = lookupSecureRandom() + val weakRandom = SecureRandom.getInstance(SHA1PRNG) + + val secureBytes = ByteArray(SECURE_NONCE_COUNT * NONCE_SIZE_IN_BYTES) + val weakBytes = ByteArray(secureBytes.size * INSECURE_NONCE_COUNT_FACTOR) + + weakRandom.setSeed(secureInstance.generateSeed(secureBytes.size)) + + try { + while (true) { + // fill both + secureInstance.nextBytes(secureBytes) + weakRandom.nextBytes(weakBytes) + + // mix secure and weak + for (i in 0 until secureBytes.size) { + weakBytes[i * INSECURE_NONCE_COUNT_FACTOR] = secureBytes[i] + } + + // reseed weak bytes + // if too much time then reseed completely + // otherwise simply reseed with mixed + val currentTime = System.currentTimeMillis() + + if (currentTime - lastReseed > SECURE_RESEED_PERIOD) { + weakRandom.setSeed(lastReseed - currentTime) + weakRandom.setSeed(secureInstance.generateSeed(secureBytes.size)) + lastReseed = currentTime + } else { + weakRandom.setSeed(secureBytes) + } + + // concat entries with entries from the previous round + // and shuffle with weak random (reseeded) + val randomNonceList = (hex(weakBytes).chunked(16) + previousRoundNonceList).shuffled(weakRandom) + + // send first part to the channel + for (index in 0 until randomNonceList.size / 2) { + seedChannel.send(randomNonceList[index]) + } + + // stash the second part for the next round + previousRoundNonceList.clear() + for (index in randomNonceList.size / 2 until randomNonceList.size) { + previousRoundNonceList.add(randomNonceList[index]) } - } catch (t: Throwable) { - seedChannel.close(t) - } finally { - seedChannel.close() } + } catch (t: Throwable) { + seedChannel.close(t) + } finally { + seedChannel.close() } +} internal fun ensureNonceGeneratorRunning() { nonceGeneratorJob.start() diff --git a/ktor-utils/jvm/src/io/ktor/util/cio/FileChannels.kt b/ktor-utils/jvm/src/io/ktor/util/cio/FileChannels.kt index 1b9f859dfcc..94e64626669 100644 --- a/ktor-utils/jvm/src/io/ktor/util/cio/FileChannels.kt +++ b/ktor-utils/jvm/src/io/ktor/util/cio/FileChannels.kt @@ -91,6 +91,7 @@ public fun File.readChannel( * This is why [coroutineContext] should have [Dispatchers.IO] or * a coroutine dispatcher that is properly configured for blocking IO. */ +@OptIn(DelicateCoroutinesApi::class) public fun File.writeChannel( coroutineContext: CoroutineContext = Dispatchers.IO ): ByteWriteChannel = GlobalScope.reader(CoroutineName("file-writer") + coroutineContext, autoFlush = true) { diff --git a/ktor-utils/jvm/src/io/ktor/util/date/DateJvm.kt b/ktor-utils/jvm/src/io/ktor/util/date/DateJvm.kt index f86d31cb4dc..e9000772b41 100644 --- a/ktor-utils/jvm/src/io/ktor/util/date/DateJvm.kt +++ b/ktor-utils/jvm/src/io/ktor/util/date/DateJvm.kt @@ -38,7 +38,6 @@ public actual fun GMTDate( set(Calendar.MILLISECOND, 0) }.toDate(timestamp = null) -@InternalAPI public fun Calendar.toDate(timestamp: Long?): GMTDate { timestamp?.let { timeInMillis = it } diff --git a/ktor-utils/jvm/src/io/ktor/util/internal/LockFreeLinkedList.kt b/ktor-utils/jvm/src/io/ktor/util/internal/LockFreeLinkedList.kt index 5363bd284c6..c92f73cdc72 100644 --- a/ktor-utils/jvm/src/io/ktor/util/internal/LockFreeLinkedList.kt +++ b/ktor-utils/jvm/src/io/ktor/util/internal/LockFreeLinkedList.kt @@ -10,7 +10,6 @@ package io.ktor.util.internal * Copied from kotlinx.coroutines */ -import io.ktor.util.* import kotlinx.atomicfu.* private typealias Node = LockFreeLinkedListNode @@ -54,7 +53,6 @@ private class Symbol(val symbol: String) { * * @suppress **This is unstable API and it is subject to change.** */ -@InternalAPI public abstract class OpDescriptor { /** * Returns `null` is operation was performed successfully or some other @@ -76,7 +74,6 @@ private val NO_DECISION: Any = Symbol("NO_DECISION") * * @suppress **This is unstable API and it is subject to change.** */ -@InternalAPI public abstract class AtomicOp : OpDescriptor() { private val _consensus = atomic(NO_DECISION) @@ -112,7 +109,6 @@ public abstract class AtomicOp : OpDescriptor() { * * @suppress **This is unstable API and it is subject to change.** */ -@InternalAPI public abstract class AtomicDesc { // returns `null` if prepared successfully @@ -138,7 +134,6 @@ public abstract class AtomicDesc { * @suppress **This is unstable API and it is subject to change.** */ @Suppress("LeakingThis") -@InternalAPI public open class LockFreeLinkedListNode { // Node | Removed | OpDescriptor @@ -506,7 +501,6 @@ public open class LockFreeLinkedListNode { final override fun finishOnSuccess(affected: Node, next: Node): Unit = affected.finishRemove(next) } - @InternalAPI public abstract class AbstractAtomicDesc : AtomicDesc() { protected abstract val affectedNode: Node? protected abstract val originalNext: Node? @@ -779,7 +773,6 @@ internal fun Any.unwrap(): Node = (this as? Removed)?.ref ?: this as Node * * @suppress **This is unstable API and it is subject to change.** */ -@InternalAPI public open class LockFreeLinkedListHead : LockFreeLinkedListNode() { public val isEmpty: Boolean get() = next === this diff --git a/ktor-utils/jvm/test/io/ktor/tests/utils/PipelineStackFramesTest.kt b/ktor-utils/jvm/test/io/ktor/tests/utils/PipelineStackFramesTest.kt deleted file mode 100644 index ee194bf2397..00000000000 --- a/ktor-utils/jvm/test/io/ktor/tests/utils/PipelineStackFramesTest.kt +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2014-2019 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -package io.ktor.tests.utils - -import io.ktor.util.* -import io.ktor.util.pipeline.* -import kotlinx.coroutines.* -import kotlin.coroutines.* -import kotlin.coroutines.intrinsics.* -import kotlin.test.* - -class PipelineStackFramesTest { - private val phase = PipelinePhase("StubPhase") - private lateinit var capturedStackTrace: String - private lateinit var capturedStackTrace2: String - - @Test - fun testStackTraceWalking() { - val pipeline = Pipeline(phase) - pipeline.intercept(phase) { - captureStackTrace() - } - - runBlocking { - runPipeline(pipeline) - } - - assertEquals( - capturedStackTrace, - "io.ktor.tests.utils.PipelineStackFramesTest.nestedCapture(PipelineStackFramesTest.kt)\n" + - "io.ktor.tests.utils.PipelineStackFramesTest.captureStackTrace(PipelineStackFramesTest.kt)\n" + - "io.ktor.tests.utils.PipelineStackFramesTest.runPipeline(PipelineStackFramesTest.kt)\n" - ) - - assertEquals( - capturedStackTrace2, - "io.ktor.tests.utils.PipelineStackFramesTest.nestedCapture(PipelineStackFramesTest.kt)\n" + - "io.ktor.tests.utils.PipelineStackFramesTest.captureStackTrace(PipelineStackFramesTest.kt)\n" - ) - } - - @Test - fun testNestedStackTraceWalking() { - val pipeline = Pipeline(phase) - pipeline.intercept(phase) { - callProceed() - } - - pipeline.intercept(phase) { - captureStackTrace() - } - - runBlocking { - runPipeline(pipeline) - } - - assertEquals( - capturedStackTrace, - "io.ktor.tests.utils.PipelineStackFramesTest.nestedCapture(PipelineStackFramesTest.kt)\n" + - "io.ktor.tests.utils.PipelineStackFramesTest.captureStackTrace(PipelineStackFramesTest.kt)\n" + - "io.ktor.tests.utils.PipelineStackFramesTest.callProceed(PipelineStackFramesTest.kt)\n" + - "io.ktor.tests.utils.PipelineStackFramesTest.runPipeline(PipelineStackFramesTest.kt)\n" - ) - - assertEquals( - capturedStackTrace2, - "io.ktor.tests.utils.PipelineStackFramesTest.nestedCapture(PipelineStackFramesTest.kt)\n" + - "io.ktor.tests.utils.PipelineStackFramesTest.captureStackTrace(PipelineStackFramesTest.kt)\n" - ) - } - - private suspend fun PipelineContext.callProceed() { - proceed() - preventTailCall() - } - - private fun interceptorStackTrace(continuation: Continuation<*>): String { - val frame = continuation as CoroutineStackFrame - val stacktrace = buildString { - var currentTop: CoroutineStackFrame? = frame - while (currentTop != null) { - val element = currentTop.getStackTraceElement() - if (element != null) { - append(element) - append('\n') - } - currentTop = currentTop.callerFrame - } - } - return stacktrace - .replace(Regex(":[0-9]+"), "") // line numbers - .replace(Regex("\n.*invokeSuspend.*\n"), "\n") - } - - private suspend fun runPipeline(pipeline: Pipeline) { - pipeline.execute(Unit, Unit) - preventTailCall() - } - - private suspend fun captureStackTrace() { - nestedCapture() - preventTailCall() - } - - private suspend fun nestedCapture() { - suspendCoroutineUninterceptedOrReturn { - capturedStackTrace = interceptorStackTrace(it) - capturedStackTrace2 = interceptorStackTrace(it) - Unit - } - preventTailCall() - } - - private fun preventTailCall() { - } -} diff --git a/ktor-utils/jvm/test/io/ktor/tests/utils/PipelineTest.kt b/ktor-utils/jvm/test/io/ktor/tests/utils/PipelineTest.kt index c3fdc37b50d..556f2e44ca1 100644 --- a/ktor-utils/jvm/test/io/ktor/tests/utils/PipelineTest.kt +++ b/ktor-utils/jvm/test/io/ktor/tests/utils/PipelineTest.kt @@ -431,19 +431,4 @@ class PipelineTest { pipeline.insertPhaseAfter(before, after) checkBeforeAfterPipeline(after, before, pipeline) } - - private suspend fun interceptor1(context: PipelineContext, content: String) { - yield() - context.proceedWith("$content first") - } - - private suspend fun interceptor2(context: PipelineContext, content: String) { - yield() - context.proceedWith("$content second") - } - - private suspend fun interceptor3(context: PipelineContext, content: String) { - yield() - error(content) - } } diff --git a/ktor-utils/posix/src/io/ktor/util/CollectionsNative.kt b/ktor-utils/posix/src/io/ktor/util/CollectionsNative.kt index 4ff3fa6d258..206b184bf68 100644 --- a/ktor-utils/posix/src/io/ktor/util/CollectionsNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/CollectionsNative.kt @@ -4,5 +4,4 @@ package io.ktor.util -@InternalAPI public actual fun Set.unmodifiable(): Set = this diff --git a/ktor-utils/posix/src/io/ktor/util/CoroutinesUtilsNative.kt b/ktor-utils/posix/src/io/ktor/util/CoroutinesUtilsNative.kt index 114603acd5a..70bec312d7d 100644 --- a/ktor-utils/posix/src/io/ktor/util/CoroutinesUtilsNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/CoroutinesUtilsNative.kt @@ -7,7 +7,6 @@ package io.ktor.util import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* -@InternalAPI @Suppress("NOTHING_TO_INLINE") internal actual inline fun (suspend R.(A) -> Unit).startCoroutineUninterceptedOrReturn3( receiver: R, diff --git a/ktor-utils/posix/src/io/ktor/util/CryptoNative.kt b/ktor-utils/posix/src/io/ktor/util/CryptoNative.kt index f2dba4ca3c8..6d86217e83a 100644 --- a/ktor-utils/posix/src/io/ktor/util/CryptoNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/CryptoNative.kt @@ -9,7 +9,6 @@ import platform.posix.* /** * Generates a nonce string 16 characters long. Could block if the system's entropy source is empty */ -@InternalAPI public actual fun generateNonce(): String { val builder = StringBuilder() repeat(16) { @@ -22,7 +21,6 @@ public actual fun generateNonce(): String { /** * Create [Digest] from specified hash [name]. */ -@InternalAPI public actual fun Digest(name: String): Digest = error("[Digest] is not supported on iOS") /** diff --git a/ktor-utils/posix/src/io/ktor/util/LockNative.kt b/ktor-utils/posix/src/io/ktor/util/LockNative.kt index a531ae824c0..4e72d812fa2 100644 --- a/ktor-utils/posix/src/io/ktor/util/LockNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/LockNative.kt @@ -8,7 +8,6 @@ import kotlinx.cinterop.* import utils.* import kotlin.native.concurrent.* -@InternalAPI public actual class Lock { private val mutex = nativeHeap.alloc() diff --git a/ktor-utils/posix/src/io/ktor/util/PlatformUtils.kt b/ktor-utils/posix/src/io/ktor/util/PlatformUtils.kt index 853622b98ed..1239e3ad552 100644 --- a/ktor-utils/posix/src/io/ktor/util/PlatformUtils.kt +++ b/ktor-utils/posix/src/io/ktor/util/PlatformUtils.kt @@ -4,7 +4,6 @@ package io.ktor.util -@InternalAPI public actual object PlatformUtils { public actual val IS_BROWSER: Boolean = false public actual val IS_NODE: Boolean = false diff --git a/ktor-utils/posix/src/io/ktor/util/network/NetworkAddressNative.kt b/ktor-utils/posix/src/io/ktor/util/network/NetworkAddressNative.kt index 0f3591e8ca8..e36ebcfdcd3 100644 --- a/ktor-utils/posix/src/io/ktor/util/network/NetworkAddressNative.kt +++ b/ktor-utils/posix/src/io/ktor/util/network/NetworkAddressNative.kt @@ -30,8 +30,10 @@ public actual class NetworkAddress constructor( public actual fun NetworkAddress(hostname: String, port: Int): NetworkAddress = NetworkAddress(hostname, port, null) +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public actual val NetworkAddress.hostname: String get() = hostname +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public actual val NetworkAddress.port: Int get() = port public actual class UnresolvedAddressException : IllegalArgumentException() diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 7da0fdf9cd8..00000000000 --- a/settings.gradle +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2014-2020 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -pluginManagement { - repositories { - mavenCentral() - google() - gradlePluginPortal() - } - resolutionStrategy { - eachPlugin { - if (requested.id.id == "kotlin2js") { - useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") - } - } - } -} -rootProject.name = 'ktor' - -ext.native_targets_enabled = properties['disable_native_targets'] == null - -// copied from versions.gradle -def versionComponents = System.getProperty('java.version')?. - split("\\.")?. - take(2)?. - findAll { !it.isBlank() }?. - collect { Integer.parseInt(it) } ?: - [1] - -ext.currentJdk = versionComponents[0] == 1 ? versionComponents[1] : versionComponents[0] - -def CACHE_USER = System.getenv("GRADLE_CACHE_USER") - -if (CACHE_USER != null) { - def CACHE_PASSWORD = System.getenv("GRADLE_CACHE_PASSWORD") - buildCache { - remote(HttpBuildCache) { - push = true - setUrl("https://ktor-gradle-cache.teamcity.com/cache/") - credentials { - username = CACHE_USER - password = CACHE_PASSWORD - } - } - } -} - -include ':ktor-server' -include ':ktor-server:ktor-server-core' -include ':ktor-server:ktor-server-tests' -include ':ktor-server:ktor-server-host-common' -include ':ktor-server:ktor-server-test-host' -include ':ktor-server:ktor-server-test-suites' -include ':ktor-server:ktor-server-jetty' -include ':ktor-server:ktor-server-jetty:ktor-server-jetty-test-http2' -include ':ktor-server:ktor-server-servlet' -include ':ktor-server:ktor-server-tomcat' -include ':ktor-server:ktor-server-netty' -include ':ktor-server:ktor-server-cio' -include ':ktor-client' -include ':ktor-client:ktor-client-core' -include ':ktor-client:ktor-client-tests' -include ':ktor-client:ktor-client-apache' -include ':ktor-client:ktor-client-android' -include ':ktor-client:ktor-client-cio' -if (native_targets_enabled) { - include ':ktor-client:ktor-client-curl' - include ':ktor-client:ktor-client-ios' -} -if (ext.currentJdk >= 11) { - include ':ktor-client:ktor-client-java' -} -include ':ktor-client:ktor-client-jetty' -include ':ktor-client:ktor-client-js' -include ':ktor-client:ktor-client-mock' -include ':ktor-client:ktor-client-okhttp' -include ':ktor-client:ktor-client-plugins' -include ':ktor-client:ktor-client-plugins:ktor-client-json' -include ':ktor-client:ktor-client-plugins:ktor-client-json:ktor-client-json-tests' -include ':ktor-client:ktor-client-plugins:ktor-client-json:ktor-client-gson' -include ':ktor-client:ktor-client-plugins:ktor-client-json:ktor-client-jackson' -include ':ktor-client:ktor-client-plugins:ktor-client-json:ktor-client-serialization' -include ':ktor-client:ktor-client-plugins:ktor-client-auth' -include ':ktor-client:ktor-client-plugins:ktor-client-logging' -include ':ktor-client:ktor-client-plugins:ktor-client-encoding' -include ':ktor-client:ktor-client-plugins:ktor-client-websockets' -include ':ktor-client:ktor-client-plugins:ktor-client-content-negotiation' -include ':ktor-client:ktor-client-plugins:ktor-client-content-negotiation:ktor-client-content-negotiation-tests' -//include ':ktor-client:ktor-client-plugins:ktor-client-tracing' -//include ':ktor-client:ktor-client-plugins:ktor-client-tracing:ktor-client-tracing-stetho' -include ':ktor-server:ktor-server-plugins:ktor-server-auth' -include ':ktor-server:ktor-server-plugins:ktor-server-auth-jwt' -include ':ktor-server:ktor-server-plugins:ktor-server-auth-ldap' -include ':ktor-server:ktor-server-plugins:ktor-server-auto-head-response' -include ':ktor-server:ktor-server-plugins:ktor-server-caching-headers' -include ':ktor-server:ktor-server-plugins:ktor-server-call-id' -include ':ktor-server:ktor-server-plugins:ktor-server-call-logging' -include ':ktor-server:ktor-server-plugins:ktor-server-compression' -include ':ktor-server:ktor-server-plugins:ktor-server-conditional-headers' -include ':ktor-server:ktor-server-plugins:ktor-server-content-negotiation' -include ':ktor-server:ktor-server-plugins:ktor-server-cors' -include ':ktor-server:ktor-server-plugins:ktor-server-data-conversion' -include ':ktor-server:ktor-server-plugins:ktor-server-default-headers' -include ':ktor-server:ktor-server-plugins:ktor-server-double-receive' -include ':ktor-server:ktor-server-plugins:ktor-server-forwarded-header' -include ':ktor-server:ktor-server-plugins:ktor-server-freemarker' -include ':ktor-server:ktor-server-plugins:ktor-server-hsts' -include ':ktor-server:ktor-server-plugins:ktor-server-html-builder' -include ':ktor-server:ktor-server-plugins:ktor-server-http-redirect' -include ':ktor-server:ktor-server-plugins:ktor-server-locations' -include ':ktor-server:ktor-server-plugins:ktor-server-metrics' -include ':ktor-server:ktor-server-plugins:ktor-server-metrics-micrometer' -include ':ktor-server:ktor-server-plugins:ktor-server-mustache' -include ':ktor-server:ktor-server-plugins:ktor-server-partial-content' -include ':ktor-server:ktor-server-plugins:ktor-server-pebble' -include ':ktor-server:ktor-server-plugins:ktor-server-sessions' -include ':ktor-server:ktor-server-plugins:ktor-server-status-pages' -include ':ktor-server:ktor-server-plugins:ktor-server-thymeleaf' -include ':ktor-server:ktor-server-plugins:ktor-server-velocity' -include ':ktor-server:ktor-server-plugins:ktor-server-webjars' -include ':ktor-server:ktor-server-plugins:ktor-server-websockets' -include ':ktor-server:ktor-server-plugins' -include ':ktor-http' -include ':ktor-http:ktor-http-cio' -include ':ktor-io' -include ':ktor-utils' -include ':ktor-network' -include ':ktor-network:ktor-network-tls' -include ':ktor-network:ktor-network-tls:ktor-network-tls-certificates' -include ':ktor-bom' -include ':ktor-test-dispatcher' -include ':ktor-shared' -include ':ktor-shared:ktor-shared-serialization' -include ':ktor-shared:ktor-shared-serialization-kotlinx' -include ':ktor-shared:ktor-shared-serialization-gson' -include ':ktor-shared:ktor-shared-serialization-jackson' -include ':ktor-shared:ktor-shared-events' diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 00000000000..c4f8b8b1310 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,140 @@ +/* + * Copyright 2014-2020 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +pluginManagement { + repositories { + mavenCentral() + google() + gradlePluginPortal() + } + resolutionStrategy { + eachPlugin { + if (requested.id.id == "kotlin2js") { + useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") + } + } + } +} + +rootProject.name = "ktor" + +val native_targets_enabled = !extra.has("disable_native_targets") + + + +val CACHE_USER = System.getenv("GRADLE_CACHE_USER") + +if (CACHE_USER != null) { + val CACHE_PASSWORD = System.getenv("GRADLE_CACHE_PASSWORD") + buildCache { + remote(HttpBuildCache::class) { + isPush = true + setUrl("https://ktor-gradle-cache.teamcity.com/cache/") + credentials { + username = CACHE_USER + password = CACHE_PASSWORD + } + } + } +} + +val fullVersion = System.getProperty("java.version", "8.0.0") +val versionComponents = fullVersion + .split(".") + .take(2) + .filter { it.isNotBlank() } + .map { Integer.parseInt(it) } + +val currentJdk = if (versionComponents[0] == 1) versionComponents[1] else versionComponents[0] + +include(":ktor-server") +include(":ktor-server:ktor-server-core") +include(":ktor-server:ktor-server-tests") +include(":ktor-server:ktor-server-host-common") +include(":ktor-server:ktor-server-test-host") +include(":ktor-server:ktor-server-test-suites") +include(":ktor-server:ktor-server-jetty") +include(":ktor-server:ktor-server-jetty:ktor-server-jetty-test-http2") +include(":ktor-server:ktor-server-servlet") +include(":ktor-server:ktor-server-tomcat") +include(":ktor-server:ktor-server-netty") +include(":ktor-server:ktor-server-cio") +include(":ktor-client") +include(":ktor-client:ktor-client-core") +include(":ktor-client:ktor-client-tests") +include(":ktor-client:ktor-client-apache") +include(":ktor-client:ktor-client-android") +include(":ktor-client:ktor-client-cio") +if (native_targets_enabled) { + include(":ktor-client:ktor-client-curl") + include(":ktor-client:ktor-client-ios") +} +if (currentJdk >= 11) { + include(":ktor-client:ktor-client-java") +} +include(":ktor-client:ktor-client-jetty") +include(":ktor-client:ktor-client-js") +include(":ktor-client:ktor-client-mock") +include(":ktor-client:ktor-client-okhttp") +include(":ktor-client:ktor-client-plugins") +include(":ktor-client:ktor-client-plugins:ktor-client-json") +include(":ktor-client:ktor-client-plugins:ktor-client-json:ktor-client-json-tests") +include(":ktor-client:ktor-client-plugins:ktor-client-json:ktor-client-gson") +include(":ktor-client:ktor-client-plugins:ktor-client-json:ktor-client-jackson") +include(":ktor-client:ktor-client-plugins:ktor-client-json:ktor-client-serialization") +include(":ktor-client:ktor-client-plugins:ktor-client-auth") +include(":ktor-client:ktor-client-plugins:ktor-client-logging") +include(":ktor-client:ktor-client-plugins:ktor-client-encoding") +include(":ktor-client:ktor-client-plugins:ktor-client-websockets") +include(":ktor-client:ktor-client-plugins:ktor-client-content-negotiation") +include(":ktor-client:ktor-client-plugins:ktor-client-content-negotiation:ktor-client-content-negotiation-tests") +//include(":ktor-client:ktor-client-plugins:ktor-client-tracing") +//include(":ktor-client:ktor-client-plugins:ktor-client-tracing:ktor-client-tracing-stetho") +include(":ktor-server:ktor-server-plugins:ktor-server-auth") +include(":ktor-server:ktor-server-plugins:ktor-server-auth-jwt") +include(":ktor-server:ktor-server-plugins:ktor-server-auth-ldap") +include(":ktor-server:ktor-server-plugins:ktor-server-auto-head-response") +include(":ktor-server:ktor-server-plugins:ktor-server-caching-headers") +include(":ktor-server:ktor-server-plugins:ktor-server-call-id") +include(":ktor-server:ktor-server-plugins:ktor-server-call-logging") +include(":ktor-server:ktor-server-plugins:ktor-server-compression") +include(":ktor-server:ktor-server-plugins:ktor-server-conditional-headers") +include(":ktor-server:ktor-server-plugins:ktor-server-content-negotiation") +include(":ktor-server:ktor-server-plugins:ktor-server-cors") +include(":ktor-server:ktor-server-plugins:ktor-server-data-conversion") +include(":ktor-server:ktor-server-plugins:ktor-server-default-headers") +include(":ktor-server:ktor-server-plugins:ktor-server-double-receive") +include(":ktor-server:ktor-server-plugins:ktor-server-forwarded-header") +include(":ktor-server:ktor-server-plugins:ktor-server-freemarker") +include(":ktor-server:ktor-server-plugins:ktor-server-hsts") +include(":ktor-server:ktor-server-plugins:ktor-server-html-builder") +include(":ktor-server:ktor-server-plugins:ktor-server-http-redirect") +include(":ktor-server:ktor-server-plugins:ktor-server-locations") +include(":ktor-server:ktor-server-plugins:ktor-server-metrics") +include(":ktor-server:ktor-server-plugins:ktor-server-metrics-micrometer") +include(":ktor-server:ktor-server-plugins:ktor-server-mustache") +include(":ktor-server:ktor-server-plugins:ktor-server-partial-content") +include(":ktor-server:ktor-server-plugins:ktor-server-pebble") +include(":ktor-server:ktor-server-plugins:ktor-server-sessions") +include(":ktor-server:ktor-server-plugins:ktor-server-status-pages") +include(":ktor-server:ktor-server-plugins:ktor-server-thymeleaf") +include(":ktor-server:ktor-server-plugins:ktor-server-velocity") +include(":ktor-server:ktor-server-plugins:ktor-server-webjars") +include(":ktor-server:ktor-server-plugins:ktor-server-websockets") +include(":ktor-server:ktor-server-plugins") +include(":ktor-http") +include(":ktor-http:ktor-http-cio") +include(":ktor-io") +include(":ktor-utils") +include(":ktor-network") +include(":ktor-network:ktor-network-tls") +include(":ktor-network:ktor-network-tls:ktor-network-tls-certificates") +include(":ktor-bom") +include(":ktor-test-dispatcher") +include(":ktor-shared") +include(":ktor-shared:ktor-shared-serialization") +include(":ktor-shared:ktor-shared-serialization-kotlinx") +include(":ktor-shared:ktor-shared-serialization-gson") +include(":ktor-shared:ktor-shared-serialization-jackson") +include(":ktor-shared:ktor-shared-events")