From b40c0325abd6a0952948dd266d7409af557fc0e7 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 21 Apr 2025 13:00:15 +0200 Subject: Add upload handler --- src/pics/core.clj | 7 ++++++- src/pics/handler/upload.clj | 37 +++++++++++++++++++++++++++++++++++++ src/pics/routes.clj | 11 ++++++++--- 3 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 src/pics/handler/upload.clj (limited to 'src') diff --git a/src/pics/core.clj b/src/pics/core.clj index 68826f9..82c6d4a 100644 --- a/src/pics/core.clj +++ b/src/pics/core.clj @@ -2,9 +2,14 @@ (:require [org.httpkit.server :as http-server] [pics.routes :as proutes] [dotenv :as env]) - (:gen-class)) + (:gen-class) + (:import java.io.File)) (defn -main [& args] + (let [img-folder (File. "./img/")] + (when-not (.exists img-folder) + (.mkdirs img-folder))) + (let [port (or (env/env "PORT") 8080)] (println (str "Starting server on port " port "...")) (http-server/run-server proutes/ring-handler {:port port}))) diff --git a/src/pics/handler/upload.clj b/src/pics/handler/upload.clj new file mode 100644 index 0000000..d3fa2cc --- /dev/null +++ b/src/pics/handler/upload.clj @@ -0,0 +1,37 @@ +(ns pics.handler.upload + (:require [clojure.string :as cstr] + [dotenv :as env] + [ring.util.response :as ruresp] + [clojure.java.io :as cjio])) + +(def ^:private name-chars "abcdefghijklmnopqrstuvwxyz") +(defn gen-random-name [] + (->> (map (fn [_] (rand-nth name-chars)) + (range 10)) + vec + (apply str))) + +(defn save-image [multipart-params name] + (cjio/copy (get-in multipart-params ["image" :tempfile]) + (cjio/file (str "./img/" name "." (-> multipart-params + (get-in ["image" :content-type]) + (cstr/split #"\/") + second))))) + +(defn authorized? [multipart-params] + (let [auth-keys-str (env/env "AUTH_KEYS") + auth-keys (delay (cstr/split auth-keys-str #","))] + (and (not (cstr/blank? auth-keys-str)) + (some #(= % (get multipart-params "auth-key")) @auth-keys)))) + +(defn handle [req] + (let [multipart-params (:multipart-params req) + name (gen-random-name)] + (if (authorized? multipart-params) + (do (save-image multipart-params name) + (ruresp/response (str "http://" (:server-name req) + (when (not= (:server-port req) 80) + (str ":" (:server-port req))) + "/" name))) + (-> (ruresp/response "Forbidden.") + (ruresp/status 403))))) diff --git a/src/pics/routes.clj b/src/pics/routes.clj index 67793f9..a10ab95 100644 --- a/src/pics/routes.clj +++ b/src/pics/routes.clj @@ -1,10 +1,15 @@ (ns pics.routes (:require [reitit.ring :as rring] + [ring.middleware.multipart-params :as rmmultiparams] - [pics.handler.home :as phhome])) + [pics.handler.home :as phhome] + [pics.handler.upload :as phupload])) (def ^:private router - (rring/router [["/" {:get {:handler phhome/handle}}]])) + (rring/router [["/" {:get {:handler phhome/handle}}] + ["/upload" {:post {:handler phupload/handle}}]])) (def ring-handler - (rring/ring-handler router)) + (-> router + rring/ring-handler + rmmultiparams/wrap-multipart-params)) -- cgit v1.2.3