Created
June 16, 2024 12:17
-
-
Save jarppe/3dfa15c00a63db797fbce811f260e59a to your computer and use it in GitHub Desktop.
Converting Channel to Java InputStream and OutputStream using proxies
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns proxy-byte-channels-example | |
(:import (java.io InputStream | |
OutputStream) | |
(java.nio ByteBuffer) | |
(java.net UnixDomainSocketAddress | |
StandardProtocolFamily) | |
(java.nio.channels ByteChannel | |
SocketChannel) | |
(java.nio.charset StandardCharsets))) | |
(defn ch->in ^InputStream [^ByteChannel ch] | |
(let [buffer (doto (ByteBuffer/allocate 1024) | |
(.flip)) | |
ensure-data (fn [] | |
(if (.hasRemaining buffer) | |
true | |
(do (.clear buffer) | |
(if (= (.read ch buffer) -1) | |
false | |
(do (.flip buffer) | |
true)))))] | |
(proxy [InputStream] [] | |
(read | |
([] | |
(if (ensure-data) | |
(-> (.get buffer) (bit-and 0xff)) | |
-1)) | |
([b] | |
(if (ensure-data) | |
(.get buffer b) | |
-1)) | |
([b off len] | |
(if (ensure-data) | |
(.get buffer b off len) | |
-1)))))) | |
(defn ch->out ^OutputStream [^ByteChannel ch] | |
(proxy [OutputStream] [] | |
(write | |
([v] | |
(if (bytes? v) | |
(.write ch (ByteBuffer/wrap v)) | |
(let [buffer (ByteBuffer/allocate 1)] | |
(.put buffer (-> (Integer. v) (.byteValue))) | |
(.flip buffer) | |
(.write ch buffer)))) | |
([v off len] | |
(.write ch (ByteBuffer/wrap v off len)))))) | |
(defn open-docker-channel [] | |
(doto (SocketChannel/open StandardProtocolFamily/UNIX) | |
(.connect (UnixDomainSocketAddress/of "/var/run/docker.sock")) | |
(.finishConnect))) | |
(defn get-docker-version [] | |
(with-open [ch (open-docker-channel)] | |
(doto (ch->out ch) | |
(.write (-> (str "GET /version HTTP/1.0\r\n" | |
"Host: docker.com\r\n" | |
"\r\n") | |
(.getBytes StandardCharsets/UTF_8))) | |
(.flush)) | |
(let [in (ch->in ch)] | |
(loop [c (.read in)] | |
(when-not (= c -1) | |
(when-not (= c (int \return)) | |
(print (char c))) | |
(recur (.read in))))))) | |
(comment | |
(get-docker-version) | |
;=> | |
; HTTP/1.0 200 OK | |
; Api-Version: 1.45 | |
; Content-Type: application/json | |
; Date: Sun, 16 Jun 2024 11:53:10 GMT | |
; Docker-Experimental: false | |
; Ostype: linux | |
; Server: Docker/26.1.1 (linux) | |
; | |
; {"Platform":{"Name":"Docker Desktop 4.30.0 (149282)"},"Components":[{"Name"... | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment