【问题标题】:Handling 404 via Maybe in http-conduit在 http-conduit 中通过 Maybe 处理 404
【发布时间】:2014-07-30 22:11:10
【问题描述】:

使用http-conduit 我想下载一个实现以下语义的HTTP URL(导致IO (Maybe LB.ByteString)):

  1. 如果HTTP响应码是2xx,返回Just响应体
  2. 如果HTTP响应码是404,返回Nothing
  3. 如果响应代码指示重定向,请按照标准 http-conduit 设置进行操作
  4. 对于任何其他响应代码,请抛出 StatusCodeException

如果没有http-conduit 之外的任何库及其依赖项,我如何使用httpLbs 做到这一点?

注意:这个问题是以问答形式回答的,因此故意不显示研究成果。

【问题讨论】:

    标签: haskell http-conduit


    【解决方案1】:

    这可以通过使用类似于offical examples 之一的自定义checkStatus 来实现。

    如果响应状态码为 2xx 或 404,我们将声明 checkStatus200 通过。如果没有通过,它会调用默认的 checkStatus 函数来抛出相应的异常。

    在使用checkStatus200 使用Request 调用httpLbs 后,我们可以检查状态码并返回Just 响应码或Nothing

    import Data.Conduit.Binary (sinkFile)
    import Network.HTTP.Types.Status (Status(..))
    import Network.HTTP.Conduit
    import qualified Data.Conduit as C
    import Network
    import Data.Default (def)
    import qualified Data.ByteString.Lazy as LB
    
    -- | @checkStatus@ implementation that accepts 
    --   2xx status codes and 404. Calls default implementation
    --   on other status codes (i.e. throws exception)
    checkStatus200 st@(Status sc _) rh cj =
        if (200 <= sc && sc < 300) || sc == 404
            then Nothing
            else (checkStatus def) st rh cj
    
    -- | Download a HTTP link, returning @Nothing@ on 404 status code
    downloadCatch404 :: String
                     -> IO (Maybe LB.ByteString)
    downloadCatch404 url = withSocketsDo $ do
        request <- parseUrl url
        let request' = request { checkStatus = checkStatus200 }
        res <- withManager $ httpLbs request'
        let status =  statusCode . responseStatus $ res
        -- Return Nothing if status code == 404
        return $ if status == 404
            then Nothing
            else Just $ responseBody res
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-03
      • 2011-01-09
      • 1970-01-01
      • 1970-01-01
      • 2012-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多