2010-09-24 60 views
3

Haskell的Network.Browser模块似乎没有做任何压缩。我怎样才能配置它,以便它假定服务器支持它进行gzip压缩(或者如果不支持则不会回退到压缩)?如何让Haskell的Network.Browser做gzip压缩?

+0

你指的是客户端压缩,即POST-ING gzip压缩格式的数据?这将需要OPTIONS“预飞行”请求。为了响应OPTIONS请求,大多数流行的HTTP服务器通常不会发送Accept-Encoding标头。相反,解压缩gzip编码的响应相当容易。 – rkhayrov 2010-09-24 09:32:08

回答

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(未压缩)主页。

+0

嗨特拉维斯。谢谢。似乎不“干净”,但工程。 – qrest 2010-09-28 03:00:15