Liking cljdoc? Tell your friends :D

Zeph Server Design

Overview

Zephはクロスプラットフォームな高性能HTTPサーバーで、Java NIOをI/Oバックエンドとして使用します。 HTTP/1.1とHTTP/2の両方に対応し、TLS/SSLもサポートしています。

Note: io_uringバックエンドはio_uringブランチで利用可能です。

Protocol Implementation Matrix

ProtocolNIO
HTTP/1.1OK
HTTP/1.1 + TLSOK
HTTP/2 (h2c)OK
HTTP/2 (h2 over TLS)OK

Implementation Classes

ProtocolClass
HTTP/1.1HttpServerNio
HTTP/1.1 + TLSHttpsServerNio
HTTP/2 (h2c)HttpServerNio
HTTP/2 (h2 over TLS)HttpsServerNio

System Architecture

High-Level Overview

+------------------------------------------------------------------------------+
|                              Clojure Application                             |
|                                                                              |
|   (run-server handler {:port 8080 :ssl? true})                              |
+------------------------------------------------------------------------------+
                                       |
                                       v
+------------------------------------------------------------------------------+
|                              server.clj                                      |
|  +-------------------------------------------------------------------------+ |
|  |  run-server: SSL設定、サーバー起動                                       | |
|  +-------------------------------------------------------------------------+ |
+------------------------------------------------------------------------------+
                                       |
                                       v
+------------------------------------------------------------------------------+
|                           NIO Backend                                        |
|                    (Windows/macOS/Linux)                                     |
+------------------------------------------------------------------------------+
|  +---------------+  +-------------------+                                    |
|  |HttpServerNio  |  |  HttpsServerNio   |                                    |
|  +---------------+  +-------------------+                                    |
+------------------------------------------------------------------------------+

Layer Architecture

Zephは3層のレイヤーアーキテクチャを採用しています:

+------------------------------------------------------------------------------+
|                                                                              |
|  +========================================================================+  |
|  ||                      Protocol Layer (プロトコル層)                    ||  |
|  ||                                                                      ||  |
|  ||   HTTP/1.1解析、HTTP/2フレーム処理、ストリーミング、チャンク転送      ||  |
|  ||                                                                      ||  |
|  ||  +-------------------------+    +-------------------------------+    ||  |
|  ||  |      Http1Handler       |    |      Http2ServerHandler       |    ||  |
|  ||  |  +------------------+   |    |  +-------------------------+  |    ||  |
|  ||  |  |   HttpParser     |   |    |  |    Http2Connection      |  |    ||  |
|  ||  |  +------------------+   |    |  +-------------------------+  |    ||  |
|  ||  |  - Request parsing      |    |  |    HpackEncoder/Decoder |  |    ||  |
|  ||  |  - Response building    |    |  +-------------------------+  |    ||  |
|  ||  |  - Keep-alive mgmt      |    |  |    Stream management    |  |    ||  |
|  ||  |  - Chunked encoding     |    |  |    Flow control         |  |    ||  |
|  ||  +-------------------------+    +-------------------------------+    ||  |
|  ||                                                                      ||  |
|  +|======================================================================|+  |
|  ||                      Transport Layer (トランスポート層)               ||  |
|  ||                                                                      ||  |
|  ||   TLS暗号化/復号化、ALPN交渉、SSL ハンドシェイク                      ||  |
|  ||                                                                      ||  |
|  ||  +------------------------------------------------------------------+||  |
|  ||  |                        SslHandler                                |||  |
|  ||  |  +-------------+  +-------------+  +---------------------+       |||  |
|  ||  |  |  SSLEngine  |  | Handshake   |  |  ALPN Negotiation   |       |||  |
|  ||  |  +-------------+  +-------------+  +---------------------+       |||  |
|  ||  +------------------------------------------------------------------+||  |
|  ||                                                                      ||  |
|  +|======================================================================|+  |
|  ||                      I/O Backend Layer (I/Oバックエンド層)           ||  |
|  ||                                                                      ||  |
|  ||   接続管理、非同期I/O、イベントループ、マルチワーカー                 ||  |
|  ||                                                                      ||  |
|  ||  +------------------------------------------------------------------+||  |
|  ||  |                        NIO Backend                               |||  |
|  ||  |  +----------------------------+                                  |||  |
|  ||  |  |   Selector                 |                                  |||  |
|  ||  |  |   SelectionKey             |                                  |||  |
|  ||  |  +----------------------------+                                  |||  |
|  ||  |  - Multi-selector workers                                        |||  |
|  ||  |  - SocketChannel                                                 |||  |
|  ||  |  - Platform portable                                             |||  |
|  ||  +------------------------------------------------------------------+||  |
|  ||                                                                      ||  |
|  +========================================================================+  |
|                                                                              |
+------------------------------------------------------------------------------+

