如何使用Yesod和Http-Conduit将FileInfo发布到Web服务? [英] How can I post FileInfo to a web service using Yesod and Http-Conduit?
问题描述
我正在使用默认的Yesod scaffolding项目。
我创建了一个显示上传文件的简单表单的页面。
(该表单可能会创建客户端使用Javascript。)
为简洁起见,表单有一个文件输入:
< form method =postaction = @ {UploadR}>
< input type =filename =myfile>
< button type =submit>
我的目标是处理表单数据,然后将文件上传到Web服务。
我没有麻烦处理表单,我关心的是与web服务交互。
例如,给定以下的Yesod处理程序:
postUploadR :: Handler Html
postUploadR = do
mgr< - fmap httpManager getYesod
fi< - runInputPost $ ireq fileFieldmyfile
let fSource = fileSource fi
fName = fileName fi
req< - parseUrlhttp:// webservice / upload
let areq = req {method = methodPost
,requestBody = requestBodySourceChunked fSource
}
res< - httpLbs areq mgr
defaultLayout $ do
setTitlefile uploaded
[whamlet |
< h3>成功
< p>您上传了#{fName}。
$]
web服务返回错误:失败发布内容长度
,但其他一切按预期工作。也许服务器不支持分块请求体?
我想你对分块请求体的猜测是正确的。您需要做的是:
requestBodySource
并提供文件长度及其内容。
幸运的是,步骤(1)和(2)可以通过 sinkCacheLength 函数。您最终会得到如下结果:
(fSize,fSource)< - fileSource fi $$ sinkCacheLength
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?
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
这篇关于如何使用Yesod和Http-Conduit将FileInfo发布到Web服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!