Migrating 0.9.2 → 1.0.0-beta-3
Table of contents:
1.0.0-beta-3
This is the third beta of Ktor. And the first version of Ktor using Kotlin 1.3.0 and kotlinx.coroutines 1.0.0 final versions!
- Full changelog: https://github.com/ktorio/ktor/compare/1.0.0-beta-2…1.0.0-beta-3
- API Documentation: https://api.ktor.io/1.0.0-beta-3
Published 29 Oct 2018
Version bumps:
Kotlin: 1.3.0-rc-146 -> 1.3.0
Kotlinx IO: 0.1.0-alpha-25-rc13 -> 0.1.0-beta-1
Kotlinx Coroutines: 1.0.0-RC1 -> 1.0.0
Kotlinx Serialization: 0.8.2-rc13 -> 0.9.0
AtomicFU: 0.11.11 -> 0.11.12
Improvements:
- Add js support in kotlinx.serialization feature (commit) (Close #666)
- Avoid blocking PRNG (commit)
- Improve OAuth2 diagnostics for token acquisition failure (#550)
- Lookup serializer with .serializer (commit)
- Added a bunch of KDocs and clarified old ones
Fixes:
- Fix handling auth errors (#676)
Minor:
- Remove the redundant flag from ApacheHttpRequest (commit)
How to try
You need to use Kotlin 1.3.0
or later. That version should be available at Maven Central and jcenter:
buildscript {
ext.kotlin_version = '1.3.0'
}
You will also need to use the Kotlin 1.3 inside IntelliJ IDEA.
1.0.0-beta-2
This is the second beta of Ktor.
- Full changelog: https://github.com/ktorio/ktor/compare/1.0.0-beta-1…1.0.0-beta-2
- API Documentation: https://api.ktor.io/1.0.0-beta-2
Published 24 Oct 2018
Version bumps:
Kotlin: 1.3.0-rc-131 -> 1.3.0-rc-146
Kotlinx IO: 0.1.0-alpha-19-rc13 -> 0.1.0-alpha-25-rc13
Kotlinx Coroutines: 0.30.2-eap13 -> 1.0.0-RC1
AtomicFU: 0.11.10-eap13 -> 0.11.11
Major changes:
Marked as experimental:
- Mark locations API as experimental (commit)
- Introduce stopServerOnCancellation instead of the cancellation helper (commit)
Deprecations:
- Rename nextNonce to generateNonce (commit)
Added:
- Introduce application coroutine scope (commit)
- Introduce ability to specify an coroutine scope for embedded server (commit)
- ktor-client: Add HttpsURLConnection config to AndroidEngineConfig (commit)
- ktor-client: Add proxy to AndroidEngineConfig (commit)
- Add KotlinxSerializer.register() with explicit KSerializer (commit)
- Add default serializers to KotlinxSerializer (commit)
- Add KotlinxSerializer register() to use reified generics to set mapper (commit)
- Introduce href extension function for the Locations feature (#597)
Minor changes:
- Restrict Location annotation targets, allow on a typealias (#539)
- Remove default connector on port 80 (#670)
- Do not disable Kotlin Native devirtualization (commit)
Improvements:
- Improve JWT diagnostics (#664)
- Improve OAuth2 diagnostics for token acquisition failure (#550)
- Replace Unconfined in blocking servlets implementation (commit)
- Improve nextNonce strength (now called generateNonce) (commit)
- Improve error handling of KotlinxSerializer (commit)
Fixes:
- Fix multipart part disposal on Windows (commit)
- Fix websocket IDLE timeout on Jetty (commit)
- Fix broken compression that caused channel to be closed too early (commit)
- Properly construct request headers in JS engine (#665)
- Fix engine’s suite socket connect timeout (commit)
- Fix embedded tomcat engine stop (commit)
- Eliminate using Unconfined for reading from file (fixes selector infinite loop) (commit)
- Fix StatusPages to handle child job failures (#646)
Removed:
- Fix experimental annotation in benchmark (commit)
How to try
You need to include kotlin-eap
repository and use Kotlin 1.3.0-rc-146
or later:
buildscript {
ext.kotlin_version = '1.3.0-rc-146'
repositories {
// ...
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
}
}
repositories {
// ...
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
maven { url 'https://dl.bintray.com/kotlin/kotlinx' }
maven { url 'https://dl.bintray.com/kotlin/ktor' }
jcenter()
}
You will also need to use the Early Access Preview 1.3 inside IntelliJ IDEA.
To do so, Tools -> Kotlin -> Configure Kotlin Updates
and as Update Channel, select Early Access Preview 1.3
and install that version of the plugin.
DevelopmentEngine to EngineMain
We have renamed the DevelopmentEngine
classes to EngineMain
, and you will have to update your application.conf
configuration files.
The DevelopmentEngine
classes were used as entry point for Ktor applications. It loaded the application.conf
and parsed CLI parameters, in addition tocreate an embedded server and loading the specified module.
The problem with DevelopmentEngine
was that it was confusing since some people identified Development
as opposed to Production
.
The new name reflects that it serves as entry point of the application, and that it is independent on the environment being suitable for both: development and production.
1.0.0-beta-1
This is the first beta of Ktor! This page includes changes from the alpha-2, alpha-3 and beta-1.
- Full changelog: https://github.com/ktorio/ktor/compare/1.0.0-alpha-1…1.0.0-beta-1
- API Documentation: https://api.ktor.io/1.0.0-beta-1/
Published 15 Oct 2018
Version bumps:
Kotlinx IO: 0.1.0-alpha-17-rc13 -> 0.1.0-alpha-19-rc13
Additions:
- Add js client engine (commit)
- Introduce client Send feature. Migrate HttpRedirect (commit)
- Introduce ExpectSuccess feature (commit)
Improvements:
- URLBuilder now distinguishes between a port not being specified and falling back to the defaultPort for the protocol (#561)
- Use UTF-8 encoding as fallback in client response config (commit)
- Use default port in client builders by default (port 0 now means the default port for the protocol)
- Provide user-defined function to configure Netty’s HttpServerCodec (#629) fixes #580
- Add missing HttpClient constructor (commit)
- Add MockEngine content test (commit)
- Add convenience methods to the WebSockets API (commit)
- Prepare to migration to coroutines 1.0.0-RC (#642)
- Use client status message from engine response (commit)
Fixes:
- Fix TLS decryptor loop bug and reduce garbage (commit)
- Fix escapeHTML utility function (commit)
- Fix client HttpSend loop to not exit if a call has been changed (commit)
- Fix broken normalizeAndRelativize, add documentation (commit)
- Fix cookies case sensitive (commit)
- Fix cookies and parameters duplication (commit)
Performance improvements:
- Improve internal utility ByteBuffer.moveTo (commit)
Documentation:
- Improve documentation, API cleanup, introduce experimental annotation (commit)
Minor and cleanups:
- Eliminate suspend function with CoroutineScope receiver (commit)
- Add more words to spell checker dictionary (commit)
- Eliminate unreachable code warning (commit)
- Fix test packets in client (commit)
- Drop Apache URIBuilder (commit)
- Fix Test names (commit)
- Fix .editorconfig to append trailing newline (commit)
How to try
You need to include kotlin-eap
repository and use Kotlin 1.3.0-rc-131
or later:
buildscript {
ext.kotlin_version = '1.3.0-rc-131'
repositories {
// ...
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
}
}
repositories {
// ...
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
maven { url 'https://dl.bintray.com/kotlin/kotlinx' }
maven { url 'https://dl.bintray.com/kotlin/ktor' }
jcenter()
}
You will also need to use the Early Access Preview 1.3 inside IntelliJ IDEA.
To do so, Tools -> Kotlin -> Configure Kotlin Updates
and as Update Channel, select Early Access Preview 1.3
and install that version of the plugin.
1.0.0-alpha-1
Ktor 1.0.0-alpha-1
is the initial pre-release version that preludes the 1.0.This version is the first one using Kotlin 1.3.0-rc-131
, and bumps the kotlinx.coroutines
version to 0.30.2-eap13
.As an important change, Ktor now uses the structured concurrency from kotlinx.coroutines
.In addition it adds
- Full changelog: https://github.com/ktorio/ktor/compare/0.9.5…1.0.0-alpha-1
- API Documentation: https://api.ktor.io/1.0.0-alpha-1/
Published 9 Oct 2018
Version Bumps:
Kotlin: 1.2.70 -> 1.3.0-rc-131
Kotlinx IO: 0.1.0-alpha-4 -> 0.1.0-alpha-17-rc13
Kotlinx Coroutines: 0.25.0 -> 0.30.2-eap13
Atomic FU: 0.11.3 -> 0.11.10-eap13
Major changes:
- Migrated to Kotlin 1.3
- Migrated to new coroutines with structured concurrency: https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/basics.md#structured-concurrency
Deprecations, renames and API changes:
- Increased some old deprecations to DeprecationLevel.ERROR
- Deprecated
ByteBufferBuilder
- Renamed
RoutingException
->LocationRoutingException
HttpMessageBuilder.contentLength()
andHttpMessage.contentLength()
now return Long- Remove some deprecated and changed to experimental internal APIs. (eg.
WebSocketInternalAPI
) AndroidClientEngine
is now@UseExperimental(InternalAPI::class)
- Deprecated
ApacheBackend
typealias forApache
engine
Fixes:
- Make default call pipeline discard request body content (Fixes #609, #574)
- Fixes url path encoding
- Fix server response logging after release
- Make
Cookie.matches
ignore a leading dot in the domain
Additions:
- Added
TestApplicationEngine.cookiesSession
https://github.com/ktorio/ktor/commit/1af97b8fcb3096cb390480508c4abd49c13a34de - Added
ContentTypes.CSV
#613 - Added
IosClientEngineConfig
Added call.responseConfig.defaultCharset
HttpResponseConfig
Improvements:
- Unify mimetype + use random from the Kotlin 1.3 stdlib
- Test Kotlin/Native on MacOS
Minor changes:
- Some API documentation
- Add editorconfig for external editors
- Use
kotlin.code.style=official
New coroutines
Since 1.0.0-alpha-1, Ktor is using the latest kotlinx.coroutines version that is using structured concurrency.Now each request has its own CoroutineScope
and you can also use the GlobalScope
.
For more information:https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/basics.md#structured-concurrency
0.9.5
Ktor 0.9.5 is a minor update, fixing some bugs, bumping some versions, and adding some minor stuff.
- Full changelog: https://github.com/ktorio/ktor/compare/0.9.4…0.9.5
- API Documentation: https://api.ktor.io/0.9.5/
- Example of migration: https://github.com/ktorio/ktor-samples/commit/499e88dd3ea98538445150ed611560259d5ea316
Published 19 Sep 2018
Version Bumps:
Kotlin: 1.2.61 -> 1.2.70
Minor potential breaking changes:
- Client’s
CookiesStorage.get
,CookiesStorage.addCookie
andHttpCookies.get
now accepts the requestUrlinstead of the host. Now the get returns a list of cookies. - Made HTTP Client extension method
HttpRequest.takeFrom(builder: HttpRequestBuilder): HttpRequestBuilder
. Now also sets the typed call attributes from thebuilder
.into a member method. Shouldn’t be a source compatibility problem when using star imports*
since it is in the same package.
Fixes:
HttpClient.config
was not preserving the base configuration (#559)- Fixed path and query escaping and make it consistent with
URLBuilder
(#577). - Fixed setting charset encoding for non-text content types
Additions:
- Introduced
CallId
feature - Added
MDC
support toCallLogging
feature
API Improvements:
- Added shorthand client functions for
HEAD
,OPTIONS
,PATCH
andDELETE
methods (#562) - HTTP Client: Added
List<Cookie>.get(name: String): Cookie?
shortcut. - HTTP Client: Added
fun FormBuilder.append(key: String, filename: String, block: BytePacketBuilder.() -> Unit)
to the FORM DSL. - URLBuilder’s parser improved (#553, #567)
- Added
respondOutputStream { }
response function - Split
Infrastructure
phase intoMonitoring
andFeatures
phases
Internal:
- Made
AcceptAllCookiesStorage
be the same for all the implementations. - Improved client’s cookie matching and processing
New http method shorcuts for the HTTP client
Before 0.9.5, when using the HTTP client and wanting to make a HEAD
, OPTIONS
, PATCH
or DELETE
request,you had to either use the HttpClient.request
or the HttpClient.call
.
As for 0.9.5, in addition to HttpClient.get
and HttpClient.post
there are now four more convenience methodsHttpClient.head
, HttpClient.options
, HttpClient.patch
and HttpClient.delete
HTTP verbs.
Split Infrastructure phase into Monitoring and Features phases
In most of the cases, you should use the Features
phase instead of the Infrastructure
one:
intercept(ApplicationCallPipeline.Infrastructure) {
// ...
}
would become:
intercept(ApplicationCallPipeline.Features) {
// ...
}
CallId and MDC support in CallLogging
The CallLogging feature have been updated to allow to specify MDC (Mapped Diagnostic Context) keys + providersto be associated to a specific call/request regardless of the ThreadScheduler.The feature is implemented using kotlinx.coroutines ThreadContextElement,so it is transparent and works well with slf4j.
0.9.5 includes a new CallId
feature that allows to identify calls from an ID. It allows to provide several methodsfor receiving or generating that Call Identifier, and also optionally allows to include the id as part of the response,for example as a header. The CallId is also associated to the MDC of the call, so the logs for a specific call can beidentified and grouped together.
0.9.4
Ktor 0.9.4 fixes some bugs, bumps some versions, moves a few classes, improves the overall performance of the server.This version deprecate some APIs, introduce new ones, and includes a new multiplatform HTTP client (initially supporting JVM, iOS and Android).
This version is expected to be mostly source-code compatible with 0.9.3 except for the deprecate APIs.
https://github.com/ktorio/ktor/compare/0.9.3…0.9.4
Published 29 Aug 2018
Version Bumps:
Kotlin: 1.2.50 -> 1.2.61
kotlin-native -> 0.8.2
jetty_alpn_boot_version: 8.1.11.v20170118 -> 8.1.12.v20180117
coroutines_version: 0.23.3 -> 0.25.0
atomic_fu_version: -> 0.11.3
kotlinx_io_version: -> 0.1.0-alpha-4
Deprecations:
- Deprecate
response.contentType
andresponse.contentLength
extensions (UnsafeHeaderException: Header Content is controlled by the engine and cannot be set explicitly
) - Strengthen
IncomingContent
deprecation, prepare for complete removal - Remove obsolete H2 protocol type
- Rename
XForwardedHeadersSupport
toXForwardedHeaderSupport
(#547)
Minor potentially breaking changes:
- URL building: Set the default port too when changing the protocol
- Prohibit appending unsafe headers to request headers
- Client: the
io.ktor:ktor-client-json
artifact has been renamed toio.ktor:io.ktor:ktor-client-gson
(to support a new JacksonSerializer) - Now all the Client JSON-related (
ktor-client-json
,ktor-client-gson
andktor-client-jackson
) artifacts require thekotlinx.serialization
and thus require themaven { url "https://kotlin.bintray.com/kotlinx" }
repo to be included - Changed
Date
toGMTDate
in some specific internal places - Internal Client
HttpRequest
,HttpResponse
andHttpRequestData
changes - Package
io.ktor.content
moved toio.ktor.http.content
- Top-level
encodeURLQueryComponent
method is now a extension method of Stringfun String.encodeURLQueryComponent()
PartData.FileItem
now requires a lambda with anInput
, instead of anInputStream
- Now
PartData
has a new elementPartData.BinaryItem
, thus might require an additional branch or an else to be exhaustive when used in a expression
Fixes:
- Netty: fix write pipeline to not drop connection too early. Large responses are not completely sent with ‘Connection: close’ (#534)
- Fixes
CharBufferBuilder
issue: CIO Responses with more than 2048 characters in header result inIndexOutOfBoundsException
(#419) - Fix push promise headers order with Netty and HTTP/2
- Eliminate sending transfer-encoding sending with Netty and HTTP/2
- Fixed encoding issue with binary data in
TestApplicationRequest.setBody
- Fix native Deflater leak (#489)
- Fix resourceResource to check for regular file to prevent failing later with folders (#490)
- Fix
StringIndexOutOfBoundsException
in static resource resolution (#493) - Fixes: When config is passed via
-config=<filename>
, environment variables are not resolved (#374) - Fixes Client connection close in pipelining
- TLS: Fix exception on expected channel close
- Fix Jetty client engine response cancel
- Compression: fix messages with predefined identity encoding
- Fix HTTP 417 status message
- Fix JWT error handling for missing keyId or broken token
- CIO: fix duplicate content-length header handling
- Fix CIO pipeline to not interrupt write pipeline. This was causing pipeline to be cancelled and 400 Bad Request response was lost
- Fix closed byte channel error handling for WriteChannelContent
- Fix CIO client joining
- Fix race responding bytes that caused an empty response with Netty relates to issue #350
- Avoid closing ServletOutputStream even in case of error
- Suppress already completed
AsyncContext
error - Handle response cancel in Jetty client engine
- Make
SessionTransportTransformerEncrypt
return null on failure - Fix client attributes evaluation
Optimizations:
- Use garbage-free headers API in Netty
- Avoid unnecessary allocations in Pipeline#merge
- Improve best function selection in ApplicationEngineEnvironmentReloading
- Do not scan classpath on every
HttpClient
instantiation, provide better error message
Improvements to existing APIs:
- JWK: add verify configuration with optional issuer
- Url and URLBuilder improvements
- Make TypeInfo a data class (#459) (#471)
Testing: Add advanced test exception logging
Add client form data and multipart support (#500)
Add
HttpStatusCode
constants for the status codes defined in RFC 2518 (WebDAV)Add jetty server engine failed callback handler(http2)
- Wrap Jetty channel fail into
ChannelIOException
Wrap client exception from response pipeline with request and typeInfo
Add utility to append header value (such as content type)
Improve netty response pipeline for HTTP/2 case
- Set default random algorithm from system provided
New features:
- New multiplatform HTTP Client:
- Add initial webjars feature (#498)
- Add
EngineAPI
marker annotation - Add
JacksonSerializer
to HTTP Client - Client: Add
HttpResponse.receive
method - Client: Add default request configurator
- Client: New way to configure or reconfigure the HttpClient Engine
Internal changes:
- Internal: Update modules layout
New multiplatform HTTP Client
Starting with Ktor 0.9.4, there is a MPP HTTP Client included with Ktor.
In 0.9.4, the client is implemented for the JVM, Android and iOS.
We provide a sample of this feature as part of the ktor-samples repo:ktor-samples/client-mpp
You can read more about this feature in the Multiplatform HTTP Client page.
Reconfiguring the HttpClientEngineConfig
Prior to 0.9.4, you had to configure the HttpClient Engine by:
HttpClient(MyEngine.config {
// ... config ...
}) {
install {
}
}
Since 0.9.4, HttpClientConfig
provides an engine
method to reconfigure or configure the HttpClientEngineConfig
:
HttpClient(MyEngine) {
engine {
// ... config ...
}
install {
}
}
UnsafeHeaderException
Since 0.9.4, and after a period of deprecation, Ktor started to completely forbid to set contentType
and contentLength
headers directly.This is because those are bound to the OutgoingContent
instances, that is the object describing the body of the response.
The respondText
, respondBytes
and other methods, allow you to set the Content-Type as an optional argument.And when using any subtype of OutgoingContent
, you can set the contentType
there.
For more information about this topic, check the Generating HTTP Responses page.
GMTDate
In some places (like Client HttpResponse
) we were using Java’s Date
class. Now we are using GMTDate
instead.
Client HttpRequest, HttpResponse and HttpRequestData changes
Previously the HttpRequestData
, had an attributes method to build an Attributes
instance from another.Now it is a property instead. Attributes().apply { data.attributes(this) }
would become data.attributes
.
This change, affects, for example when implementing a HttpRequest
:
override val attributes: Attributes = Attributes().apply { data.attributes(this) }
// -->
//override val attributes: Attributes = data.attributes
And the HttpResponse
changed its requestTime
and responseTime
from java’s Date
to io.ktor.util.date.GMTDate
.
0.9.3
Ktor 0.9.3 fixes some bugs, bumps some versions, improves the overall performance of the server,and introduces new APIs and changes for some of them.
This version is expected to be mostly source-code compatible with 0.9.2except for advanced use-cases related with kotlinx.coroutines
and Ktor Raw sockets.
- You can check the breaking changes from
kotlinx.coroutines
. - You can check the breaking changes from
ktor raw sockets
.
https://github.com/ktorio/ktor/compare/0.9.2…0.9.3
Published 26 Jun 2018
- Improved WebSocket API
- Websocket header Sec-WebSocket-Key is now optional
- Fixed client cookies rendering to avoid x-enc
- Fixed plain text client reader (#392)
- Added EC support in CIO TLS (#394: ECDHE_RSA_AES256_SHA384, ECDHE_RSA_AES128_SHA256)
- Fix client certificate validation
- Introduced optional authentication
- Added ApplicationCall as receiver for auth validate functions
- Introduced call.respondBytes (#395)
- Improved JWT support: multiple schemes, nullable issuer
- Conversion service enum type diagnostics improved (#403)
- Avoided using apos entity in HTML escaping as IE doesn’t support it (#400)
- Converter support for java big numbers
- Ability to add auth methods to existing feature on the fly
- Improved auth header scheme and contents validation (#415)
- Default charset for BasicAuth is now UTF-8 (#420)
- Added ByteArrayContent.contentLength (#421)
- Fixed headersOf case insensitive issue (#426)
- Client deserialization improved by using type token
- Ability to disable client default transformers
- Explicit Accept header in client request
- Turn on masking in client websockets (#423)
- Fixed inverted PartialContent.Configuration.maxRangeCount check (#440)
- Fixed uncaught UnsupportedMediaTypeException from receiveOrNull() (#442)
- Fix multipart boundary header parsing
- Upgraded jwks/jwt, applied RSA256 by default if unspecified (#434, #435)
- Upgrade kotlinx.coroutines to 0.23.3
- Upgrade Jetty version to 9.4.11.v20180605
- Add client-mock-engine for testing purpose
- HttpClient allows to use default available engine if not provided one
- Upgrade kotlin to 1.2.50
- Move ktor-samples to a separate repository (#340). https://github.com/ktorio/ktor-samples
- Added client redirect feature *
Client
WebSocket improvements
Now webSocketSession
and webSocketRawSession
return DefaultClientWebSocketSession
and webSocket
, ws
and wss
methods also receives a DefaultClientWebSocketSession
and other methodsreturn a ClientWebSocketSession
.
This prevents having to cast to access some properties from the client session:
var DefaultWebSocketSession.pingInterval: Duration?
var DefaultWebSocketSession.timeout: Duration
val DefaultWebSocketSession.closeReason: Deferred<CloseReason?>
var DefaultClientWebSocketSession.masking: Boolean
HttpClient MockEngine
We had a MockEngine
available internally for our tests for creating an HttpClient that was able to respondfrom our code programmatically without actually performing any request.
We have now exposed it in the io.ktor:ktor-client-mock
artifact.
For example:
val mockEngine = MockEngine { call -> // suspend HttpRequest.(call: HttpClientCall) -> MockHttpResponse
assertEquals("*/*", headers[HttpHeaders.Accept])
MockHttpResponse(call, HttpStatusCode.OK, writer(ioCoroutineDispatcher) { channel.writeStringUtf8("HELLO") }.channel, headersOf(
"X-Custom-Header" to listOf("value")
))
}
val client = HttpClient(mockEngine)
Inside the MockEngine block, you can assert things from the request,or decide how to generate a response based on the request.
HttpClient default Engine
Now you can instantiate a HttpClient by just HttpClient()
without providing an engine.In that case it will use a ServiceLoader
to find a suitable implementation based on the artifacts you have included.
HttpClient HttpRedirect feature
Now you can use the new client HttpRedirect feature to follow HTTP Location
-based redirections.Read the documentation for more information.
HttpClient bug fixes
Now the HttpClient sends cookies in a standard way with one single header separating cookies by ;
.
Reading an empty body as String with an Httpclient (HttpClient.get<String>
) was causing aNo transformation found: class io.ktor.client.engine.apache.ApacheHttpResponse -> class kotlin.String
exception.
HttpClientEngine changes
HttpClientEngine now has a config
field. So you will have to provide it in the case you have a custom engine.
HttpClient changes
Now the HttpClient sends an Accept
header. If you have a test checking all the headers, you will need to update them.
Sockets
TLS improvements
Ktor implements secure sockets using CIO, and the TLS availablebefore 0.9.3 missed some cypher suites and encryption methods. We have updated it to support more required stuff.
Some errors you could encounter that now might be fixed:
Exception in thread "io-thread-1" io.ktor.network.tls.TLSException: Received alert during handshake. Level: FATAL, code: HandshakeFailure
Exception in thread "io-thread-2" io.ktor.network.tls.TLSException: Unsupported TLS handshake type CertificateRequest
aSocket breaking change
aSocket
now requires a SelectorManager to be provided.
For example:
aSocket(ActorSelectorManager(ioCoroutineDispatcher))
Of course, you can reuse the SelectorManager:
val mySocketSelector = ActorSelectorManager(ioCoroutineDispatcher)
val socket = aSocket(mySocketSelector).tcp()
Server
WebSocket improvements
Before 0.9.3, when a WS request was made without the Sec-WebSocket-Key
header,an IllegalArgumentException
was thrown. Now it is optional.
Optional Authentication
Now it is possible to define a set of routes where you can provide authentication, but it is optional:
authenticate("method", optional = true) {
// routes
}
The authenticate behaviour:
- No authentication provided:
optional=false
: challenge is performedoptional=true
: route handler is executed with principal=null
- Wrong credentials: Unauthorized
- Valid credentials: route handler is executed with the principal generated from the authentication method
Missing call.respondBytes
Before 0.9.3 we had call.respondText
but missed call.respondBytes
. We have solved this.
Version bumps
Ktor now uses Kotlin 1.2.50
and kotlinx.coroutines 0.23.3
.
kotlinx.coroutines has some breaking changes for advanced use-cases.
generateCertificate
We have moved the generateCertificate
function for generating self-signed certificates to the ktor-network-tls
artifact:compile("io.ktor:ktor-network-tls:$ktor_version")
New ktor-samples repository
Before 0.9.3, we had several sample projects integrated directly in the ktor repository.They have grown, and we have moved them to their own repository: https://github.com/ktorio/ktor-samples
0.9.2
Ktor 0.9.2 fixes some bugs, improves the overall performance of the server, partially starts supporting JVM 9,and introduces new APIs and changes for some of them.
In this section, we will discuss how to convert existing code from 0.9.1 to 0.9.2.
- New auth DSL, more suspendable functions (such as verify/validate)
- RoutingResolveTrace for introspecting routing resolution process
- HTTP client improvements and bugfixes (DSL, reconnect, redirect, cookies, websockets and more)
- CIO http client pipelining support, chunked and more
- CIO initial TLS support
- Session authentication provider
- OAuth2: introduced the ability to generate and verify state field
- OAuth: fix scopes parameter to conform to RFC (#329)
- OAuth2: fix bug with double scopes encoding (#370)
- OAuth2: add the ability to intercept redirect URL
- CORS: introduced the allowSameOrigin option
- Auth: provide application call as receiver for validating functions (#375 and related)
- Test host reworked, handleRequest reads the body and redirects the exceptions correctly
- Servlets: fixed inputStream acquisition, fixed error handling
- Java 9 compatibility improved (no modules yet)
- Digest auth fixes (#380)
- Log running connectors details for better development experience (#318)
- Last-Modified header and related functionality to work in proper GMT time zone (#344)
- IncomingContent is deprecated
- URLBuilder fixes and improvements
- Documentation improvements
- Performance optimizations (Netty, CIO server backends)
- CIO server improved stability
- Encrypted session support (SessionTransportTransformerEncrypt)
- Empty (null) model for freemarker (#291)
- ContentNegotiation missing Accept header support (#317)
Authentication
The biggest change in this version since 0.9.1, is authentication. Which has been redesigned:
In previous versions, you had to define an authentication
block inside your Application or in a Route block,applying that authentication to all the subroutes matching that block.
That forced you to redefine several authentication providers, or in some cases that would force you to includeauthentication in unexpected routes.
authentication {
basicAuthentication("ktor") { credentials ->
if (credentials.password == "${credentials.name}123") UserIdPrincipal(credentials.name) else null
}
}
In 0.9.2, all the authentication mechanisms are defined at the Application level and have an optional nameassociated with them.Also, the method names for defining different mechanisms have changed. Now the new name of the authentication mechanismis part of the function call, and all its old parameters are defined using a DSL instead.
For example, to define a basic authentication myauth1
, you should add this code to your application configuration:
install(Authentication) {
basic(name = "myauth1") {
realm = "Ktor Server"
validate { credentials ->
if (credentials.password == "${credentials.name}123") UserIdPrincipal(credentials.name) else null
}
}
}
And now you can create a Route node to apply the defined authentication to several routes using the authenticate
method:
routing {
authenticate("myauth1") {
get("/authenticated/route1") {
// ...
}
get("/other/route2") {
// ...
}
}
get("/") {
// ...
}
}
Authentication method name changes:
basicAuthentication
→basic
formAuthentication
→form
digestAuthentication
→digest
jwtAuthentication
→jwt
oauthAuthentication
→oauth
You can read the new authentication page to see in detail how to use the new methods.
Test host reworked, handleRequest reads the body and redirects the exceptions correctly
The body
property from TestApplicationRequest
builder has been changed to a suspend setBody
method:
handleRequest(HttpMethod.Post, "/") {
addHeader("Accept", "text/plain")
addHeader("Content-Type", "application/json")
//body = """{"id":1,"title":"Hello, World!"}"""
setBody("""{"id":1,"title":"Hello, World!"}""")
}.response.let { response ->
// ...
}
Before 0.9.2, you had to call the method awaitCompletion
in the response in the case the requestwas not generating the response body synchronously. In 0.9.2, the awaitCompletion
method doesn’t exist,and it awaits completion automatically before returning the response.
IncomingContent deprecation
If you are using call.request.receiveContent().readChannel()
, call.request.receiveContent().multiPartData()
or call.request.receiveContent().inputStream()
, you should consider changing it tocall.receive<ByteReadChannel>()
, call.receive<MultiPartData>()
and/or call.receive<InputStream>()
since it is deprecated and will be removed in future versions of Ktor.
Also, remember that InputStream
is a synchronous API, so you should avoid it if possible.
WebSockets
In order to support WebSockets at the client side, we have changed some of the transitive dependenciesand moved some classes: now there is a transitive dependency called ktor-http-cio
that includes commonWebSockets code among other things, which the ktor-websockets
server feature depends on.But since it is a transitive dependency, that should be transparent to you.
Classes like WebSocketSession
and Frame
have been moved from the io.ktor.websocket
package to theio.ktor.http.cio.websocket
package.
import io.ktor.websocket.*
→
import io.ktor.http.cio.websocket.*
HttpClient
When building a new CIO HttpClient, while configuring the endpoint(it has been renamed from endpointConfig
to endpoint
, and now the property is immutable,so you have to mutate its contents):
Prior to 0.9.2:
val client = HttpClient(CIO.config {
endpointConfig = EndpointConfig().apply {
}
})
After 0.9.2:
val client = HttpClient(CIO.config {
endpoint.apply {
// ...
}
})