如何使用Yesod和Http-Conduit将FileInfo发布到Web服务? [英] How can I post FileInfo to a web service using Yesod and Http-Conduit?

查看:84
本文介绍了如何使用Yesod和Http-Conduit将FileInfo发布到Web服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用默认的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