{-# LANGUAGE OverloadedStrings #-}moduleNetwork.Wai.Handler.WebSockets(intercept,interceptWith)whereimportControl.Monad.IO.Class(liftIO)importData.ByteString(ByteString)importData.Char(toLower)importqualifiedData.ByteString.Char8asSimportqualifiedData.ConduitasCimportqualifiedData.EnumeratorasEimportqualifiedNetwork.WaiasWaiimportqualifiedNetwork.Wai.Handler.WarpasWarpimportqualifiedNetwork.WebSocketsasWS-- | For use with 'settingsIntercept' from the Warp web server.intercept::WS.Protocolp=>(WS.Request->WS.WebSocketsp())->Wai.Request->Maybe(C.Source(C.ResourceTIO)ByteString->Warp.Connection->C.ResourceTIO())intercept=interceptWithWS.defaultWebSocketsOptions-- | Variation of 'intercept' which allows custom options.interceptWith::WS.Protocolp=>WS.WebSocketsOptions->(WS.Request->WS.WebSocketsp())->Wai.Request->Maybe(C.Source(C.ResourceTIO)ByteString->Warp.Connection->C.ResourceTIO())interceptWithoptsappreq=caselookup"upgrade"$Wai.requestHeadersreqofJusts|S.maptoLowers=="websocket"->Just$runWebSocketsoptsreq'app|otherwise->Nothing_->Nothingwherereq'=WS.RequestHttpPart(Wai.rawPathInforeq)(Wai.requestHeadersreq)(Wai.isSecurereq)-- | Internal function to run the WebSocket iteratee using the conduit libraryrunWebSockets::WS.Protocolp=>WS.WebSocketsOptions->WS.RequestHttpPart->(WS.Request->WS.WebSocketsp())->C.Source(C.ResourceTIO)ByteString->Warp.Connection->C.ResourceTIO()runWebSocketsoptsreqappsourceconn=dostep<-liftIO$E.runIteratee$WS.runWebSocketsWithoptsreqappsendsourceC.$$C.sinkState(E.returnIstep)pushclosewheresend=iterConnectionconnpushiterbs=dostep<-liftIO$E.runIteratee$E.enumList1[bs]E.$$iterreturn$C.StateProcessing$E.returnIstepcloseiter=do_<-liftIO$E.runIteratee$E.enumEOFE.$$iterreturn()iterConnection::Warp.Connection->E.IterateeByteStringIO()iterConnectionc=E.continuegowherego(E.Chunks[])=E.continuegogo(E.Chunkscs)=E.tryIO(Warp.connSendManyccs)>>E.continuegogoE.EOF=E.continuego