Misc Ring middleware. | (ns metabase.server.middleware.misc (:require [clojure.string :as str] [metabase.async.streaming-response] [metabase.db :as mdb] [metabase.public-settings :as public-settings] [metabase.request.core :as request] [metabase.util.log :as log]) (:import (clojure.core.async.impl.channels ManyToManyChannel) (metabase.async.streaming_response StreamingResponse))) |
(comment metabase.async.streaming-response/keep-me) | |
(defn- add-content-type* [{:keys [body], {:strs [Content-Type]} :headers, :as response}] (cond-> response (not Content-Type) (assoc-in [:headers "Content-Type"] (if (string? body) "text/plain" "application/json; charset=utf-8")))) | |
Add an appropriate Content-Type header to response if it doesn't already have one. Most responses should already have one, so this is a fallback for ones that for one reason or another do not. | (defn add-content-type [handler] (fn [request respond raise] (handler request (if-not (request/api-call? request) respond (comp respond add-content-type*)) raise))) |
------------------------------------------------ SETTING SITE-URL ------------------------------------------------ | |
It's important for us to know what the site URL is for things like returning links, etc. this is stored in the
Effectively the very first API request that gets sent to us (usually some sort of setup request) ends up setting
the (initial) value of | (defn- maybe-set-site-url* [{{:strs [origin x-forwarded-host host user-agent]} :headers, uri :uri}] (when (and (mdb/db-is-set-up?) (not (public-settings/site-url)) (not= uri "/api/health") (or (nil? user-agent) ((complement str/includes?) user-agent "HealthChecker"))) (when-let [site-url (or origin x-forwarded-host host)] (log/infof "Setting Metabase site URL to %s" site-url) (try (public-settings/site-url! site-url) (catch Throwable e (log/warn e "Failed to set site-url")))))) |
Middleware to set the | (defn maybe-set-site-url [handler] (fn [request respond raise] (maybe-set-site-url* request) (handler request respond raise))) |
------------------------------------------ Disable Streaming Buffering ------------------------------------------- | |
(defn- maybe-add-disable-buffering-header [{:keys [body], :as response}] (cond-> response (or (instance? StreamingResponse body) (instance? ManyToManyChannel body)) (assoc-in [:headers "X-Accel-Buffering"] "no"))) | |
Tell nginx not to batch streaming responses -- otherwise load balancers are liable to cancel our request prematurely if they aren't configured for longer timeouts. See https://nginx.org/en/docs/http/ngxhttpproxymodule.html#proxycache | (defn disable-streaming-buffering [handler] (fn [request respond raise] (handler request (comp respond maybe-add-disable-buffering-header) raise))) |
-------------------------------------------------- Bind request -------------------------------------------------- | |
Ring middleware that binds | (defn bind-request [handler] (fn [request respond raise] (request/with-current-request request (handler request respond raise)))) |