diff --git a/backend/vendor/vertx/README.md b/backend/vendor/vertx/README.md index 2b4a617a3..c06cb4586 100644 --- a/backend/vendor/vertx/README.md +++ b/backend/vendor/vertx/README.md @@ -75,6 +75,7 @@ The `deploy!` function also accepts an additional parameter for options, and at this momment it only accepts as single option: - `:instances` - number of instances to launch of the same verticle. +- `:worker` - use worker thread pool or the default event-loop. ### Event Bus @@ -196,7 +197,7 @@ Lets start with a complete example: ```clojure (require '[vertx.http :as vh]) (require '[vertx.web :as vw]) -(require '[vertx.web.interceptors :as vwi]) +(require '[vertx.web.middleware :as vwm]) (defn hello-world-handler [req] @@ -205,8 +206,9 @@ Lets start with a complete example: (defn on-start [ctx] - (let [routes [["/" {:interceptors [(vwi/cookies)] - :all hello-world-handler}]] + (let [routes [["/" {:middleware [vwm/cookies] + :handler hello-world-handler + :method :get}]] handler (vw/handler ctx (vw/assets "/static/*" {:root "resources/public/static"}) (vw/router routes))] @@ -217,25 +219,24 @@ Lets start with a complete example: (vc/deploy! system)) ``` -The routes are defined using `reitit-core` and the interceptors are -using `sieppari` as underlying implementation. The request object is -very similar to the one explained in `vertx.http`. +The routes are defined using `reitit-core`. The request object is very +similar to the one explained in `vertx.http`. The main difference with `vertx.http` is that the handler is called when the body is ready to be used and is available under `:body` keyword on the request. All additional features such that reading the query/form params, -parse/write cookies, cors and file uploads are provided with -interceptors as pluggable pieces: +parse/write cookies, cors and file uploads are provided with additional middleware +wrappers: -- `vertx.web.interceptors/uploads` parses the vertx uploaded file data +- `vertx.web.middleware/uploads` parses the vertx uploaded file data structure and expose it as clojure maps under `:uploads` key. -- `vertx.web.interceptors/params` parses the query string and form +- `vertx.web.middleware/params` parses the query string and form params in the body if the content-type is appropriate and exposes them under `:params`. -- `vertx.web.interceptors/cors` properly sets the CORS headers. -- `vertx.web.interceptors/cookies` handles the cookies reading from +- `vertx.web.middleware/cors` properly sets the CORS headers. +- `vertx.web.middleware/cookies` handles the cookies reading from the request and cookies writing from the response. diff --git a/backend/vendor/vertx/deps.edn b/backend/vendor/vertx/deps.edn index 5de7cdf30..ab120edb6 100644 --- a/backend/vendor/vertx/deps.edn +++ b/backend/vendor/vertx/deps.edn @@ -2,7 +2,6 @@ {org.clojure/tools.logging {:mvn/version "0.5.0"} funcool/promesa {:mvn/version "5.0.0"} metosin/reitit-core {:mvn/version "0.3.10"} - metosin/sieppari {:mvn/version "0.0.0-alpha8"} org.clojure/core.async {:mvn/version "0.7.559"} io.vertx/vertx-core {:mvn/version "4.0.0-milestone4"} io.vertx/vertx-web {:mvn/version "4.0.0-milestone4"} diff --git a/backend/vendor/vertx/pom.xml b/backend/vendor/vertx/pom.xml index 83135b41a..3b681c540 100644 --- a/backend/vendor/vertx/pom.xml +++ b/backend/vendor/vertx/pom.xml @@ -57,11 +57,6 @@ core.async 0.7.559 - - metosin - sieppari - 0.0.0-alpha8 - diff --git a/backend/vendor/vertx/src/vertx/web.clj b/backend/vendor/vertx/src/vertx/web.clj index 2b028633f..5fa090cf0 100644 --- a/backend/vendor/vertx/src/vertx/web.clj +++ b/backend/vendor/vertx/src/vertx/web.clj @@ -10,8 +10,8 @@ [clojure.tools.logging :as log] [clojure.spec.alpha :as s] [promesa.core :as p] - [sieppari.core :as sp] [reitit.core :as rt] + [reitit.middleware :as rmw] [vertx.http :as http] [vertx.impl :as impl]) (:import @@ -57,10 +57,7 @@ (defn handler "Wraps a user defined funcion based handler into a vertx-web aware - handler (with support for multipart uploads. - - If the handler is a vector, the sieppari intercerptos engine will be used - to resolve the execution of the interceptors + handler." + handler (with support for multipart uploads)." [vsm & handlers] (let [^Vertx vsm (impl/resolve-system vsm) ^Router router (Router/router vsm)] @@ -89,23 +86,13 @@ {:status 500 :body "Internal server error!\n"}) -(defn- run-chain - [ctx chain handler] - (let [d (p/deferred)] - (sp/execute (conj chain handler) ctx #(p/resolve! d %) #(p/reject! d %)) - d)) - (defn- router-handler [router {:keys [path method] :as ctx}] - (let [{:keys [data path-params] :as match} (rt/match-by-path router path) - handler-fn (or (get data method) - (get data :all) - default-handler) - interceptors (get data :interceptors) - ctx (assoc ctx ::match match :path-params path-params)] - (if (empty? interceptors) - (handler-fn ctx) - (run-chain ctx interceptors handler-fn)))) + (if-let [{:keys [result path-params] :as match} (rt/match-by-path router path)] + (let [handler-fn (:handler result) + ctx (assoc ctx ::match match :path-params path-params)] + (handler-fn ctx)) + (default-handler ctx))) (defn router ([routes] (router routes {})) @@ -120,8 +107,8 @@ log-requests? false time-response? true} :as options}] - (let [rtr (rt/router routes options) - f #(router-handler rtr %)] + (let [rtr (rt/router routes {:compile rmw/compile-result}) + rtf #(router-handler rtr %)] (fn [^Router router] (let [^Route route (.route router)] (when time-response? (.handler route (ResponseTimeHandler/create))) @@ -149,8 +136,9 @@ (.put ^RoutingContext rc "vertx$clj$req" req) (.fail ^RoutingContext rc ^Throwable err))] (try - (-> (http/-handle-response (f req) req) - (p/catch' efn)) + (let [result (rtf req)] + (-> (http/-handle-response result req) + (p/catch' efn))) (catch Exception err (efn err))))))))) router)))) diff --git a/backend/vendor/vertx/src/vertx/web/client.clj b/backend/vendor/vertx/src/vertx/web/client.clj index 4ad0ef5a5..9cfd73fec 100644 --- a/backend/vendor/vertx/src/vertx/web/client.clj +++ b/backend/vendor/vertx/src/vertx/web/client.clj @@ -10,7 +10,6 @@ (:require [clojure.spec.alpha :as s] [promesa.core :as p] - [sieppari.core :as sp] [reitit.core :as rt] [vertx.http :as http] [vertx.impl :as impl]) diff --git a/backend/vendor/vertx/src/vertx/web/interceptors.clj b/backend/vendor/vertx/src/vertx/web/middleware.clj similarity index 57% rename from backend/vendor/vertx/src/vertx/web/interceptors.clj rename to backend/vendor/vertx/src/vertx/web/middleware.clj index df092c9fd..b3a2954b4 100644 --- a/backend/vendor/vertx/src/vertx/web/interceptors.clj +++ b/backend/vendor/vertx/src/vertx/web/middleware.clj @@ -4,8 +4,8 @@ ;; ;; Copyright (c) 2019 Andrey Antukh -(ns vertx.web.interceptors - "High level api for http servers." +(ns vertx.web.middleware + "Common middleware's." (:require [clojure.spec.alpha :as s] [clojure.string :as str] @@ -13,9 +13,7 @@ [reitit.core :as r] [vertx.http :as http] [vertx.web :as web] - [vertx.util :as util] - [sieppari.context :as spx] - [sieppari.core :as sp]) + [vertx.util :as util]) (:import clojure.lang.Keyword clojure.lang.MapEntry @@ -41,24 +39,36 @@ (:path data) (.setPath (:path data)) (:secure data) (.setSecure true))) -(defn cookies - [] - {:enter - (fn [data] - (let [^HttpServerRequest req (get-in data [:request ::http/request]) - parse-cookie (fn [^Cookie item] [(.getName item) (.getValue item)]) - cookies (into {} (map parse-cookie) (vals (.cookieMap req)))] - (update data :request assoc :cookies cookies))) - :leave - (fn [data] - (let [cookies (get-in data [:response :cookies]) - ^HttpServerResponse res (get-in data [:request ::http/response])] - (when (map? cookies) - (util/doseq [[key val] cookies] - (if (nil? val) - (.removeCookie res key) - (.addCookie res (build-cookie key val))))) - data))}) +(defn- handle-cookies-response + [request {:keys [cookies] :as response}] + (let [^HttpServerResponse res (::http/response request)] + (util/doseq [[key val] cookies] + (if (nil? val) + (.removeCookie res key) + (.addCookie res (build-cookie key val)))))) + +(defn- cookie->vector + [^Cookie item] + [(.getName item) (.getValue item)]) + +(defn- wrap-cookies + [handler] + (let [xf (map cookie->vector)] + (fn [request] + (let [req (::http/request request) + cookies (.cookieMap ^HttpServerRequest req) + cookies (into {} xf (vals cookies))] + (-> (p/do! (handler (assoc request :cookies cookies))) + (p/then' (fn [response] + (when (and (map? response) + (map? (:cookies response))) + (handle-cookies-response request response)) + response))))))) + +(def cookies + {:name ::cookies + :compile (constantly wrap-cookies)}) + ;; --- Params @@ -83,46 +93,54 @@ (recur (assoc! m key [prv val])))) (persistent! m))))) -(defn params - ([] (params nil)) - ([{:keys [attr] :or {attr :params}}] - {:enter (fn [data] - (let [request (get-in data [:request ::http/request]) - params (parse-params request)] - (update data :request assoc attr params)))})) +(defn- wrap-params + [handler] + (fn [request] + (let [req (::http/request request) + params (parse-params req)] + (handler (assoc request :params params))))) + +(def params + {:name ::params + :compile (constantly wrap-params)}) + ;; --- Uploads -(defn uploads - ([] (uploads nil)) - ([{:keys [attr] :or {attr :uploads}}] - {:enter (fn [data] - (let [context (get-in data [:request ::web/routing-context]) - uploads (reduce (fn [acc ^FileUpload upload] - (assoc! acc - (keyword (.name upload)) - {:type :uploaded-file - :mtype (.contentType upload) - :path (.uploadedFileName upload) - :name (.fileName upload) - :size (.size upload)})) - (transient {}) - (.fileUploads ^RoutingContext context))] - (update data :request assoc attr (persistent! uploads))))})) +(defn- wrap-uploads + [handler] + (fn [request] + (let [rctx (::web/routing-context request) + uploads (.fileUploads ^RoutingContext rctx) + uploads (reduce (fn [acc ^FileUpload upload] + (assoc acc + (keyword (.name upload)) + {:type :uploaded-file + :mtype (.contentType upload) + :path (.uploadedFileName upload) + :name (.fileName upload) + :size (.size upload)})) + {} + uploads)] + (handler (assoc request :uploads uploads))))) + +(def uploads + {:name ::uploads + :compile (constantly wrap-uploads)}) ;; --- Errors -(defn errors - "A error handling interceptor." - [handler-fn] - {:error - (fn [data] - (let [request (:request data) - error (:error data) - response (handler-fn error request)] - (-> data - (assoc :response response) - (dissoc :error))))}) +(defn- wrap-errors + [handler on-error] + (fn [request] + (-> (p/do! (handler request)) + (p/catch (fn [error] + (on-error error request)))))) + +(def errors + {:name ::errors + :compile (constantly wrap-errors)}) + ;; --- CORS @@ -140,8 +158,8 @@ ::expose-headers ::max-age])) -(defn cors - [opts] +(defn wrap-cors + [handler opts] (s/assert ::cors-opts opts) (letfn [(preflight? [{:keys [method headers] :as ctx}] (and (= method :options) @@ -184,19 +202,16 @@ (:allow-headers opts) (assoc "access-control-allow-headers" (-> (normalize (:allow-headers opts)) - (str/lower-case)))))) + (str/lower-case))))))] + (fn [request] + (if (preflight? request) + {:status 204 :headers (get-headers request)} + (-> (p/do! (handler request)) + (p/then (fn [response] + (if (map? response) + (update response :headers merge (get-headers request)) + response)))))))) - (enter [data] - (let [ctx (:request data)] - (if (preflight? ctx) - (spx/terminate (assoc data ::preflight true)) - data))) - - (leave [data] - (let [headers (get-headers (:request data))] - (if (::preflight data) - (assoc data :response {:status 204 :headers headers}) - (update-in data [:response :headers] merge headers))))] - - {:enter enter - :leave leave})) +(def cors + {:name ::cors + :compile (constantly wrap-cors)}) diff --git a/backend/vendor/vertx/test/user.clj b/backend/vendor/vertx/test/user.clj index ff556433c..8878ac639 100644 --- a/backend/vendor/vertx/test/user.clj +++ b/backend/vendor/vertx/test/user.clj @@ -12,8 +12,7 @@ [vertx.core :as vc] [vertx.eventbus :as ve] [vertx.http :as vh] - [vertx.web :as vw] - [vertx.web.interceptors :as vwi]) + [vertx.web :as vw]) (:import io.vertx.core.http.HttpServerRequest io.vertx.core.http.HttpServerResponse))