grape
grape copied to clipboard
Content type validation
Hey folks!
I just implemented a custom content type validator here and I wonder whether you think it is worth to add to grape, it seems legit to me given its short implementation.
The api looks like:
params do
requires :file, type: File, content_type: ["text/plain", "application/csv"]
end
I would be happy to send a PR if so.
Thanks.
Definitely!
My first implementation was using MIME::Types.type_for("file.ext").first.content_type
but I found out this method figures the content type out through the file extension, which is not much reliable (unless we check both content type and extension maybe). It would add a dependency to grape as well. Ex:
params do
requires :file, type: File, content_type: ["text/plain", "application/csv"], extension: :csv
end
I ended up changing to use file --mime -b file.ext
, but it seems not to work on Windows (for my project is ok, but not to grape likely).
Any recommendation?
As far as Grape is concerned what we want is to ensure that the request carries the right content-type in the headers, that's all. It's the parser's/consumer's job to ensure that the contents actually are plain text, CSV, etc.
Given
params do
requires :file, type: File
end
If I send a jpg file with the csv extension, I receive a mistaken content type (type
key) from the browser like:
{
"file" => {
"filename" => "IMG_20180512_094654650.csv",
"type" => "text/csv",
"name" => "file",
"tempfile" => #<Tempfile:/var/folders/9k/vvnb2hnn15scm131t157j_4c0000gn/T/RackMultipart20180813-13774-1vn5s0o.csv>,
"head" => "Content-Disposition: form-data; name=\"file\"; filename=\"IMG_20180512_094654650.csv\"\r\nContent-Type: text/csv\r\n"
}
}
Even so, you think we should check just the type
key?
I think the browser "sees" that this file is not a CSV by examining some local file system attribute, but the server can't without parsing the file. We can add validators for formats (parsers) of course, too.
@glaucocustodio Any progress on this one? This is a nice-to-have feature. Thanks for proposing 👍