1 ------------------------------------------------------------------------------ 2 -- | This module contains primitives and helper functions for handling 3 -- requests with @Content-type: multipart/form-data@, i.e. HTML forms and file 4 -- uploads. 5 -- 6 -- Typically most users will want to use 'handleFileUploads', which writes 7 -- uploaded files to a temporary directory before sending them on to a handler 8 -- specified by the user. 9 -- 10 -- Users who wish to handle their file uploads differently can use the 11 -- lower-level interface called 'handleMultipart'. That function takes 12 -- uploaded files and streams them to a consumer of the user's choosing. 13 -- 14 -- Using these functions requires making \"policy\" decisions which Snap can't 15 -- really make for users, such as \"what's the largest PDF file a user is 16 -- allowed to upload?\" and \"should we read form inputs into the parameters 17 -- mapping?\". Policy is specified on a \"global\" basis (using 18 -- 'UploadPolicy'), and on a per-file basis (using 'PartUploadPolicy', which 19 -- allows you to reject or limit the size of certain uploaded 20 -- @Content-type@s). 21 -- 22 -- Example usage: 23 -- 24 -- @ 25 -- {-\# LANGUAGE OverloadedStrings #-} 26 -- 27 -- module Main where 28 -- 29 -- import qualified Data.ByteString.Char8 as B8 30 -- import Data.Functor ((\<$>)) 31 -- import "Snap.Core" ('Snap.Core.Snap', 'Snap.Core.route', 'Snap.Core.writeBS') 32 -- import Snap.Http.Server (quickHttpServe) 33 -- import "Snap.Util.FileUploads" 34 -- import System.Posix (FileOffset, fileSize, getFileStatus) 35 -- 36 -- uploadForm :: 'Snap.Core.Snap' () 37 -- uploadForm = 'Snap.Core.writeBS' \"\<form enctype=\\\"multipart\/form-data\\\" action=\\"\/do-upload\\\" method=\\\"POST\\\">\\ 38 -- \\\<input name=\\\"file\\\" type=\\\"file\\\" \/>\\ 39 -- \\\<input type=\\\"submit\\\" value=\\\"Send File\\\" \/>\\ 40 -- \\\<\/form>\" 41 -- 42 -- getFileSize :: FilePath -> IO FileOffset 43 -- getFileSize path = fileSize \<$> getFileStatus path 44 -- 45 -- -- Upload handler that prints out the uploaded file\'s size. 46 -- doUpload :: 'Snap.Core.Snap' () 47 -- doUpload = do 48 -- l \<- 'handleFileUploads' \"\/tmp\" 'defaultUploadPolicy' 49 -- (const $ 'allowWithMaximumSize' ('getMaximumFormInputSize' 'defaultUploadPolicy')) 50 -- (\\pinfo mbfname -> do fsize \<- either (const $ return 0) getFileSize mbfname 51 -- return ('partFileName' pinfo, fsize)) 52 -- 'writeBS' . B8.pack . show $ l 53 -- 54 -- site :: 'Snap.Core.Snap' () 55 -- site = 'Snap.Core.route' 56 -- [ (\"\/upload\", uploadForm) 57 -- , (\"\/do-upload\", doUpload)] 58 -- 59 -- main :: IO () 60 -- main = quickHttpServe site 61 -- @ 62 module Snap.Util.FileUploads 63 ( -- * Functions 64 handleFileUploads 65 , handleMultipart 66 , PartProcessor 67 68 -- * Uploaded parts 69 , PartInfo 70 , PartDisposition(..) 71 , partFieldName 72 , partFileName 73 , partContentType 74 , partHeaders 75 , partDisposition 76 77 -- ** Policy 78 -- *** General upload policy 79 , UploadPolicy 80 , defaultUploadPolicy 81 , doProcessFormInputs 82 , setProcessFormInputs 83 , getMaximumFormInputSize 84 , setMaximumFormInputSize 85 , getMaximumNumberOfFormInputs 86 , setMaximumNumberOfFormInputs 87 , getMinimumUploadRate 88 , setMinimumUploadRate 89 , getMinimumUploadSeconds 90 , setMinimumUploadSeconds 91 , getUploadTimeout 92 , setUploadTimeout 93 94 -- *** Per-file upload policy 95 , PartUploadPolicy 96 , disallow 97 , allowWithMaximumSize 98 99 -- * Exceptions 100 , FileUploadException 101 , fileUploadExceptionReason 102 , BadPartException 103 , badPartExceptionReason 104 , PolicyViolationException 105 , policyViolationExceptionReason 106 ) where 107 108 109 import Snap.Internal.Util.FileUploads (BadPartException (badPartExceptionReason), FileUploadException, PartDisposition (..), PartInfo (..), PartProcessor, PartUploadPolicy, PolicyViolationException (policyViolationExceptionReason), UploadPolicy, allowWithMaximumSize, defaultUploadPolicy, disallow, doProcessFormInputs, fileUploadExceptionReason, getMaximumFormInputSize, getMaximumNumberOfFormInputs, getMinimumUploadRate, getMinimumUploadSeconds, getUploadTimeout, handleFileUploads, handleMultipart, setMaximumFormInputSize, setMaximumNumberOfFormInputs, setMinimumUploadRate, setMinimumUploadSeconds, setProcessFormInputs, setUploadTimeout)