Class Diagram

Protocol Layer

                              +-----------------------------+
                              |    <<interface>>            |
                              |    ProtocolHandler          |
                              +-----------------------------+
                              | + processData(byte[]): byte[]|
                              | + hasPendingStreaming(): bool|
                              | + continueStreaming(): byte[]|
                              | + isKeepAlive(): boolean    |
                              | + isOpen(): boolean         |
                              | + close(): void             |
                              +-----------------------------+
                                           ^
                                           |
                    +----------------------+----------------------+
                    |                                             |
        +-----------+-----------+                   +-------------+-------------+
        |     Http1Handler      |                   |    Http2ServerHandler     |
        +-----------------------+                   +---------------------------+
        | - parser: HttpParser  |                   | - conn: Http2Connection   |
        | - handler: Function   |                   | - handler: Function       |
        | - serverPort: int     |                   | - serverPort: int         |
        | - keepAlive: boolean  |                   | - streams: Map            |
        +-----------------------+                   +---------------------------+
        | + parse(): ParseResult|                   | + processData(): byte[]   |
        | + getRequest(): Req   |                   | + handleFrame(): void     |
        | + handleRequest(): Res|                   | + sendResponse(): void    |
        | + reset(): void       |                   | + handleGoAway(): void    |
        +-----------------------+                   +---------------------------+

Server Classes

                              +-----------------------------+
                              |    <<interface>>            |
                              |      HttpServer             |
                              +-----------------------------+
                              | + run(): void               |
                              | + stop(): void              |
                              | + isRunning(): boolean      |
                              | + getPort(): int            |
                              | + close(): void             |
                              +-----------------------------+
                                           ^
                                           |
          +--------------------------------+--------------------------------+
          |                                                                |
+---------+---------+                                            +---------+---------+
|   HttpServerNio   |                                            |  HttpsServerNio   |
+-------------------+                                            +-------------------+
| - workers[]       |                                            | - sslConfig       |
| - selector        |                                            | - sslHandler      |
| - connections     |                                            +-------------------+
+-------------------+                                            | Inner classes:    |
| Inner classes:    |                                            | - NioConnection   |
| - NioWorker       |                                            |   (Http1Handler   |
| - NioConnection   |                                            |    + SslHandler)  |
|   (Http1Handler)  |                                            +-------------------+
+-------------------+

Data Flow

HTTP/1.1 Request Flow (NIO)

                                    +-----------------------------+
                                    |         Client              |
                                    +-------------+---------------+
                                                  |
                                                  | TCP Connection
                                                  v
+------------------------------------------------------------------------------+
|                             HttpServerNio                                    |
|                                                                              |
|  +------------------------------------------------------------------------+  |
|  |                          NioWorker                                     |  |
|  |                                                                        |  |
|  |   +------------+     +--------------------------------------------+    |  |
|  |   | Selector   |---->|            Selection Events                |    |  |
|  |   |            |     |  (ACCEPT, READ, WRITE)                     |    |  |
|  |   +------------+     +--------------------------------------------+    |  |
|  |        |                              |                                |  |
|  |        | select                       | process events                 |  |
|  |        v                              v                                |  |
|  |   +------------------------------------------------------------------+ |  |
|  |   |                    handleRead()                                  | |  |
|  |   |                         |                                        | |  |
|  |   |   +---------------------+---------------------+                  | |  |
|  |   |   |         ProtocolDetector                  |                  | |  |
|  |   |   |    isHttp2Preface() ? -> HTTP/2 path      |                  | |  |
|  |   |   +---------------------+---------------------+                  | |  |
|  |   |                         |                                        | |  |
|  |   |                         v (HTTP/1.1 path)                        | |  |
|  |   |   +-------------------------------------------+                  | |  |
|  |   |   |            NioConnection                  |                  | |  |
|  |   |   |   +-------------------------------------+ |                  | |  |
|  |   |   |   |         Http1Handler                | |                  | |  |
|  |   |   |   |                                     | |                  | |  |
|  |   |   |   |   parse() --> ParseResult           | |                  | |  |
|  |   |   |   |       |                             | |                  | |  |
|  |   |   |   |       +-- NEED_MORE_DATA            | |                  | |  |
|  |   |   |   |       +-- HEADERS_COMPLETE          | |                  | |  |
|  |   |   |   |       +-- REQUEST_COMPLETE ---------|--|--> handler()    | |  |
|  |   |   |   |       +-- ERROR                     | |      |           | |  |
|  |   |   |   |                                     | |      |           | |  |
|  |   |   |   |   handleRequest() <-----------------|--|-----+           | |  |
|  |   |   |   |       |                             | |                  | |  |
|  |   |   |   |       v                             | |                  | |  |
|  |   |   |   |   HttpResponse                      | |                  | |  |
|  |   |   |   +-------------------------------------+ |                  | |  |
|  |   |   +-------------------------------------------+                  | |  |
|  |   +------------------------------------------------------------------+ |  |
|  |                         |                                              |  |
|  |                         v                                              |  |
|  |   +------------------------------------------------------------------+ |  |
|  |   |                    write()                                       | |  |
|  |   |         response.encode() -> SocketChannel.write()               | |  |
|  |   +------------------------------------------------------------------+ |  |
|  +------------------------------------------------------------------------+  |
+------------------------------------------------------------------------------+

