- 
                Notifications
    You must be signed in to change notification settings 
- Fork 526
File Uploads
Uploading a file to a website requires multipart form handling, which Ring provides with its wrap-multipart-params middleware.
(wrap-multipart-params handler)
(wrap-multipart-params handler options)The options for this middleware function are:
- 
:encodingThe character encoding of the parameters. Acts the same as the same option inwrap-params.
- 
:storeA function to use to store the uploaded files. There are two stores included with Ring.
A full example:
(require '[ring.middleware.params :refer [wrap-params]]
         '[ring.middleware.multipart-params :refer [wrap-multipart-params]])
(def app
  (-> your-handler
      wrap-params
      wrap-multipart-params))Uploaded files can be found with the :multipart-params key in the response.
By default, uploads are stored in temporary files that are deleted an hour after being uploaded. This is handled by ring.middleware.multipart-params.temp-file/temp-file-store function.
For example,
curl -XPOST  "http://localhost:3000" -F [email protected]
This adds a file key to the :params map of the request where :tempfile is a java.io.File object that contains the uploaded data. You can use this to perform any further processing you want.
{...
 :params
  {"file" {:filename     "words.txt"
           :content-type "text/plain"
           :tempfile     #object[java.io.File ...]
           :size         51}}
 ...}Building on the above example, if you wanted to save the tempfile created by the Ring server to a different and/or permanent location on your server, you can use bean to get the path information for the tempfile, and a combination of io/copy and io/file to read the file and save it to that new location:
(def demo-ring-req
  {:params {"file"
            {:filename     "words.txt"}
            :content-type "text/plain"
            :tempfile     #object[java.io.File ...]
            :size         51}})
 
(defn save-file [req]
  (let [tmpfilepath (:path (bean (get-in req [:params "file" :tempfile])))
        custom-path "/your/custom/path/file.txt"]
    (io/copy (io/file tmpfilepath) (io/file custom-path))
    {:status 200
     :headers  {"Content-Type" "text/html"}
     :body (str "File now available for download at: http://localhost:3000/" custom-path)}))
(save-file demo-ring-req)