Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump dependencies versions #5

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .clj-kondo/config.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{:skip-comments true
:linters {:private-call {:level :warn}
:redundant-do {:level :error}
:single-key-in {:level :info}
:single-operand-comparison {:level :info}
:shadowed-var {:level :info}
:syntax {:level :error}
:unused-binding {:exclude-destructured-keys-in-fn-args true}
:unresolved-symbol {:report-duplicates true
:exclude [(clojure.test/are [thrown-on-path?])
(cljs.test/are [thrown-on-path?])
(clojure.test/is [thrown-on-path?])
(cljs.test/is [thrown-on-path?])]}
:use {:level :error}}
:lint-as {clojure.test.check.properties/for-all clojure.core/let
clojure.test.check.clojure-test/defspec clojure.test/deftest}
:output {:pattern "[{{LEVEL}}] {{filename}} [{{row}}:{{coll}}]: {{message}}"}
:hooks {}}
7 changes: 7 additions & 0 deletions .cljfmt.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{:remove-surrounding-whitespace? true
:remove-trailing-whitespace? true
:remove-consecutive-blank-lines? false
:insert-missing-whitespace? true
:align-associative? true
:indents {clojure.spec.alpha/def [[:block 1]]
clojure.test.check.properties/for-all [[:block 1]]}}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ pom.xml.asc
/.nrepl-port
.hgignore
.hg/
.lsp/
.calva/
.clj-kondo/.cache
12 changes: 6 additions & 6 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
(defproject duct/server.http.aleph "0.1.2"
(defproject duct/server.http.aleph "0.2.0"
:description "Integrant methods for running an Aleph web server"
:url "https://github.com/duct-framework/server.http.aleph"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.9.0-beta3"]
[duct/core "0.6.1"]
[aleph "0.4.3"]
[duct/logger "0.2.1"]
[integrant "0.6.1"]]
:dependencies [[org.clojure/clojure "1.10.3"]
[duct/core "0.8.0"]
[aleph "0.4.7-alpha7"]
[duct/logger "0.3.0"]
[integrant "0.8.0"]]
:profiles
{:dev {:dependencies [[clj-http "3.7.0"]]}})
10 changes: 7 additions & 3 deletions src/duct/server/http/aleph.clj
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
(ns duct.server.http.aleph
(:require [aleph.http :as aleph]
[duct.logger :as logger]
[duct.server.http.spec :as spec]
[integrant.core :as ig]))

(defmethod ig/pre-init-spec :duct.server.http/aleph [_]
::spec/config)

