10

HTTP でいくつかのファイルをダウンロードするアプリケーションを作成しています。ある時点まで、次のコード スニペットを使用してページの本文をダウンロードしていました。

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

正常に動作していましたが、HTTPS プロトコルによる接続を確立できませんでした。これを修正するために、HTTP コンジットに切り替え、次のコードを使用しています。

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

HTTPS に接続できますが、新しいイライラする問題が発生しました。約 5 番目の接続ごとに失敗し、次の例外が発生します。

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

network.HTTP が同じ一連のページ (https ページを除く) で正常に動作していたため、これは HTTP コンジットの問題であると確信しています。

誰かがそのような問題に遭遇し、Conduit ライブラリに代わる解決策を知っていますか?

4

1 に答える 1

2

簡単な代替手段の 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

更新:問題を再現しようとしましたが、すべてうまくいきました。問題を示す短い自己完結型のコンパイル可能な例を投稿できますか? 私のコード:

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
于 2013-12-21T19:17:29.340 に答える