mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
157 lines
5.5 KiB
Clojure
157 lines
5.5 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
|
;; defined by the Mozilla Public License, v. 2.0.
|
|
;;
|
|
;; Copyright (c) 2020-2021 UXBOX Labs SL
|
|
|
|
(ns app.http
|
|
(:require
|
|
[app.common.data :as d]
|
|
[app.common.spec :as us]
|
|
[app.config :as cfg]
|
|
[app.http.auth :as auth]
|
|
[app.http.errors :as errors]
|
|
[app.http.middleware :as middleware]
|
|
[app.metrics :as mtx]
|
|
[clojure.spec.alpha :as s]
|
|
[clojure.tools.logging :as log]
|
|
[integrant.core :as ig]
|
|
[reitit.ring :as rr]
|
|
[ring.adapter.jetty9 :as jetty])
|
|
(:import
|
|
org.eclipse.jetty.server.Server
|
|
org.eclipse.jetty.server.handler.ErrorHandler
|
|
org.eclipse.jetty.server.handler.StatisticsHandler))
|
|
|
|
(s/def ::handler fn?)
|
|
(s/def ::ws (s/map-of ::us/string fn?))
|
|
(s/def ::port ::cfg/http-server-port)
|
|
(s/def ::name ::us/string)
|
|
|
|
(defmethod ig/pre-init-spec ::server [_]
|
|
(s/keys :req-un [::handler ::port]
|
|
:opt-un [::ws ::name ::mtx/metrics]))
|
|
|
|
(defmethod ig/prep-key ::server
|
|
[_ cfg]
|
|
(merge {:name "http"}
|
|
(d/without-nils cfg)))
|
|
|
|
(defmethod ig/init-key ::server
|
|
[_ {:keys [handler ws port name metrics] :as opts}]
|
|
(log/infof "Starting %s server on port %s." name port)
|
|
(let [pre-start (fn [^Server server]
|
|
(let [handler (doto (ErrorHandler.)
|
|
(.setShowStacks true)
|
|
(.setServer server))]
|
|
(.setErrorHandler server ^ErrorHandler handler)
|
|
(when metrics
|
|
(let [stats (new StatisticsHandler)]
|
|
(.setHandler ^StatisticsHandler stats (.getHandler server))
|
|
(.setHandler server stats)
|
|
(mtx/instrument-jetty! (:registry metrics) stats)))))
|
|
|
|
options (merge
|
|
{:port port
|
|
:h2c? true
|
|
:join? false
|
|
:allow-null-path-info true
|
|
:configurator pre-start}
|
|
(when (seq ws)
|
|
{:websockets ws}))
|
|
|
|
server (jetty/run-jetty handler options)]
|
|
(assoc opts :server server)))
|
|
|
|
(defmethod ig/halt-key! ::server
|
|
[_ {:keys [server name port] :as opts}]
|
|
(log/infof "Stoping %s server on port %s." name port)
|
|
(jetty/stop-server server))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Http Main Handler (Router)
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(declare create-router)
|
|
|
|
(s/def ::rpc map?)
|
|
(s/def ::session map?)
|
|
(s/def ::metrics map?)
|
|
(s/def ::google-auth map?)
|
|
(s/def ::gitlab-auth map?)
|
|
(s/def ::ldap-auth fn?)
|
|
(s/def ::storage map?)
|
|
(s/def ::assets map?)
|
|
|
|
(defmethod ig/pre-init-spec ::router [_]
|
|
(s/keys :req-un [::rpc ::session ::metrics ::google-auth ::gitlab-auth ::storage ::assets]))
|
|
|
|
(defmethod ig/init-key ::router
|
|
[_ cfg]
|
|
(let [handler (rr/ring-handler
|
|
(create-router cfg)
|
|
(rr/routes
|
|
(rr/create-resource-handler {:path "/"})
|
|
(rr/create-default-handler))
|
|
{:middleware [middleware/server-timing]})]
|
|
(fn [request]
|
|
(try
|
|
(handler request)
|
|
(catch Throwable e
|
|
(try
|
|
(let [cdata (errors/get-error-context request e)]
|
|
(errors/update-thread-context! cdata)
|
|
(log/errorf e "Unhandled exception: %s (id: %s)" (ex-message e) (str (:id cdata)))
|
|
{:status 500
|
|
:body "internal server error"})
|
|
(catch Throwable e
|
|
(log/errorf e "Unhandled exception: %s" (ex-message e))
|
|
{:status 500
|
|
:body "internal server error"})))))))
|
|
|
|
(defn- create-router
|
|
[{:keys [session rpc google-auth gitlab-auth github-auth metrics ldap-auth svgparse assets] :as cfg}]
|
|
(rr/router
|
|
[["/metrics" {:get (:handler metrics)}]
|
|
|
|
["/assets" {:middleware [[middleware/format-response-body]
|
|
[middleware/errors errors/handle]]}
|
|
["/by-id/:id" {:get (:objects-handler assets)}]
|
|
["/by-file-media-id/:id" {:get (:file-objects-handler assets)}]
|
|
["/by-file-media-id/:id/thumbnail" {:get (:file-thumbnails-handler assets)}]]
|
|
|
|
["/dbg"
|
|
["/error-by-id/:id" {:get (:error-report-handler cfg)}]]
|
|
|
|
["/api" {:middleware [[middleware/format-response-body]
|
|
[middleware/params]
|
|
[middleware/multipart-params]
|
|
[middleware/keyword-params]
|
|
[middleware/parse-request-body]
|
|
[middleware/errors errors/handle]
|
|
[middleware/cookies]]}
|
|
|
|
["/svg" {:post svgparse}]
|
|
|
|
["/oauth"
|
|
["/google" {:post (:auth-handler google-auth)}]
|
|
["/google/callback" {:get (:callback-handler google-auth)}]
|
|
|
|
["/gitlab" {:post (:auth-handler gitlab-auth)}]
|
|
["/gitlab/callback" {:get (:callback-handler gitlab-auth)}]
|
|
|
|
["/github" {:post (:auth-handler github-auth)}]
|
|
["/github/callback" {:get (:callback-handler github-auth)}]]
|
|
|
|
["/login" {:post #(auth/login-handler cfg %)}]
|
|
["/logout" {:post #(auth/logout-handler cfg %)}]
|
|
|
|
["/login-ldap" {:post ldap-auth}]
|
|
|
|
["/rpc" {:middleware [(:middleware session)]}
|
|
["/query/:type" {:get (:query-handler rpc)}]
|
|
["/mutation/:type" {:post (:mutation-handler rpc)}]]]]))
|