haskell - 使用管道将文件作为 HTTP 请求的源

标签 haskell amazon-web-services amazon-s3 yesod

我在尝试构造 RequestBody ResourceT IO 时遇到问题。 我对管道比较陌生,正在尝试使用 aws 包将文件上传到 S3。

io $ withManager $ \mgr ->
      do Aws.pureAws cfg s3cfg mgr $ S3.putObject stcompleted "job.zip" $ 
            RequestBodySourceChunked $ do
                  CB.sourceFile "job.zip"

我收到的类型错误是这样的。

  Couldn't match type `Data.ByteString.Internal.ByteString'
                  with `Blaze.ByteString.Builder.Internal.Types.Builder'
    Expected type: Source
                     (ResourceT IO) Blaze.ByteString.Builder.Internal.Types.Builder
      Actual type: ConduitM
                     () Data.ByteString.Internal.ByteString (ResourceT IO) ()
    In the return type of a call of `CB.sourceFile'
    In a stmt of a 'do' block: CB.sourceFile "job.zip"
    In the second argument of `($)', namely
      `do { CB.sourceFile "job.zip" }'

putObject 的类型是

putObject
  :: Bucket
     -> Data.Text.Internal.Text
     -> http-conduit-1.9.5.2:Network.HTTP.Conduit.Types.RequestBody
          (Control.Monad.Trans.Resource.Internal.ResourceT IO)
     -> PutObject

我看不到如何构造 RequestBody ResourceT IO,因为 RequestBody 的可能构造函数不包含 ResoureceT IO

data RequestBody m
  = RequestBodyLBS Data.ByteString.Lazy.Internal.ByteString
  | RequestBodyBS Data.ByteString.Internal.ByteString
  | RequestBodyBuilder GHC.Int.Int64
                       Blaze.ByteString.Builder.Internal.Types.Builder
  | RequestBodySource GHC.Int.Int64
                      (Data.Conduit.Internal.Source
                         m Blaze.ByteString.Builder.Internal.Types.Builder)
  | RequestBodySourceChunked (Data.Conduit.Internal.Source
                                m Blaze.ByteString.Builder.Internal.Types.Builder)

最佳答案

这里的关键(稍微清理一下)是:

Couldn't match type ByteString with Builder

所以第一个问题是:如何将 ByteString 转换为 Builder? Using Hoogle我们得到了一些可能的命中,并且 fromByteString事实证明是最好的。

下一个问题是如何转换Source以产生新类型的值。这需要对管道有一定的了解,对此我推荐 the conduit tutorial 。但其想法是创建一个数据转换器(Conduit),用于转换 ByteString 的传入流并生成 Builder 的输出流,并将其与融合。

第一步,我们要使用 Data.Conduit.List 中的 map 抽象。对于第二个,融合运算符是$=。将所有这些放在一起,我们有:

CB.sourceFile "job.zip" $= Data.Conduit.List.map fromByteString

关于haskell - 使用管道将文件作为 HTTP 请求的源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21169112/

相关文章:

haskell - 覆盖派生类型类实例的默认实现

amazon-web-services - 在 route53 中没有这样的主机

amazon-web-services - 在没有负载均衡器的情况下向公共(public) Internet 公开 K8s TCP 服务端点

java - 是否可以将 BufferedWriter 的内容作为字符串获取?

list - Haskell: "list comprehension"是否使用急切求值?

haskell - haskell中公平并发 `map`函数?

ruby - AWS Codedeploy 在安装期间失败 : UnknownError "\xCC" from ASCII-8BIT to UTF-8

html - 如何使用mapbox gl js添加栅格数据?

javascript - Heroku Node.js Amazon S3 直接上传教程 - SignatureDoesNotMatch

haskell - 为什么 id 的类型不能专门化为 (forall a.a -> a) -> (forall b.b -> b)?