### Start an Aleph HTTP Server with Ring Handler Source: https://github.com/clj-commons/aleph/blob/master/README.md This example illustrates how to set up and start an HTTP server using aleph.http/start-server. It defines a basic Ring-compliant handler function and shows configurations for both HTTP/1-only and HTTP/2 with SSL, highlighting Aleph's compatibility with the Ring specification. ```Clojure (require '[aleph.http :as http]) (defn handler [req] {:status 200 :headers {"content-type" "text/plain"} :body "hello!"}) (http/start-server handler {:port 8080}) ; HTTP/1-only ;; To support HTTP/2, do the following: ;; (def my-ssl-context ...) (http/start-server handler {:port 443 :http-versions [:http2 :http1] :ssl-context my-ssl-context}) ;; See aleph.examples.http2 for more details ``` -------------------------------- ### Install Root CA and Generate Certificates with mkcert Source: https://github.com/clj-commons/aleph/blob/master/CONTRIBUTING.md Demonstrates how to use the `mkcert` tool to install a trusted root certificate authority for browsers, OS, and Java, and then generate local SSL certificates and private keys for `aleph.localhost` and `localhost` for TLS development. It also shows how to handle multiple JVMs. ```Shell # first check $JAVA_HOME is not empty, mkcert will use it to know where to install echo $JAVA_HOME # this is installs the root certificate authority (CA) for browsers/OS/Java mkcert -install # if you have multiple JVMs in use, you will need to install the CA for each one separately export JAVA_HOME=/path/to/some/other/jdk TRUST_STORES=java mkcert -install # this will generate a cert file and a key file in .pem format mkcert aleph.localhost localhost 127.0.0.1 ::1 # e.g., aleph.localhost+3.pem and aleph.localhost+3-key.pem ``` -------------------------------- ### Starting an Aleph HTTP Server Source: https://github.com/clj-commons/aleph/blob/master/docs/http.md This snippet demonstrates how to start a basic HTTP server using Aleph. It defines a Ring-compliant handler function that returns a simple 'hello!' response with a 200 status and text/plain content type. The `http/start-server` function is then used to launch the server on port 8080 with the defined handler. ```clj (require '[aleph.http :as http]) (defn handler [req] {:status 200 :headers {"content-type" "text/plain"} :body "hello!"}) (http/start-server handler {:port 8080}) ``` -------------------------------- ### Aleph TCP Server API Reference Source: https://github.com/clj-commons/aleph/blob/master/docs/tcp.md Reference for starting a TCP server using Aleph. The `aleph.tcp/start-server` function binds a handler function to a specified port, creating a listening server. The handler receives a duplex stream and client information for each connection. ```APIDOC aleph.tcp/start-server Parameters: handler (function): A function that takes a duplex stream and client info map as arguments. options: map :port (integer): The port on which the server will listen. ``` -------------------------------- ### Making HTTP Client Requests with Aleph in Clojure Source: https://github.com/clj-commons/aleph/blob/master/README.md This snippet demonstrates how to make basic HTTP GET requests using Aleph's client, which returns a Manifold deferred. It shows both dereferencing the deferred and chaining operations. It also includes an example of configuring a connection pool to support HTTP/2 for subsequent requests. ```clojure (require '[aleph.http :as http] '[manifold.deferred :as d] '[clj-commons.byte-streams :as bs]) (-> @(http/get "https://google.com/") :body bs/to-string prn) (d/chain (http/get "https://google.com") :body bs/to-string prn) ;; To support HTTP/2, do the following: (def conn-pool (http/connection-pool {:connection-options {:http-versions [:http2 :http1]}})) @(http/get "https://google.com" {:pool conn-pool}) ;; See aleph.examples.http2 for more details ``` -------------------------------- ### Create a TCP Echo Server in Clojure Source: https://github.com/clj-commons/aleph/blob/master/README.md This Clojure example illustrates how to set up a simple TCP echo server with Aleph. The handler receives a duplex stream and client information, then connects the stream to itself to echo all incoming byte-array messages back to the client. ```Clojure (require '[aleph.tcp :as tcp]) (defn echo-handler [s info] (s/connect s s)) (tcp/start-server echo-handler {:port 10001}) ``` -------------------------------- ### Making HTTP Client Requests with Aleph Source: https://github.com/clj-commons/aleph/blob/master/docs/http.md This snippet shows two ways to make HTTP GET requests using Aleph's client. The first example uses `@` to dereference the deferred response synchronously, then extracts the body and converts it to a string. The second example uses `manifold.deferred/chain` for asynchronous processing, demonstrating how to chain operations on the deferred response without blocking. ```clj (require '[manifold.deferred :as d] '[byte-streams :as bs]) (-> @(http/get "https://google.com/") :body bs/to-string prn) (d/chain (http/get "https://google.com") :body bs/to-string prn) ``` -------------------------------- ### Implementing an Aleph WebSocket Echo Server Source: https://github.com/clj-commons/aleph/blob/master/docs/http.md This snippet provides an example of a WebSocket echo handler. It takes an incoming HTTP request, establishes a WebSocket connection using `aleph.http/websocket-connection`, and then uses `manifold.stream/connect` to pipe all incoming messages from the client back to the client, effectively creating an echo service. Text messages are handled as strings, and binary messages as byte arrays. ```clj (require '[manifold.stream :as s]) (defn echo-handler [req] (let [s @(http/websocket-connection req)] (s/connect s s)))) ``` -------------------------------- ### Implement an Echo TCP Server with Aleph Source: https://github.com/clj-commons/aleph/blob/master/docs/tcp.md This snippet demonstrates how to create a simple TCP echo server using Aleph. The `echo-handler` function connects the input stream `s` back to itself, effectively echoing any received data. The server starts listening on port 10001. ```Clojure (require '[aleph.tcp :as tcp]) (defn echo-handler [s info] (s/connect s s)) (tcp/start-server echo-handler {:port 10001}) ``` -------------------------------- ### Run Aleph Unit Tests Source: https://github.com/clj-commons/aleph/blob/master/CONTRIBUTING.md Explains the command to execute the test suite for the Aleph project using Leiningen. It emphasizes that tests should pass before submitting changes to GitHub and encourages writing tests for bug fixes first. ```Shell lein test ``` -------------------------------- ### Configure DNS for Aleph Localhost Source: https://github.com/clj-commons/aleph/blob/master/CONTRIBUTING.md Provides the necessary entries to add to the `/etc/hosts` file, mapping `aleph.localhost` to both IPv4 and IPv6 loopback addresses, ensuring proper local DNS resolution for Aleph development. ```Text 127.0.0.1 aleph.localhost ::1 aleph.localhost ``` -------------------------------- ### Aleph HTTP/2 Client and Server Support Details Source: https://github.com/clj-commons/aleph/blob/master/README.md This section details Aleph's HTTP/2 support, highlighting its general drop-in nature while also listing important caveats and limitations. It covers unsupported features like multipart uploads, CONNECT method, server push, trailers, and discusses flow control and pipeline transformations. ```APIDOC 1. Multipart uploads: Not yet supported under HTTP/2 due to Netty limitations. For new development, use separate H2 streams/requests for each file. 2. CONNECT method: Not currently supported under HTTP/2. 3. HTTP/2 server push: Not supported (deprecated and effectively disabled by Chrome). 4. HTTP/2 trailers: Not currently supported (headers arriving after the body). 5. Priority information: Aleph does nothing with priority information. Future aim is to back-port HTTP/3 priority headers to HTTP/2. 6. Flow control: Currently uses Netty's default (64 kb window, bytes acknowledged on receipt). Future release plans to add support for adjusting default window size and strategy. 7. pipeline-transform: Usage needs to be checked for HTTP/2 due to Netty's multiplexed pipeline setup (shared connection-level pipeline feeds stream-specific frames to individual stream pipelines). ``` -------------------------------- ### Generate Aleph SSL Server Context in Clojure Source: https://github.com/clj-commons/aleph/blob/master/CONTRIBUTING.md Illustrates how to create an `SslContext` for an Aleph server using `aleph.netty/ssl-server-context`, referencing the generated certificate chain and private key files. This is crucial for enabling TLS/SSL in Aleph applications. ```Clojure (aleph.netty/ssl-server-context {:certificate-chain "/path/to/aleph.localhost+3.pem" :private-key "/path/to/aleph.localhost+3-key.pem" ...}) ``` -------------------------------- ### Synchronize project.clj with deps.edn Source: https://github.com/clj-commons/aleph/blob/master/CONTRIBUTING.md Details the command to run the `deps/lein-to-deps` script. This script updates the `deps.edn` file based on changes in `project.clj`, ensuring consistency for users who rely on `deps.edn` for dependency management. ```Shell deps/lein-to-deps ``` -------------------------------- ### Debug TLS Traffic with Curl and Wireshark Source: https://github.com/clj-commons/aleph/blob/master/CONTRIBUTING.md Shows how to use `curl` with the `SSLKEYLOGFILE` environment variable and specific flags (`--cacert`, `--http2-prior-knowledge`, `--tls-max`) to log TLS session keys. This log file can then be used by Wireshark to decrypt TLS traffic for in-depth debugging. ```Shell curl --cacert "$(mkcert -CAROOT)/rootCA.pem" --http2-prior-knowledge --max-time 3 --tls-max 1.2 https://aleph.localhost:11256/ ``` -------------------------------- ### Aleph HTTP Client API Differences and Features Source: https://github.com/clj-commons/aleph/blob/master/README.md This section outlines key differences and extended functionalities of the Aleph HTTP client compared to clj-http, along with other notable features and limitations. It covers proxy configuration, cookie handling, debug options, logging, and unsupported features. ```APIDOC - Proxy configuration: Must be set for the connection pool; per-request proxy setups are not allowed. - HTTP proxy functionality: Extended with tunneling settings, optional HTTP headers, and connection timeout control. - :proxy-ignore-hosts: Not supported. - Cookie support: Built-in cookie storages do not support cookie parameters obsoleted since RFC2965 (comment, comment URL, discard, version). - Debug options (:debug, :save-request?, :debug-body?): Corresponding requests are stored in :aleph/netty-request, :aleph/request, :aleph/request-body keys of the response map. - :response-interceptor: Not supported. - :log-activity: Connection pool configuration option to switch on logging of connection status changes and request/response hex dumps. - :cache and :cache-config: Not supported. - DNS resolver: Fully async and highly customizable. ``` -------------------------------- ### Configure Aleph Dependency in deps.edn Source: https://github.com/clj-commons/aleph/blob/master/README.md This snippet demonstrates how to include Aleph as a dependency in a Clojure project using deps.edn, providing options for both Maven version and Git SHA reference. ```Clojure aleph/aleph {:mvn/version "0.8.3"} ;; alternatively io.github.clj-commons/aleph {:git/sha "..."} ``` -------------------------------- ### Implement a WebSocket Echo Server in Clojure Source: https://github.com/clj-commons/aleph/blob/master/README.md This Clojure snippet demonstrates how to create a basic WebSocket echo server using Aleph. It establishes a duplex stream for bidirectional communication, taking incoming messages from the client and immediately sending them back. ```Clojure (require '[manifold.stream :as s]) (defn echo-handler [req] (let [s @(http/websocket-connection req)] (s/connect s s))) ``` -------------------------------- ### SSL/TLS Context Management (APIDOC) Source: https://github.com/clj-commons/aleph/blob/master/CHANGES.md Outlines changes and fixes related to SSL/TLS context configuration for Aleph clients, including new options and removal of deprecated Netty methods. ```APIDOC SSL/TLS Configuration: - Allow for `:ssl-context` to be defined for clients. - Add `aleph.netty/ssl-client-context` for basic SSL configuration. - Fix bug in client SSL context creation. - Get rid of deprecated `SslContext` methods. ``` -------------------------------- ### Aleph TCP Client API Reference Source: https://github.com/clj-commons/aleph/blob/master/docs/tcp.md Reference for creating a TCP client connection using Aleph. The `aleph.tcp/client` function initiates a connection to a specified host and port, returning a deferred value that resolves to a duplex stream upon successful connection. ```APIDOC aleph.tcp/client Parameters: options: map :host (string): The target host. :port (integer): The target port. Returns: deferred (duplex stream) ``` -------------------------------- ### Clojure: Basic Multipart Request Handler with Automatic Cleanup Source: https://github.com/clj-commons/aleph/blob/master/docs/http/multipart.md Demonstrates a basic Aleph handler for decoding multipart requests using `aleph.http.multipart/decode-request`. It processes each part from the stream, handling content based on whether it's in memory or a temporary file, with automatic resource cleanup upon stream closure. The default memory limit is 16 KB. ```Clojure (require '[aleph.http.multipart :as mp]) (require '[clojure.java.io :as io]) (require '[manifold.stream :as s]) (defn multipart-handler [req] (let [s (mp/decode-request req {:memory-limit (* 16 1024)})] (doseq [part (s/stream->seq s)] (if (:memory? part)) (:content part) ;; do what you want with the content (io/copy (:file part) (io/file "..."))))) ;; copy the file on another location ``` -------------------------------- ### Configure Aleph Dependency in Leiningen Source: https://github.com/clj-commons/aleph/blob/master/README.md This snippet shows how to add the Aleph library as a dependency to a Clojure project managed by Leiningen, specifying the version 0.8.3. ```Clojure [aleph "0.8.3"] ``` -------------------------------- ### Netty Integration and API Updates (APIDOC) Source: https://github.com/clj-commons/aleph/blob/master/CHANGES.md Summarizes updates to Netty versions and related API changes within Aleph, including the adoption of newer Netty features and the removal of deprecated methods across various components. ```APIDOC Netty Integration: - Bump to Netty 4.1.30.Final. - Target latest Netty version. - Use built-in `ChannelInitializer` to build pipeline when Channel is registered. - Remove unused `netty/HeaderMap` declaration. - Permanently added `ChunkedWriteHandler` to deal with potential multipart upload. - Get rid of deprecated Netty methods from `http/server`, `http/core`, and `aleph.http.client` namespaces. - Get rid of the hack with `PluggableDnsAddressResolverGroup`. ``` -------------------------------- ### Core Utilities and Stream API Changes (APIDOC) Source: https://github.com/clj-commons/aleph/blob/master/CHANGES.md Details modifications to core utility methods and the `manifold.stream` API, along with general improvements like logging configuration. ```APIDOC Core Utilities: - Add `aleph.netty/wait-for-close` method to prevent premature process closing. - `coerce-element` helper for streaming body no longer needs Netty channel. - Allow to set `log4j2` logger. Manifold Stream API: - Altered shape of `manifold.stream/description` for Netty sources and sinks. ``` -------------------------------- ### HTTP Client Features and Configuration (APIDOC) Source: https://github.com/clj-commons/aleph/blob/master/CHANGES.md Documents new and updated configuration options for the Aleph HTTP client, including request saving, activity logging, DNS resolution, proxy support, cookie handling, and multipart upload capabilities. It also notes the deprecation of `aleph.http.multipart/encode-body`. ```APIDOC aleph.http.client/request options: :save-request? (boolean): Option to save Netty's HttpMessage internally for later use. :log-activity (boolean): Enables logging for connection activity. :dns-resolver (interface): Custom DNS resolver for all client protocols. :follow-redirects? (boolean): Handler provides extra options for redirect following. HTTP Client Features: - Support for cookies in HTTP client requests and responses. - Proxy support for HTTP client. - Matches nested query parameter behavior of clj-http. - Supports custom date header in responses. - Handles empty "Set-Cookie" response headers without crashing default middleware. Multipart Uploads: aleph.http.multipart/encode-body (function): Deprecated. Use alternative multipart encoding. - Supports manually specified charsets for file uploads. - Supports binary content parts. - Integrates `ChunkedWriteHandler` for potential multipart uploads. - Netty's multipart encoder may return either a full request or a chunked stream. ``` -------------------------------- ### Clojure: Multipart Part Specification Source: https://github.com/clj-commons/aleph/blob/master/docs/http/multipart.md Defines the specification for individual parts within a multipart request stream using Clojure's `clojure.spec.alpha`. It details expected keys like `part-name`, `content` (string or input stream), `name`, `charset`, `mime-type`, `transfer-encoding`, and file-related properties such as `memory?`, `file?`, `file` (java.io.File), and `size`. ```Clojure (s/def ::part-name string?) (s/def ::content (s/or :string string? :input-stream (partial instance? java.io.InputStream))) (s/def ::name (s/nilable string?)) (s/def ::charset string?) (s/def ::mime-type string?) (s/def ::transfer-encoding (s/nilable string?)) (s/def ::memory? boolean?) (s/def ::file? boolean?) (s/def ::file (s/nilable (partial instance? java.io.File))) (s/def ::size int?) (s/def ::part (s/keys :req-un [::part-name ::content ::name ::charset ::mime-type ::transfer-encoding ::memory? ::file? ::file ::size])) ``` -------------------------------- ### WebSocket API Enhancements and Fixes (APIDOC) Source: https://github.com/clj-commons/aleph/blob/master/CHANGES.md Details improvements and bug fixes related to the Aleph WebSocket API, including support for PING frames, enhanced stream descriptions, and memory leak resolutions for binary frames. ```APIDOC WebSocket API: - Add support for WebSocket `PING` frames. - Add websocket close status and message to stream description. - Fix memory leak in handling of binary websocket frames. - Ensure post-websocket upgrade 'response' is always nil in examples. ``` -------------------------------- ### Integrate Netty HashedWheelTimer as Manifold Scheduler Source: https://github.com/clj-commons/aleph/blob/master/docs/advanced/replace-internal-scheduler.md This Clojure code demonstrates how to replace the default `manifold.time/*clock*` with an instance of Netty's `HashedWheelTimer` for improved performance in high-volume scheduling scenarios. It defines a `hashed-timer-clock` that implements the `IClock` protocol, delegating `in` calls to `HashedWheelTimer` and `every` calls to a standard `ScheduledExecutorService` wrapped as a clock. Finally, it updates the `mtime/*clock*` var-root to use this new custom clock. ```clojure (import '[java.util.concurrent Executors TimeUnit]) (import '[io.netty.util HashedWheelTimer TimerTask]) (import '[manifold.time IClock]) (require '[aleph.netty :refer [enumerating-thread-factory]]) (require '[manifold.time :as mtime]) (def hashed-timer-clock (let [timer (HashedWheelTimer. (enumerating-thread-factory "manifold-timeout-scheduler" false) 10 TimeUnit/MILLISECONDS 1024) periodic-clock (mtime/scheduled-executor->clock (Executors/newSingleThreadScheduledExecutor (enumerating-thread-factory "manifold-periodic-scheduler" false)))] (reify IClock (in [_ interval f] (.newTimeout timer (reify TimerTask (run [_ _] (f))) interval TimeUnit/MILLISECONDS)) (every [_ delay period f] (.every ^IClock periodic-clock delay period f))))) (alter-var-root #'mtime/*clock* (constantly hashed-timer-clock)) ``` -------------------------------- ### Clojure: Multipart Request Handler with Manual Cleanup Source: https://github.com/clj-commons/aleph/blob/master/docs/http/multipart.md Illustrates how to disable automatic resource cleanup for multipart requests by setting `manual-cleanup?` to `true`. This returns a vector containing the manifold stream and a cleanup function, allowing the user to explicitly manage temporary files after processing, which is useful for very large files that cannot fit into memory. ```Clojure (defn multipart-handler [req] (let [[s cleanup-fn] (mp/decode-request req {:manual-cleanup? true})] (doseq [part (s/stream->seq s)] (if (:memory? part)) (:content part) ;; do what you want with the content (io/copy (:file part))) ;; copy the file on another location (cleanup-fn))) ``` -------------------------------- ### Clojure UDP Message Map Structure in Aleph Source: https://github.com/clj-commons/aleph/blob/master/docs/udp.md Illustrates the structure of a message map used with Aleph UDP sockets, including fields for host, port, and the message payload. Incoming messages have a byte-array for ':message', while outgoing messages can be any data coercible to binary. ```clj {:host "example.com" :port 10001 :message ...} ``` -------------------------------- ### Define UDP Message Structure in Aleph Source: https://github.com/clj-commons/aleph/blob/master/README.md This snippet outlines the expected map structure for messages sent and received over a UDP socket in Aleph. Incoming messages will have a byte-array for `:message`, while outgoing messages can be any data coercible to binary. ```Clojure {:host "example.com" :port 10001 :message ...} ``` -------------------------------- ### Clojure: Overriding Memory Limit for Multipart Requests Source: https://github.com/clj-commons/aleph/blob/master/docs/http/multipart.md Shows how to increase the `memory-limit` for `decode-request` to ensure larger parts are stored in memory. This can prevent issues where temporary files are cleaned up automatically before they can be processed or copied, especially when dealing with moderate file sizes. ```Clojure (mp/decode-request req {:memory-limit (* 16 1024 1024)}) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.