mirror of
https://github.com/penpot/penpot.git
synced 2025-05-18 15:06:11 +02:00
🐛 Fix issues on rlimit module
This commit is contained in:
parent
d98fd76032
commit
73658c47f3
1 changed files with 69 additions and 53 deletions
|
@ -182,78 +182,94 @@
|
||||||
(assoc ::lresult/remaining remaining)
|
(assoc ::lresult/remaining remaining)
|
||||||
(assoc ::lresult/reset (dt/plus ts {unit 1})))))))))
|
(assoc ::lresult/reset (dt/plus ts {unit 1})))))))))
|
||||||
|
|
||||||
(defn- process-limits
|
(defn- process-limits!
|
||||||
[redis user-id limits now]
|
[redis user-id limits now]
|
||||||
(-> (p/all (map (partial process-limit redis user-id now) limits))
|
(->> (p/all (map (partial process-limit redis user-id now) limits))
|
||||||
(p/then (fn [results]
|
(p/fmap (fn [results]
|
||||||
(let [remaining (->> results
|
(let [remaining (->> results
|
||||||
(d/index-by ::name ::lresult/remaining)
|
(d/index-by ::name ::lresult/remaining)
|
||||||
(uri/map->query-string))
|
(uri/map->query-string))
|
||||||
reset (->> results
|
reset (->> results
|
||||||
(d/index-by ::name (comp dt/->seconds ::lresult/reset))
|
(d/index-by ::name (comp dt/->seconds ::lresult/reset))
|
||||||
(uri/map->query-string))
|
(uri/map->query-string))
|
||||||
rejected (->> results
|
rejected (->> results
|
||||||
(filter (complement ::lresult/allowed?))
|
(filter (complement ::lresult/allowed?))
|
||||||
(first))]
|
(first))]
|
||||||
|
|
||||||
(when rejected
|
(when rejected
|
||||||
(l/warn :hint "rejected rate limit"
|
(l/warn :hint "rejected rate limit"
|
||||||
:user-id (str user-id)
|
:user-id (str user-id)
|
||||||
:limit-service (-> rejected ::service name)
|
:limit-service (-> rejected ::service name)
|
||||||
:limit-name (-> rejected ::name name)
|
:limit-name (-> rejected ::name name)
|
||||||
:limit-strategy (-> rejected ::strategy name)))
|
:limit-strategy (-> rejected ::strategy name)))
|
||||||
|
|
||||||
{:enabled? true
|
{:enabled? true
|
||||||
:allowed? (not (some? rejected))
|
:allowed? (not (some? rejected))
|
||||||
:headers {"x-rate-limit-remaining" remaining
|
:headers {"x-rate-limit-remaining" remaining
|
||||||
"x-rate-limit-reset" reset}})))))
|
"x-rate-limit-reset" reset}})))))
|
||||||
|
|
||||||
(defn- handle-response
|
(defn- handle-response
|
||||||
[f cfg params result]
|
[f cfg params result]
|
||||||
(if (:enabled? result)
|
(if (:enabled? result)
|
||||||
(let [headers (:headers result)]
|
(let [headers (:headers result)]
|
||||||
(when-not (:allowed? result)
|
(if (:allowed? result)
|
||||||
(ex/raise :type :rate-limit
|
(->> (f cfg params)
|
||||||
:code :request-blocked
|
(p/fmap (fn [response]
|
||||||
:hint "rate limit reached"
|
(vary-meta response update ::http/headers merge headers))))
|
||||||
::http/headers headers))
|
(p/rejected
|
||||||
(-> (f cfg params)
|
(ex/error :type :rate-limit
|
||||||
(p/then (fn [response]
|
:code :request-blocked
|
||||||
(vary-meta response update ::http/headers merge headers)))))
|
:hint "rate limit reached"
|
||||||
|
::http/headers headers))))
|
||||||
(f cfg params)))
|
(f cfg params)))
|
||||||
|
|
||||||
|
(defn- get-limits
|
||||||
|
[state skey sname]
|
||||||
|
(some->> (or (get-in @state [::limits skey])
|
||||||
|
(get-in @state [::limits :default]))
|
||||||
|
(map #(assoc % ::service sname))
|
||||||
|
(seq)))
|
||||||
|
|
||||||
|
(defn- get-uid
|
||||||
|
[{:keys [::http/request] :as params}]
|
||||||
|
(or (::rpc/profile-id params)
|
||||||
|
(some-> request parse-client-ip)
|
||||||
|
uuid/zero))
|
||||||
|
|
||||||
(defn wrap
|
(defn wrap
|
||||||
[{:keys [rlimit redis] :as cfg} f mdata]
|
[{:keys [rlimit redis] :as cfg} f mdata]
|
||||||
(if rlimit
|
(if rlimit
|
||||||
(let [skey (keyword (::rpc/type cfg) (->> mdata ::sv/spec name))
|
(let [skey (keyword (::rpc/type cfg) (->> mdata ::sv/spec name))
|
||||||
sname (str (::rpc/type cfg) "." (->> mdata ::sv/spec name))]
|
sname (str (::rpc/type cfg) "." (->> mdata ::sv/spec name))]
|
||||||
(fn [cfg {:keys [::http/request] :as params}]
|
|
||||||
(let [uid (or (:profile-id params)
|
|
||||||
(some-> request parse-client-ip)
|
|
||||||
uuid/zero)
|
|
||||||
|
|
||||||
rsp (when (and uid @enabled?)
|
(fn [cfg params]
|
||||||
(when-let [limits (or (get-in @rlimit [::limits skey])
|
(if @enabled?
|
||||||
(get-in @rlimit [::limits :default]))]
|
(try
|
||||||
(let [redis (redis/get-or-connect redis ::rlimit default-options)
|
(let [uid (get-uid params)
|
||||||
limits (map #(assoc % ::service sname) limits)
|
rsp (when-let [limits (get-limits rlimit skey sname)]
|
||||||
resp (-> (process-limits redis uid limits (dt/now))
|
(let [redis (redis/get-or-connect redis ::rpc/rlimit default-options)
|
||||||
(p/catch (fn [cause]
|
rsp (->> (process-limits! redis uid limits (dt/now))
|
||||||
;; If we have an error on processing the rate-limit we just skip
|
(p/merr (fn [cause]
|
||||||
;; it for do not cause service interruption because of redis
|
;; If we have an error on processing the rate-limit we just skip
|
||||||
;; downtime or similar situation.
|
;; it for do not cause service interruption because of redis
|
||||||
(l/error :hint "error on processing rate-limit" :cause cause)
|
;; downtime or similar situation.
|
||||||
{:enabled? false})))]
|
(l/error :hint "error on processing rate-limit" :cause cause)
|
||||||
|
(p/resolved {:enabled? false}))))]
|
||||||
|
|
||||||
;; If soft rate are enabled, we process the rate-limit but return unprotected
|
;; If soft rate are enabled, we process the rate-limit but return unprotected
|
||||||
;; response.
|
;; response.
|
||||||
(if (contains? cf/flags :soft-rpc-rlimit)
|
(if (contains? cf/flags :soft-rpc-rlimit)
|
||||||
(p/resolved {:enabled? false})
|
{:enabled? false}
|
||||||
resp))))
|
rsp)))]
|
||||||
|
|
||||||
rsp (or rsp (p/resolved {:enabled? false}))]
|
(->> (p/promise rsp)
|
||||||
|
(p/fmap #(or % {:enabled? false}))
|
||||||
|
(p/mcat #(handle-response f cfg params %))))
|
||||||
|
|
||||||
(p/then rsp (partial handle-response f cfg params)))))
|
(catch Throwable cause
|
||||||
|
(p/rejected cause)))
|
||||||
|
|
||||||
|
(f cfg params))))
|
||||||
f))
|
f))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue