ring-clojure / ring

Clojure HTTP server abstraction
MIT License
3.73k stars 518 forks source link

wrap-multipart-params creates an empty file when an empty file input is submitted #502

Closed rutchkiwi closed 3 months ago

rutchkiwi commented 3 months ago

When you have an HTML form with enctype="multipart/form-data" and a file input, then submit the form without any files, wrap-multipart-params still creates a file of 0 length:

"image" {:filename "",
                             :content-type "application/octet-stream",
                             :tempfile #object[java.io.File
                                               0x2a85b8fb
                                               "/var/folders/hk/ssb3bsh12bs8l3pd4wct1_0m0000gn/T/ring-multipart-12791286223966256629.tmp"],
                             :size 0},

I was expecting this to be nil in the case of no file being uploaded, not an empty file. Seems somewhat reasonable but it is annoying to handle in code, as now I need to be extra carefull and check the size before I access the file. Would you be open to a PR changing this behaviour to give you :image nil instead?

weavejester commented 3 months ago

Is there a way of reliably determining, for all browsers, whether the file has been omitted from the input, or whether a zero-byte file has been submitted?

rutchkiwi commented 3 months ago

Hadn't thought about that, but it looks like that can be determined from the filename:

-----------------------------264040574727381079401146929549
Content-Disposition: form-data; name="image"; filename="zerobytes.png"
Content-Type: image/png

-----------------------------264040574727381079401146929549

VS

-----------------------------6155252271109589944108876070
Content-Disposition: form-data; name="image"; filename=""
Content-Type: application/octet-stream

-----------------------------6155252271109589944108876070

This behaviour is the same for Firefox, Chrome and Safari.

But going into the nitty grittys, I can't find a canonical reference for how you can determine this. RFC2388 seems to say the filename is optional.

So I'd suggest to only nil it when the filename is empty?

weavejester commented 3 months ago

I suspect there isn't a foolproof way of determining this, so I think the current behavior of Ring will have to remain. However, what you could do is to make some additional middleware in your project to update zero-byte files to nil responses.

rutchkiwi commented 3 months ago

ok thats fair! just wasted an hour on this, so thought i would ask about it to save someone else the time. But you're likely right in that it cant be 100% accurately determined.

Thanks for the quick reply!