Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow overriding of the file name in multi part uploads #617

Open
wants to merge 1 commit into
base: 3.x
Choose a base branch
from

Conversation

ahammel
Copy link

@ahammel ahammel commented Jul 19, 2022

The Problem

I have to interact with a hateful API which expects a file uploaded as part of a multi-part field, where both the multi-part field and the file name have to be a specific value:

(let [file (io/file "foo.txt")]
  (client/post "https://hateful.io"
               {:multipart [{:name "special-snowflake", :content file}]}))
;; => 200

(let [file (io/file "foo.txt")]
  (client/post "https://hateful.io"
               {:multipart [{:name "something-else", :content file}]}))
;; => 400 "Expected multi-part field "special-snowflake" but didn't find it"

(let [file (io/file "foo.txt")
      other-file (io/file "bar.txt")]
  (io/copy file other-file)
  (client/post "https://hateful.io"
               {:multipart [{:name "special-snowflake", :content other-file}]}))
;; => 400 Expected file in the "special-snowflake" field to be called "foo.txt"

This is inconvenient in a server context, because I cannot safely use java.io.File/createTempFile, because it dynamically generates file names in order to avoid race conditions.

What I did instead

Something sad:

(defn- with-name-override
  [file file-name]
  (with-meta {:file file, :name file-name} {:type :file-with-name-override}))

(defmethod make-multipart-body :file-with-name-override
  [{:keys [name content]}]
  (if (and name content)
    (FileBody. (:file content)
               ContentType/APPLICATION_OCTET_STREAM
               (:name file-name))
    (throw
      (Exception.
        "Multipart :file-with-name-override must contain :name and :content"))))

(let [file (io/file "foo.txt")
      temp-file (with-name-override (File/createTempFile "foo" ".txt")
                                     "foo.txt")]
  (io/copy file (:file temp-file))
  (client/post "https://hateful.io"
               {:multipart [{:name "special-snowflake", :content temp-file}]}))

Proposed Enhancement

Allow a :file-name key in multipart field arguments, which overrides the name of the file if specified.

@ahammel ahammel changed the title Allow overriding of the file name Allow overriding of the file name in multi part uploads Jul 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant