【问题标题】:How can I post FileInfo to a web service using Yesod and Http-Conduit?如何使用 Yesod 和 Http-Conduit 将 FileInfo 发布到 Web 服务?
【发布时间】:2014-09-30 18:55:44
【问题描述】:

我正在使用默认的 Yesod 脚手架项目。
我创建了一个页面,显示一个简单的表单来上传文件。
(可能会使用 Javascript 在客户端上创建表单。)
为简洁起见,表单只有一个文件输入:

<form method="post" action=@{UploadR}>
   <input type="file" name="myfile">
   <button type="submit">

我的目标是处理表单数据,然后将文件上传到网络服务。
我处理表单没有问题,我关心的是与 Web 服务的交互。
例如,给定以下 Yesod 处理程序:

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}.
      |]

网络服务返回错误:fail post content-length,但其他一切都按预期工作。也许服务器不支持分块的请求正文?

【问题讨论】:

    标签: web-services http haskell yesod http-conduit


    【解决方案1】:

    我认为您对分块请求正文的猜测是正确的。你需要做的是:

    • 将上传的内容流式传输到临时文件中。
    • 获取该文件的大小。
    • 使用requestBodySource 并提供文件长度及其内容。

    幸运的是,sinkCacheLength 函数可以很容易地处理步骤 (1) 和 (2)。你最终会得到类似的东西:

    (fSize, fSource) <- fileSource fi $$ sinkCacheLength
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多