packages feed

http-client-brread-timeout 0.1.1.1 → 0.2.0.0

raw patch · 4 files changed

+67/−31 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Network.HTTP.Client.BrReadWithTimeout: brConsumeWithTimeout :: Int -> Request -> BodyReader -> IO [ByteString]
+ Network.HTTP.Client.BrReadWithTimeout: brReadSomeWithTimeout :: Int -> Request -> BodyReader -> Int -> IO ByteString

Files

Changelog.md view
@@ -1,3 +1,7 @@+### 0.2.0.0++- Added functions *brReadSomeWithTimeout* and *brConsumeWithTimeout*.+ ### 0.1.1.1  - Refactor module imports.
Network/HTTP/Client/BrReadWithTimeout.hs view
@@ -18,23 +18,27 @@ -----------------------------------------------------------------------------  -module Network.HTTP.Client.BrReadWithTimeout (-                                              fromResponseTimeout+module Network.HTTP.Client.BrReadWithTimeout (fromResponseTimeout                                              ,brReadWithTimeout+                                             ,brReadSomeWithTimeout+                                             ,brConsumeWithTimeout                                              ,httpLbsBrReadWithCustomTimeout                                              ,httpLbsBrReadWithTimeout                                              ) where  import           Network.HTTP.Client-import qualified Network.HTTP.Client.Internal as I (ResponseTimeout (..)-                                                   ,mResponseTimeout-                                                   )+import qualified Network.HTTP.Client.Internal+                    as I (ResponseTimeout (..), mResponseTimeout) import           Data.ByteString (ByteString) import qualified Data.ByteString.Lazy as L import           Control.Exception import           System.Timeout  -- | Converts t'ResponseTimeout' of the request into the number of microseconds.+--+-- This function returns the value of the timeout on reading response headers+-- which can be used to apply equal timeouts between body read events in+-- `brReadWithTimeout`, `brReadSomeWithTimeout`, and `brConsumeWithTimeout`. fromResponseTimeout :: Request -> Manager -> Int fromResponseTimeout req man =     case responseTimeout req of@@ -58,14 +62,39 @@ -- Throws v'ResponseTimeout' if reading of the next chunk of the response body -- timed out. brReadWithTimeout :: Int -> Request -> BodyReader -> IO ByteString-brReadWithTimeout tmo req br = do-    x <- timeout tmo br-    case x of-        Nothing -> throwIO $ HttpExceptionRequest-            req { responseTimeout = I.ResponseTimeoutMicro tmo }-                ResponseTimeout-        Just bs -> return bs+brReadWithTimeout tmo req br = timeout tmo br+    >>= maybe (throwIO $+                  HttpExceptionRequest+                      req { responseTimeout = I.ResponseTimeoutMicro tmo }+                      ResponseTimeout+              ) return +-- | This is like 'brReadSome' but with a timeout between body read events.+--+-- The value of the timeout is passed in the first parameter as a number of+-- microseconds. A negative value effectively disables the timeout which makes+-- the function behave exactly as 'brReadSome'.+--+-- Implemented as `brReadSome` with `brReadWithTimeout` passed in its first+-- parameter.+--+-- @since 0.2.0.0+brReadSomeWithTimeout :: Int -> Request -> BodyReader -> Int -> IO L.ByteString+brReadSomeWithTimeout tmo req br = brReadSome $ brReadWithTimeout tmo req br++-- | This is like 'brConsume' but with a timeout between body read events.+--+-- The value of the timeout is passed in the first parameter as a number of+-- microseconds. A negative value effectively disables the timeout which makes+-- the function behave exactly as 'brConsume'.+--+-- Implemented as `brConsume` with `brReadWithTimeout` passed in its first+-- parameter.+--+-- @since 0.2.0.0+brConsumeWithTimeout :: Int -> Request -> BodyReader -> IO [ByteString]+brConsumeWithTimeout tmo req br = brConsume $ brReadWithTimeout tmo req br+ -- | This is like 'httpLbs' but with a timeout between body read events. -- -- The value of the timeout is passed in the first parameter as a number of@@ -74,7 +103,7 @@ httpLbsBrReadWithCustomTimeout :: Int -> Request -> Manager ->     IO (Response L.ByteString) httpLbsBrReadWithCustomTimeout tmo req man = withResponse req man $ \res -> do-    bss <- brConsume $ brReadWithTimeout tmo req $ responseBody res+    bss <- brConsumeWithTimeout tmo req $ responseBody res     return res { responseBody = L.fromChunks bss }  -- | This is like 'httpLbs' but with a timeout between body read events.
README.md view
@@ -15,6 +15,8 @@  A slow server can be emulated in *Nginx* with the following configuration. +##### nginx.conf+ ```nginx user                    nobody; worker_processes        2;@@ -50,18 +52,15 @@ } ``` -*GHCI* session.+##### GHCi REPL session (*cabal repl*).  <pre>-<b>Prelude&gt;</b> import Network.HTTP.Client as HTTP.Client-<b>Prelude HTTP.Client&gt;</b> import Network.HTTP.Client.BrReadWithTimeout as BrReadWithTimeout-<b>Prelude HTTP.Client BrReadWithTimeout&gt;</b> httpManager = newManager defaultManagerSettings-<b>Prelude HTTP.Client BrReadWithTimeout&gt;</b> man &lt;- httpManager-<b>Prelude HTTP.Client BrReadWithTimeout&gt;</b> reqVerySlow &lt;- parseRequest "GET http://127.0.0.1:8010/very/slow"-<b>Prelude HTTP.Client BrReadWithTimeout&gt;</b> reqSlow &lt;- parseRequest "GET http://127.0.0.1:8010/slow"-<b>Prelude HTTP.Client BrReadWithTimeout&gt;</b> :set +s-<b>Prelude HTTP.Client BrReadWithTimeout&gt;</b> httpLbs reqVerySlow man-Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}, responseVersion = HTTP/1.1, responseHeaders = [("Server","nginx/1.22.0"),("Date","Thu, 23 Jun 2022 22:04:02 GMT"),("Content-Type","application/octet-stream"),("Transfer-Encoding","chunked"),("Connection","keep-alive")], responseBody = "1\n2\n3\n4\n", responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose, responseOriginalRequest = Request {+<b>&ast;N.HTTP.C.BrReadWithTimeout&gt;</b> man &lt;- newManager defaultManagerSettings+<b>&ast;N.HTTP.C.BrReadWithTimeout&gt;</b> reqVerySlow &lt;- parseRequest "GET http://127.0.0.1:8010/very/slow"+<b>&ast;N.HTTP.C.BrReadWithTimeout&gt;</b> reqSlow &lt;- parseRequest "GET http://127.0.0.1:8010/slow"+<b>&ast;N.HTTP.C.BrReadWithTimeout&gt;</b> :set +s+<b>&ast;N.HTTP.C.BrReadWithTimeout&gt;</b> httpLbs reqVerySlow man+Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}, responseVersion = HTTP/1.1, responseHeaders = [("Server","nginx/1.28.0"),("Date","Thu, 26 Feb 2026 13:33:38 GMT"),("Content-Type","application/octet-stream"),("Transfer-Encoding","chunked"),("Connection","keep-alive")], responseBody = "1\n2\n3\n4\n", responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose, responseOriginalRequest = Request {   host                 = "127.0.0.1"   port                 = 8010   secure               = False@@ -76,9 +75,9 @@   requestVersion       = HTTP/1.1   proxySecureMode      = ProxySecureWithConnect }-}-(80.09 secs, 1,084,840 bytes)-<b>Prelude HTTP.Client BrReadWithTimeout&gt;</b> httpLbsBrReadWithTimeout reqVerySlow man+, responseEarlyHints = []}+(80.08 secs, 1,266,728 bytes)+<b>&ast;N.HTTP.C.BrReadWithTimeout&gt;</b> httpLbsBrReadWithTimeout reqVerySlow man &ast;&ast;&ast; Exception: HttpExceptionRequest Request {   host                 = "127.0.0.1"   port                 = 8010@@ -95,8 +94,12 @@   proxySecureMode      = ProxySecureWithConnect }  ResponseTimeout-<b>Prelude HTTP.Client BrReadWithTimeout&gt;</b> httpLbsBrReadWithTimeout reqSlow man-Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}, responseVersion = HTTP/1.1, responseHeaders = [("Server","nginx/1.22.0"),("Date","Thu, 23 Jun 2022 22:08:46 GMT"),("Content-Type","application/octet-stream"),("Transfer-Encoding","chunked"),("Connection","keep-alive")], responseBody = "1\n2\n3\n4\n", responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose, responseOriginalRequest = Request {++HasCallStack backtrace:+  throwIO, called at ./Network/HTTP/Client/BrReadWithTimeout.hs:64:20 in http-client-brread-timeout-0.1.1.1-inplace:Network.HTTP.Client.BrReadWithTimeout++<b>&ast;N.HTTP.C.BrReadWithTimeout&gt;</b> httpLbsBrReadWithTimeout reqSlow man+Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}, responseVersion = HTTP/1.1, responseHeaders = [("Server","nginx/1.28.0"),("Date","Thu, 26 Feb 2026 13:37:49 GMT"),("Content-Type","application/octet-stream"),("Transfer-Encoding","chunked"),("Connection","keep-alive")], responseBody = "1\n2\n3\n4\n", responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose, responseOriginalRequest = Request {   host                 = "127.0.0.1"   port                 = 8010   secure               = False@@ -111,8 +114,8 @@   requestVersion       = HTTP/1.1   proxySecureMode      = ProxySecureWithConnect }-}-(60.07 secs, 1,082,880 bytes)+, responseEarlyHints = []}+(60.05 secs, 1,261,728 bytes) </pre>  Here, the first request comes from the standard `httpLbs` which, after timely
http-client-brread-timeout.cabal view
@@ -1,5 +1,5 @@ name:                   http-client-brread-timeout-version:                0.1.1.1+version:                0.2.0.0 synopsis:       Http client with time-limited brRead description:    Http client with timeouts applied in between body read events.         .