如何让Haskell的Network.Browser做gzip压缩?

时间:2010-09-24 06:39:41

标签: haskell networking

Haskell的Network.Browser模块似乎没有做任何压缩。我如何配置它以便它假设服务器支持它进行gzip压缩(如果不支持则回退到没有压缩)?

1 个答案:

答案 0 :(得分:3)

这是rkhayrov提到的“相当简单”解决方案的快速版本:

import Codec.Compression.GZip (decompress)
import Control.Arrow (second)
import Control.Monad (liftM)
import qualified Data.ByteString.Lazy as B
import Network.Browser
import Network.HTTP (Request, Response, getRequest, getResponseBody, rspBody)
import Network.HTTP.Headers (HasHeaders, HeaderName (..), findHeader, replaceHeader)
import Network.TCP (HStream, HandleStream)
import Network.URI (URI, parseURI)

gzipRequest :: URI -> BrowserAction (HandleStream B.ByteString) (URI, Response B.ByteString)
gzipRequest
  = liftM (second unzipIfNeeded)
  . request
  . replaceHeader HdrAcceptEncoding "gzip"
  . defaultGETRequest_
  where
    unzipIfNeeded rsp
      | isGz rsp  = rsp { rspBody = decompress $ rspBody rsp }
      | otherwise = rsp
      where
        isGz rsp = maybe False (== "gzip") $ findHeader HdrContentEncoding rsp

我用以下方法进行了几项测试:

main = print =<< rspBody . snd <$> (getResponse =<< head <$> getArgs)
  where
    getResponse = browse . gzipRequest . fromJust . parseURI

它在Yahoo(压缩)和Google(未压缩)主页上按预期工作。