{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE InstanceSigs #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE TypeApplications #-} -- | @multipart/form-data@ support for servant. -- -- This is mostly useful for adding file upload support to -- an API. See haddocks of 'MultipartForm' for an introduction. module Servant.Multipart ( MultipartForm , MultipartData(..) , FromMultipart(..) , lookupInput , lookupFile , MultipartOptions(..) , defaultMultipartOptions , MultipartBackend(..) , Tmp , TmpBackendOptions(..) , Mem , defaultTmpBackendOptions , Input(..) , FileData(..) -- * servant-client , genBoundary , ToMultipart(..) , multipartToBody -- * servant-docs , ToMultipartSample(..) ) where import Control.Lens ((<>~), (&), view, (.~)) import Control.Monad (replicateM) import Control.Monad.IO.Class import Control.Monad.Trans.Resource import Data.Array (listArray, (!)) import Data.Foldable (foldMap, foldl') import Data.List (find) import Data.Maybe import Data.Monoid import Data.Text (Text, unpack) import Data.Text.Encoding (decodeUtf8, encodeUtf8) import Data.Typeable import Network.HTTP.Media.MediaType ((//), (/:)) import Network.Wai import Network.Wai.Parse import Servant import Servant.Client.Core (HasClient(..), RequestBody(RequestBodySource), setRequestBody) import Servant.Docs import Servant.Foreign import Servant.Server.Internal import Servant.Types.SourceT (SourceT(..), source, StepT(..), fromActionStep) import System.Directory import System.IO (IOMode(ReadMode), withFile) import System.Random (getStdRandom, Random(randomR)) import qualified Data.ByteString as SBS import qualified Data.ByteString.Lazy as LBS -- | Combinator for specifying a @multipart/form-data@ request -- body, typically (but not always) issued from an HTML @\