问题
I am working with the default Yesod scaffolding project.
I have created a page that displays a simple form to upload files.
(The form will likely be created on the client using Javascript.)
For brevity, the form has a single file input:
<form method="post" action=@{UploadR}>
<input type="file" name="myfile">
<button type="submit">
My objective is to process the form data and then upload the file to a web service.
I have no trouble processing the form, my concern is interacting with the web service.
For example, given the following Yesod handler:
postUploadR :: Handler Html
postUploadR = do
mgr <- fmap httpManager getYesod
fi <- runInputPost $ ireq fileField "myfile"
let fSource = fileSource fi
fName = fileName fi
req <- parseUrl "http://webservice/upload"
let areq = req { method = methodPost
, requestBody = requestBodySourceChunked fSource
}
res <- httpLbs areq mgr
defaultLayout $ do
setTitle "file uploaded"
[whamlet|
<h3> Success
<p> You uploaded #{fName}.
|]
The webservice returns the error: fail post content-length
, but everything else works as expected. Perhaps the server doesn't support a chunked request body?
回答1:
I think your guess about chunked request body is correct. What you need to do is:
- Stream the uploaded contents into a temporary file.
- Get the size of that file.
- Use
requestBodySource
and provide the file length and its contents.
Fortunately, steps (1) and (2) can be handled quite easily by the sinkCacheLength function. You'll end up with something like:
(fSize, fSource) <- fileSource fi $$ sinkCacheLength
来源:https://stackoverflow.com/questions/26109017/how-can-i-post-fileinfo-to-a-web-service-using-yesod-and-http-conduit