简体   繁体   English

使用ByteString的Haskell HTTP客户端

[英]Haskell HTTP client using ByteString

I'm doing some HTTP Requests and I want to get the corresponding Responses as ByteString instead of String. 我正在做一些HTTP请求,我希望得到相应的响应为ByteString而不是String。 I'm using HTTP-4000.2.18 . 我正在使用HTTP-4000.2.18

As far as I can tell, this is precisely what BufferType is for: 据我所知,这正是BufferType的用途:

to give the user freedom in how request and response content is represented 使用户可以自由地表示请求和响应内容

However, I'm at a loss on how to make it work. 但是,我对如何使其发挥作用感到茫然。 Here's what I have so far: I'm constructing requests using a function called getLazyRequest as follows: 这是我到目前为止所做的:我正在使用一个名为getLazyRequest的函数构建请求,如下所示:

getLazyRequest
    :: String                   -- ^URL to fetch
    -> Request Lazy.ByteString  -- ^The constructed request

and then I should be able to pass the requests directly to simpleHTTP . 然后我应该能够将请求直接传递给simpleHTTP The getLazyRequest function is identical with getRequest except it returns a request with type ByteString instead of String. getLazyRequest函数与getRequest相同,除了它返回类型为ByteString而不是String的请求。 But it doesn't work.. 但它不起作用..

Complete source: 完整来源:

import Network.HTTP
import Network.URI ( parseURI )
import qualified Data.ByteString.Lazy as Lazy
import Network.BufferType ( BufferOp(..), BufferType(..) )


main = do
    let req = getLazyRequest "http://hackage.haskell.org/"
    rsp <- simpleHTTP req
    line <- fmap (take 100) (getResponseBody rsp)
    putStrLn ""


getLazyRequest
    :: String                   -- ^URL to fetch
    -> Request Lazy.ByteString  -- ^The constructed request
getLazyRequest urlString =
  case parseURI urlString of
    Nothing -> error ("getLazyRequest: Not a valid URL - " ++ urlString)
    Just u  -> mkRequest GET u

The errors: 错误:

No instance for (HStream Lazy.ByteString)
  arising from a use of `simpleHTTP'
Possible fix:
  add an instance declaration for (HStream Lazy.ByteString)
In a stmt of a 'do' block: rsp <- simpleHTTP req

No instance for (BufferType Lazy.ByteString)
  arising from a use of `mkRequest'
Possible fix:
  add an instance declaration for (BufferType Lazy.ByteString)
In the expression: mkRequest GET u
In a case alternative: Just u -> mkRequest GET u

I don't understand why these errors, since Lazy.ByteString is an instance both of HStream and BufferType . 我不明白为什么会出现这些错误,因为Lazy.ByteString是HStreamBufferType的一个实例。

EDIT 编辑

Indeed, I have to versions of bytestring installed. 的确,我必须安装bytestring的版本。 Is it possible that I installed one of them using sudo and the other using my user? 是否有可能使用sudo安装其中一个而另一个使用我的用户?

$ ghc-pkg list bytestring
/var/lib/ghc/package.conf.d
   bytestring-0.9.2.1
/home/adizere/.ghc/x86_64-linux-7.4.1/package.conf.d
   bytestring-0.10.4.1

I couldn't unregister any of these two versions, so instead I cabalized the code and it seems to work now. 我无法取消注册这两个版本中的任何一个版本,所以我改变了代码并且它现在似乎正常工作。

Change: 更改:

    line <- fmap (take 100) (getResponseBody rsp)

to: 至:

    line <- fmap (Lazy.take 100) (getResponseBody rsp)

Your code type-checks on my system with this change. 您的代码使用此更改检查我的系统。

Since @user5402 confirmed that your code is correct (modulo take vs Lazy.take ), then I'm almost sure you have multiple versions of bytestring package installed. 由于@ user5402确认你的代码是正确的( take对比Lazy.take ),所以我几乎可以肯定你已经安装了多个版本的bytestring包。 Eg you are importing one version, but HTTP is compiled against other one. 例如,您正在导入一个版本,但HTTP是针对其他版本编译的。

Check ghc-pkg list bytestring and unregister/hide one unnecessary version. 检查ghc-pkg list bytestring并取消注册/隐藏一个不必要的版本。

Or, better, cabalize your code and/or use cabal sandbox. 或者,更好地,使用cabalize代码和/或使用cabal沙箱。

See also: Acid-state: MonadState instance for Update and https://ghc.haskell.org/trac/ghc/ticket/8278#comment:2 另请参阅: 酸状态:更新的MonadState实例https://ghc.haskell.org/trac/ghc/ticket/8278#comment:2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM