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