(defmethod ig/init-key :duct.server.http/aleph [_ {:keys [handler logger] :as opts}]
(let [handler (atom (delay (:handler opts)))
logger (atom logger)
Expand All @@ -19,10 +23,10 @@
(defmethod ig/suspend-key! :duct.server.http/aleph [_ {:keys [handler]}]
(reset! handler (promise)))

(defmethod ig/resume-key :duct.server.http/aleph [key opts old-opts old-impl]
(defmethod ig/resume-key :duct.server.http/aleph [kw opts old-opts old-impl]
(if (= (dissoc opts :handler :logger) (dissoc old-opts :handler :logger))
(do (deliver @(:handler old-impl) (:handler opts))
(reset! (:logger old-impl) (:logger opts))
old-impl)
(do (ig/halt-key! key old-impl)
(ig/init-key key opts))))
(do (ig/halt-key! kw old-impl)
(ig/init-key kw opts))))
67 changes: 67 additions & 0 deletions src/duct/server/http/spec.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
(ns duct.server.http.spec
(:require [clojure.spec.alpha :as s]
[duct.logger :as logger])
(:import [duct.logger Logger]
[java.net SocketAddress]
[java.util.concurrent Executor]
[io.netty.handler.ssl SslContext]))

(def ^:private port-max-value (int (Character/MAX_VALUE)))

(def ^:private fn-instance? (partial partial instance?))

(s/def ::port
(s/or :any zero?
:specific #(< 0 % port-max-value)))

(s/def ::socket-address
(fn-instance? SocketAddress))

(s/def ::bootstrap-transform ifn?)

(s/def ::ssl-context
(fn-instance? SslContext))

(s/def ::pipeline-transform ifn?)

(s/def ::executor
(s/or :none (partial = :none)
:some (fn-instance? Executor)))

(s/def ::shutdown-executor? boolean?)

(s/def ::request-buffer-size pos-int?)

(s/def ::raw-stream? boolean?)

(s/def ::rejected-handler ifn?)

(s/def ::max-initial-line-length pos-int?)

(s/def ::max-header-size pos-int?)

(s/def ::max-chunk-size pos-int?)

(s/def ::epoll? boolean?)

(s/def ::compression? boolean?)

(s/def ::compression-level
(s/and pos-int?
#(<= 1 % 9)))

(s/def ::idle-timeout (complement neg-int?))

(s/def ::logger (fn-instance? Logger))

(s/def ::handler ifn?)

(s/def ::config
(s/keys :req-un [::logger ::handler]
:opt-un [::port ::socket-address ::bootstrap-transform
::ssl-context ::pipeline-transform ::executor
::shutdown-executor? ::request-buffer-size
::raw-stream? ::rejected-handler
::max-initial-line-length ::max-header-size
::max-chunk-size ::epoll? ::compression?
::compression-level ::idle-timeout]))
130 changes: 123 additions & 7 deletions test/duct/server/http/aleph_test.clj
Original file line number Diff line number Diff line change
@@ -1,19 +1,134 @@
(ns duct.server.http.aleph-test
(:import java.net.ConnectException)
(:require [clj-http.client :as http]
[clojure.test :refer :all]
(:require [aleph
[flow :as flow]
[netty :as netty]]
[clj-http.client :as http]
[clojure.spec.alpha :as s]
[clojure.test :refer [deftest is testing assert-expr do-report]]
[duct.core :as duct]
[duct.logger :as logger]
[duct.server.http.aleph :as aleph]
[integrant.core :as ig]))
[integrant.core :as ig])
(:import [clojure.lang ExceptionInfo]
java.net.ConnectException
[java.net InetSocketAddress]
[sun.security.provider.certpath SunCertPathBuilderException]))

(defrecord TestLogger [logs]
logger/Logger
(-log [_ level ns-str file line id event data]
(-log [_ _ _ _ _ _ event data]
(swap! logs conj [event data])))

(duct/load-hierarchy)

(defmethod assert-expr 'thrown-on-path? [msg form]
(let [selector (nth form 1)
body (nthnext form 2)]
`(try
~@body
(do-report {:type :fail
:message ~msg
:expected '~form
:actual "Nothing was thrown"})
(catch ExceptionInfo e#
(let [path# (some-> (ex-data e#)
:explain
::s/problems
first
:path)]
(if (= path# ~selector)
(do-report {:type :pass
:message ~msg
:expected '~form
:actual path#})
(do-report {:type :fail
:message ~msg
:expected '~form
:actual path#}))))
(catch Exception e#
(do-report {:type :fail
:message ~msg
:expected '~form
:actual e#})))))

(deftest pre-init-spec-test
(let [logger (->TestLogger (atom []))
response {:status 200
:body "test"}
config {:duct.server.http/aleph {:port 3400
:executor (flow/fixed-thread-executor 2)
:shutdown-executor? true
:request-buffer-size 8196
:raw-stream? false
:max-initial-line-length 8196
:max-header-size 8196
:max-chunk-size 8196
:epoll? false
:compression? false
:idle-timeout 0
:logger logger
:handler (constantly response)}}]
(testing "server starts"
(let [system (ig/init config)]
(try
(let [{:keys [status body]} (http/get "http://127.0.0.1:3400/")]
(is (= 200 status))
(is (= "test" body)))
(finally
(ig/halt! system)))))
(testing "ssl context"
(testing "servers starts"
(let [system (ig/init (assoc-in config [:duct.server.http/aleph :ssl-context]
(netty/self-signed-ssl-context)))]
(try
(is (thrown? SunCertPathBuilderException
(http/get "https://127.0.0.1:3400")))
(finally
(ig/halt! system)))))
(testing "not valid cert"
(is (thrown-on-path?
[:ssl-context]
(-> config
(assoc-in [:duct.server.http/aleph :ssl-context]
"Not a ssl cert.")
(ig/init))))))
(testing "socket-address"
(let [config (update config :duct.server.http/aleph
dissoc :port)]
(testing "server starts"
(let [system (-> config
(assoc-in [:duct.server.http/aleph :socket-address]
(InetSocketAddress. 3400))
(ig/init))]
(try
(let [{:keys [status body]} (http/get "http://127.0.0.1:3400/")]
(is (= 200 status))
(is (= "test" body)))
(finally
(ig/halt! system)))))
(testing "not valid socket"
(is (thrown-on-path? [:socket-address]
(ig/init
(assoc-in config
[:duct.server.http/aleph :socket-address]
"Invalid socket object")))))))
(testing "executor"
(testing "server starts on :none"
(let [system (ig/init (assoc-in config
[:duct.server.http/aleph :executor]
:none))]
(try
(let [{:keys [status body]} (http/get "http://127.0.0.1:3400/")]
(is (= 200 status))
(is (= "test" body)))
(finally
(ig/halt! system)))))
(testing "should fail on a non valid executor"
(is (thrown-on-path? [:executor :none]
(ig/init (assoc-in config
[:duct.server.http/aleph :executor]
:nothing))))))))

(deftest key-test
(is (isa? :duct.server.http/aleph :duct.server/http)))

Expand Down Expand Up @@ -49,8 +164,9 @@
(deftest resume-and-suspend-test
(let [response1 {:status 200 :headers {} :body "foo"}
response2 {:status 200 :headers {} :body "bar"}
config1 {:duct.server.http/aleph {:port 3400, :handler (constantly response1)}}
config2 {:duct.server.http/aleph {:port 3400, :handler (constantly response2)}}]
logger (->TestLogger (atom []))
config1 {:duct.server.http/aleph {:port 3400, :handler (constantly response1), :logger logger}}
config2 {:duct.server.http/aleph {:port 3400, :handler (constantly response2), :logger logger}}]

(testing "suspend and resume"
(let [system1 (doto (ig/init config1) ig/suspend!)
Expand Down