HTTPS + HTTP/2 Request Flow

                                    +-----------------------------+
                                    |         Client              |
                                    |    (ALPN: h2)               |
                                    +-------------+---------------+
                                                  |
                                                  | TLS Connection
                                                  v
+------------------------------------------------------------------------------+
|                          HttpsServerNio                                      |
|                                                                              |
|   +----------------------------------------------------------------------+   |
|   |                         NioConnection                                |   |
|   |                                                                      |   |
|   |   +------------------------------------------------------------------+   |
|   |   |                      SslHandler                                |   |
|   |   |                                                                |   |
|   |   |   1. TLS Handshake                                             |   |
|   |   |      +-- processHandshake() --> ClientHello                    |   |
|   |   |                              <-- ServerHello + Certificate     |   |
|   |   |                              --> ClientKeyExchange             |   |
|   |   |                              <-- Finished                      |   |
|   |   |                                                                |   |
|   |   |   2. ALPN Negotiation                                          |   |
|   |   |      +-- getApplicationProtocol() --> "h2"                     |   |
|   |   |                                                                |   |
|   |   |   3. Decrypt Application Data                                  |   |
|   |   |      +-- decrypt(encrypted) --> plaintext                      |   |
|   |   |                                                                |   |
|   |   +------------------------------------------------------------------+   |
|   |                              |                                       |   |
|   |                              | isHttp2 = true (ALPN)                 |   |
|   |                              v                                       |   |
|   |   +------------------------------------------------------------------+   |
|   |   |                  Http2ServerHandler                            |   |
|   |   |                                                                |   |
|   |   |   +----------------------------------------------------------+ |   |
|   |   |   |               Http2Connection                            | |   |
|   |   |   |                                                          | |   |
|   |   |   |   Connection Preface (server):                           | |   |
|   |   |   |     SETTINGS frame                                       | |   |
|   |   |   |                                                          | |   |
|   |   |   |   Frame Processing:                                      | |   |
|   |   |   |     HEADERS (stream 1) --> HPACK decode --> HttpRequest  | |   |
|   |   |   |                                     |                    | |   |
|   |   |   |                                     v                    | |   |
|   |   |   |                              handler.apply()             | |   |
|   |   |   |                                     |                    | |   |
|   |   |   |                                     v                    | |   |
|   |   |   |     HEADERS (stream 1) <-- HPACK encode <-- HttpResponse | |   |
|   |   |   |     DATA (stream 1)                                      | |   |
|   |   |   |                                                          | |   |
|   |   |   |   Multiplexing:                                          | |   |
|   |   |   |     Stream 1 --> request/response                        | |   |
|   |   |   |     Stream 3 --> request/response (concurrent)           | |   |
|   |   |   |     Stream 5 --> request/response (concurrent)           | |   |
|   |   |   |                                                          | |   |
|   |   |   +----------------------------------------------------------+ |   |
|   |   +------------------------------------------------------------------+   |
|   +----------------------------------------------------------------------+   |
|                              |                                               |
|                              | encrypt()                                     |
|                              v                                               |
|                        Write to socket                                       |
+------------------------------------------------------------------------------+

