簡體   English   中英

通過Maybe在http-conduit中處理404

[英]Handling 404 via Maybe in http-conduit

我想使用http-conduit下載實現以下語義的HTTP URL(導致IO (Maybe LB.ByteString) ):

  1. 如果HTTP響應代碼為2xx,則返回Just響應正文
  2. 如果HTTP響應代碼為404,則返回Nothing
  3. 如果響應代碼指示重定向,請按照標准的http-conduit設置進行操作
  4. 對於任何其他響應代碼,拋出StatusCodeException

在沒有http-conduit及其依賴項的庫的情況下,如何使用httpLbs做到這httpLbs

注意:此問題以問答形式回答,因此有意不顯示研究成果。

這可以通過使用類似於官方示例之一的自定義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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM