From 4b26544e44cbdb309f91681d704237235591a7a4 Mon Sep 17 00:00:00 2001 From: Rahul De Date: Sun, 8 Oct 2023 19:51:34 +0100 Subject: [PATCH 1/5] [#9] Support ring.core.protocols/StreamableResponseBody --- deps.edn | 3 ++- src/s_exp/mina/response.clj | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/deps.edn b/deps.edn index 2defffd..ae0bcf9 100644 --- a/deps.edn +++ b/deps.edn @@ -10,7 +10,8 @@ com.github.strojure/zmap {:mvn/version "1.3.26"} io.helidon.http/helidon-http {:mvn/version "4.0.0-RC1"} io.helidon.webserver/helidon-webserver {:mvn/version "4.0.0-RC1"} - io.helidon.webserver/helidon-webserver-http2 {:mvn/version "4.0.0-RC1"}} + io.helidon.webserver/helidon-webserver-http2 {:mvn/version "4.0.0-RC1"} + ring/ring-core {:mvn/version "1.10.0"}} :aliases {:test {:extra-paths ["test"] diff --git a/src/s_exp/mina/response.clj b/src/s_exp/mina/response.clj index 717bb83..4d32891 100644 --- a/src/s_exp/mina/response.clj +++ b/src/s_exp/mina/response.clj @@ -1,4 +1,5 @@ (ns s-exp.mina.response + (:require [ring.core.protocols :as p]) (:import (io.helidon.http Header Headers HeaderNames @@ -35,7 +36,9 @@ Object (write-body! [o server-response] - (.send ^ServerResponse server-response o))) + (if (satisfies? p/StreamableResponseBody o) + (p/write-body-to-stream o nil (.outputStream server-response)) + (.send ^ServerResponse server-response o)))) (defn header-name ^HeaderName [ring-header-name] (HeaderNames/createFromLowercase (name ring-header-name))) @@ -62,4 +65,3 @@ (set-headers! server-response headers) (set-status! server-response status) (write-body! body server-response)) - From 565d9de5d8c672eb8bf5270d34b815ddb23f5f4e Mon Sep 17 00:00:00 2001 From: Rahul De Date: Mon, 9 Oct 2023 23:07:59 +0100 Subject: [PATCH 2/5] [#9] Conditionally load ring-core --- deps.edn | 3 +-- src/s_exp/mina/response.clj | 9 +++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/deps.edn b/deps.edn index ae0bcf9..2defffd 100644 --- a/deps.edn +++ b/deps.edn @@ -10,8 +10,7 @@ com.github.strojure/zmap {:mvn/version "1.3.26"} io.helidon.http/helidon-http {:mvn/version "4.0.0-RC1"} io.helidon.webserver/helidon-webserver {:mvn/version "4.0.0-RC1"} - io.helidon.webserver/helidon-webserver-http2 {:mvn/version "4.0.0-RC1"} - ring/ring-core {:mvn/version "1.10.0"}} + io.helidon.webserver/helidon-webserver-http2 {:mvn/version "4.0.0-RC1"}} :aliases {:test {:extra-paths ["test"] diff --git a/src/s_exp/mina/response.clj b/src/s_exp/mina/response.clj index 4d32891..5cc02d4 100644 --- a/src/s_exp/mina/response.clj +++ b/src/s_exp/mina/response.clj @@ -1,5 +1,4 @@ (ns s-exp.mina.response - (:require [ring.core.protocols :as p]) (:import (io.helidon.http Header Headers HeaderNames @@ -8,6 +7,12 @@ (io.helidon.webserver.http ServerResponse) (java.io FileInputStream InputStream OutputStream))) +(def ^:no-doc ring-core-loaded + (try + (require '[ring.core.protocols :as p]) + true + (catch Throwable _ false))) + (defprotocol BodyWriter (write-body! [x server-response])) @@ -36,7 +41,7 @@ Object (write-body! [o server-response] - (if (satisfies? p/StreamableResponseBody o) + (if (and ring-core-loaded (satisfies? p/StreamableResponseBody o)) (p/write-body-to-stream o nil (.outputStream server-response)) (.send ^ServerResponse server-response o)))) From ab4230159259e1c192d218f71224d771915542cb Mon Sep 17 00:00:00 2001 From: Rahul De Date: Tue, 10 Oct 2023 08:14:05 +0100 Subject: [PATCH 3/5] [#9] extend proto at compile time --- src/s_exp/mina/response.clj | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/s_exp/mina/response.clj b/src/s_exp/mina/response.clj index 5cc02d4..1d2ffdf 100644 --- a/src/s_exp/mina/response.clj +++ b/src/s_exp/mina/response.clj @@ -9,7 +9,7 @@ (def ^:no-doc ring-core-loaded (try - (require '[ring.core.protocols :as p]) + (require 'ring.core.protocols) true (catch Throwable _ false))) @@ -41,9 +41,17 @@ Object (write-body! [o server-response] - (if (and ring-core-loaded (satisfies? p/StreamableResponseBody o)) - (p/write-body-to-stream o nil (.outputStream server-response)) - (.send ^ServerResponse server-response o)))) + (.send ^ServerResponse server-response o))) + +(when ring-core-loaded + (extend-protocol BodyWriter + Object + (write-body! [o server-response] + (let [StreamableResponseBody @(ns-resolve 'ring.core.protocols 'StreamableResponseBody) + write-body-to-stream (ns-resolve 'ring.core.protocols 'write-body-to-stream)] + (if (satisfies? StreamableResponseBody o) + (write-body-to-stream o nil (.outputStream server-response)) + (.send ^ServerResponse server-response o)))))) (defn header-name ^HeaderName [ring-header-name] (HeaderNames/createFromLowercase (name ring-header-name))) From bef54716e0a5b34e7589433a51621603c71c17a8 Mon Sep 17 00:00:00 2001 From: Rahul De Date: Tue, 10 Oct 2023 12:02:03 +0100 Subject: [PATCH 4/5] [#9] add tests --- deps.edn | 3 ++- test/s_exp/mina_test.clj | 22 +++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/deps.edn b/deps.edn index 2defffd..163693a 100644 --- a/deps.edn +++ b/deps.edn @@ -17,7 +17,8 @@ :extra-deps {org.clojure/test.check {:mvn/version "1.1.1"} less-awful-ssl/less-awful-ssl {:mvn/version "1.0.6"} eftest/eftest {:mvn/version "0.6.0"} - clj-http/clj-http {:mvn/version "3.12.0"}}} + clj-http/clj-http {:mvn/version "3.12.0"} + ring/ring-core {:mvn/version "1.10.0"}}} :project {:extra-deps {io.github.exoscale/tools.project {:git/sha "4ad527fac7bdc24f649404205ca31754339f856d"}} :ns-default exoscale.tools.project diff --git a/test/s_exp/mina_test.clj b/test/s_exp/mina_test.clj index 234cbc1..8e1a594 100644 --- a/test/s_exp/mina_test.clj +++ b/test/s_exp/mina_test.clj @@ -3,7 +3,9 @@ [clojure.string :as str] [clojure.test :refer :all] [less.awful.ssl :as ls] - [s-exp.mina :as m]) + [s-exp.mina :as m] + [ring.core.protocols :as p] + [clojure.java.io :as io]) (:import (io.helidon.common.tls Tls TlsClientAuth) (io.helidon.common.tls TlsConfig))) @@ -94,5 +96,19 @@ :trust-store "test/keystore.jks" :trust-store-pass "password"})))))) - - +(deftest test-streamable-body + (with-server {:handler (fn [_req] + {:status 200 + :headers {"content-type" "text/event-stream" + "transfer-encoding" "chunked"} + :body (reify p/StreamableResponseBody + (write-body-to-stream [_ _ output-stream] + (with-open [w (io/writer output-stream)] + (doseq [n (range 1 6)] + (doto w + (.write (str "data: " n "\n\n")) + (.flush))))))})} + (let [resp (client/get *endpoint*)] + (is (status-ok? resp)) + (is (= "data: 1\n\ndata: 2\n\ndata: 3\n\ndata: 4\n\ndata: 5\n\n" + (:body resp)))))) From 5baa9ee81e6ce7f69baca7ce7e06d8ea5f79906a Mon Sep 17 00:00:00 2001 From: Rahul De Date: Tue, 10 Oct 2023 12:05:10 +0100 Subject: [PATCH 5/5] [#9] rename --- src/s_exp/mina/response.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/s_exp/mina/response.clj b/src/s_exp/mina/response.clj index 1d2ffdf..6992fd0 100644 --- a/src/s_exp/mina/response.clj +++ b/src/s_exp/mina/response.clj @@ -7,7 +7,7 @@ (io.helidon.webserver.http ServerResponse) (java.io FileInputStream InputStream OutputStream))) -(def ^:no-doc ring-core-loaded +(def ^:no-doc ring-core-loaded? (try (require 'ring.core.protocols) true @@ -43,7 +43,7 @@ (write-body! [o server-response] (.send ^ServerResponse server-response o))) -(when ring-core-loaded +(when ring-core-loaded? (extend-protocol BodyWriter Object (write-body! [o server-response]