packages feed

http2-client 0.8.0.1 → 0.8.0.2

raw patch · 4 files changed

+60/−27 lines, 4 filesPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ Network.HTTP2.Client.RawConnection: newRawHttp2ConnectionSocket :: Socket -> Maybe ClientParams -> IO RawHttp2Connection

Files

+ ChangeLog.md view
@@ -0,0 +1,9 @@+# Changelog for http2-client++## Unreleased changes++## v0.8.0.2++- first Changelog!+- performance improvement: use `TCP_NODELAY`+- performance improvement: change stream-initialization functions to make less work under the HEADER-protection lock
http2-client.cabal view
@@ -1,5 +1,5 @@ name:                http2-client-version:             0.8.0.1+version:             0.8.0.2 synopsis:            A native HTTP2 client library. description:         Please read the README.md at the homepage. homepage:            https://github.com/lucasdicioccio/http2-client@@ -10,7 +10,7 @@ copyright:           2017 Lucas DiCioccio category:            Web build-type:          Simple-extra-source-files:  README.md+extra-source-files:  README.md, ChangeLog.md cabal-version:       >=1.10  library
src/Network/HTTP2/Client.hs view
@@ -415,8 +415,10 @@                                             goAwayHandler                                             fallbackHandler -    _initIncomingFlowControl <- newIncomingFlowControl dispatchControl controlStream-    (_initOutgoingFlowControl,windowUpdatesChan) <- newOutgoingFlowControl dispatchControl 0+    let baseWindowSize = return HTTP2.defaultInitialWindowSize+    _initIncomingFlowControl <- newIncomingFlowControl dispatchControl baseWindowSize (sendWindowUpdateFrame controlStream)+    windowUpdatesChan <- newChan+    _initOutgoingFlowControl <- newOutgoingFlowControl dispatchControl windowUpdatesChan baseWindowSize      dispatchHPACK <- newDispatchHPACKIO decoderBufSize     (incomingLoop,endIncomingLoop) <- dispatchLoop conn dispatch dispatchControl windowUpdatesChan _initIncomingFlowControl dispatchHPACK@@ -437,12 +439,14 @@             then                 return $ Left $ TooMuchConcurrency roomNeeded             else Right <$> do+                windowUpdatesChan <- newChan                 cont <- withClientStreamId $ \sid -> do                     dispatchStream <- newDispatchStreamIO sid                     initializeStream conn                                      dispatch                                      dispatchControl                                      dispatchStream+                                     windowUpdatesChan                                      getWork                                      Idle                 v <- cont@@ -480,20 +484,16 @@   -> Dispatch   -> DispatchControl   -> DispatchStream+  -> Chan (FrameHeader, FramePayload)   -> (Http2Stream -> StreamDefinition a)   -> StreamFSMState   -> IO (IO a)-initializeStream conn dispatch control stream getWork initialState = do+initializeStream conn dispatch control stream windowUpdatesChan getWork initialState = do     let sid = _dispatchStreamId stream     let frameStream = makeFrameClientStream conn sid      let events        = _dispatchStreamReadEvents stream -    -- Builds a flow-control context.-    incomingStreamFlowControl <- newIncomingFlowControl control frameStream-    (outgoingStreamFlowControl, windowUpdatesChan) <- newOutgoingFlowControl control sid-    registerStream dispatch sid (StreamState windowUpdatesChan events initialState)-     -- Prepare handlers.     let _headers headersList flags = do             splitter <- settingsPayloadSplitter <$> readSettings control@@ -513,21 +513,32 @@     let _handlePushPromise ppSid ppHeaders ppHandler = do             let mkStreamActions s = StreamDefinition (return CST) (ppHandler sid s ppHeaders)             newStream <- newDispatchStreamIO ppSid+            ppWindowsUpdatesChan <- newChan             ppCont <- initializeStream conn                                        dispatch                                        control                                        newStream+                                       ppWindowsUpdatesChan                                        mkStreamActions                                        ReservedRemote             ppCont      let streamActions = getWork $ Http2Stream{..} -    -- Perform the 1st action, the stream won't be idle anymore.+    -- Register handlers for receiving frames and perform the 1st action, the+    -- stream won't be idle anymore.+    registerStream dispatch sid (StreamState windowUpdatesChan events initialState)     _ <- _initStream streamActions      -- Returns 2nd action.-    return $ _handleStream streamActions incomingStreamFlowControl outgoingStreamFlowControl+    -- We build the flow control contexts in this action outside the exclusive+    -- lock on clientStreamIdMutex will be released.+    return $ do+        let baseIncomingWindowSize = initialWindowSize . _clientSettings <$> readSettings control+        isfc <- newIncomingFlowControl control baseIncomingWindowSize (sendWindowUpdateFrame frameStream)+        let baseOutgoingWindowSize = initialWindowSize . _serverSettings <$> readSettings control+        osfc <- newOutgoingFlowControl control windowUpdatesChan baseOutgoingWindowSize+        _handleStream streamActions isfc osfc  dispatchLoop   :: Http2FrameConnection@@ -732,12 +743,12 @@  newIncomingFlowControl   :: DispatchControl-  -> Http2FrameClientStream+  -> IO Int+  -- ^ Action to get the base window size.+  -> (WindowSize -> IO())+  -- ^ Action to send the window update to the server.   -> IO IncomingFlowControl-newIncomingFlowControl control stream = do-    let getBase = if _getStreamId stream == 0-                  then return HTTP2.defaultInitialWindowSize-                  else initialWindowSize . _clientSettings <$> readSettings control+newIncomingFlowControl control getBase doSendUpdate = do     creditAdded <- newIORef 0     creditConsumed <- newIORef 0     let _addCredit n = atomicModifyIORef' creditAdded (\c -> (c + n, ()))@@ -756,22 +767,20 @@              _addCredit (negate transferred)             _ <- _consumeCredit (negate transferred)--            when shouldUpdate (sendWindowUpdateFrame stream transferred)+            when shouldUpdate (doSendUpdate transferred)              return shouldUpdate     return $ IncomingFlowControl _addCredit _consumeCredit _updateWindow  newOutgoingFlowControl ::      DispatchControl-  -> StreamId-  -> IO (OutgoingFlowControl, Chan (FrameHeader, FramePayload))-newOutgoingFlowControl control sid = do+  -- ^ Control dispatching reference.+  -> Chan (FrameHeader, FramePayload)+  -> IO Int+  -- ^ Action to get the instantaneous base window-size.+  -> IO OutgoingFlowControl+newOutgoingFlowControl control frames getBase = do     credit <- newIORef 0-    frames <- newChan-    let getBase = if sid == 0-                  then return HTTP2.defaultInitialWindowSize-                  else initialWindowSize . _serverSettings <$> readSettings control     let receive n = atomicModifyIORef' credit (\c -> (c + n, ()))     let withdraw 0 = return 0         withdraw n = do@@ -786,7 +795,7 @@                 amount <- race (waitSettingsChange base) (waitSomeCredit frames)                 receive (either (const 0) id amount)                 withdraw n-    return $ (OutgoingFlowControl receive withdraw, frames)+    return $ OutgoingFlowControl receive withdraw   where     -- TODO: broadcast settings changes from ConnectionSettings using a better data type     -- than IORef+busy loop. Currently the busy loop is fine because
src/Network/HTTP2/Client/RawConnection.hs view
@@ -5,6 +5,7 @@ module Network.HTTP2.Client.RawConnection (       RawHttp2Connection (..)     , newRawHttp2Connection+    , newRawHttp2ConnectionSocket     ) where  import           Control.Monad (forever, when)@@ -45,8 +46,22 @@     let hints = defaultHints { addrFlags = [AI_NUMERICSERV], addrSocketType = Stream }     addr:_ <- getAddrInfo (Just hints) (Just host) (Just $ show port)     skt <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)+    setSocketOption skt NoDelay 1     connect skt (addrAddress addr)+    newRawHttp2ConnectionSocket skt mparams +-- | Initiates a RawHttp2Connection with a server over a connected socket.+--+-- The current code does not handle closing the connexion, yikes.+-- Since 0.8.0.2+newRawHttp2ConnectionSocket+  :: Socket+  -- ^ A connected socket.+  -> Maybe TLS.ClientParams+  -- ^ TLS parameters. The 'TLS.onSuggestALPN' hook is+  -- overwritten to always return ["h2", "h2-17"].+  -> IO RawHttp2Connection+newRawHttp2ConnectionSocket skt mparams = do     -- Prepare structure with abstract API.     conn <- maybe (plainTextRaw skt) (tlsRaw skt) mparams