1use crate::error::CodecError;
11use crate::kvp::KeyValuePair;
12use crate::types::read_bytes;
13use crate::types::*;
14use crate::types::{check_group_range, check_location_range, check_open_ended_group_range};
15use crate::varint::VarInt;
16use bytes::{Buf, BufMut};
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20#[repr(u64)]
21pub enum MessageType {
22 SubscribeUpdate = 0x02,
24 Subscribe = 0x03,
26 SubscribeOk = 0x04,
28 SubscribeError = 0x05,
30 Announce = 0x06,
32 AnnounceOk = 0x07,
34 AnnounceError = 0x08,
36 Unannounce = 0x09,
38 Unsubscribe = 0x0A,
40 SubscribeDone = 0x0B,
42 AnnounceCancel = 0x0C,
44 TrackStatusRequest = 0x0D,
46 TrackStatus = 0x0E,
48 GoAway = 0x10,
50 SubscribeAnnounces = 0x11,
52 SubscribeAnnouncesOk = 0x12,
54 SubscribeAnnouncesError = 0x13,
56 UnsubscribeAnnounces = 0x14,
58 MaxSubscribeId = 0x15,
60 Fetch = 0x16,
62 FetchCancel = 0x17,
64 FetchOk = 0x18,
66 FetchError = 0x19,
68 SubscribesBlocked = 0x1A,
70 ClientSetup = 0x40,
72 ServerSetup = 0x41,
74}
75
76impl MessageType {
77 pub fn from_id(id: u64) -> Option<Self> {
79 match id {
80 0x02 => Some(MessageType::SubscribeUpdate),
81 0x03 => Some(MessageType::Subscribe),
82 0x04 => Some(MessageType::SubscribeOk),
83 0x05 => Some(MessageType::SubscribeError),
84 0x06 => Some(MessageType::Announce),
85 0x07 => Some(MessageType::AnnounceOk),
86 0x08 => Some(MessageType::AnnounceError),
87 0x09 => Some(MessageType::Unannounce),
88 0x0A => Some(MessageType::Unsubscribe),
89 0x0B => Some(MessageType::SubscribeDone),
90 0x0C => Some(MessageType::AnnounceCancel),
91 0x0D => Some(MessageType::TrackStatusRequest),
92 0x0E => Some(MessageType::TrackStatus),
93 0x10 => Some(MessageType::GoAway),
94 0x11 => Some(MessageType::SubscribeAnnounces),
95 0x12 => Some(MessageType::SubscribeAnnouncesOk),
96 0x13 => Some(MessageType::SubscribeAnnouncesError),
97 0x14 => Some(MessageType::UnsubscribeAnnounces),
98 0x15 => Some(MessageType::MaxSubscribeId),
99 0x16 => Some(MessageType::Fetch),
100 0x17 => Some(MessageType::FetchCancel),
101 0x18 => Some(MessageType::FetchOk),
102 0x19 => Some(MessageType::FetchError),
103 0x1A => Some(MessageType::SubscribesBlocked),
104 0x40 => Some(MessageType::ClientSetup),
105 0x41 => Some(MessageType::ServerSetup),
106 _ => None,
107 }
108 }
109
110 pub fn id(&self) -> u64 {
112 *self as u64
113 }
114
115 pub fn name(&self) -> &'static str {
118 match self {
119 MessageType::SubscribeUpdate => "subscribe_update",
120 MessageType::Subscribe => "subscribe",
121 MessageType::SubscribeOk => "subscribe_ok",
122 MessageType::SubscribeError => "subscribe_error",
123 MessageType::Announce => "announce",
124 MessageType::AnnounceOk => "announce_ok",
125 MessageType::AnnounceError => "announce_error",
126 MessageType::Unannounce => "unannounce",
127 MessageType::Unsubscribe => "unsubscribe",
128 MessageType::SubscribeDone => "subscribe_done",
129 MessageType::AnnounceCancel => "announce_cancel",
130 MessageType::TrackStatusRequest => "track_status_request",
131 MessageType::TrackStatus => "track_status",
132 MessageType::GoAway => "goaway",
133 MessageType::SubscribeAnnounces => "subscribe_announces",
134 MessageType::SubscribeAnnouncesOk => "subscribe_announces_ok",
135 MessageType::SubscribeAnnouncesError => "subscribe_announces_error",
136 MessageType::UnsubscribeAnnounces => "unsubscribe_announces",
137 MessageType::MaxSubscribeId => "max_subscribe_id",
138 MessageType::Fetch => "fetch",
139 MessageType::FetchCancel => "fetch_cancel",
140 MessageType::FetchOk => "fetch_ok",
141 MessageType::FetchError => "fetch_error",
142 MessageType::SubscribesBlocked => "subscribes_blocked",
143 MessageType::ClientSetup => "client_setup",
144 MessageType::ServerSetup => "server_setup",
145 }
146 }
147}
148
149#[derive(Debug, Clone, PartialEq, Eq)]
155pub struct ClientSetup {
156 pub supported_versions: Vec<VarInt>,
158 pub parameters: Vec<KeyValuePair>,
160}
161
162#[derive(Debug, Clone, PartialEq, Eq)]
164pub struct ServerSetup {
165 pub selected_version: VarInt,
167 pub parameters: Vec<KeyValuePair>,
169}
170
171#[derive(Debug, Clone, PartialEq, Eq)]
173pub struct GoAway {
174 pub new_session_uri: Vec<u8>,
176}
177
178#[derive(Debug, Clone, PartialEq, Eq)]
180pub struct MaxSubscribeId {
181 pub subscribe_id: VarInt,
183}
184
185#[derive(Debug, Clone, PartialEq, Eq)]
187pub struct SubscribesBlocked {
188 pub maximum_subscribe_id: VarInt,
190}
191
192#[derive(Debug, Clone, PartialEq, Eq)]
201pub struct Subscribe {
202 pub subscribe_id: VarInt,
204 pub track_alias: VarInt,
206 pub track_namespace: TrackNamespace,
208 pub track_name: Vec<u8>,
210 pub subscriber_priority: u8,
212 pub group_order: GroupOrder,
214 pub filter_type: FilterType,
216 pub start_location: Option<Location>,
218 pub end_group: Option<VarInt>,
220 pub parameters: Vec<KeyValuePair>,
222}
223
224#[derive(Debug, Clone, PartialEq, Eq)]
226pub struct SubscribeOk {
227 pub subscribe_id: VarInt,
229 pub expires: VarInt,
231 pub group_order: GroupOrder,
233 pub content_exists: ContentExists,
235 pub largest_group_id: Option<VarInt>,
237 pub largest_object_id: Option<VarInt>,
239 pub parameters: Vec<KeyValuePair>,
241}
242
243#[derive(Debug, Clone, PartialEq, Eq)]
245pub struct SubscribeError {
246 pub subscribe_id: VarInt,
248 pub error_code: VarInt,
250 pub reason_phrase: Vec<u8>,
252 pub track_alias: VarInt,
254}
255
256#[derive(Debug, Clone, PartialEq, Eq)]
258pub struct SubscribeUpdate {
259 pub subscribe_id: VarInt,
261 pub start_group: VarInt,
263 pub start_object: VarInt,
265 pub end_group: VarInt,
267 pub subscriber_priority: u8,
269 pub parameters: Vec<KeyValuePair>,
271}
272
273#[derive(Debug, Clone, PartialEq, Eq)]
275pub struct SubscribeDone {
276 pub subscribe_id: VarInt,
278 pub status_code: VarInt,
280 pub stream_count: VarInt,
282 pub reason_phrase: Vec<u8>,
284}
285
286#[derive(Debug, Clone, PartialEq, Eq)]
288pub struct Unsubscribe {
289 pub subscribe_id: VarInt,
291}
292
293#[derive(Debug, Clone, PartialEq, Eq)]
299pub struct Announce {
300 pub track_namespace: TrackNamespace,
302 pub parameters: Vec<KeyValuePair>,
304}
305
306#[derive(Debug, Clone, PartialEq, Eq)]
308pub struct AnnounceOk {
309 pub track_namespace: TrackNamespace,
311}
312
313#[derive(Debug, Clone, PartialEq, Eq)]
315pub struct AnnounceError {
316 pub track_namespace: TrackNamespace,
318 pub error_code: VarInt,
320 pub reason_phrase: Vec<u8>,
322}
323
324#[derive(Debug, Clone, PartialEq, Eq)]
326pub struct AnnounceCancel {
327 pub track_namespace: TrackNamespace,
329 pub error_code: VarInt,
331 pub reason_phrase: Vec<u8>,
333}
334
335#[derive(Debug, Clone, PartialEq, Eq)]
337pub struct Unannounce {
338 pub track_namespace: TrackNamespace,
340}
341
342#[derive(Debug, Clone, PartialEq, Eq)]
348pub struct SubscribeAnnounces {
349 pub track_namespace_prefix: TrackNamespace,
351 pub parameters: Vec<KeyValuePair>,
353}
354
355#[derive(Debug, Clone, PartialEq, Eq)]
357pub struct SubscribeAnnouncesOk {
358 pub track_namespace_prefix: TrackNamespace,
360}
361
362#[derive(Debug, Clone, PartialEq, Eq)]
364pub struct SubscribeAnnouncesError {
365 pub track_namespace_prefix: TrackNamespace,
367 pub error_code: VarInt,
369 pub reason_phrase: Vec<u8>,
371}
372
373#[derive(Debug, Clone, PartialEq, Eq)]
375pub struct UnsubscribeAnnounces {
376 pub track_namespace_prefix: TrackNamespace,
378}
379
380#[derive(Debug, Clone, PartialEq, Eq)]
386pub struct TrackStatusRequest {
387 pub track_namespace: TrackNamespace,
389 pub track_name: Vec<u8>,
391}
392
393#[derive(Debug, Clone, PartialEq, Eq)]
395pub struct TrackStatus {
396 pub track_namespace: TrackNamespace,
398 pub track_name: Vec<u8>,
400 pub status_code: VarInt,
402 pub last_group_id: VarInt,
404 pub last_object_id: VarInt,
406}
407
408#[derive(Debug, Clone, Copy, PartialEq, Eq)]
414#[repr(u64)]
415pub enum FetchType {
416 Standalone = 1,
418 Joining = 2,
420}
421
422impl FetchType {
423 pub fn from_u64(v: u64) -> Option<Self> {
425 match v {
426 1 => Some(FetchType::Standalone),
427 2 => Some(FetchType::Joining),
428 _ => None,
429 }
430 }
431}
432
433#[derive(Debug, Clone, PartialEq, Eq)]
435pub struct Fetch {
436 pub subscribe_id: VarInt,
438 pub subscriber_priority: u8,
440 pub group_order: GroupOrder,
442 pub fetch_type: FetchType,
444 pub track_namespace: Option<TrackNamespace>,
446 pub track_name: Option<Vec<u8>>,
448 pub start_group: Option<VarInt>,
450 pub start_object: Option<VarInt>,
452 pub end_group: Option<VarInt>,
454 pub end_object: Option<VarInt>,
456 pub joining_subscribe_id: Option<VarInt>,
458 pub preceding_group_offset: Option<VarInt>,
460 pub parameters: Vec<KeyValuePair>,
462}
463
464#[derive(Debug, Clone, PartialEq, Eq)]
466pub struct FetchOk {
467 pub subscribe_id: VarInt,
469 pub group_order: GroupOrder,
471 pub end_of_track: u8,
473 pub largest_group_id: VarInt,
475 pub largest_object_id: VarInt,
477 pub parameters: Vec<KeyValuePair>,
479}
480
481#[derive(Debug, Clone, PartialEq, Eq)]
483pub struct FetchError {
484 pub subscribe_id: VarInt,
486 pub error_code: VarInt,
488 pub reason_phrase: Vec<u8>,
490}
491
492#[derive(Debug, Clone, PartialEq, Eq)]
494pub struct FetchCancel {
495 pub subscribe_id: VarInt,
497}
498
499fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
514 if !buf.has_remaining() {
515 return Err(CodecError::UnexpectedEnd);
516 }
517 match GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)? {
518 GroupOrder::Publisher => Err(CodecError::InvalidField),
519 order => Ok(order),
520 }
521}
522
523fn check_track_status(
534 status_code: VarInt,
535 last_group_id: VarInt,
536 last_object_id: VarInt,
537) -> Result<(), CodecError> {
538 let code = crate::draft10::error_codes::TrackStatusCode::from_u64(status_code.into_inner())
539 .ok_or(CodecError::InvalidField)?;
540 if code.requires_zero_location()
541 && (last_group_id.into_inner() != 0 || last_object_id.into_inner() != 0)
542 {
543 return Err(CodecError::InvalidField);
544 }
545 Ok(())
546}
547
548fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
559 match message {
560 ControlMessage::Subscribe(m) => {
561 if m.filter_type == FilterType::NextGroupStart {
563 return Err(CodecError::InvalidField);
564 }
565 let wants_start =
566 matches!(m.filter_type, FilterType::AbsoluteStart | FilterType::AbsoluteRange);
567 if wants_start != m.start_location.is_some() {
568 return Err(CodecError::InvalidField);
569 }
570 if (m.filter_type == FilterType::AbsoluteRange) != m.end_group.is_some() {
571 return Err(CodecError::InvalidField);
572 }
573 Ok(())
574 }
575 ControlMessage::SubscribeOk(m) => {
576 let has = m.content_exists == ContentExists::HasLargestLocation;
577 if has != m.largest_group_id.is_some() || has != m.largest_object_id.is_some() {
578 return Err(CodecError::InvalidField);
579 }
580 Ok(())
581 }
582 ControlMessage::Fetch(m) => {
583 let standalone = m.fetch_type == FetchType::Standalone;
584 let standalone_fields = [
585 m.track_namespace.is_some(),
586 m.track_name.is_some(),
587 m.start_group.is_some(),
588 m.start_object.is_some(),
589 m.end_group.is_some(),
590 m.end_object.is_some(),
591 ];
592 if standalone_fields.iter().any(|present| *present != standalone) {
593 return Err(CodecError::InvalidField);
594 }
595 let joining_fields =
596 [m.joining_subscribe_id.is_some(), m.preceding_group_offset.is_some()];
597 if joining_fields.contains(&standalone) {
598 return Err(CodecError::InvalidField);
599 }
600 Ok(())
601 }
602 _ => Ok(()),
603 }
604}
605
606fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
611 let order = match message {
612 ControlMessage::SubscribeOk(m) => m.group_order,
613 ControlMessage::FetchOk(m) => m.group_order,
614 _ => return Ok(()),
615 };
616 if order == GroupOrder::Publisher {
617 return Err(CodecError::InvalidField);
618 }
619 Ok(())
620}
621
622#[derive(Debug, Clone, PartialEq, Eq)]
624pub enum ControlMessage {
625 ClientSetup(ClientSetup),
627 ServerSetup(ServerSetup),
629 GoAway(GoAway),
631 MaxSubscribeId(MaxSubscribeId),
633 SubscribesBlocked(SubscribesBlocked),
635 Subscribe(Subscribe),
637 SubscribeOk(SubscribeOk),
639 SubscribeError(SubscribeError),
641 SubscribeUpdate(SubscribeUpdate),
643 SubscribeDone(SubscribeDone),
645 Unsubscribe(Unsubscribe),
647 Announce(Announce),
649 AnnounceOk(AnnounceOk),
651 AnnounceError(AnnounceError),
653 AnnounceCancel(AnnounceCancel),
655 Unannounce(Unannounce),
657 SubscribeAnnounces(SubscribeAnnounces),
659 SubscribeAnnouncesOk(SubscribeAnnouncesOk),
661 SubscribeAnnouncesError(SubscribeAnnouncesError),
663 UnsubscribeAnnounces(UnsubscribeAnnounces),
665 TrackStatusRequest(TrackStatusRequest),
667 TrackStatus(TrackStatus),
669 Fetch(Fetch),
671 FetchOk(FetchOk),
673 FetchError(FetchError),
675 FetchCancel(FetchCancel),
677}
678
679fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
693 match message {
694 ControlMessage::Subscribe(m) => match (&m.start_location, &m.end_group) {
695 (Some(start), Some(end_group)) => {
696 check_group_range(start.group.into_inner(), end_group.into_inner())
697 }
698 _ => Ok(()),
699 },
700 ControlMessage::SubscribeUpdate(m) => {
701 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
702 }
703 ControlMessage::Fetch(m) => {
704 match (&m.start_group, &m.start_object, &m.end_group, &m.end_object) {
705 (Some(start_group), Some(start_object), Some(end_group), Some(end_object)) => {
706 check_location_range(
707 start_group.into_inner(),
708 start_object.into_inner(),
709 end_group.into_inner(),
710 end_object.into_inner(),
711 )
712 }
713 _ => Ok(()),
714 }
715 }
716 _ => Ok(()),
717 }
718}
719
720fn check_no_duplicate_parameters(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
731 for (i, parameter) in parameters.iter().enumerate() {
732 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
733 return Err(CodecError::DuplicateParameter(parameter.key.into_inner()));
734 }
735 }
736 Ok(())
737}
738
739const SETUP_VARINT_PARAMETERS: &[u64] = &[0x02];
746
747const VERSION_VARINT_PARAMETERS: &[u64] = &[0x03, 0x04];
760
761fn check_parameter_lengths(
779 parameters: &[KeyValuePair],
780 varint_typed: &[u64],
781) -> Result<(), CodecError> {
782 for parameter in parameters {
783 let key = parameter.key.into_inner();
784 if !varint_typed.contains(&key) {
785 continue;
786 }
787 if let crate::kvp::KvpValue::Bytes(bytes) = ¶meter.value {
788 let mut cursor = &bytes[..];
789 let one_varint = VarInt::decode(&mut cursor).is_ok() && !cursor.has_remaining();
790 if !one_varint {
791 return Err(CodecError::ParameterLengthMismatch(key));
792 }
793 }
794 }
795 Ok(())
796}
797
798fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
801 let parameters = KeyValuePair::decode_list_d07(buf)?;
802 check_no_duplicate_parameters(¶meters)?;
803 check_parameter_lengths(¶meters, VERSION_VARINT_PARAMETERS)?;
804 Ok(parameters)
805}
806
807fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
810 check_no_duplicate_parameters(parameters)?;
811 check_parameter_lengths(parameters, VERSION_VARINT_PARAMETERS)?;
812 KeyValuePair::encode_list_d07(parameters, buf);
813 Ok(())
814}
815
816fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
822 let parameters = KeyValuePair::decode_list_d07(buf)?;
823 check_no_duplicate_parameters(¶meters)?;
824 check_parameter_lengths(¶meters, SETUP_VARINT_PARAMETERS)?;
825 Ok(parameters)
826}
827
828fn encode_setup_parameters(
830 parameters: &[KeyValuePair],
831 buf: &mut impl BufMut,
832) -> Result<(), CodecError> {
833 check_no_duplicate_parameters(parameters)?;
834 check_parameter_lengths(parameters, SETUP_VARINT_PARAMETERS)?;
835 KeyValuePair::encode_list_d07(parameters, buf);
836 Ok(())
837}
838
839impl ControlMessage {
840 pub fn message_type(&self) -> MessageType {
842 match self {
843 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
844 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
845 ControlMessage::GoAway(_) => MessageType::GoAway,
846 ControlMessage::MaxSubscribeId(_) => MessageType::MaxSubscribeId,
847 ControlMessage::SubscribesBlocked(_) => MessageType::SubscribesBlocked,
848 ControlMessage::Subscribe(_) => MessageType::Subscribe,
849 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
850 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
851 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
852 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
853 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
854 ControlMessage::Announce(_) => MessageType::Announce,
855 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
856 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
857 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
858 ControlMessage::Unannounce(_) => MessageType::Unannounce,
859 ControlMessage::SubscribeAnnounces(_) => MessageType::SubscribeAnnounces,
860 ControlMessage::SubscribeAnnouncesOk(_) => MessageType::SubscribeAnnouncesOk,
861 ControlMessage::SubscribeAnnouncesError(_) => MessageType::SubscribeAnnouncesError,
862 ControlMessage::UnsubscribeAnnounces(_) => MessageType::UnsubscribeAnnounces,
863 ControlMessage::TrackStatusRequest(_) => MessageType::TrackStatusRequest,
864 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
865 ControlMessage::Fetch(_) => MessageType::Fetch,
866 ControlMessage::FetchOk(_) => MessageType::FetchOk,
867 ControlMessage::FetchError(_) => MessageType::FetchError,
868 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
869 }
870 }
871
872 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
874 check_discriminators(self)?;
875 check_group_order(self)?;
876 check_ranges(self)?;
877 let mut payload = Vec::with_capacity(256);
878 self.encode_payload(&mut payload)?;
879
880 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
888 VarInt::from_usize(payload.len()).encode(buf);
889 buf.put_slice(&payload);
890 Ok(())
891 }
892
893 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
895 let type_id = VarInt::decode(buf)?.into_inner();
896 let msg_type =
897 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
898 let payload_len = VarInt::decode(buf)?.into_inner() as usize;
899 if buf.remaining() < payload_len {
900 return Err(CodecError::UnexpectedEnd);
901 }
902 let payload_bytes = buf.copy_to_bytes(payload_len);
903 let mut payload = &payload_bytes[..];
904 let msg = match Self::decode_payload(msg_type, &mut payload) {
905 Ok(msg) => msg,
906 Err(
912 CodecError::UnexpectedEnd
913 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
914 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
915 crate::varint::VarIntError::UnexpectedEnd,
916 ))
917 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
918 ) => {
919 return Err(CodecError::ControlMessageLengthMismatch {
920 declared: payload_len,
921 detail: "its fields ran past the end",
922 });
923 }
924 Err(e) => return Err(e),
925 };
926 check_ranges(&msg)?;
927 if payload.has_remaining() {
932 return Err(CodecError::ControlMessageLengthMismatch {
933 declared: payload_len,
934 detail: "its fields left bytes unread",
935 });
936 }
937 Ok(msg)
938 }
939
940 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
941 match self {
942 ControlMessage::ClientSetup(m) => {
943 VarInt::from_usize(m.supported_versions.len()).encode(buf);
944 for v in &m.supported_versions {
945 v.encode(buf);
946 }
947 encode_setup_parameters(&m.parameters, buf)?;
948 }
949 ControlMessage::ServerSetup(m) => {
950 m.selected_version.encode(buf);
951 encode_setup_parameters(&m.parameters, buf)?;
952 }
953 ControlMessage::GoAway(m) => {
954 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
955 buf.put_slice(&m.new_session_uri);
956 }
957 ControlMessage::MaxSubscribeId(m) => {
958 m.subscribe_id.encode(buf);
959 }
960 ControlMessage::SubscribesBlocked(m) => {
961 m.maximum_subscribe_id.encode(buf);
962 }
963 ControlMessage::Subscribe(m) => {
964 m.subscribe_id.encode(buf);
965 m.track_alias.encode(buf);
966 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
967 m.track_namespace.encode(buf);
968 VarInt::from_usize(m.track_name.len()).encode(buf);
969 buf.put_slice(&m.track_name);
970 buf.put_u8(m.subscriber_priority);
971 buf.put_u8(m.group_order as u8);
972 VarInt::from_usize(m.filter_type as usize).encode(buf);
973 if let Some(loc) = &m.start_location {
974 loc.encode(buf);
975 }
976 if let Some(eg) = &m.end_group {
977 eg.encode(buf);
978 }
979 encode_parameters(&m.parameters, buf)?;
980 }
981 ControlMessage::SubscribeOk(m) => {
982 m.subscribe_id.encode(buf);
983 m.expires.encode(buf);
984 buf.put_u8(m.group_order as u8);
985 buf.put_u8(m.content_exists as u8);
986 if let Some(gid) = &m.largest_group_id {
987 gid.encode(buf);
988 }
989 if let Some(oid) = &m.largest_object_id {
990 oid.encode(buf);
991 }
992 encode_parameters(&m.parameters, buf)?;
993 }
994 ControlMessage::SubscribeError(m) => {
995 m.subscribe_id.encode(buf);
996 m.error_code.encode(buf);
997 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
998 buf.put_slice(&m.reason_phrase);
999 m.track_alias.encode(buf);
1000 }
1001 ControlMessage::SubscribeUpdate(m) => {
1002 m.subscribe_id.encode(buf);
1003 m.start_group.encode(buf);
1004 m.start_object.encode(buf);
1005 m.end_group.encode(buf);
1006 buf.put_u8(m.subscriber_priority);
1007 encode_parameters(&m.parameters, buf)?;
1008 }
1009 ControlMessage::SubscribeDone(m) => {
1010 m.subscribe_id.encode(buf);
1011 m.status_code.encode(buf);
1012 m.stream_count.encode(buf);
1013 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1014 buf.put_slice(&m.reason_phrase);
1015 }
1016 ControlMessage::Unsubscribe(m) => {
1017 m.subscribe_id.encode(buf);
1018 }
1019 ControlMessage::Announce(m) => {
1020 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
1021 m.track_namespace.encode(buf);
1022 encode_parameters(&m.parameters, buf)?;
1023 }
1024 ControlMessage::AnnounceOk(m) => {
1025 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
1026 m.track_namespace.encode(buf);
1027 }
1028 ControlMessage::AnnounceError(m) => {
1029 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
1030 m.track_namespace.encode(buf);
1031 m.error_code.encode(buf);
1032 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1033 buf.put_slice(&m.reason_phrase);
1034 }
1035 ControlMessage::AnnounceCancel(m) => {
1036 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
1037 m.track_namespace.encode(buf);
1038 m.error_code.encode(buf);
1039 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1040 buf.put_slice(&m.reason_phrase);
1041 }
1042 ControlMessage::Unannounce(m) => {
1043 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
1044 m.track_namespace.encode(buf);
1045 }
1046 ControlMessage::SubscribeAnnounces(m) => {
1047 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(10))?;
1048 m.track_namespace_prefix.encode(buf);
1049 encode_parameters(&m.parameters, buf)?;
1050 }
1051 ControlMessage::SubscribeAnnouncesOk(m) => {
1052 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(10))?;
1053 m.track_namespace_prefix.encode(buf);
1054 }
1055 ControlMessage::SubscribeAnnouncesError(m) => {
1056 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(10))?;
1057 m.track_namespace_prefix.encode(buf);
1058 m.error_code.encode(buf);
1059 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1060 buf.put_slice(&m.reason_phrase);
1061 }
1062 ControlMessage::UnsubscribeAnnounces(m) => {
1063 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(10))?;
1064 m.track_namespace_prefix.encode(buf);
1065 }
1066 ControlMessage::TrackStatusRequest(m) => {
1067 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
1068 m.track_namespace.encode(buf);
1069 VarInt::from_usize(m.track_name.len()).encode(buf);
1070 buf.put_slice(&m.track_name);
1071 }
1072 ControlMessage::TrackStatus(m) => {
1073 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
1074 m.track_namespace.encode(buf);
1075 VarInt::from_usize(m.track_name.len()).encode(buf);
1076 buf.put_slice(&m.track_name);
1077 check_track_status(m.status_code, m.last_group_id, m.last_object_id)?;
1078 m.status_code.encode(buf);
1079 m.last_group_id.encode(buf);
1080 m.last_object_id.encode(buf);
1081 }
1082 ControlMessage::Fetch(m) => {
1083 m.subscribe_id.encode(buf);
1084 buf.put_u8(m.subscriber_priority);
1085 buf.put_u8(m.group_order as u8);
1086 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1087 match m.fetch_type {
1088 FetchType::Standalone => {
1089 if let Some(ns) = &m.track_namespace {
1090 ns.encode(buf);
1091 }
1092 if let Some(name) = &m.track_name {
1093 VarInt::from_usize(name.len()).encode(buf);
1094 buf.put_slice(name);
1095 }
1096 if let Some(sg) = &m.start_group {
1097 sg.encode(buf);
1098 }
1099 if let Some(so) = &m.start_object {
1100 so.encode(buf);
1101 }
1102 if let Some(eg) = &m.end_group {
1103 eg.encode(buf);
1104 }
1105 if let Some(eo) = &m.end_object {
1106 eo.encode(buf);
1107 }
1108 }
1109 FetchType::Joining => {
1110 if let Some(jsi) = &m.joining_subscribe_id {
1111 jsi.encode(buf);
1112 }
1113 if let Some(pgo) = &m.preceding_group_offset {
1114 pgo.encode(buf);
1115 }
1116 }
1117 }
1118 encode_parameters(&m.parameters, buf)?;
1119 }
1120 ControlMessage::FetchOk(m) => {
1121 m.subscribe_id.encode(buf);
1122 buf.put_u8(m.group_order as u8);
1123 buf.put_u8(m.end_of_track);
1124 m.largest_group_id.encode(buf);
1125 m.largest_object_id.encode(buf);
1126 encode_parameters(&m.parameters, buf)?;
1127 }
1128 ControlMessage::FetchError(m) => {
1129 m.subscribe_id.encode(buf);
1130 m.error_code.encode(buf);
1131 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1132 buf.put_slice(&m.reason_phrase);
1133 }
1134 ControlMessage::FetchCancel(m) => {
1135 m.subscribe_id.encode(buf);
1136 }
1137 }
1138 Ok(())
1139 }
1140
1141 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1142 match msg_type {
1143 MessageType::ClientSetup => {
1144 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1145 if num_versions == 0 {
1155 return Err(CodecError::InvalidField);
1156 }
1157 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1158 for _ in 0..num_versions {
1159 supported_versions.push(VarInt::decode(buf)?);
1160 }
1161 let parameters = decode_setup_parameters(buf)?;
1162 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1163 }
1164 MessageType::ServerSetup => {
1165 let selected_version = VarInt::decode(buf)?;
1166 let parameters = decode_setup_parameters(buf)?;
1167 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1168 }
1169 MessageType::GoAway => {
1170 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1171 let uri = read_bytes(buf, uri_len)?;
1172 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1173 }
1174 MessageType::MaxSubscribeId => {
1175 let subscribe_id = VarInt::decode(buf)?;
1176 Ok(ControlMessage::MaxSubscribeId(MaxSubscribeId { subscribe_id }))
1177 }
1178 MessageType::SubscribesBlocked => {
1179 let maximum_subscribe_id = VarInt::decode(buf)?;
1180 Ok(ControlMessage::SubscribesBlocked(SubscribesBlocked { maximum_subscribe_id }))
1181 }
1182 MessageType::Subscribe => {
1183 let subscribe_id = VarInt::decode(buf)?;
1184 let track_alias = VarInt::decode(buf)?;
1185 let track_namespace = TrackNamespace::decode(buf)?;
1186 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1187 let track_name = read_bytes(buf, track_name_len)?;
1188 if buf.remaining() < 2 {
1189 return Err(CodecError::UnexpectedEnd);
1190 }
1191 let subscriber_priority = buf.get_u8();
1192 let group_order =
1193 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1194 let filter_val = VarInt::decode(buf)?.into_inner();
1195 if filter_val == 1 {
1198 return Err(CodecError::InvalidFilterType(filter_val));
1199 }
1200 let filter_type = FilterType::from_u64(filter_val)
1201 .ok_or(CodecError::InvalidFilterType(filter_val))?;
1202 let start_location = match filter_type {
1203 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1204 Some(Location::decode(buf)?)
1205 }
1206 _ => None,
1207 };
1208 let end_group = match filter_type {
1209 FilterType::AbsoluteRange => Some(VarInt::decode(buf)?),
1210 _ => None,
1211 };
1212 let parameters = decode_parameters(buf)?;
1213 Ok(ControlMessage::Subscribe(Subscribe {
1214 subscribe_id,
1215 track_alias,
1216 track_namespace,
1217 track_name,
1218 subscriber_priority,
1219 group_order,
1220 filter_type,
1221 start_location,
1222 end_group,
1223 parameters,
1224 }))
1225 }
1226 MessageType::SubscribeOk => {
1227 let subscribe_id = VarInt::decode(buf)?;
1228 let expires = VarInt::decode(buf)?;
1229 if buf.remaining() < 2 {
1230 return Err(CodecError::UnexpectedEnd);
1231 }
1232 let group_order = read_group_order_response(buf)?;
1233 let content_exists_val = buf.get_u8();
1234 let content_exists = match content_exists_val {
1235 0 => ContentExists::NoLargestLocation,
1236 1 => ContentExists::HasLargestLocation,
1237 other => return Err(CodecError::InvalidContentExists(other)),
1238 };
1239 let (largest_group_id, largest_object_id) =
1240 if content_exists == ContentExists::HasLargestLocation {
1241 let gid = VarInt::decode(buf)?;
1242 let oid = VarInt::decode(buf)?;
1243 (Some(gid), Some(oid))
1244 } else {
1245 (None, None)
1246 };
1247 let parameters = decode_parameters(buf)?;
1248 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1249 subscribe_id,
1250 expires,
1251 group_order,
1252 content_exists,
1253 largest_group_id,
1254 largest_object_id,
1255 parameters,
1256 }))
1257 }
1258 MessageType::SubscribeError => {
1259 let subscribe_id = VarInt::decode(buf)?;
1260 let error_code = VarInt::decode(buf)?;
1261 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1262 let reason_phrase = read_bytes(buf, reason_len)?;
1263 let track_alias = VarInt::decode(buf)?;
1264 Ok(ControlMessage::SubscribeError(SubscribeError {
1265 subscribe_id,
1266 error_code,
1267 reason_phrase,
1268 track_alias,
1269 }))
1270 }
1271 MessageType::SubscribeUpdate => {
1272 let subscribe_id = VarInt::decode(buf)?;
1273 let start_group = VarInt::decode(buf)?;
1274 let start_object = VarInt::decode(buf)?;
1275 let end_group = VarInt::decode(buf)?;
1276 if buf.remaining() < 1 {
1277 return Err(CodecError::UnexpectedEnd);
1278 }
1279 let subscriber_priority = buf.get_u8();
1280 let parameters = decode_parameters(buf)?;
1281 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1282 subscribe_id,
1283 start_group,
1284 start_object,
1285 end_group,
1286 subscriber_priority,
1287 parameters,
1288 }))
1289 }
1290 MessageType::SubscribeDone => {
1291 let subscribe_id = VarInt::decode(buf)?;
1292 let status_code = VarInt::decode(buf)?;
1293 let stream_count = VarInt::decode(buf)?;
1294 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1295 let reason_phrase = read_bytes(buf, reason_len)?;
1296 Ok(ControlMessage::SubscribeDone(SubscribeDone {
1297 subscribe_id,
1298 status_code,
1299 stream_count,
1300 reason_phrase,
1301 }))
1302 }
1303 MessageType::Unsubscribe => {
1304 let subscribe_id = VarInt::decode(buf)?;
1305 Ok(ControlMessage::Unsubscribe(Unsubscribe { subscribe_id }))
1306 }
1307 MessageType::Announce => {
1308 let track_namespace = TrackNamespace::decode(buf)?;
1309 let parameters = decode_parameters(buf)?;
1310 Ok(ControlMessage::Announce(Announce { track_namespace, parameters }))
1311 }
1312 MessageType::AnnounceOk => {
1313 let track_namespace = TrackNamespace::decode(buf)?;
1314 Ok(ControlMessage::AnnounceOk(AnnounceOk { track_namespace }))
1315 }
1316 MessageType::AnnounceError => {
1317 let track_namespace = TrackNamespace::decode(buf)?;
1318 let error_code = VarInt::decode(buf)?;
1319 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1320 let reason_phrase = read_bytes(buf, reason_len)?;
1321 Ok(ControlMessage::AnnounceError(AnnounceError {
1322 track_namespace,
1323 error_code,
1324 reason_phrase,
1325 }))
1326 }
1327 MessageType::AnnounceCancel => {
1328 let track_namespace = TrackNamespace::decode(buf)?;
1329 let error_code = VarInt::decode(buf)?;
1330 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1331 let reason_phrase = read_bytes(buf, reason_len)?;
1332 Ok(ControlMessage::AnnounceCancel(AnnounceCancel {
1333 track_namespace,
1334 error_code,
1335 reason_phrase,
1336 }))
1337 }
1338 MessageType::Unannounce => {
1339 let track_namespace = TrackNamespace::decode(buf)?;
1340 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1341 }
1342 MessageType::SubscribeAnnounces => {
1343 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1344 let parameters = decode_parameters(buf)?;
1345 Ok(ControlMessage::SubscribeAnnounces(SubscribeAnnounces {
1346 track_namespace_prefix,
1347 parameters,
1348 }))
1349 }
1350 MessageType::SubscribeAnnouncesOk => {
1351 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1352 Ok(ControlMessage::SubscribeAnnouncesOk(SubscribeAnnouncesOk {
1353 track_namespace_prefix,
1354 }))
1355 }
1356 MessageType::SubscribeAnnouncesError => {
1357 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1358 let error_code = VarInt::decode(buf)?;
1359 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1360 let reason_phrase = read_bytes(buf, reason_len)?;
1361 Ok(ControlMessage::SubscribeAnnouncesError(SubscribeAnnouncesError {
1362 track_namespace_prefix,
1363 error_code,
1364 reason_phrase,
1365 }))
1366 }
1367 MessageType::UnsubscribeAnnounces => {
1368 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1369 Ok(ControlMessage::UnsubscribeAnnounces(UnsubscribeAnnounces {
1370 track_namespace_prefix,
1371 }))
1372 }
1373 MessageType::TrackStatusRequest => {
1374 let track_namespace = TrackNamespace::decode(buf)?;
1375 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1376 let track_name = read_bytes(buf, track_name_len)?;
1377 Ok(ControlMessage::TrackStatusRequest(TrackStatusRequest {
1378 track_namespace,
1379 track_name,
1380 }))
1381 }
1382 MessageType::TrackStatus => {
1383 let track_namespace = TrackNamespace::decode(buf)?;
1384 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1385 let track_name = read_bytes(buf, track_name_len)?;
1386 let status_code = VarInt::decode(buf)?;
1387 let last_group_id = VarInt::decode(buf)?;
1388 let last_object_id = VarInt::decode(buf)?;
1389 check_track_status(status_code, last_group_id, last_object_id)?;
1390 Ok(ControlMessage::TrackStatus(TrackStatus {
1391 track_namespace,
1392 track_name,
1393 status_code,
1394 last_group_id,
1395 last_object_id,
1396 }))
1397 }
1398 MessageType::Fetch => {
1399 let subscribe_id = VarInt::decode(buf)?;
1400 if buf.remaining() < 2 {
1401 return Err(CodecError::UnexpectedEnd);
1402 }
1403 let subscriber_priority = buf.get_u8();
1404 let group_order =
1405 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1406 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1407 let fetch_type = FetchType::from_u64(fetch_type_val)
1408 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1409 let (
1410 track_namespace,
1411 track_name,
1412 start_group,
1413 start_object,
1414 end_group,
1415 end_object,
1416 joining_subscribe_id,
1417 preceding_group_offset,
1418 ) = match fetch_type {
1419 FetchType::Standalone => {
1420 let ns = TrackNamespace::decode(buf)?;
1421 let name_len = VarInt::decode(buf)?.into_inner() as usize;
1422 let name = read_bytes(buf, name_len)?;
1423 let sg = VarInt::decode(buf)?;
1424 let so = VarInt::decode(buf)?;
1425 let eg = VarInt::decode(buf)?;
1426 let eo = VarInt::decode(buf)?;
1427 (Some(ns), Some(name), Some(sg), Some(so), Some(eg), Some(eo), None, None)
1428 }
1429 FetchType::Joining => {
1430 let jsi = VarInt::decode(buf)?;
1431 let pgo = VarInt::decode(buf)?;
1432 (None, None, None, None, None, None, Some(jsi), Some(pgo))
1433 }
1434 };
1435 let parameters = decode_parameters(buf)?;
1436 Ok(ControlMessage::Fetch(Fetch {
1437 subscribe_id,
1438 subscriber_priority,
1439 group_order,
1440 fetch_type,
1441 track_namespace,
1442 track_name,
1443 start_group,
1444 start_object,
1445 end_group,
1446 end_object,
1447 joining_subscribe_id,
1448 preceding_group_offset,
1449 parameters,
1450 }))
1451 }
1452 MessageType::FetchOk => {
1453 let subscribe_id = VarInt::decode(buf)?;
1454 if buf.remaining() < 2 {
1455 return Err(CodecError::UnexpectedEnd);
1456 }
1457 let group_order = read_group_order_response(buf)?;
1458 let end_of_track = buf.get_u8();
1459 let largest_group_id = VarInt::decode(buf)?;
1460 let largest_object_id = VarInt::decode(buf)?;
1461 let parameters = decode_parameters(buf)?;
1462 Ok(ControlMessage::FetchOk(FetchOk {
1463 subscribe_id,
1464 group_order,
1465 end_of_track,
1466 largest_group_id,
1467 largest_object_id,
1468 parameters,
1469 }))
1470 }
1471 MessageType::FetchError => {
1472 let subscribe_id = VarInt::decode(buf)?;
1473 let error_code = VarInt::decode(buf)?;
1474 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1475 let reason_phrase = read_bytes(buf, reason_len)?;
1476 Ok(ControlMessage::FetchError(FetchError {
1477 subscribe_id,
1478 error_code,
1479 reason_phrase,
1480 }))
1481 }
1482 MessageType::FetchCancel => {
1483 let subscribe_id = VarInt::decode(buf)?;
1484 Ok(ControlMessage::FetchCancel(FetchCancel { subscribe_id }))
1485 }
1486 }
1487 }
1488}