diff --git a/project.clj b/project.clj index 06886fe..66fcb77 100644 --- a/project.clj +++ b/project.clj @@ -1,5 +1,6 @@ (defproject ring-server "0.1.0" :description "Library for running Ring web servers" :dependencies [[org.clojure/clojure "1.2.1"] + [org.clojure/core.incubator "0.1.0"] [ring "1.0.1"]] :dev-dependencies [[clj-http "0.3.1"]]) diff --git a/src/ring/server/options.clj b/src/ring/server/options.clj new file mode 100644 index 0000000..b5017b1 --- /dev/null +++ b/src/ring/server/options.clj @@ -0,0 +1,12 @@ +(ns ring.server.options + "Functions to retrieve options and settings with sensible defaults" + (:use [ring.util.environment :only (*env*)] + [clojure.core.incubator :only (-?>)])) + +(defn port + "Find the port or list of ports specified in the options or environment. + Defaults to a range of ports from 3000 to 3010." + [options] + (or (:port options) + (-?> (*env* "PORT") Integer.) + (range 3000 3010))) diff --git a/src/ring/server/standalone.clj b/src/ring/server/standalone.clj index 0929193..42c7d76 100644 --- a/src/ring/server/standalone.clj +++ b/src/ring/server/standalone.clj @@ -1,12 +1,20 @@ (ns ring.server.standalone "Functions to start a standalone Ring server." (:use ring.adapter.jetty - ring.util.environment)) + ring.server.options)) + +(defn- try-port [port run-server] + (if-not (sequential? port) + (run-server port) + (try (run-server (first port)) + (catch Exception _ + (try-port (next port) run-server))))) (defn serve "Start a web server to run a handler." [handler & [{:as options}]] - (let [port (Integer. (*env* "PORT" "5000"))] - (run-jetty - handler - (merge {:port port} options)))) + (try-port (port options) + (fn [port] + (run-jetty + handler + (merge {:port port} options))))) diff --git a/test/ring/server/test/standalone.clj b/test/ring/server/test/standalone.clj index 7815d6a..528f276 100644 --- a/test/ring/server/test/standalone.clj +++ b/test/ring/server/test/standalone.clj @@ -11,10 +11,28 @@ ~@body (finally (.stop server#))))) +(defn test-server [& [{:as options}]] + (let [handler (constantly (response "Hello World"))] + (serve handler (merge {:join? false} options)))) + +(defn is-server-running-on-port [port] + (let [resp (http/get (str "http://localhost:" port) + {:conn-timeout 1000})] + (is (= (:status resp) 200)))) + (deftest serve-test - (with-env {"PORT" "4563"} - (let [handler (constantly (response "Hello World"))] - (with-server (serve handler {:join? false}) - (let [resp (http/get "http://localhost:4563")] - (is (= (:status resp) 200)) - (is (= (:body resp) "Hello World"))))))) + (testing "default port" + (with-server (test-server) + (is-server-running-on-port 3000))) + (testing "fallback default ports" + (with-server (test-server) + (with-server (test-server) + (is-server-running-on-port 3000) + (is-server-running-on-port 3001)))) + (testing "PORT environment variable" + (with-env {"PORT" "4563"} + (with-server (test-server) + (is-server-running-on-port 4563)))) + (testing ":port option" + (with-server (test-server {:port 5463}) + (is-server-running-on-port 5463))))