Connection Lifecycle

HTTP/1.1 Connection

          +-------------------------------------------------------------+
          |                                                             |
          v                                                             |
   +--------------+                                                     |
   |   ACCEPT     |                                                     |
   |  (new conn)  |                                                     |
   +------+-------+                                                     |
          |                                                             |
          v                                                             |
   +--------------+     +--------------+     +--------------+           |
   |    READ      |---->|    PARSE     |---->|   HANDLER    |           |
   |  (request)   |     | (Http1Handler)|     |  (user func) |           |
   +--------------+     +--------------+     +------+-------+           |
                                                   |                    |
                                                   v                    |
                                            +--------------+            |
                                            |    WRITE     |            |
                                            |  (response)  |            |
                                            +------+-------+            |
                                                   |                    |
                               +-------------------+-------------------+ |
                               |                                       | |
                               v                                       | |
                        +------------+       +------------+            | |
                        | keep-alive |       |   close    |            | |
                        |   = true   |       | connection |            | |
                        +-----+------+       +------------+            | |
                              |                                        | |
                              +----------------------------------------+ |
                                                                         |
                                     (next request) ---------------------+

HTTP/2 Protocol Detection

h2 (over TLS) - ALPN

TLS Handshake時にALPNでプロトコルを交渉:

Client: ALPN extension [h2, http/1.1]
Server: ALPN extension [h2]  <- h2を選択

-> SSLEngine.getApplicationProtocol() = "h2"
-> Http2ServerHandler を使用

h2c (cleartext) - Upgrade

                         HTTP/1.1 Request
+---------------------------------------------------------------------+
| GET / HTTP/1.1                                                      |
| Host: example.com                                                   |
| Connection: Upgrade, HTTP2-Settings                                 |
| Upgrade: h2c                                                        |
| HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA                           |
+---------------------------------------------------------------------+
                              |
                              v
                   +---------------------+
                   | Http1Handler.parse()|
                   |                     |
                   | isH2cUpgradeRequest?|
                   +----------+----------+
                              | yes
                              v
                   +---------------------+
                   | H2cUpgradeHelper    |
                   |                     |
                   | 101 Switching Proto |
                   | + Server SETTINGS   |
                   +----------+----------+
                              |
                              v
                   +---------------------+
                   | ProtocolDetector    |
                   |                     |
                   | 以降のデータは      |
                   | HTTP/2 preface      |
                   | で始まる            |
                   +----------+----------+
                              |
                              v
                   +---------------------+
                   | Http2ServerHandler  |
                   |                     |
                   | HTTP/2 frames       |
                   +---------------------+

SSL/TLS Configuration

;; Built-in localhost certificate (development)
{:ssl? true}

;; PEM files
{:ssl? true :cert "cert.pem" :key "key.pem"}

;; PKCS12 keystore
{:ssl? true :keystore "keystore.p12" :keystore-password "secret"}

Summary: Code Organization

src/java/zeph/
├── http/
│   ├── HttpServer.java              # Interface
│   ├── HttpServerNio.java           # NIO HTTP server
│   ├── HttpsServerNio.java          # NIO HTTPS server
│   ├── Http1Handler.java            # HTTP/1.1 protocol handler
│   ├── HttpParser.java              # HTTP/1.1 parser
│   ├── HttpRequest.java             # Request model
│   ├── HttpResponse.java            # Response model
│   ├── ProtocolDetector.java        # HTTP/2 preface detection
│   └── H2cUpgradeHelper.java        # h2c upgrade helper
├── http2/
│   ├── Http2ServerHandler.java      # HTTP/2 protocol handler
│   ├── Http2Connection.java         # HTTP/2 connection state
│   ├── Http2FrameReader.java        # Frame parsing
│   ├── Http2FrameType.java          # Frame type constants
│   └── hpack/
│       ├── HpackEncoder.java        # Header compression
│       └── HpackDecoder.java        # Header decompression
├── ssl/
│   ├── SslConfig.java               # SSL configuration
│   └── SslHandler.java              # TLS handshake/encrypt/decrypt
└── client/
    ├── HttpClientNio.java           # NIO HTTP client
    ├── HttpClientRequest.java       # Client request
    └── HttpClientResponse.java      # Client response

src/clojure/zeph/
├── server.clj                       # Server API
├── client.clj                       # Client API
└── ring.clj                         # Ring adapter

Can you improve this documentation?Edit on GitLab

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close