Haskell HTTP client using ByteString
I am making HTTP requests and I want to get the corresponding responses as ByteString instead of String. I am using HTTP-4000.2.18 .
As far as I can tell, this is exactly what BufferType is for:
to give the user freedom to present the content of the request and response
However, I don't understand how to do this. Here's what I have so far: I am building queries with a function called getLazyRequest
like this:
getLazyRequest
:: String -- ^URL to fetch
-> Request Lazy.ByteString -- ^The constructed request
and then I should be able to pass requests directly to simpleHTTP . GetLazyRequest is identical to getRequest , except that it returns a ByteString request instead of a String. But it doesn't work.
Full 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
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 are, since Lazy.ByteString is an instance of HStream and BufferType .
EDIT
Indeed, I have to install bytestring versions. Is it possible that I installed one with sudo and the other with my user?
$ 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 either of these two versions, so I cabled the code instead and it seems to work now.
source to share
Since @ user5402 confirmed that your code is correct (modulo take
vs Lazy.take
), then I'm pretty sure you have multiple versions of the package installed bytestring
. For example. you are importing one version, but HTTP
compiled against the other.
Check ghc-pkg list bytestring
and unregister / hide one unnecessary version.
Or, better, cabalize your code and / or use the cabal sandbox.
See also: Acid State: MonadState instance to update and also https://ghc.haskell.org/trac/ghc/ticket/8278#comment:2
source to share