I have a Ring handler that should:
- Burn multiple files
- Zip stream for the client.
Now I have such work, but only the first record in zipped becomes streaming, and after that it stops / stops. I feel this has something to do with flushing / streaming, which is wrong.
Here is my handler (compojure):
(GET "/zip" {:as request} :query-params [order-id :- s/Any] (stream-lessons-zip (read-string order-id) (:db request) (:auth-user request)))
Here is the stream-lessons-zip function:
(defn stream-lessons-zip [] (let [lessons ...];... not shown {:status 200 :headers {"Content-Type" "application/zip, application/octet-stream" "Content-Disposition" (str "attachment; filename=\"files.zip\"") :body (futil/zip-lessons lessons)}))
And I use streamed-stream-stream to stream like this:
(defn zip-lessons "Returns an inputstream (piped-input-stream) to be used directly in Ring HTTP responses" [lessons] (let [paths (map #(select-keys % [:file_path :file_name]) lessons)] (ring-io/piped-input-stream (fn [output-stream] ; build a zip-output-stream from a normal output-stream (with-open [zip-output-stream (ZipOutputStream. output-stream)] (doseq [{:keys [file_path file_name] :as p} paths] (let [f (cio/file file_path)] (.putNextEntry zip-output-stream (ZipEntry. file_name)) (cio/copy f zip-output-stream) (.closeEntry zip-output-stream))))))))
So, I confirmed that the vector "lessons" contains as 4 entries, but the zip file contains only 1 entry. In addition, Chrome does not seem to βcompleteβ the download, i.e. he thinks he is still loading.
How can i fix this?
stream clojure zip ring
Marten sytema
source share