SkillAgentSearch skills...

Kwik

A QUIC client, client library and server implementation in Java. Supports HTTP3 with "Flupke" add-on.

Install / Use

/learn @ptrd/Kwik
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Kwik

A QUIC implementation in Java

Kwik is an implementation of the QUIC protocol in (100%) Java. Kwik started as client (library) only, but since May 2021 it supports both client and server.

If you are upgrading from a version prior to 0.10, read the CHANGELOG for upgrade instructions.

QUIC is a brand-new transport protocol developed by the IETF, and is the transport layer for the (also new) HTTP3 protocol. Although necessary for HTTP3, QUIC is more than just the transport protocol for HTTP3: most people consider QUIC as the "next generation TCP". It has similar properties as TCP, e.g. provide a reliable ordered stream, but is better in many ways:

  • it can serve multiple streams (concurrently and sequential) over the same QUIC connection
  • it does not suffer from the "head of line blocking" problem
  • it's encrypted and secured by TLS (not as a separate layer, but embedded in the protocol)
  • it requires at most only one network roundtrip to setup the connection (the combination of TCP and TLS needs much more)

If you want to know more about QUIC and are able to understand the dutch language, check out my presentation on Luminis DevCon 2019.

If you're looking for a Java HTTP3 client or server, check out Flupke, which is built on top of Kwik.

Kwik is created and maintained by Peter Doornbosch. The latest greatest can always be found on BitBucket or GitHub.

Status

Kwik implements all QUIC features, except that the server does not yet support connection migration (work in progress). With respect to the interface Kwik offers to applications, it provides all necessary operations to exchange data, but it does not support specifying stream priorities. For both roles, interoperability is tested with a large number of other implementations, see automated interoperability tests. Due to the fact that most implementations are still in active development, and that some test cases (specifically testing behaviour in the context of packet loss and packet corruption) are non-deterministic, the results of the automatic interoperability test vary with each run, but usually, Kwik is amongst the best w.r.t. the number of successful testcases.

Kwik is still in active development, see git history.

HTTP3 on top of Kwik is supported by Flupke, the pure Java HTTP3 implementation.

Kwik supports QUIC v1 (RFC 9000) and QUIC v2 (RFC 9369).

Implemented QUIC features

  • (QUIC v1) version negotiation
  • handshake based on TLS 1.3
  • data exchange over bidirectional and unidirectional streams
  • stateless retry
  • cipher suites TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384 and TLS_CHACHA20_POLY1305_SHA256
  • key update
  • session resumption
  • 0-RTT
  • Compatible Version Negotiation RFC 9368
  • QUIC V2 RFC 9369
  • Unreliable Datagram Extension RFC 9221

Client only:

  • connection migration (use the interactive mode of the sample client to try it)

Is Kwik ready for production use?

It really depends on your use-case. First of all, as with all open source software, there is no guarantee the software will work, it is provided "as is". Having said that, interoperability with other implementations is heavily tested and ok, so you can assume it works. However, Kwik is not tested in various or extreme networking conditions, so your mileage may vary.
As development focus has been on correctness and features (in that order), performance is not optimal yet.

Kwik does not yet implement all QUIC requirements. Specifically, it does not enable applications or application protocols to specify the relative priority of streams. Note that this will not introduce interoperability issues, because the concept of priorities only exists in a peer; it does not affect the wire protocol. However, the division of network capacity over streams cannot be influenced and might not even be fair (although in practice it probably will). When wondering whether limitations would harm your use case: just go ahead and test it! When in doubt, you can always contact the author (see contact details below) for more information or help.

Is Kwik secure?

The TLS library used by Kwik is also "home made". Although all security features are implemented (e.g. certificates are checked as well as the Certificate Verify message that proofs possession of the certificate private key), and only crypto algorithms provided by the JDK are used, it is not security tested nor reviewed by security experts. So if you plan to transfer sensitive data or are afraid of intelligence services trying to spy on you, using Kwik is probably not the best idea.

Usage

Maven

Maven Central

Kwik is available in the Maven Central Repository. To use it in your project, add the following dependency to your pom.xml:

<dependency>
    <groupId>tech.kwik</groupId>
    <artifactId>kwik</artifactId>
    <version>${kwik.version}</version>
</dependency>

Check Maven Central to find the version number of the latest greatest.

Java Module System

The following Kwik artifacts define a Java module with the given name:

  • kwik: tech.kwik.core
  • kwik-h09: tech.kwik.h09
  • kwik-qlog: tech.kwik.qlog
  • kwik-samples: tech.kwik.samples

Client

To connect to a QUIC server, first create a connection object with the builder, e.g.

String applicationProtocolId = "....";
QuicClientConnection connection = QuicClientConnection.newBuilder()
        .uri(URI.create("https://sample.com:443"))
        .applicationProtocol(applicationProtocolId)
        .build();

You need to provide the ALPN protocol ID of the application protocol that you want to run on top of QUIC (and that the server you connect to supports). On the connection object simply call connect():

connection.connect();

Once connected, you can create a stream and start sending/receiving data, e.g.

QuicStream quicStream = connection.createStream(true);
OutputStream output = quicStream.getOutputStream();
output.write(...)
output.close();
InputStream input = quicStream.getInputStream();
input.read(...)

As QUIC servers generally limit the number of streams that clients can open concurrently, it is wise to close streams when not used anymore. Kwik does this automatically when you close() the OutputStream and read all data from the InputStream. If, for some reason, you do not read all data from the InputStream, call QuicStream.abortReading() to free resources and let the server you know you abandoned the stream.

When, for example with local development, the server uses self-signed certificates, you need to disable certificate checking. The builder has a method for this:

builder.noServerCertificateCheck()

The builder has a lot more methods for configuring the connection, most of which are self-explanatory; see the Builder interface in QuicClientConnection.

The builder method logger() requires an implementation of the Logger interface; Kwik provides two convenient implementations that you can use: SysOutLogger and FileLogger. Various log categories can be enabled or disabled by the logXXX() methods, e.g. logger.logInfo(true).

Take a look at the samples in the sample package for more inspiration.

Server

Creating a QUIC server with Kwik consist of a few steps. First you need to create an application protocol handler by implementing the ApplicationProtocolConnectionFactory interface. Its createConnection method should return an implementation of ApplicationProtocolConnection that, as the name suggests, represents your application protocol connection. It's acceptPeerInitiatedStream method is the handler that is called by Kwik when a client initiates a stream for the given protocol. The implementation of this acceptPeerInitiatedStream method should start a stream handler, but should itself return immediately, as it is called on the thread that handles incoming QUIC messages. If, for example, your application protocol follows the request-response model, the stream handler reads the request from the QUIC stream, processes it, creates a response, writes the response to the QUIC stream and closes the stream.

To complete the ApplicationProtocolConnectionFactory you should at least override the following two methods of the ApplicationProtocolSettings interface:

int maxConcurrentPeerInitiatedUnidirectionalStreams()
int maxConcurrentPeerInitiatedBidirectionalStreams()

These methods communicate to Kwik how many (concurren

View on GitHub
GitHub Stars480
CategoryCustomer
Updated1d ago
Forks63

Languages

Java

Security Score

100/100

Audited on Mar 30, 2026

No findings