forked from lavina/lavina
				
			xmpp stream error
This commit is contained in:
		
							parent
							
								
									9bd00a5789
								
							
						
					
					
						commit
						5766734029
					
				|  | @ -616,6 +616,7 @@ pub enum ConnectionMessage { | |||
|     Stop(StopReason), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum StopReason { | ||||
|     ServerShutdown, | ||||
|     InternalError, | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ use tokio_rustls::rustls::{Certificate, PrivateKey}; | |||
| use tokio_rustls::TlsAcceptor; | ||||
| 
 | ||||
| use lavina_core::auth::{Authenticator, Verdict}; | ||||
| use lavina_core::player::{ConnectionMessage, PlayerConnection, PlayerId, PlayerRegistry}; | ||||
| use lavina_core::player::{ConnectionMessage, PlayerConnection, PlayerId, PlayerRegistry, StopReason}; | ||||
| use lavina_core::prelude::*; | ||||
| use lavina_core::repo::Storage; | ||||
| use lavina_core::room::RoomRegistry; | ||||
|  | @ -31,6 +31,7 @@ use lavina_core::terminator::Terminator; | |||
| use lavina_core::LavinaCore; | ||||
| use proto_xmpp::bind::{Name, Resource}; | ||||
| use proto_xmpp::stream::*; | ||||
| use proto_xmpp::streamerror::{StreamError, StreamErrorKind}; | ||||
| use proto_xmpp::xml::{Continuation, FromXml, Parser, ToXml}; | ||||
| use sasl::AuthBody; | ||||
| 
 | ||||
|  | @ -404,12 +405,30 @@ async fn socket_final( | |||
|                         events.clear(); | ||||
|                         xml_writer.get_mut().flush().await?; | ||||
|                     } | ||||
|                     Some(ConnectionMessage::Stop(_)) => { | ||||
|                         tracing::debug!("Connection is being terminated"); | ||||
|                     Some(ConnectionMessage::Stop(reason)) => { | ||||
|                         tracing::debug!("Connection is being terminated: {reason:?}"); | ||||
|                         let kind = match reason { | ||||
|                             StopReason::ServerShutdown => StreamErrorKind::SystemShutdown, | ||||
|                             StopReason::InternalError => StreamErrorKind::InternalServerError, | ||||
|                         }; | ||||
|                         StreamError { kind }.serialize(&mut events); | ||||
|                         ServerStreamEnd.serialize(&mut events); | ||||
|                         for i in &events { | ||||
|                             xml_writer.write_event_async(i).await?; | ||||
|                         } | ||||
|                         events.clear(); | ||||
|                         xml_writer.get_mut().flush().await?; | ||||
|                         break; | ||||
|                     } | ||||
|                     None => { | ||||
|                         log::warn!("Player is terminated, must terminate the connection"); | ||||
|                         log::error!("Player is terminated, must terminate the connection"); | ||||
|                         StreamError { kind: StreamErrorKind::SystemShutdown }.serialize(&mut events); | ||||
|                         ServerStreamEnd.serialize(&mut events); | ||||
|                         for i in &events { | ||||
|                             xml_writer.write_event_async(i).await?; | ||||
|                         } | ||||
|                         events.clear(); | ||||
|                         xml_writer.get_mut().flush().await?; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ pub mod sasl; | |||
| pub mod session; | ||||
| pub mod stanzaerror; | ||||
| pub mod stream; | ||||
| pub mod streamerror; | ||||
| pub mod tls; | ||||
| pub mod xml; | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,41 @@ | |||
| use crate::xml::ToXml; | ||||
| use quick_xml::events::{BytesEnd, BytesStart, Event}; | ||||
| 
 | ||||
| /// Stream error condition
 | ||||
| ///
 | ||||
| /// [Spec](https://xmpp.org/rfcs/rfc6120.html#streams-error-conditions).
 | ||||
| pub enum StreamErrorKind { | ||||
|     /// The server has experienced a misconfiguration or other internal error that prevents it from servicing the stream.
 | ||||
|     InternalServerError, | ||||
|     /// The server is being shut down and all active streams are being closed.
 | ||||
|     SystemShutdown, | ||||
| } | ||||
| impl StreamErrorKind { | ||||
|     pub fn from_str(s: &str) -> Option<Self> { | ||||
|         match s { | ||||
|             "internal-server-error" => Some(Self::InternalServerError), | ||||
|             "system-shutdown" => Some(Self::SystemShutdown), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
|     pub fn as_str(&self) -> &'static str { | ||||
|         match self { | ||||
|             Self::InternalServerError => "internal-server-error", | ||||
|             Self::SystemShutdown => "system-shutdown", | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct StreamError { | ||||
|     pub kind: StreamErrorKind, | ||||
| } | ||||
| impl ToXml for StreamError { | ||||
|     fn serialize(&self, events: &mut Vec<Event<'static>>) { | ||||
|         events.push(Event::Start(BytesStart::new("stream:error"))); | ||||
|         events.push(Event::Empty(BytesStart::new(format!( | ||||
|             r#"{} xmlns="urn:ietf:params:xml:ns:xmpp-streams""#, | ||||
|             self.kind.as_str() | ||||
|         )))); | ||||
|         events.push(Event::End(BytesEnd::new("stream:error"))); | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue