mongodb - How can I stream GridFS files to web clients in Clojure/Monger? -
i have web app using clojure, clojurescript, , monger. documents uploaded , stored in mongo via gridfs. same files can requested download; @ moment accomplished writing file (the server's) disk , serving static file, awkward; how can serve file represented gridfs object directly in clojure/java? routing handled ring/compojure.
it turns out ring/compojure infrastructure used in luminus able return output-streams, allowing easy transmission of files without touching drive.
(ns my-app.routes.updown "file uploading , insertion database" (:use compojure.core) (:require [my-app.db.core :as db] ;; db functions see here wrappers monger functions you'd expect [ring.util.response :as r] [ring.util.io :as io])) (defn make-file-stream "takes input stream--such mongodbobject stream--and streams it" [file] (io/piped-input-stream (fn [output-stream] (.writeto file output-stream)))) (defn download-file-by-id "downloads requested file, if privileges allowed" [id-string] (let [mongo-file (db/find-file-by-id id-string) file-map (db/map-from-mongo-obj mongo-file) content-type (-> file-map :metadata :contenttype) file-name (-> file-map :filename)] (-> mongo-file make-file-stream r/response (#(r/header % "content-disposition" ; right default file-name (str "attachment; filename=\"" file-name "\""))) (#(r/header % "content-type" content-type))))) ; final wrapper: offer right "open with" dialogue ;; called main routes def so: ;; (notice no wrappers needed, wrapping took place in download-file-by-id) ;; (defroutes home-routes ;; (get "/files/:id-string" [id-string] ;; (up/download-file-by-id id-string)))
Comments
Post a Comment