2

I use the http-conduit library version 2.0+ to fetch the contents from a HTTP webservice:

import Network.HTTP.Conduit
main = do content <- simpleHttp "http://stackoverflow.com"
          print $ content

As stated in the docs, the default timeout is 5 seconds.

Note: This question was answered by me immediately and therefore intentionally does not show further research effort.

Erik Kaplun
  • 37,128
  • 15
  • 99
  • 111
Uli Köhler
  • 13,012
  • 16
  • 70
  • 120

2 Answers2

2

Similar to this previous question you can't do that with simpleHttp alone. You need to use a Manager together with httpLbs in order to be able to set the timeout.

Note that you don't need to set the timeout in the manager but you can set it for each request individually.

Here is a full example that behaves like your function above, but allows you to modify the timeout:

import Network.HTTP.Conduit
import Control.Monad (liftM)
import qualified Data.ByteString.Lazy.Char8 as LB

-- | A simpleHttp alternative that allows to specify the timeout
-- | Note that the timeout parameter is in microseconds!
downloadHttpTimeout :: Manager -> String -> Int -> IO LB.ByteString
downloadHttpTimeout manager url timeout = do req <- parseUrl url
                                             let req' = req {responseTimeout = Just timeout}
                                             liftM responseBody $ httpLbs req' manager

main = do manager <- newManager conduitManagerSettings
          let timeout = 15000000 -- Microseconds --> 15 secs
          content <- downloadHttpTimeout manager "http://stackoverflow.com" timeout
          print $ content
Community
  • 1
  • 1
Uli Köhler
  • 13,012
  • 16
  • 70
  • 120
  • since you're not customising the manager anyway, you might as well create it automatically inside `downloadHttpTimeout`, for what it's worth. – Erik Kaplun Nov 27 '15 at 12:41
  • @ErikAllik I certainly could but IMO the most common usecase for an utility method like this is to integrate it into a larger application. Every application I've written so far using HTTP Conduits required a customized `Manager` instance at some point, so I think the extra argument is useful here compared to the minimal implementation – Uli Köhler Nov 28 '15 at 15:44
1

I've found the following to be a version of Uli's downloadHttpTimeout that resembles simpleHTTP more closely:

simpleHTTPWithTimeout :: Int -> Request a -> IO (Response LB.ByteString)
simpleHTTPWithTimeout timeout req =
  do mgr <- newManager tlsManagerSettings
     let req = req { responseTimeout = Just timeout }
     httpLbs req mgr

the only difference from simpleHTTP being a slightly different return type, so to extract e.g. the response body, one uses conduit's responseBody not Network.HTTP.getResponseBody.

Erik Kaplun
  • 37,128
  • 15
  • 99
  • 111