6

我使用http-conduit库版本 2.0+ 从http://URL 获取内容:

import Network.HTTP.Conduit
myurl = ... -- Your URL goes here
main = do content <- simpleHttp myurl
          print $ content

运行此程序时,我收到此错误:

*** Exception: TlsException (HandshakeFailed (Error_Protocol
      ("certificate rejected: certificate is not allowed to sign another certificate",
        True,CertificateUnknown)))

从错误消息中可以看出,问题是无法Network.HTTP.Conduit正确验证服务器证书(在这种情况下,证书链中似乎存在问题)

如何更改上述代码以忽略证书错误(即根本不验证证书)?

4

1 回答 1

8

simpleHttp本身不支持此功能。您需要创建一个修改后的管理器,ManagerSettings然后使用它来获取 URL。

请注意,此代码仅适用于http-conduits2.0+ 版本——库版本 1 具有用于此目的的类似但不同的 API。

import Network.HTTP.Conduit
import Network.Connection
import qualified Data.ByteString.Lazy.Char8 as LB

myurl = ... -- Your URL goes here

-- | Get a new Manager that doesn't verify SSL certificates
noSSLVerifyManager :: IO Manager
noSSLVerifyManager = let tlsSettings = TLSSettingsSimple {
                            -- This is where we disable certificate verification
                            settingDisableCertificateValidation = True,
                            settingDisableSession=False,
                            settingUseServerName=True}
                     in newManager $ mkManagerSettings tlsSettings Nothing

-- | Download like with simpleHttp, but using an existing manager for the task
simpleHttpWithManager :: Manager -> String -> IO LB.ByteString
simpleHttpWithManager manager url = do url' <- parseUrl url
                                       fmap responseBody $ httpLbs url' manager

main = do manager <- noSSLVerifyManager
          content <- simpleHttpWithManager manager myurl
          print $ content

请注意,仅在绝对必要时才应禁用 SSL 证书验证,因为它会使您容易受到中间人攻击

于 2014-01-23T14:16:56.510 回答