Reputation: 2041
I have some servant-multipart
endpoint which is defined with something like MultipartForm Mem (MultipartData Mem)
. However, this endpoint does not let me upload long-named files because of defaultParseRequestBodyOptions
.
Somehow, I want to replace Mem
with some Mem'
which is associated with noLimitParseRequestBodyOptions
, but I am not able to figure out how to do this. How do I use servant-multipart endpoints with this option from Network.Wai.Parse
?
The Multipart
type in the form is parametrised by tag
, which has two implemented values in the Servant.Multipart
module, Tmp
and Mem
. Now, Mem
is an instance of MultipartBackend
which has an associated type MultipartBackendOptions
. I am guessing I have to modify something here to tweak the relevant ParseRequestBodyOptions
.
Upvotes: 1
Views: 223
Reputation: 1022
You don't need to define an alternative to Mem
. Given the way servant-multipart is currently written, you do not by default have to specify any multipart options. However, you can specify them, using serveWithContext
and a suitable Context
that contains your options. Below is a complete example that just overrides the maximum filename length to be 512. Of particular interest is ctxt
, which contains multipartOpts
, our custom options.
{-# LANGUAGE DataKinds, TypeOperators #-}
import Data.Proxy
import Network.Wai.Handler.Warp
import Network.Wai.Parse
import Servant
import Servant.Multipart
type API = MultipartForm Tmp (MultipartData Tmp) :> Post '[PlainText] String
api :: Proxy API
api = Proxy
server :: MultipartData Tmp -> Handler String
server multipartData = return str
where str = "The form was submitted with "
++ show nInputs ++ " textual inputs and "
++ show nFiles ++ " files."
nInputs = length (inputs multipartData)
nFiles = length (files multipartData)
main :: IO ()
main = run 8080 (serveWithContext api ctxt server)
where ctxt = multipartOpts :. EmptyContext
multipartOpts = (defaultMultipartOptions (Proxy :: Proxy Tmp))
{ generalOptions = setMaxRequestKeyLength 512 defaultParseRequestBodyOptions
}
EDIT: If you're a Nix user, you can put the following at the top of the haskell file with this code, make it executable and then just launch it, letting Nix fetch all the deps etc.
#!/usr/bin/env nix-shell
#!nix-shell -i runhaskell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [servant-server servant-multipart wai-extra warp ])"
Upvotes: 3