How can I post FileInfo to a web service using Yesod and Http-Conduit?

半腔热情 提交于 2019-12-07 10:31:28

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!