Note that there are some explanatory texts on larger screens.

plurals
  1. POEfficient large file upload with Yesod
    primarykey
    data
    text
    <p>I want to implement large file upload with my Yesod application. Right now I have:</p> <pre><code>module Handler.File where import Import import System.Random import System.FilePath import Control.Monad import qualified Data.ByteString.Lazy as LBS import qualified Data.Text.Encoding -- upload uploadDirectory :: FilePath -- FIXME: make this configurable uploadDirectory = "incoming" randomFileName :: IO FilePath randomFileName = do fname'base &lt;- replicateM 20 (randomRIO ('a','z')) let fname = uploadDirectory &lt;/&gt; fname'base &lt;.&gt; "bin" return fname fileUploadForm :: Form (FileInfo, Textarea) fileUploadForm = renderDivs $ (,) &lt;$&gt; fileAFormReq "Choose a file" &lt;*&gt; areq textareaField "What's on the file?" Nothing getFileNewR :: Handler RepHtml getFileNewR = do (formWidget, formEnctype) &lt;- generateFormPost fileUploadForm defaultLayout $ do setTitle "Upload new file." $(widgetFile "file-new") postFileNewR :: Handler RepHtml postFileNewR = do user &lt;- requireAuth ((result, formWidget), formEnctype) &lt;- runFormPost fileUploadForm case result of FormSuccess (fi,info) -&gt; do fn &lt;- liftIO randomFileName liftIO (LBS.writeFile fn (fileContent fi)) let newFile = File (entityKey user) fn info (fileName fi) (fileContentType fi) fid &lt;- runDB $ insert newFile redirect (FileViewR fid) _ -&gt; return () defaultLayout $ do setTitle "Upload new file." $(widgetFile "file-new") </code></pre> <p>It is mostly fine, except few issues:</p> <ol> <li><p>Maximum size of a file is around 2 megabytes. I have a fix, but is it right way to do this? My fix is overriding default implementation of maximumContentLength method in Yesod instance for my app, like this:</p> <p>maximumContentLength _ (Just (FileNewR _)) = 2 * 1024 * 1024 * 1024 -- 2 gigabytes maximumContentLength _ _ = 2 * 1024 * 1024 -- 2 megabytes</p></li> <li><p>The amount of memory used is equal to the size of a file. This is really suboptimal. I would like to use tempFileBackEnd from <a href="http://hackage.haskell.org/packages/archive/wai-extra/1.2.0.4/doc/html/Network-Wai-Parse.html" rel="noreferrer">http://hackage.haskell.org/packages/archive/wai-extra/1.2.0.4/doc/html/Network-Wai-Parse.html</a> but I have no idea how to actually wire that into my request and make it work with forms logic (hidden _token field etc.).</p></li> <li><p>The upload is 'single shot': any examples of how to make it work with Flash/Html5 based uploaders that show progress to user?</p></li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload