Reputation: 10363
I need to understand the file uploading process with Snap.
Given this form:
<form id="form" action="/files/upload" method="POST" enctype="multipart/form-data">
<input type="file" id="files" name="files[]" multiple />
<button type="submit" onclick="handleFiles(e)">Upload</button>
</form>
Do I use the same functions like getPostParams to process binary files or do I use functions from Snap.Util.FileUploads?
I need to upload and save binary files like PDF in the database. The database driver will accept a ByteString to store a binary file.
I went through the Snap.Util.FileUploads but it does not look like it is what I need. So I am not sure how to process this in the handler?
Thanks.
EDIT
With some help from IRC I managed to come up with the below construct. I think it should be close to correct?? Well, it compiles and dumps the file to mongodb. I can also read it back. Although I don't quite understand the enumerators and Iteratee stuff ...
handleFiles :: AppHandler ()
handleFiles = do
[file] <- handleMultipart defaultUploadPolicy $ \part -> do
content <- liftM BS.concat EL.consume
return content
let b = ["file" =: Binary file]
r <- eitherWithDB $ insert "tests" b
either (error . show) (const $ return () ) r
Upvotes: 2
Views: 490
Reputation: 7272
Use Snap.Util.FileUploads. It's quite tricky to get file uploading right without leaving yourself open to security vulnerabilities. That FileUploads module has been carefully designed with this in mind.
The docs describe handleFileUploads
pretty well. It "reads uploaded files into a temporary directory and calls a user handler to process them." You supply it with a handler with the type:
[(PartInfo, Either PolicyViolationException FilePath)] -> m a
handleFileUploads
stores all the incoming files on disk subject to the policy you specify. Then it calls your handler and passes it the list of files handled.
Upvotes: 4