Http-Conduit частые сбои подключения - программирование

Http-Conduit частые сбои подключения

Я пишу приложение, которое будет загружать некоторые файлы по HTTP. До некоторой степени я использовал следующий фрагмент кода для загрузки тела страницы:

import network.HTTP
simpleHTTP (getRequest "http://www.haskell.org/") >>= getResponseBody

Он работал нормально, но не смог установить соединение по протоколу HTTPS. Поэтому, чтобы исправить это, я переключился на HTTP-Conduit, и теперь я использую следующий код:

simpleHttp' :: Manager -> String -> IO (C.Response LBS.ByteString)
simpleHttp' manager url = do
     request <- parseUrl url
     runResourceT $ httpLbs request manager

Он может подключаться к HTTPS, но появилась новая неприятная проблема. О каждом пятом подключении не удается исключить:

getpics.hs: FailedConnectionException "i.imgur.com" 80

Я убежден, что это проблема HTTP-Conduit, потому что network.HTTP отлично работает на одном и том же наборе страниц (исключая страницы https).

Кто-нибудь встретил такую ​​проблему и знал решение или лучше (и просто потому, что это простая задача, которая не должна принимать более нескольких строк кода), альтернативу библиотеке Conduit?

4b9b3361

Ответ 1

Один простой вариант - использовать пакет curl. Он поддерживает HTTP, HTTPS и множество других альтернативных протоколов, а также множество параметров, чтобы настроить его поведение. Цена вводит внешнюю зависимость от libcurl, необходимую для сборки пакета.

Пример:

import Network.Curl

main :: IO ()
main = do
  let addr = "https://google.com/" 
  -- Explicit type annotation is required for calls to curlGetresponse_.
  -- Use ByteString instead of String for higher performance:
  r <- curlGetResponse_ addr [] :: IO (CurlResponse_ [(String,String)] String)

  print $ respHeaders r
  putStr $ respBody r

Обновление: Я пытался реплицировать вашу проблему, но все работает для меня. Не могли бы вы опубликовать Short, Self Contained, Compilable, Example, который демонстрирует проблему? Мой код:

import Control.Monad
import qualified Data.Conduit as C
import qualified Data.ByteString.Lazy as LBS
import Network.HTTP.Conduit

simpleHttp'' :: String -> Manager -> C.ResourceT IO (Response LBS.ByteString)
simpleHttp'' url manager = do
     request <- parseUrl url
     httpLbs request manager

main :: IO ()
main = do
  let url = "http://i.imgur.com/"
      count = 100
  rs <- withManager $ \m -> replicateM count (simpleHttp'' url m)
  mapM_ (print . responseStatus) $ rs