如何使Haskell的Network.Browser进行gzip压缩?

3

如何在Haskell的Network.Browser模块中启用gzip压缩?

看起来Haskell的Network.Browser模块没有进行任何压缩。如果服务器支持gzip压缩,我该如何配置它以启用gzip压缩(如果服务器不支持,则回退到未压缩)?


你是指客户端压缩,即POST gzip压缩的表单数据吗?这将需要OPTIONS“预检”请求。大多数流行的HTTP服务器通常不会在响应OPTIONS请求时发送Accept-Encoding头。相反,解压gzip编码的响应相当容易。 - rkhayrov
1个回答

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(未压缩)首页上,它都能够按预期工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接