Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

making mkConn of WarpTLS interruptible #984

Merged
merged 1 commit into from
Apr 19, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 30 additions & 16 deletions warp-tls/Network/Wai/Handler/WarpTLS.hs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ import UnliftIO.Exception (
try,
)
import qualified UnliftIO.Exception as E
import UnliftIO.Concurrent (newEmptyMVar, putMVar, takeMVar, forkIOWithUnmask)
import UnliftIO.Timeout (timeout)

----------------------------------------------------------------

Expand Down Expand Up @@ -318,8 +320,18 @@ mkConn
-> Socket
-> params
-> IO (Connection, Transport)
mkConn tlsset set s params = (safeRecv s 4096 >>= switch) `onException` close s
mkConn tlsset set s params = do
var <- newEmptyMVar
_ <- forkIOWithUnmask $ \umask -> do
let tm = settingsTimeout set * 1000000
mct <- umask (timeout tm recvFirstBS)
putMVar var mct
mbs <- takeMVar var
case mbs of
Nothing -> throwIO IncompleteHeaders
Just bs -> switch bs
where
recvFirstBS = safeRecv s 4096 `onException` close s
switch firstBS
| S.null firstBS = close s >> throwIO ClientClosedConnectionPrematurely
| S.head firstBS == 0x16 = httpOverTls tlsset set s firstBS params
Expand All @@ -335,22 +347,24 @@ httpOverTls
-> S.ByteString
-> params
-> IO (Connection, Transport)
httpOverTls TLSSettings{..} _set s bs0 params = do
pool <- newBufferPool 2048 16384
rawRecvN <- makeRecvN bs0 $ receive s pool
let recvN = wrappedRecvN rawRecvN
ctx <- TLS.contextNew (backend recvN) params
TLS.contextHookSetLogging ctx tlsLogging
TLS.handshake ctx
h2 <- (== Just "h2") <$> TLS.getNegotiatedProtocol ctx
isH2 <- I.newIORef h2
writeBuffer <- createWriteBuffer 16384
writeBufferRef <- I.newIORef writeBuffer
-- Creating a cache for leftover input data.
tls <- getTLSinfo ctx
mysa <- getSocketName s
return (conn ctx writeBufferRef isH2 mysa, tls)
httpOverTls TLSSettings{..} _set s bs0 params =
makeConn `onException` close s
where
makeConn = do
pool <- newBufferPool 2048 16384
rawRecvN <- makeRecvN bs0 $ receive s pool
let recvN = wrappedRecvN rawRecvN
ctx <- TLS.contextNew (backend recvN) params
TLS.contextHookSetLogging ctx tlsLogging
TLS.handshake ctx
h2 <- (== Just "h2") <$> TLS.getNegotiatedProtocol ctx
isH2 <- I.newIORef h2
writeBuffer <- createWriteBuffer 16384
writeBufferRef <- I.newIORef writeBuffer
-- Creating a cache for leftover input data.
tls <- getTLSinfo ctx
mysa <- getSocketName s
return (conn ctx writeBufferRef isH2 mysa, tls)
backend recvN =
TLS.Backend
{ TLS.backendFlush = return ()
Expand Down
Loading