2014-09-29 83 views
4

我正在使用默认的Yesod脚手架项目。
我创建了一个显示上传文件的简单表单的页面。
(形式将可能使用Javascript在客户机上创建的。)
为简洁起见,形式有一个单一的文件输入:如何使用Yesod和Http-Conduit将FileInfo发布到Web服务?

<form method="post" [email protected]{UploadR}> 
    <input type="file" name="myfile"> 
    <button type="submit"> 

我的目标是处理表单数据,然后将文件上传到一个Web服务。
我在处理表单时没有问题,我担心的是与Web服务交互。
例如,给出以下耶索德处理程序:

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

WebService的返回错误:fail post content-length,但一切工作正常。也许服务器不支持分块的请求体?

回答

2

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

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

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

(fSize, fSource) <- fileSource fi $$ sinkCacheLength 
相关问题