fix p2phttp server to not get stuck
Process 1 command, then stop. Hopefully each of the Handlers will only need 1 command.
This commit is contained in:
parent
3d13521479
commit
dcd77ee555
2 changed files with 26 additions and 9 deletions
|
@ -131,9 +131,7 @@ withLocalP2PConnections a = do
|
||||||
(const True) h2 h1
|
(const True) h2 h1
|
||||||
(ConnIdent (Just "http client"))
|
(ConnIdent (Just "http client"))
|
||||||
runst <- liftIO $ mkrunst connparams
|
runst <- liftIO $ mkrunst connparams
|
||||||
-- TODO is this right? It needs to exit
|
let server = P2P.serveOneCommandAuthed
|
||||||
-- when the client stops sending messages.
|
|
||||||
let server = P2P.serveAuthed
|
|
||||||
(connectionServerMode connparams)
|
(connectionServerMode connparams)
|
||||||
(connectionServerUUID connparams)
|
(connectionServerUUID connparams)
|
||||||
let protorunner = void $
|
let protorunner = void $
|
||||||
|
|
|
@ -42,6 +42,7 @@ import qualified Data.ByteString as B
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import qualified Data.Set as S
|
import qualified Data.Set as S
|
||||||
import Data.Char
|
import Data.Char
|
||||||
|
import Data.Maybe
|
||||||
import Data.Time.Clock.POSIX
|
import Data.Time.Clock.POSIX
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Control.DeepSeq
|
import Control.DeepSeq
|
||||||
|
@ -472,7 +473,14 @@ data ServerHandler a
|
||||||
|
|
||||||
-- Server loop, getting messages from the client and handling them
|
-- Server loop, getting messages from the client and handling them
|
||||||
serverLoop :: (Message -> Proto (ServerHandler a)) -> Proto (Maybe a)
|
serverLoop :: (Message -> Proto (ServerHandler a)) -> Proto (Maybe a)
|
||||||
serverLoop a = do
|
serverLoop a = serveOneMessage a serverLoop
|
||||||
|
|
||||||
|
-- Get one message from the client and handle it.
|
||||||
|
serveOneMessage
|
||||||
|
:: (Message -> Proto (ServerHandler a))
|
||||||
|
-> ((Message -> Proto (ServerHandler a)) -> Proto (Maybe a))
|
||||||
|
-> Proto (Maybe a)
|
||||||
|
serveOneMessage a cont = do
|
||||||
mcmd <- net receiveMessage
|
mcmd <- net receiveMessage
|
||||||
case mcmd of
|
case mcmd of
|
||||||
-- When the client sends ERROR to the server, the server
|
-- When the client sends ERROR to the server, the server
|
||||||
|
@ -480,16 +488,16 @@ serverLoop a = do
|
||||||
-- is in, and so not possible to recover.
|
-- is in, and so not possible to recover.
|
||||||
Just (ERROR _) -> return Nothing
|
Just (ERROR _) -> return Nothing
|
||||||
-- When the client sends an unparsable message, the server
|
-- When the client sends an unparsable message, the server
|
||||||
-- responds with an error message, and loops. This allows
|
-- responds with an error message, and continues. This allows
|
||||||
-- expanding the protocol with new messages.
|
-- expanding the protocol with new messages.
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
net $ sendMessage (ERROR "unknown command")
|
net $ sendMessage (ERROR "unknown command")
|
||||||
serverLoop a
|
cont a
|
||||||
Just cmd -> do
|
Just cmd -> do
|
||||||
v <- a cmd
|
v <- a cmd
|
||||||
case v of
|
case v of
|
||||||
ServerGot r -> return (Just r)
|
ServerGot r -> return (Just r)
|
||||||
ServerContinue -> serverLoop a
|
ServerContinue -> cont a
|
||||||
-- If the client sends an unexpected message,
|
-- If the client sends an unexpected message,
|
||||||
-- the server will respond with ERROR, and
|
-- the server will respond with ERROR, and
|
||||||
-- always continues processing messages.
|
-- always continues processing messages.
|
||||||
|
@ -501,7 +509,7 @@ serverLoop a = do
|
||||||
-- support some new feature, and fall back.
|
-- support some new feature, and fall back.
|
||||||
ServerUnexpected -> do
|
ServerUnexpected -> do
|
||||||
net $ sendMessage (ERROR "unexpected command")
|
net $ sendMessage (ERROR "unexpected command")
|
||||||
serverLoop a
|
cont a
|
||||||
|
|
||||||
-- | Serve the protocol, with an unauthenticated peer. Once the peer
|
-- | Serve the protocol, with an unauthenticated peer. Once the peer
|
||||||
-- successfully authenticates, returns their UUID.
|
-- successfully authenticates, returns their UUID.
|
||||||
|
@ -530,7 +538,18 @@ data ServerMode
|
||||||
|
|
||||||
-- | Serve the protocol, with a peer that has authenticated.
|
-- | Serve the protocol, with a peer that has authenticated.
|
||||||
serveAuthed :: ServerMode -> UUID -> Proto ()
|
serveAuthed :: ServerMode -> UUID -> Proto ()
|
||||||
serveAuthed servermode myuuid = void $ serverLoop handler
|
serveAuthed servermode myuuid = void $ serverLoop $
|
||||||
|
serverHandler servermode myuuid
|
||||||
|
|
||||||
|
-- | Serve a single command in the protocol, the same as serveAuthed,
|
||||||
|
-- but without looping to handle the next command.
|
||||||
|
serveOneCommandAuthed :: ServerMode -> UUID -> Proto ()
|
||||||
|
serveOneCommandAuthed servermode myuuid = fromMaybe () <$>
|
||||||
|
serveOneMessage (serverHandler servermode myuuid)
|
||||||
|
(const $ pure Nothing)
|
||||||
|
|
||||||
|
serverHandler :: ServerMode -> UUID -> Message -> Proto (ServerHandler ())
|
||||||
|
serverHandler servermode myuuid = handler
|
||||||
where
|
where
|
||||||
handler (VERSION theirversion) = do
|
handler (VERSION theirversion) = do
|
||||||
let v = min theirversion maxProtocolVersion
|
let v = min theirversion maxProtocolVersion
|
||||||
|
|
Loading…
Add table
Reference in a new issue