parent
8d92817e15
commit
5c7f71b368
@ -1,24 +0,0 @@
|
|||||||
.devbar {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
font-family: monospace;
|
|
||||||
background-color: #ccc;
|
|
||||||
|
|
||||||
ol {
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
li {
|
|
||||||
padding: .5rem;
|
|
||||||
border: 1px solid black;
|
|
||||||
margin: .5rem;
|
|
||||||
|
|
||||||
pre {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
(ns wanijo.infrastructure.devmode
|
|
||||||
(:require [hiccup.core :as hcore]
|
|
||||||
[clojure.string :as cljs]))
|
|
||||||
|
|
||||||
(def bar-entries (atom []))
|
|
||||||
|
|
||||||
(defn send-to-bar [msg]
|
|
||||||
(swap! bar-entries #(conj % msg)))
|
|
||||||
|
|
||||||
(defn devmode-on? [req]
|
|
||||||
(let [query-param (get-in req [:query-params "dev"])
|
|
||||||
cookie (get-in req [:cookies "devmode" :value])]
|
|
||||||
(or (= query-param "on")
|
|
||||||
(and (= cookie "1")
|
|
||||||
(not= query-param "off")))))
|
|
||||||
|
|
||||||
(defn devbar [resp]
|
|
||||||
(hcore/html
|
|
||||||
[:section.devbar
|
|
||||||
[:ol
|
|
||||||
(for [entry @bar-entries]
|
|
||||||
[:li [:pre entry]])]]))
|
|
||||||
|
|
||||||
(defn append-devbar [resp]
|
|
||||||
(let [body (:body resp)
|
|
||||||
new-body (cljs/replace
|
|
||||||
body "</body>" (str (devbar resp) "</body>"))]
|
|
||||||
(assoc resp :body new-body)))
|
|
||||||
|
|
||||||
(defn wrap-devmode [handler]
|
|
||||||
(fn [req]
|
|
||||||
(let [on? (devmode-on? req)
|
|
||||||
query-param? (get-in req [:query-params "dev"])
|
|
||||||
new-req (assoc-in req [:session :devmode] on?)
|
|
||||||
resp (handler new-req)
|
|
||||||
new-resp (cond
|
|
||||||
on? (-> resp
|
|
||||||
append-devbar
|
|
||||||
(assoc-in [:cookies :devmode] 1))
|
|
||||||
(some? query-param?) (assoc-in
|
|
||||||
resp
|
|
||||||
[:cookies :devmode]
|
|
||||||
(if on? 1 0))
|
|
||||||
:else resp)]
|
|
||||||
(reset! bar-entries [])
|
|
||||||
new-resp)))
|
|
@ -0,0 +1,77 @@
|
|||||||
|
(ns wanijo.infrastructure.gzip
|
||||||
|
(:require [clojure.java.io :as io])
|
||||||
|
(:import (java.io InputStream
|
||||||
|
Closeable
|
||||||
|
File
|
||||||
|
PipedInputStream
|
||||||
|
PipedOutputStream)
|
||||||
|
(java.util.zip GZIPOutputStream)))
|
||||||
|
|
||||||
|
(defn set-response-headers
|
||||||
|
[headers]
|
||||||
|
(if-let [vary (or (get headers "vary") (get headers "Vary"))]
|
||||||
|
(-> headers
|
||||||
|
(assoc "Vary" (str vary ", Accept-Encoding"))
|
||||||
|
(assoc "Content-Encoding" "gzip")
|
||||||
|
(dissoc "Content-Length" "content-length")
|
||||||
|
(dissoc "vary"))
|
||||||
|
(-> headers
|
||||||
|
(assoc "Vary" "Accept-Encoding")
|
||||||
|
(assoc "Content-Encoding" "gzip")
|
||||||
|
(dissoc "Content-Length" "content-length"))))
|
||||||
|
|
||||||
|
(defn accepts-gzip?
|
||||||
|
[req]
|
||||||
|
(if-let [accepts (get-in req [:headers "accept-encoding"])]
|
||||||
|
;; Be aggressive in supporting clients with mangled headers (due to
|
||||||
|
;; proxies, av software, buggy browsers, etc...)
|
||||||
|
(re-seq
|
||||||
|
#"(gzip\s*,?\s*(gzip|deflate)?|X{4,13}|~{4,13}|\-{4,13})"
|
||||||
|
accepts)))
|
||||||
|
|
||||||
|
(defn supported-response? [resp]
|
||||||
|
(let [{:keys [status headers body]} resp
|
||||||
|
min-bytes 859]
|
||||||
|
(and
|
||||||
|
;; correct status code
|
||||||
|
(#{200 201 202 203 204 205 403 404} status)
|
||||||
|
;; not already encoded
|
||||||
|
(not (or (headers "Content-Encoding")
|
||||||
|
(headers "content-encoding")))
|
||||||
|
;; correct data type in body
|
||||||
|
(or (string? body)
|
||||||
|
(seq? body)
|
||||||
|
(instance? InputStream body)
|
||||||
|
(and (instance? File body)
|
||||||
|
(re-seq #"(?i)\.(htm|html|css|js|json|xml)"
|
||||||
|
(pr-str body))))
|
||||||
|
;; sensible body sizes
|
||||||
|
(cond (string? body) (> (count body) min-bytes)
|
||||||
|
(seq? body) (> (count body) min-bytes)
|
||||||
|
(instance? File body) (> (.length body) min-bytes)
|
||||||
|
:else true))))
|
||||||
|
|
||||||
|
(defn compress-body [body]
|
||||||
|
(let [p-in (PipedInputStream.)
|
||||||
|
p-out (PipedOutputStream. p-in)]
|
||||||
|
(future
|
||||||
|
(with-open [out (GZIPOutputStream. p-out)]
|
||||||
|
(if (seq? body)
|
||||||
|
(doseq [string body] (io/copy (str string) out))
|
||||||
|
(io/copy body out)))
|
||||||
|
(when (instance? Closeable body)
|
||||||
|
(.close ^Closeable body)))
|
||||||
|
p-in))
|
||||||
|
|
||||||
|
(defn gzip-response [resp]
|
||||||
|
(-> resp
|
||||||
|
(update :headers set-response-headers)
|
||||||
|
(update :body compress-body)))
|
||||||
|
|
||||||
|
(defn wrap-gzip [handler]
|
||||||
|
(fn [req]
|
||||||
|
(let [resp (handler req)]
|
||||||
|
(if (and (accepts-gzip? req)
|
||||||
|
(supported-response? resp))
|
||||||
|
(gzip-response resp)
|
||||||
|
resp))))
|
Loading…
Reference in new issue