warp-tls 3.4.16 → 3.4.17
raw patch · 3 files changed
+73/−20 lines, 3 filesdep ~networkPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: network
API changes (from Hackage documentation)
Files
- ChangeLog.md +15/−0
- Network/Wai/Handler/WarpTLS.hs +55/−17
- warp-tls.cabal +3/−3
ChangeLog.md view
@@ -1,5 +1,20 @@ # ChangeLog +## 3.4.17++Requires network 3.2.12.++* The listening socket, and a connection socket no TLS context or+ connection thread uses yet, are closed with `unsafeClose`.+* With warp 3.4.21's `setUnsafeClose`, a TLS connection is closed with+ `unsafeGracefulClose`.+* Sends use network's `sendAllWith`, so warp's timeout reaches a send on+ Windows too, and close_notify is given a quarter of the timeout, at+ most a second.+* A send after the peer's close_notify is dropped. The GOAWAY which ends+ an HTTP/2 connection the client has closed used to reach+ `settingsOnException` as `PostHandshake Error_EOF`.+ ## 3.4.16 `tlsEarlyDataSize` defaults to 0, so 0-RTT is off unless a server asks for
Network/Wai/Handler/WarpTLS.hs view
@@ -60,7 +60,9 @@ import Control.Applicative ((<|>)) #if MIN_VERSION_warp(3,4,13)-import Control.Concurrent.STM (TVar, check, newTVarIO, readTVar, registerDelay)+import Control.Concurrent.STM (STM, TVar, check, newTVarIO, readTVar, registerDelay, retry)+#else+import Control.Concurrent.STM (STM, retry) #endif import Control.Exception ( Exception,@@ -85,15 +87,20 @@ import Network.Socket ( SockAddr, Socket,- close, getSocketName, #if MIN_VERSION_network(3,1,1) gracefulClose,+#else+ close, #endif+ unsafeClose, withSocketsDo, )+#if MIN_VERSION_warp(3,4,21)+import Network.Socket (unsafeGracefulClose)+#endif import Network.Socket.BufferPool-import Network.Socket.ByteString (recvWith, sendAll)+import Network.Socket.ByteString (recvWith, sendAll, sendAllWith) import qualified Network.TLS as TLS import qualified Network.TLS.SessionManager as SM import Network.Wai (Application)@@ -226,7 +233,7 @@ withSocketsDo $ bracket (bindPortTCP (getPort set) (getHost set))- close+ unsafeClose ( \sock -> do setSocketCloseOnExec sock runTLSSocket tset set sock app@@ -395,14 +402,14 @@ where recvFirstBS expired = (recvWith s 4096 (check =<< readTVar expired) `E.catch` resetIsEOF)- `onException` close s+ `onException` unsafeClose s -- What streaming-commons' safeRecv did for us: a connection reset is -- the end of the connection, not an error to report. resetIsEOF e | ioeGetErrorType e == ResourceVanished = return $ Right "" | otherwise = E.throwIO (e :: E.IOException) switch firstBS- | S.null firstBS = close s >> throwIO ClientClosedConnectionPrematurely+ | S.null firstBS = unsafeClose s >> throwIO ClientClosedConnectionPrematurely | S.head firstBS == 0x16 = httpOverTls tlsset set s firstBS params | otherwise = plainHTTP tlsset set s firstBS @@ -428,7 +435,7 @@ -> params -> IO (Connection, Transport) httpOverTls TLSSettings{..} set s bs0 params =- makeConn `onException` close s+ makeConn `onException` unsafeClose s where makeConn = do pool <- newBufferPool 2048 16384@@ -448,26 +455,39 @@ TLS.handshake ctx mysa <- getSocketName s #if MIN_VERSION_warp(3,4,13)- attachConn mysa ctx appsInProgress+ attachConnWith byeTimeout mysa ctx appsInProgress #else- attachConn mysa ctx+ attachConnWith byeTimeout mysa ctx #endif case mconn of Nothing -> throwIO IncompleteHeaders Just conn -> return conn wrappedRecvN recvN n = handle (throughAsync (return "")) $ recvN n+ -- A peer which does not read is why a timed-out connection is+ -- closed, so close_notify is given a quarter of the timeout, at most+ -- a second, rather than waiting for that peer for ever.+ byeTimeout+ | settingsTimeout set <= 0 = 1000000+ | otherwise = max 1 $ min 1000000 $ settingsTimeout set * 250000+ gracefulCloser+#if MIN_VERSION_warp(3,4,21)+ | settingsUnsafeClose set = unsafeGracefulClose+#endif+ | otherwise = gracefulClose backend recvN = TLS.Backend { TLS.backendFlush = return () #if MIN_VERSION_network(3,1,1) , TLS.backendClose =- gracefulClose s 5000 `E.catch` throughAsync (return ())+ gracefulCloser s 5000 `E.catch` throughAsync (return ()) #else , TLS.backendClose = close s #endif , TLS.backendSend = sendAll' s , TLS.backendRecv = recvN }+ -- A plain send is a foreign call no asynchronous exception+ -- reaches on Windows; this one waits in STM, so the timeout can. sendAll' sock bs = E.handleJust ( \e ->@@ -476,7 +496,7 @@ else Nothing ) throwIO- $ sendAll sock bs+ $ void (sendAllWith sock bs (retry :: STM ())) -- | Get "Connection" and "Transport" for a TLS connection that is already did the handshake. -- @since 3.4.7@@ -485,11 +505,23 @@ -> TLS.Context #if MIN_VERSION_warp(3,4,13) -> TVar Int -> IO (Connection, Transport)-attachConn mysa ctx appsInProgress = do #else -> IO (Connection, Transport)-attachConn mysa ctx = do #endif+attachConn = attachConnWith 1000000++-- | 'attachConn' giving close_notify the microseconds given.+attachConnWith+ :: Int+ -> SockAddr+ -> TLS.Context+#if MIN_VERSION_warp(3,4,13)+ -> TVar Int -> IO (Connection, Transport)+attachConnWith byeTimeout mysa ctx appsInProgress = do+#else+ -> IO (Connection, Transport)+attachConnWith byeTimeout mysa ctx = do+#endif h2 <- (== Just "h2") <$> TLS.getNegotiatedProtocol ctx isH2 <- I.newIORef h2 writeBuffer <- createWriteBuffer 16384@@ -500,7 +532,7 @@ where conn writeBufferRef isH2 = Connection- { connSendMany = TLS.sendData ctx . L.fromChunks+ { connSendMany = afterCloseNotify . TLS.sendData ctx . L.fromChunks , connSendAll = sendall , connSendFile = sendfile , connClose = close'@@ -514,7 +546,13 @@ #endif } where- sendall = TLS.sendData ctx . L.fromChunks . return+ sendall = afterCloseNotify . TLS.sendData ctx . L.fromChunks . return+ -- tls answers the peer's close_notify with its own, so a send after+ -- it has nowhere to go: dropped, as the GOAWAY which ends an HTTP/2+ -- connection the peer has closed.+ afterCloseNotify = handle $ \e -> case E.fromException e of+ Just (TLS.PostHandshake TLS.Error_EOF) -> return ()+ _ -> throwIO (e :: SomeException) recv = handle onEOF $ TLS.recvData ctx where onEOF e@@ -544,7 +582,7 @@ headers close' =- void (tryIO sendBye)+ void (tryIO $ timeout byeTimeout sendBye) `finally` TLS.contextClose ctx sendBye =@@ -613,7 +651,7 @@ \\r\nConnection: Upgrade\ \\r\nContent-Type: text/plain\r\n\r\n" mapM_ (sendAll s) $ L.toChunks lbs- close s+ unsafeClose s throwIO InsecureConnectionDenied ----------------------------------------------------------------
warp-tls.cabal view
@@ -1,5 +1,5 @@ Name: warp-tls-Version: 3.4.16+Version: 3.4.17 Synopsis: HTTP over TLS support for Warp via the TLS package License: MIT License-file: LICENSE@@ -22,8 +22,8 @@ , bytestring >= 0.9 , wai >= 3.2 && < 3.3 , warp >= 3.3.29 && < 3.6- , tls >= 2.1.3 && < 2.5- , network >= 2.2.1+ , tls >= 2.1.3 && < 2.6+ , network >= 3.2.12 , streaming-commons , stm >= 2.3 , tls-session-manager >= 0.0.4