@@ -50,6 +50,7 @@ import qualified Network.TLS as TLS
5050import qualified Network.TLS.Extra as TLSExtra
5151import Network.Wai (Application)
5252import Network.Wai.Handler.Warp
53+import Network.Wai.Handler.Warp.Internal
5354import System.IO.Error (isEOFError)
5455
5556----------------------------------------------------------------
@@ -255,21 +256,21 @@ getter tlsset@TLSSettings{..} sock params = do
255256mkConn :: TLS.TLSParams params => TLSSettings -> Socket -> params -> IO (Connection, Transport)
256257mkConn tlsset s params = do
257258 firstBS <- safeRecv s 4096
258− cachedRef <- I.newIORef firstBS
259259 (if not (S.null firstBS) && S.head firstBS == 0x16 then
260− httpOverTls tlsset s cachedRef params
260+ httpOverTls tlsset s firstBS params
261261 else
262− plainHTTP tlsset s cachedRef) `onException` sClose s
262+ plainHTTP tlsset s firstBS) `onException` sClose s
263263
264264----------------------------------------------------------------
265265
266−httpOverTls :: TLS.TLSParams params => TLSSettings -> Socket -> I.IORef S.ByteString -> params -> IO (Connection, Transport)
267−httpOverTls TLSSettings{..} s cachedRef params = do
266+httpOverTls :: TLS.TLSParams params => TLSSettings -> Socket -> S.ByteString -> params -> IO (Connection, Transport)
267+httpOverTls TLSSettings{..} s bs0 params = do
268+ recvN <- makePlainReceiveN s bs0
268269#if MIN_VERSION_tls(1,3,0)
269− ctx <- TLS.contextNew backend params
270+ ctx <- TLS.contextNew (backend recvN) params
270271#else
271272 gen <- Crypto.Random.AESCtr.makeSystem
272− ctx <- TLS.contextNew backend params gen
273+ ctx <- TLS.contextNew (backend recvN) params gen
273274#endif
274275 TLS.contextHookSetLogging ctx tlsLogging
275276 TLS.handshake ctx
@@ -277,11 +278,11 @@ httpOverTls TLSSettings{..} s cachedRef params = do
277278 tls <- getTLSinfo ctx
278279 return (conn ctx writeBuf, tls)
279280 where
280− backend = TLS.Backend {
281+ backend recvN = TLS.Backend {
281282 TLS.backendFlush = return ()
282283 , TLS.backendClose = sClose s
283284 , TLS.backendSend = sendAll s
284− , TLS.backendRecv = recvTLS cachedRef s
285+ , TLS.backendRecv = recvN
285286 }
286287 conn ctx writeBuf = Connection {
287288 connSendMany = TLS.sendData ctx . L.fromChunks
@@ -338,10 +339,11 @@ tryIO = try
338339
339340----------------------------------------------------------------
340341
341−plainHTTP :: TLSSettings -> Socket -> I.IORef S.ByteString -> IO (Connection, Transport)
342−plainHTTP TLSSettings{..} s cachedRef = case onInsecure of
342+plainHTTP :: TLSSettings -> Socket -> S.ByteString -> IO (Connection, Transport)
343+plainHTTP TLSSettings{..} s bs0 = case onInsecure of
343344 AllowInsecure -> do
344345 conn' <- socketConnection s
346+ cachedRef <- I.newIORef bs0
345347 let conn'' = conn'
346348 { connRecv = recvPlain cachedRef (connRecv conn')
347349 }
@@ -354,26 +356,6 @@ plainHTTP TLSSettings{..} s cachedRef = case onInsecure of
354356
355357----------------------------------------------------------------
356358
357−recvTLS :: I.IORef S.ByteString -> Socket -> Int -> IO S.ByteString
358−recvTLS cachedRef s size = do
359− cached <- I.readIORef cachedRef
360− loop cached
361− where
362− loop bs | S.length bs >= size = do
363− let (x, y) = S.splitAt size bs
364− I.writeIORef cachedRef y
365− return x
366− loop bs1 = do
367− bs2 <- safeRecv s 4096
368− if S.null bs2 then do
369− -- FIXME does this deserve an exception being thrown?
370− I.writeIORef cachedRef S.empty
371− return bs1
372− else
373− loop $ S.append bs1 bs2
374−
375−----------------------------------------------------------------
376−
377359-- | Modify the given receive function to first check the given @IORef@ for a
378360-- chunk of data. If present, takes the chunk of data from the @IORef@ and
379361-- empties out the @IORef@. Otherwise, calls the supplied receive function.