|
|
|
@ -127,9 +127,10 @@ startStream = runErrorT $ do |
|
|
|
(Secured , (Just (jid, _ ))) -> Just jid |
|
|
|
(Secured , (Just (jid, _ ))) -> Just jid |
|
|
|
(Secured , Nothing ) -> Nothing |
|
|
|
(Secured , Nothing ) -> Nothing |
|
|
|
(Closed , _ ) -> Nothing |
|
|
|
(Closed , _ ) -> Nothing |
|
|
|
|
|
|
|
(Finished , _ ) -> Nothing |
|
|
|
case streamAddress st of |
|
|
|
case streamAddress st of |
|
|
|
Nothing -> do |
|
|
|
Nothing -> do |
|
|
|
lift $ lift $ errorM "Pontarius.XMPP" "Server sent no hostname." |
|
|
|
lift $ lift $ errorM "Pontarius.Xmpp" "Server sent no hostname." |
|
|
|
throwError XmppOtherFailure |
|
|
|
throwError XmppOtherFailure |
|
|
|
Just address -> do |
|
|
|
Just address -> do |
|
|
|
pushing pushXmlDecl |
|
|
|
pushing pushXmlDecl |
|
|
|
@ -194,7 +195,7 @@ startStream = runErrorT $ do |
|
|
|
void . lift . pushElement . pickleElem xpStreamError |
|
|
|
void . lift . pushElement . pickleElem xpStreamError |
|
|
|
$ StreamErrorInfo sec Nothing el |
|
|
|
$ StreamErrorInfo sec Nothing el |
|
|
|
void . lift $ closeStreams' |
|
|
|
void . lift $ closeStreams' |
|
|
|
liftIO $ errorM "Pontarius.XMPP" $ "closeStreamWithError: " ++ msg |
|
|
|
liftIO $ errorM "Pontarius.Xmpp" $ "closeStreamWithError: " ++ msg |
|
|
|
throwError XmppOtherFailure |
|
|
|
throwError XmppOtherFailure |
|
|
|
checkchildren children = |
|
|
|
checkchildren children = |
|
|
|
let to' = lookup "to" children |
|
|
|
let to' = lookup "to" children |
|
|
|
@ -234,7 +235,7 @@ flattenAttrs attrs = Prelude.map (\(name, cont) -> |
|
|
|
-- and calls xmppStartStream. |
|
|
|
-- and calls xmppStartStream. |
|
|
|
restartStream :: StateT StreamState IO (Either XmppFailure ()) |
|
|
|
restartStream :: StateT StreamState IO (Either XmppFailure ()) |
|
|
|
restartStream = do |
|
|
|
restartStream = do |
|
|
|
liftIO $ debugM "Pontarius.XMPP" "Restarting stream..." |
|
|
|
liftIO $ debugM "Pontarius.Xmpp" "Restarting stream..." |
|
|
|
raw <- gets (streamReceive . streamHandle) |
|
|
|
raw <- gets (streamReceive . streamHandle) |
|
|
|
let newSource =loopRead raw $= XP.parseBytes def |
|
|
|
let newSource =loopRead raw $= XP.parseBytes def |
|
|
|
buffered <- liftIO . bufferSrc $ newSource |
|
|
|
buffered <- liftIO . bufferSrc $ newSource |
|
|
|
@ -309,7 +310,7 @@ streamS _expectedTo = do -- TODO: check expectedTo |
|
|
|
e <- lift $ elements =$ CL.head |
|
|
|
e <- lift $ elements =$ CL.head |
|
|
|
case e of |
|
|
|
case e of |
|
|
|
Nothing -> do |
|
|
|
Nothing -> do |
|
|
|
lift $ lift $ errorM "Pontarius.XMPP" "streamS: Stream ended." |
|
|
|
lift $ lift $ errorM "Pontarius.Xmpp" "streamS: Stream ended." |
|
|
|
throwError XmppOtherFailure |
|
|
|
throwError XmppOtherFailure |
|
|
|
Just r -> streamUnpickleElem xpStreamFeatures r |
|
|
|
Just r -> streamUnpickleElem xpStreamFeatures r |
|
|
|
|
|
|
|
|
|
|
|
@ -317,7 +318,7 @@ streamS _expectedTo = do -- TODO: check expectedTo |
|
|
|
-- realm. |
|
|
|
-- realm. |
|
|
|
openStream :: HostName -> StreamConfiguration -> IO (Either XmppFailure (Stream)) |
|
|
|
openStream :: HostName -> StreamConfiguration -> IO (Either XmppFailure (Stream)) |
|
|
|
openStream realm config = runErrorT $ do |
|
|
|
openStream realm config = runErrorT $ do |
|
|
|
lift $ debugM "Pontarius.XMPP" "Opening stream..." |
|
|
|
lift $ debugM "Pontarius.Xmpp" "Opening stream..." |
|
|
|
stream' <- createStream realm config |
|
|
|
stream' <- createStream realm config |
|
|
|
ErrorT . liftIO $ withStream startStream stream' |
|
|
|
ErrorT . liftIO $ withStream startStream stream' |
|
|
|
return stream' |
|
|
|
return stream' |
|
|
|
@ -330,7 +331,7 @@ closeStreams = withStream closeStreams' |
|
|
|
|
|
|
|
|
|
|
|
closeStreams' :: StateT StreamState IO (Either XmppFailure [Element]) |
|
|
|
closeStreams' :: StateT StreamState IO (Either XmppFailure [Element]) |
|
|
|
closeStreams' = do |
|
|
|
closeStreams' = do |
|
|
|
lift $ debugM "Pontarius.XMPP" "Closing stream..." |
|
|
|
lift $ debugM "Pontarius.Xmpp" "Closing stream..." |
|
|
|
send <- gets (streamSend . streamHandle) |
|
|
|
send <- gets (streamSend . streamHandle) |
|
|
|
cc <- gets (streamClose . streamHandle) |
|
|
|
cc <- gets (streamClose . streamHandle) |
|
|
|
void . liftIO $ send "</stream:stream>" |
|
|
|
void . liftIO $ send "</stream:stream>" |
|
|
|
@ -338,6 +339,7 @@ closeStreams' = do |
|
|
|
threadDelay 3000000 -- TODO: Configurable value |
|
|
|
threadDelay 3000000 -- TODO: Configurable value |
|
|
|
void ((Ex.try cc) :: IO (Either Ex.SomeException ())) |
|
|
|
void ((Ex.try cc) :: IO (Either Ex.SomeException ())) |
|
|
|
return () |
|
|
|
return () |
|
|
|
|
|
|
|
put xmppNoStream{ streamConnectionState = Finished } |
|
|
|
collectElems [] |
|
|
|
collectElems [] |
|
|
|
where |
|
|
|
where |
|
|
|
-- Pulls elements from the stream until the stream ends, or an error is |
|
|
|
-- Pulls elements from the stream until the stream ends, or an error is |
|
|
|
@ -361,7 +363,7 @@ wrapIOException action = do |
|
|
|
case r of |
|
|
|
case r of |
|
|
|
Right b -> return $ Right b |
|
|
|
Right b -> return $ Right b |
|
|
|
Left e -> do |
|
|
|
Left e -> do |
|
|
|
lift $ warningM "Pontarius.XMPP" $ "wrapIOException: Exception wrapped: " ++ (show e) |
|
|
|
lift $ warningM "Pontarius.Xmpp" $ "wrapIOException: Exception wrapped: " ++ (show e) |
|
|
|
return $ Left $ XmppIOException e |
|
|
|
return $ Left $ XmppIOException e |
|
|
|
|
|
|
|
|
|
|
|
pushElement :: Element -> StateT StreamState IO (Either XmppFailure Bool) |
|
|
|
pushElement :: Element -> StateT StreamState IO (Either XmppFailure Bool) |
|
|
|
@ -421,18 +423,18 @@ pullElement = do |
|
|
|
e <- runEventsSink (elements =$ await) |
|
|
|
e <- runEventsSink (elements =$ await) |
|
|
|
case e of |
|
|
|
case e of |
|
|
|
Nothing -> do |
|
|
|
Nothing -> do |
|
|
|
lift $ errorM "Pontarius.XMPP" "pullElement: Stream ended." |
|
|
|
lift $ errorM "Pontarius.Xmpp" "pullElement: Stream ended." |
|
|
|
return . Left $ XmppOtherFailure |
|
|
|
return . Left $ XmppOtherFailure |
|
|
|
Just r -> return $ Right r |
|
|
|
Just r -> return $ Right r |
|
|
|
) |
|
|
|
) |
|
|
|
[ ExL.Handler (\StreamEnd -> return $ Left StreamEndFailure) |
|
|
|
[ ExL.Handler (\StreamEnd -> return $ Left StreamEndFailure) |
|
|
|
, ExL.Handler (\(InvalidXmppXml s) -- Invalid XML `Event' encountered, or missing element close tag |
|
|
|
, ExL.Handler (\(InvalidXmppXml s) -- Invalid XML `Event' encountered, or missing element close tag |
|
|
|
-> do |
|
|
|
-> do |
|
|
|
lift $ errorM "Pontarius.XMPP" $ "pullElement: Invalid XML: " ++ (show s) |
|
|
|
lift $ errorM "Pontarius.Xmpp" $ "pullElement: Invalid XML: " ++ (show s) |
|
|
|
return . Left $ XmppOtherFailure) |
|
|
|
return . Left $ XmppOtherFailure) |
|
|
|
, ExL.Handler $ \(e :: InvalidEventStream) |
|
|
|
, ExL.Handler $ \(e :: InvalidEventStream) |
|
|
|
-> do |
|
|
|
-> do |
|
|
|
lift $ errorM "Pontarius.XMPP" $ "pullElement: Invalid event stream: " ++ (show e) |
|
|
|
lift $ errorM "Pontarius.Xmpp" $ "pullElement: Invalid event stream: " ++ (show e) |
|
|
|
return . Left $ XmppOtherFailure |
|
|
|
return . Left $ XmppOtherFailure |
|
|
|
] |
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
@ -446,7 +448,7 @@ pullUnpickle p = do |
|
|
|
let res = unpickleElem p elem' |
|
|
|
let res = unpickleElem p elem' |
|
|
|
case res of |
|
|
|
case res of |
|
|
|
Left e -> do |
|
|
|
Left e -> do |
|
|
|
lift $ errorM "Pontarius.XMPP" $ "pullUnpickle: Unpickle failed: " ++ (ppUnpickleError e) |
|
|
|
lift $ errorM "Pontarius.Xmpp" $ "pullUnpickle: Unpickle failed: " ++ (ppUnpickleError e) |
|
|
|
return . Left $ XmppOtherFailure |
|
|
|
return . Left $ XmppOtherFailure |
|
|
|
Right r -> return $ Right r |
|
|
|
Right r -> return $ Right r |
|
|
|
|
|
|
|
|
|
|
|
@ -470,18 +472,21 @@ catchPush p = ExL.catch |
|
|
|
_ -> ExL.throwIO e |
|
|
|
_ -> ExL.throwIO e |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
-- Stream state used when there is no connection. |
|
|
|
zeroHandle :: StreamHandle |
|
|
|
xmppNoStream :: StreamState |
|
|
|
zeroHandle = StreamHandle { streamSend = \_ -> return False |
|
|
|
xmppNoStream = StreamState { |
|
|
|
|
|
|
|
streamConnectionState = Closed |
|
|
|
|
|
|
|
, streamHandle = StreamHandle { streamSend = \_ -> return False |
|
|
|
|
|
|
|
, streamReceive = \_ -> do |
|
|
|
, streamReceive = \_ -> do |
|
|
|
errorM "Pontarius.XMPP" "xmppNoStream: No stream on receive." |
|
|
|
errorM "Pontarius.Xmpp" |
|
|
|
ExL.throwIO $ |
|
|
|
"xmppNoStream: Stream is closed." |
|
|
|
XmppOtherFailure |
|
|
|
ExL.throwIO XmppOtherFailure |
|
|
|
, streamFlush = return () |
|
|
|
, streamFlush = return () |
|
|
|
, streamClose = return () |
|
|
|
, streamClose = return () |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Stream state used when there is no connection. |
|
|
|
|
|
|
|
xmppNoStream :: StreamState |
|
|
|
|
|
|
|
xmppNoStream = StreamState { |
|
|
|
|
|
|
|
streamConnectionState = Closed |
|
|
|
|
|
|
|
, streamHandle = zeroHandle |
|
|
|
, streamEventSource = zeroSource |
|
|
|
, streamEventSource = zeroSource |
|
|
|
, streamFeatures = StreamFeatures Nothing [] [] |
|
|
|
, streamFeatures = StreamFeatures Nothing [] [] |
|
|
|
, streamAddress = Nothing |
|
|
|
, streamAddress = Nothing |
|
|
|
@ -494,7 +499,7 @@ xmppNoStream = StreamState { |
|
|
|
|
|
|
|
|
|
|
|
zeroSource :: Source IO output |
|
|
|
zeroSource :: Source IO output |
|
|
|
zeroSource = liftIO $ do |
|
|
|
zeroSource = liftIO $ do |
|
|
|
errorM "Pontarius.Xmpp" "zeroSource" |
|
|
|
debugM "Pontarius.Xmpp" "zeroSource" |
|
|
|
ExL.throwIO XmppOtherFailure |
|
|
|
ExL.throwIO XmppOtherFailure |
|
|
|
|
|
|
|
|
|
|
|
createStream :: HostName -> StreamConfiguration -> ErrorT XmppFailure IO (Stream) |
|
|
|
createStream :: HostName -> StreamConfiguration -> ErrorT XmppFailure IO (Stream) |
|
|
|
@ -705,14 +710,14 @@ srvLookup realm resolvSeed = ErrorT $ do |
|
|
|
rest <- orderSublist sublist'' |
|
|
|
rest <- orderSublist sublist'' |
|
|
|
return $ ((priority, weight, port, domain):rest) |
|
|
|
return $ ((priority, weight, port, domain):rest) |
|
|
|
|
|
|
|
|
|
|
|
-- Closes the connection and updates the XmppConMonad Stream state. |
|
|
|
-- | Close the connection and updates the XmppConMonad Stream state. Does |
|
|
|
-- killStream :: Stream -> IO (Either ExL.SomeException ()) |
|
|
|
-- not send the stream end tag. |
|
|
|
killStream :: Stream -> IO (Either XmppFailure ()) |
|
|
|
killStream :: Stream -> IO (Either XmppFailure ()) |
|
|
|
killStream = withStream $ do |
|
|
|
killStream = withStream $ do |
|
|
|
cc <- gets (streamClose . streamHandle) |
|
|
|
cc <- gets (streamClose . streamHandle) |
|
|
|
err <- wrapIOException cc |
|
|
|
err <- wrapIOException cc |
|
|
|
-- (ExL.try cc :: IO (Either ExL.SomeException ())) |
|
|
|
-- (ExL.try cc :: IO (Either ExL.SomeException ())) |
|
|
|
put xmppNoStream |
|
|
|
put xmppNoStream{ streamConnectionState = Finished } |
|
|
|
return err |
|
|
|
return err |
|
|
|
|
|
|
|
|
|
|
|
-- Sends an IQ request and waits for the response. If the response ID does not |
|
|
|
-- Sends an IQ request and waits for the response. If the response ID does not |
|
|
|
@ -734,13 +739,13 @@ pushIQ iqID to tp lang body stream = runErrorT $ do |
|
|
|
Right (IQResultS r) -> do |
|
|
|
Right (IQResultS r) -> do |
|
|
|
unless |
|
|
|
unless |
|
|
|
(iqID == iqResultID r) $ liftIO $ do |
|
|
|
(iqID == iqResultID r) $ liftIO $ do |
|
|
|
liftIO $ errorM "Pontarius.XMPP" $ "pushIQ: ID mismatch (" ++ (show iqID) ++ " /= " ++ (show $ iqResultID r) ++ ")." |
|
|
|
liftIO $ errorM "Pontarius.Xmpp" $ "pushIQ: ID mismatch (" ++ (show iqID) ++ " /= " ++ (show $ iqResultID r) ++ ")." |
|
|
|
liftIO $ ExL.throwIO XmppOtherFailure |
|
|
|
liftIO $ ExL.throwIO XmppOtherFailure |
|
|
|
-- TODO: Log: ("In sendIQ' IDs don't match: " ++ show iqID ++ |
|
|
|
-- TODO: Log: ("In sendIQ' IDs don't match: " ++ show iqID ++ |
|
|
|
-- " /= " ++ show (iqResultID r) ++ " .") |
|
|
|
-- " /= " ++ show (iqResultID r) ++ " .") |
|
|
|
return $ Right r |
|
|
|
return $ Right r |
|
|
|
_ -> do |
|
|
|
_ -> do |
|
|
|
liftIO $ errorM "Pontarius.XMPP" $ "pushIQ: Unexpected stanza type." |
|
|
|
liftIO $ errorM "Pontarius.Xmpp" $ "pushIQ: Unexpected stanza type." |
|
|
|
throwError XmppOtherFailure |
|
|
|
throwError XmppOtherFailure |
|
|
|
|
|
|
|
|
|
|
|
debugConduit :: (Show o, MonadIO m) => ConduitM o o m b |
|
|
|
debugConduit :: (Show o, MonadIO m) => ConduitM o o m b |
|
|
|
@ -748,7 +753,7 @@ debugConduit = forever $ do |
|
|
|
s' <- await |
|
|
|
s' <- await |
|
|
|
case s' of |
|
|
|
case s' of |
|
|
|
Just s -> do |
|
|
|
Just s -> do |
|
|
|
liftIO $ debugM "Pontarius.XMPP" $ "debugConduit: In: " ++ (show s) |
|
|
|
liftIO $ debugM "Pontarius.Xmpp" $ "debugConduit: In: " ++ (show s) |
|
|
|
yield s |
|
|
|
yield s |
|
|
|
Nothing -> return () |
|
|
|
Nothing -> return () |
|
|
|
|
|
|
|
|
|
|
|
|