1use crate::error::CodecError;
4use crate::kvp::KeyValuePair;
5use crate::types::read_bytes;
6use crate::types::*;
7use crate::types::{check_group_range, check_location_range, check_open_ended_group_range};
8use crate::varint::VarInt;
9use bytes::{Buf, BufMut};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13#[repr(u64)]
14pub enum MessageType {
15 SubscribeUpdate = 0x02,
17 Subscribe = 0x03,
19 SubscribeOk = 0x04,
21 SubscribeError = 0x05,
23 Announce = 0x06,
25 AnnounceOk = 0x07,
27 AnnounceError = 0x08,
29 Unannounce = 0x09,
31 Unsubscribe = 0x0A,
33 SubscribeDone = 0x0B,
35 AnnounceCancel = 0x0C,
37 TrackStatusRequest = 0x0D,
39 TrackStatus = 0x0E,
41 GoAway = 0x10,
43 SubscribeAnnounces = 0x11,
45 SubscribeAnnouncesOk = 0x12,
47 SubscribeAnnouncesError = 0x13,
49 UnsubscribeAnnounces = 0x14,
51 MaxSubscribeId = 0x15,
53 Fetch = 0x16,
55 FetchCancel = 0x17,
57 FetchOk = 0x18,
59 FetchError = 0x19,
61 SubscribesBlocked = 0x1A,
63 ClientSetup = 0x40,
65 ServerSetup = 0x41,
67}
68
69impl MessageType {
70 pub fn from_id(id: u64) -> Option<Self> {
72 match id {
73 0x02 => Some(MessageType::SubscribeUpdate),
74 0x03 => Some(MessageType::Subscribe),
75 0x04 => Some(MessageType::SubscribeOk),
76 0x05 => Some(MessageType::SubscribeError),
77 0x06 => Some(MessageType::Announce),
78 0x07 => Some(MessageType::AnnounceOk),
79 0x08 => Some(MessageType::AnnounceError),
80 0x09 => Some(MessageType::Unannounce),
81 0x0A => Some(MessageType::Unsubscribe),
82 0x0B => Some(MessageType::SubscribeDone),
83 0x0C => Some(MessageType::AnnounceCancel),
84 0x0D => Some(MessageType::TrackStatusRequest),
85 0x0E => Some(MessageType::TrackStatus),
86 0x10 => Some(MessageType::GoAway),
87 0x11 => Some(MessageType::SubscribeAnnounces),
88 0x12 => Some(MessageType::SubscribeAnnouncesOk),
89 0x13 => Some(MessageType::SubscribeAnnouncesError),
90 0x14 => Some(MessageType::UnsubscribeAnnounces),
91 0x15 => Some(MessageType::MaxSubscribeId),
92 0x16 => Some(MessageType::Fetch),
93 0x17 => Some(MessageType::FetchCancel),
94 0x18 => Some(MessageType::FetchOk),
95 0x19 => Some(MessageType::FetchError),
96 0x1A => Some(MessageType::SubscribesBlocked),
97 0x40 => Some(MessageType::ClientSetup),
98 0x41 => Some(MessageType::ServerSetup),
99 _ => None,
100 }
101 }
102
103 pub fn id(&self) -> u64 {
105 *self as u64
106 }
107
108 pub fn name(&self) -> &'static str {
111 match self {
112 MessageType::SubscribeUpdate => "subscribe_update",
113 MessageType::Subscribe => "subscribe",
114 MessageType::SubscribeOk => "subscribe_ok",
115 MessageType::SubscribeError => "subscribe_error",
116 MessageType::Announce => "announce",
117 MessageType::AnnounceOk => "announce_ok",
118 MessageType::AnnounceError => "announce_error",
119 MessageType::Unannounce => "unannounce",
120 MessageType::Unsubscribe => "unsubscribe",
121 MessageType::SubscribeDone => "subscribe_done",
122 MessageType::AnnounceCancel => "announce_cancel",
123 MessageType::TrackStatusRequest => "track_status_request",
124 MessageType::TrackStatus => "track_status",
125 MessageType::GoAway => "goaway",
126 MessageType::SubscribeAnnounces => "subscribe_announces",
127 MessageType::SubscribeAnnouncesOk => "subscribe_announces_ok",
128 MessageType::SubscribeAnnouncesError => "subscribe_announces_error",
129 MessageType::UnsubscribeAnnounces => "unsubscribe_announces",
130 MessageType::MaxSubscribeId => "max_subscribe_id",
131 MessageType::Fetch => "fetch",
132 MessageType::FetchCancel => "fetch_cancel",
133 MessageType::FetchOk => "fetch_ok",
134 MessageType::FetchError => "fetch_error",
135 MessageType::SubscribesBlocked => "subscribes_blocked",
136 MessageType::ClientSetup => "client_setup",
137 MessageType::ServerSetup => "server_setup",
138 }
139 }
140}
141
142#[derive(Debug, Clone, PartialEq, Eq)]
148pub struct ClientSetup {
149 pub supported_versions: Vec<VarInt>,
151 pub parameters: Vec<KeyValuePair>,
153}
154
155#[derive(Debug, Clone, PartialEq, Eq)]
157pub struct ServerSetup {
158 pub selected_version: VarInt,
160 pub parameters: Vec<KeyValuePair>,
162}
163
164#[derive(Debug, Clone, PartialEq, Eq)]
166pub struct GoAway {
167 pub new_session_uri: Vec<u8>,
169}
170
171#[derive(Debug, Clone, PartialEq, Eq)]
173pub struct MaxSubscribeId {
174 pub subscribe_id: VarInt,
176}
177
178#[derive(Debug, Clone, PartialEq, Eq)]
180pub struct SubscribesBlocked {
181 pub maximum_subscribe_id: VarInt,
183}
184
185#[derive(Debug, Clone, PartialEq, Eq)]
193pub struct Subscribe {
194 pub subscribe_id: VarInt,
196 pub track_alias: VarInt,
198 pub track_namespace: TrackNamespace,
200 pub track_name: Vec<u8>,
202 pub subscriber_priority: u8,
204 pub group_order: GroupOrder,
206 pub filter_type: FilterType,
208 pub start_location: Option<Location>,
210 pub end_group: Option<VarInt>,
212 pub parameters: Vec<KeyValuePair>,
214}
215
216#[derive(Debug, Clone, PartialEq, Eq)]
218pub struct SubscribeOk {
219 pub subscribe_id: VarInt,
221 pub expires: VarInt,
223 pub group_order: GroupOrder,
225 pub content_exists: ContentExists,
227 pub largest_group_id: Option<VarInt>,
229 pub largest_object_id: Option<VarInt>,
231 pub parameters: Vec<KeyValuePair>,
233}
234
235#[derive(Debug, Clone, PartialEq, Eq)]
237pub struct SubscribeError {
238 pub subscribe_id: VarInt,
240 pub error_code: VarInt,
242 pub reason_phrase: Vec<u8>,
244 pub track_alias: VarInt,
246}
247
248#[derive(Debug, Clone, PartialEq, Eq)]
252pub struct SubscribeUpdate {
253 pub subscribe_id: VarInt,
255 pub start_group: VarInt,
257 pub start_object: VarInt,
259 pub end_group: VarInt,
261 pub subscriber_priority: u8,
263 pub parameters: Vec<KeyValuePair>,
265}
266
267#[derive(Debug, Clone, PartialEq, Eq)]
271pub struct SubscribeDone {
272 pub subscribe_id: VarInt,
274 pub status_code: VarInt,
276 pub stream_count: VarInt,
278 pub reason_phrase: Vec<u8>,
280}
281
282#[derive(Debug, Clone, PartialEq, Eq)]
284pub struct Unsubscribe {
285 pub subscribe_id: VarInt,
287}
288
289#[derive(Debug, Clone, PartialEq, Eq)]
295pub struct Announce {
296 pub track_namespace: TrackNamespace,
298 pub parameters: Vec<KeyValuePair>,
300}
301
302#[derive(Debug, Clone, PartialEq, Eq)]
304pub struct AnnounceOk {
305 pub track_namespace: TrackNamespace,
307}
308
309#[derive(Debug, Clone, PartialEq, Eq)]
311pub struct AnnounceError {
312 pub track_namespace: TrackNamespace,
314 pub error_code: VarInt,
316 pub reason_phrase: Vec<u8>,
318}
319
320#[derive(Debug, Clone, PartialEq, Eq)]
322pub struct AnnounceCancel {
323 pub track_namespace: TrackNamespace,
325 pub error_code: VarInt,
327 pub reason_phrase: Vec<u8>,
329}
330
331#[derive(Debug, Clone, PartialEq, Eq)]
333pub struct Unannounce {
334 pub track_namespace: TrackNamespace,
336}
337
338#[derive(Debug, Clone, PartialEq, Eq)]
344pub struct SubscribeAnnounces {
345 pub track_namespace_prefix: TrackNamespace,
347 pub parameters: Vec<KeyValuePair>,
349}
350
351#[derive(Debug, Clone, PartialEq, Eq)]
353pub struct SubscribeAnnouncesOk {
354 pub track_namespace_prefix: TrackNamespace,
356}
357
358#[derive(Debug, Clone, PartialEq, Eq)]
360pub struct SubscribeAnnouncesError {
361 pub track_namespace_prefix: TrackNamespace,
363 pub error_code: VarInt,
365 pub reason_phrase: Vec<u8>,
367}
368
369#[derive(Debug, Clone, PartialEq, Eq)]
371pub struct UnsubscribeAnnounces {
372 pub track_namespace_prefix: TrackNamespace,
374}
375
376#[derive(Debug, Clone, PartialEq, Eq)]
382pub struct TrackStatusRequest {
383 pub track_namespace: TrackNamespace,
385 pub track_name: Vec<u8>,
387}
388
389#[derive(Debug, Clone, PartialEq, Eq)]
391pub struct TrackStatus {
392 pub track_namespace: TrackNamespace,
394 pub track_name: Vec<u8>,
396 pub status_code: VarInt,
398 pub last_group_id: VarInt,
400 pub last_object_id: VarInt,
402}
403
404#[derive(Debug, Clone, Copy, PartialEq, Eq)]
410#[repr(u64)]
411pub enum FetchType {
412 Standalone = 1,
414 Joining = 2,
416}
417
418impl FetchType {
419 pub fn from_u64(v: u64) -> Option<Self> {
421 match v {
422 1 => Some(FetchType::Standalone),
423 2 => Some(FetchType::Joining),
424 _ => None,
425 }
426 }
427}
428
429#[derive(Debug, Clone, PartialEq, Eq)]
433pub struct Fetch {
434 pub subscribe_id: VarInt,
436 pub subscriber_priority: u8,
438 pub group_order: GroupOrder,
440 pub fetch_type: FetchType,
442 pub track_namespace: Option<TrackNamespace>,
444 pub track_name: Option<Vec<u8>>,
446 pub start_group: Option<VarInt>,
448 pub start_object: Option<VarInt>,
450 pub end_group: Option<VarInt>,
452 pub end_object: Option<VarInt>,
454 pub joining_subscribe_id: Option<VarInt>,
456 pub preceding_group_offset: Option<VarInt>,
458 pub parameters: Vec<KeyValuePair>,
460}
461
462#[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::draft08::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 let wants_start =
562 matches!(m.filter_type, FilterType::AbsoluteStart | FilterType::AbsoluteRange);
563 if wants_start != m.start_location.is_some() {
564 return Err(CodecError::InvalidField);
565 }
566 if (m.filter_type == FilterType::AbsoluteRange) != m.end_group.is_some() {
567 return Err(CodecError::InvalidField);
568 }
569 Ok(())
570 }
571 ControlMessage::SubscribeOk(m) => {
572 let has = m.content_exists == ContentExists::HasLargestLocation;
573 if has != m.largest_group_id.is_some() || has != m.largest_object_id.is_some() {
574 return Err(CodecError::InvalidField);
575 }
576 Ok(())
577 }
578 ControlMessage::Fetch(m) => {
579 let standalone = m.fetch_type == FetchType::Standalone;
580 let standalone_fields = [
581 m.track_namespace.is_some(),
582 m.track_name.is_some(),
583 m.start_group.is_some(),
584 m.start_object.is_some(),
585 m.end_group.is_some(),
586 m.end_object.is_some(),
587 ];
588 if standalone_fields.iter().any(|present| *present != standalone) {
589 return Err(CodecError::InvalidField);
590 }
591 let joining_fields =
592 [m.joining_subscribe_id.is_some(), m.preceding_group_offset.is_some()];
593 if joining_fields.contains(&standalone) {
594 return Err(CodecError::InvalidField);
595 }
596 Ok(())
597 }
598 _ => Ok(()),
599 }
600}
601
602fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
607 let order = match message {
608 ControlMessage::SubscribeOk(m) => m.group_order,
609 ControlMessage::FetchOk(m) => m.group_order,
610 _ => return Ok(()),
611 };
612 if order == GroupOrder::Publisher {
613 return Err(CodecError::InvalidField);
614 }
615 Ok(())
616}
617
618#[derive(Debug, Clone, PartialEq, Eq)]
620pub enum ControlMessage {
621 ClientSetup(ClientSetup),
623 ServerSetup(ServerSetup),
625 GoAway(GoAway),
627 MaxSubscribeId(MaxSubscribeId),
629 SubscribesBlocked(SubscribesBlocked),
631 Subscribe(Subscribe),
633 SubscribeOk(SubscribeOk),
635 SubscribeError(SubscribeError),
637 SubscribeUpdate(SubscribeUpdate),
639 SubscribeDone(SubscribeDone),
641 Unsubscribe(Unsubscribe),
643 Announce(Announce),
645 AnnounceOk(AnnounceOk),
647 AnnounceError(AnnounceError),
649 AnnounceCancel(AnnounceCancel),
651 Unannounce(Unannounce),
653 SubscribeAnnounces(SubscribeAnnounces),
655 SubscribeAnnouncesOk(SubscribeAnnouncesOk),
657 SubscribeAnnouncesError(SubscribeAnnouncesError),
659 UnsubscribeAnnounces(UnsubscribeAnnounces),
661 TrackStatusRequest(TrackStatusRequest),
663 TrackStatus(TrackStatus),
665 Fetch(Fetch),
667 FetchOk(FetchOk),
669 FetchError(FetchError),
671 FetchCancel(FetchCancel),
673}
674
675fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
689 match message {
690 ControlMessage::Subscribe(m) => match (&m.start_location, &m.end_group) {
691 (Some(start), Some(end_group)) => {
692 check_group_range(start.group.into_inner(), end_group.into_inner())
693 }
694 _ => Ok(()),
695 },
696 ControlMessage::SubscribeUpdate(m) => {
697 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
698 }
699 ControlMessage::Fetch(m) => {
700 match (&m.start_group, &m.start_object, &m.end_group, &m.end_object) {
701 (Some(start_group), Some(start_object), Some(end_group), Some(end_object)) => {
702 check_location_range(
703 start_group.into_inner(),
704 start_object.into_inner(),
705 end_group.into_inner(),
706 end_object.into_inner(),
707 )
708 }
709 _ => Ok(()),
710 }
711 }
712 _ => Ok(()),
713 }
714}
715
716fn check_no_duplicate_parameters(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
727 for (i, parameter) in parameters.iter().enumerate() {
728 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
729 return Err(CodecError::DuplicateParameter(parameter.key.into_inner()));
730 }
731 }
732 Ok(())
733}
734
735const SETUP_VARINT_PARAMETERS: &[u64] = &[0x02];
742
743const VERSION_VARINT_PARAMETERS: &[u64] = &[0x03, 0x04];
756
757fn check_parameter_lengths(
775 parameters: &[KeyValuePair],
776 varint_typed: &[u64],
777) -> Result<(), CodecError> {
778 for parameter in parameters {
779 let key = parameter.key.into_inner();
780 if !varint_typed.contains(&key) {
781 continue;
782 }
783 if let crate::kvp::KvpValue::Bytes(bytes) = ¶meter.value {
784 let mut cursor = &bytes[..];
785 let one_varint = VarInt::decode(&mut cursor).is_ok() && !cursor.has_remaining();
786 if !one_varint {
787 return Err(CodecError::ParameterLengthMismatch(key));
788 }
789 }
790 }
791 Ok(())
792}
793
794fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
797 let parameters = KeyValuePair::decode_list_d07(buf)?;
798 check_no_duplicate_parameters(¶meters)?;
799 check_parameter_lengths(¶meters, VERSION_VARINT_PARAMETERS)?;
800 Ok(parameters)
801}
802
803fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
806 check_no_duplicate_parameters(parameters)?;
807 check_parameter_lengths(parameters, VERSION_VARINT_PARAMETERS)?;
808 KeyValuePair::encode_list_d07(parameters, buf);
809 Ok(())
810}
811
812fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
818 let parameters = KeyValuePair::decode_list_d07(buf)?;
819 check_no_duplicate_parameters(¶meters)?;
820 check_parameter_lengths(¶meters, SETUP_VARINT_PARAMETERS)?;
821 Ok(parameters)
822}
823
824fn encode_setup_parameters(
826 parameters: &[KeyValuePair],
827 buf: &mut impl BufMut,
828) -> Result<(), CodecError> {
829 check_no_duplicate_parameters(parameters)?;
830 check_parameter_lengths(parameters, SETUP_VARINT_PARAMETERS)?;
831 KeyValuePair::encode_list_d07(parameters, buf);
832 Ok(())
833}
834
835impl ControlMessage {
836 pub fn message_type(&self) -> MessageType {
838 match self {
839 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
840 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
841 ControlMessage::GoAway(_) => MessageType::GoAway,
842 ControlMessage::MaxSubscribeId(_) => MessageType::MaxSubscribeId,
843 ControlMessage::SubscribesBlocked(_) => MessageType::SubscribesBlocked,
844 ControlMessage::Subscribe(_) => MessageType::Subscribe,
845 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
846 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
847 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
848 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
849 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
850 ControlMessage::Announce(_) => MessageType::Announce,
851 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
852 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
853 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
854 ControlMessage::Unannounce(_) => MessageType::Unannounce,
855 ControlMessage::SubscribeAnnounces(_) => MessageType::SubscribeAnnounces,
856 ControlMessage::SubscribeAnnouncesOk(_) => MessageType::SubscribeAnnouncesOk,
857 ControlMessage::SubscribeAnnouncesError(_) => MessageType::SubscribeAnnouncesError,
858 ControlMessage::UnsubscribeAnnounces(_) => MessageType::UnsubscribeAnnounces,
859 ControlMessage::TrackStatusRequest(_) => MessageType::TrackStatusRequest,
860 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
861 ControlMessage::Fetch(_) => MessageType::Fetch,
862 ControlMessage::FetchOk(_) => MessageType::FetchOk,
863 ControlMessage::FetchError(_) => MessageType::FetchError,
864 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
865 }
866 }
867
868 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
870 check_discriminators(self)?;
871 check_group_order(self)?;
872 check_ranges(self)?;
873 let mut payload = Vec::with_capacity(256);
874 self.encode_payload(&mut payload)?;
875
876 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
884 VarInt::from_usize(payload.len()).encode(buf);
885 buf.put_slice(&payload);
886 Ok(())
887 }
888
889 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
891 let type_id = VarInt::decode(buf)?.into_inner();
892 let msg_type =
893 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
894 let payload_len = VarInt::decode(buf)?.into_inner() as usize;
895 if buf.remaining() < payload_len {
896 return Err(CodecError::UnexpectedEnd);
897 }
898 let payload_bytes = buf.copy_to_bytes(payload_len);
899 let mut payload = &payload_bytes[..];
900 let msg = match Self::decode_payload(msg_type, &mut payload) {
901 Ok(msg) => msg,
902 Err(
908 CodecError::UnexpectedEnd
909 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
910 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
911 crate::varint::VarIntError::UnexpectedEnd,
912 ))
913 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
914 ) => {
915 return Err(CodecError::ControlMessageLengthMismatch {
916 declared: payload_len,
917 detail: "its fields ran past the end",
918 });
919 }
920 Err(e) => return Err(e),
921 };
922 check_ranges(&msg)?;
923 if payload.has_remaining() {
928 return Err(CodecError::ControlMessageLengthMismatch {
929 declared: payload_len,
930 detail: "its fields left bytes unread",
931 });
932 }
933 Ok(msg)
934 }
935
936 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
937 match self {
938 ControlMessage::ClientSetup(m) => {
939 VarInt::from_usize(m.supported_versions.len()).encode(buf);
940 for v in &m.supported_versions {
941 v.encode(buf);
942 }
943 encode_setup_parameters(&m.parameters, buf)?;
944 }
945 ControlMessage::ServerSetup(m) => {
946 m.selected_version.encode(buf);
947 encode_setup_parameters(&m.parameters, buf)?;
948 }
949 ControlMessage::GoAway(m) => {
950 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
951 buf.put_slice(&m.new_session_uri);
952 }
953 ControlMessage::MaxSubscribeId(m) => {
954 m.subscribe_id.encode(buf);
955 }
956 ControlMessage::SubscribesBlocked(m) => {
957 m.maximum_subscribe_id.encode(buf);
958 }
959 ControlMessage::Subscribe(m) => {
960 m.subscribe_id.encode(buf);
961 m.track_alias.encode(buf);
962 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
963 m.track_namespace.encode(buf);
964 VarInt::from_usize(m.track_name.len()).encode(buf);
965 buf.put_slice(&m.track_name);
966 buf.put_u8(m.subscriber_priority);
967 buf.put_u8(m.group_order as u8);
968 VarInt::from_usize(m.filter_type as usize).encode(buf);
969 if let Some(loc) = &m.start_location {
970 loc.encode(buf);
971 }
972 if let Some(eg) = &m.end_group {
973 eg.encode(buf);
974 }
975 encode_parameters(&m.parameters, buf)?;
976 }
977 ControlMessage::SubscribeOk(m) => {
978 m.subscribe_id.encode(buf);
979 m.expires.encode(buf);
980 buf.put_u8(m.group_order as u8);
981 buf.put_u8(m.content_exists as u8);
982 if let Some(gid) = &m.largest_group_id {
983 gid.encode(buf);
984 }
985 if let Some(oid) = &m.largest_object_id {
986 oid.encode(buf);
987 }
988 encode_parameters(&m.parameters, buf)?;
989 }
990 ControlMessage::SubscribeError(m) => {
991 m.subscribe_id.encode(buf);
992 m.error_code.encode(buf);
993 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
994 buf.put_slice(&m.reason_phrase);
995 m.track_alias.encode(buf);
996 }
997 ControlMessage::SubscribeUpdate(m) => {
998 m.subscribe_id.encode(buf);
999 m.start_group.encode(buf);
1000 m.start_object.encode(buf);
1001 m.end_group.encode(buf);
1002 buf.put_u8(m.subscriber_priority);
1003 encode_parameters(&m.parameters, buf)?;
1004 }
1005 ControlMessage::SubscribeDone(m) => {
1006 m.subscribe_id.encode(buf);
1007 m.status_code.encode(buf);
1008 m.stream_count.encode(buf);
1009 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1010 buf.put_slice(&m.reason_phrase);
1011 }
1012 ControlMessage::Unsubscribe(m) => {
1013 m.subscribe_id.encode(buf);
1014 }
1015 ControlMessage::Announce(m) => {
1016 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
1017 m.track_namespace.encode(buf);
1018 encode_parameters(&m.parameters, buf)?;
1019 }
1020 ControlMessage::AnnounceOk(m) => {
1021 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
1022 m.track_namespace.encode(buf);
1023 }
1024 ControlMessage::AnnounceError(m) => {
1025 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
1026 m.track_namespace.encode(buf);
1027 m.error_code.encode(buf);
1028 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1029 buf.put_slice(&m.reason_phrase);
1030 }
1031 ControlMessage::AnnounceCancel(m) => {
1032 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
1033 m.track_namespace.encode(buf);
1034 m.error_code.encode(buf);
1035 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1036 buf.put_slice(&m.reason_phrase);
1037 }
1038 ControlMessage::Unannounce(m) => {
1039 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
1040 m.track_namespace.encode(buf);
1041 }
1042 ControlMessage::SubscribeAnnounces(m) => {
1043 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(8))?;
1044 m.track_namespace_prefix.encode(buf);
1045 encode_parameters(&m.parameters, buf)?;
1046 }
1047 ControlMessage::SubscribeAnnouncesOk(m) => {
1048 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(8))?;
1049 m.track_namespace_prefix.encode(buf);
1050 }
1051 ControlMessage::SubscribeAnnouncesError(m) => {
1052 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(8))?;
1053 m.track_namespace_prefix.encode(buf);
1054 m.error_code.encode(buf);
1055 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1056 buf.put_slice(&m.reason_phrase);
1057 }
1058 ControlMessage::UnsubscribeAnnounces(m) => {
1059 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(8))?;
1060 m.track_namespace_prefix.encode(buf);
1061 }
1062 ControlMessage::TrackStatusRequest(m) => {
1063 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
1064 m.track_namespace.encode(buf);
1065 VarInt::from_usize(m.track_name.len()).encode(buf);
1066 buf.put_slice(&m.track_name);
1067 }
1068 ControlMessage::TrackStatus(m) => {
1069 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
1070 m.track_namespace.encode(buf);
1071 VarInt::from_usize(m.track_name.len()).encode(buf);
1072 buf.put_slice(&m.track_name);
1073 check_track_status(m.status_code, m.last_group_id, m.last_object_id)?;
1074 m.status_code.encode(buf);
1075 m.last_group_id.encode(buf);
1076 m.last_object_id.encode(buf);
1077 }
1078 ControlMessage::Fetch(m) => {
1079 m.subscribe_id.encode(buf);
1080 buf.put_u8(m.subscriber_priority);
1081 buf.put_u8(m.group_order as u8);
1082 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1083 match m.fetch_type {
1084 FetchType::Standalone => {
1085 if let Some(ns) = &m.track_namespace {
1086 ns.encode(buf);
1087 }
1088 if let Some(name) = &m.track_name {
1089 VarInt::from_usize(name.len()).encode(buf);
1090 buf.put_slice(name);
1091 }
1092 if let Some(sg) = &m.start_group {
1093 sg.encode(buf);
1094 }
1095 if let Some(so) = &m.start_object {
1096 so.encode(buf);
1097 }
1098 if let Some(eg) = &m.end_group {
1099 eg.encode(buf);
1100 }
1101 if let Some(eo) = &m.end_object {
1102 eo.encode(buf);
1103 }
1104 }
1105 FetchType::Joining => {
1106 if let Some(jsi) = &m.joining_subscribe_id {
1107 jsi.encode(buf);
1108 }
1109 if let Some(pgo) = &m.preceding_group_offset {
1110 pgo.encode(buf);
1111 }
1112 }
1113 }
1114 encode_parameters(&m.parameters, buf)?;
1115 }
1116 ControlMessage::FetchOk(m) => {
1117 m.subscribe_id.encode(buf);
1118 buf.put_u8(m.group_order as u8);
1119 buf.put_u8(m.end_of_track);
1120 m.largest_group_id.encode(buf);
1121 m.largest_object_id.encode(buf);
1122 encode_parameters(&m.parameters, buf)?;
1123 }
1124 ControlMessage::FetchError(m) => {
1125 m.subscribe_id.encode(buf);
1126 m.error_code.encode(buf);
1127 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1128 buf.put_slice(&m.reason_phrase);
1129 }
1130 ControlMessage::FetchCancel(m) => {
1131 m.subscribe_id.encode(buf);
1132 }
1133 }
1134 Ok(())
1135 }
1136
1137 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1138 match msg_type {
1139 MessageType::ClientSetup => {
1140 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1141 if num_versions == 0 {
1151 return Err(CodecError::InvalidField);
1152 }
1153 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1154 for _ in 0..num_versions {
1155 supported_versions.push(VarInt::decode(buf)?);
1156 }
1157 let parameters = decode_setup_parameters(buf)?;
1158 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1159 }
1160 MessageType::ServerSetup => {
1161 let selected_version = VarInt::decode(buf)?;
1162 let parameters = decode_setup_parameters(buf)?;
1163 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1164 }
1165 MessageType::GoAway => {
1166 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1167 let uri = read_bytes(buf, uri_len)?;
1168 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1169 }
1170 MessageType::MaxSubscribeId => {
1171 let subscribe_id = VarInt::decode(buf)?;
1172 Ok(ControlMessage::MaxSubscribeId(MaxSubscribeId { subscribe_id }))
1173 }
1174 MessageType::SubscribesBlocked => {
1175 let maximum_subscribe_id = VarInt::decode(buf)?;
1176 Ok(ControlMessage::SubscribesBlocked(SubscribesBlocked { maximum_subscribe_id }))
1177 }
1178 MessageType::Subscribe => {
1179 let subscribe_id = VarInt::decode(buf)?;
1180 let track_alias = VarInt::decode(buf)?;
1181 let track_namespace = TrackNamespace::decode(buf)?;
1182 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1183 let track_name = read_bytes(buf, track_name_len)?;
1184 if buf.remaining() < 2 {
1185 return Err(CodecError::UnexpectedEnd);
1186 }
1187 let subscriber_priority = buf.get_u8();
1188 let group_order =
1189 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1190 let filter_val = VarInt::decode(buf)?.into_inner();
1191 let filter_type = FilterType::from_u64(filter_val)
1192 .ok_or(CodecError::InvalidFilterType(filter_val))?;
1193 let start_location = match filter_type {
1194 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1195 Some(Location::decode(buf)?)
1196 }
1197 _ => None,
1198 };
1199 let end_group = match filter_type {
1200 FilterType::AbsoluteRange => Some(VarInt::decode(buf)?),
1201 _ => None,
1202 };
1203 let parameters = decode_parameters(buf)?;
1204 Ok(ControlMessage::Subscribe(Subscribe {
1205 subscribe_id,
1206 track_alias,
1207 track_namespace,
1208 track_name,
1209 subscriber_priority,
1210 group_order,
1211 filter_type,
1212 start_location,
1213 end_group,
1214 parameters,
1215 }))
1216 }
1217 MessageType::SubscribeOk => {
1218 let subscribe_id = VarInt::decode(buf)?;
1219 let expires = VarInt::decode(buf)?;
1220 if buf.remaining() < 2 {
1221 return Err(CodecError::UnexpectedEnd);
1222 }
1223 let group_order = read_group_order_response(buf)?;
1224 let content_exists_val = buf.get_u8();
1225 let content_exists = match content_exists_val {
1226 0 => ContentExists::NoLargestLocation,
1227 1 => ContentExists::HasLargestLocation,
1228 other => return Err(CodecError::InvalidContentExists(other)),
1229 };
1230 let (largest_group_id, largest_object_id) =
1231 if content_exists == ContentExists::HasLargestLocation {
1232 let gid = VarInt::decode(buf)?;
1233 let oid = VarInt::decode(buf)?;
1234 (Some(gid), Some(oid))
1235 } else {
1236 (None, None)
1237 };
1238 let parameters = decode_parameters(buf)?;
1239 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1240 subscribe_id,
1241 expires,
1242 group_order,
1243 content_exists,
1244 largest_group_id,
1245 largest_object_id,
1246 parameters,
1247 }))
1248 }
1249 MessageType::SubscribeError => {
1250 let subscribe_id = VarInt::decode(buf)?;
1251 let error_code = VarInt::decode(buf)?;
1252 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1253 let reason_phrase = read_bytes(buf, reason_len)?;
1254 let track_alias = VarInt::decode(buf)?;
1255 Ok(ControlMessage::SubscribeError(SubscribeError {
1256 subscribe_id,
1257 error_code,
1258 reason_phrase,
1259 track_alias,
1260 }))
1261 }
1262 MessageType::SubscribeUpdate => {
1263 let subscribe_id = VarInt::decode(buf)?;
1264 let start_group = VarInt::decode(buf)?;
1265 let start_object = VarInt::decode(buf)?;
1266 let end_group = VarInt::decode(buf)?;
1267 if buf.remaining() < 1 {
1268 return Err(CodecError::UnexpectedEnd);
1269 }
1270 let subscriber_priority = buf.get_u8();
1271 let parameters = decode_parameters(buf)?;
1272 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1273 subscribe_id,
1274 start_group,
1275 start_object,
1276 end_group,
1277 subscriber_priority,
1278 parameters,
1279 }))
1280 }
1281 MessageType::SubscribeDone => {
1282 let subscribe_id = VarInt::decode(buf)?;
1283 let status_code = VarInt::decode(buf)?;
1284 let stream_count = VarInt::decode(buf)?;
1285 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1286 let reason_phrase = read_bytes(buf, reason_len)?;
1287 Ok(ControlMessage::SubscribeDone(SubscribeDone {
1288 subscribe_id,
1289 status_code,
1290 stream_count,
1291 reason_phrase,
1292 }))
1293 }
1294 MessageType::Unsubscribe => {
1295 let subscribe_id = VarInt::decode(buf)?;
1296 Ok(ControlMessage::Unsubscribe(Unsubscribe { subscribe_id }))
1297 }
1298 MessageType::Announce => {
1299 let track_namespace = TrackNamespace::decode(buf)?;
1300 let parameters = decode_parameters(buf)?;
1301 Ok(ControlMessage::Announce(Announce { track_namespace, parameters }))
1302 }
1303 MessageType::AnnounceOk => {
1304 let track_namespace = TrackNamespace::decode(buf)?;
1305 Ok(ControlMessage::AnnounceOk(AnnounceOk { track_namespace }))
1306 }
1307 MessageType::AnnounceError => {
1308 let track_namespace = TrackNamespace::decode(buf)?;
1309 let error_code = VarInt::decode(buf)?;
1310 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1311 let reason_phrase = read_bytes(buf, reason_len)?;
1312 Ok(ControlMessage::AnnounceError(AnnounceError {
1313 track_namespace,
1314 error_code,
1315 reason_phrase,
1316 }))
1317 }
1318 MessageType::AnnounceCancel => {
1319 let track_namespace = TrackNamespace::decode(buf)?;
1320 let error_code = VarInt::decode(buf)?;
1321 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1322 let reason_phrase = read_bytes(buf, reason_len)?;
1323 Ok(ControlMessage::AnnounceCancel(AnnounceCancel {
1324 track_namespace,
1325 error_code,
1326 reason_phrase,
1327 }))
1328 }
1329 MessageType::Unannounce => {
1330 let track_namespace = TrackNamespace::decode(buf)?;
1331 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1332 }
1333 MessageType::SubscribeAnnounces => {
1334 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1335 let parameters = decode_parameters(buf)?;
1336 Ok(ControlMessage::SubscribeAnnounces(SubscribeAnnounces {
1337 track_namespace_prefix,
1338 parameters,
1339 }))
1340 }
1341 MessageType::SubscribeAnnouncesOk => {
1342 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1343 Ok(ControlMessage::SubscribeAnnouncesOk(SubscribeAnnouncesOk {
1344 track_namespace_prefix,
1345 }))
1346 }
1347 MessageType::SubscribeAnnouncesError => {
1348 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1349 let error_code = VarInt::decode(buf)?;
1350 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1351 let reason_phrase = read_bytes(buf, reason_len)?;
1352 Ok(ControlMessage::SubscribeAnnouncesError(SubscribeAnnouncesError {
1353 track_namespace_prefix,
1354 error_code,
1355 reason_phrase,
1356 }))
1357 }
1358 MessageType::UnsubscribeAnnounces => {
1359 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1360 Ok(ControlMessage::UnsubscribeAnnounces(UnsubscribeAnnounces {
1361 track_namespace_prefix,
1362 }))
1363 }
1364 MessageType::TrackStatusRequest => {
1365 let track_namespace = TrackNamespace::decode(buf)?;
1366 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1367 let track_name = read_bytes(buf, track_name_len)?;
1368 Ok(ControlMessage::TrackStatusRequest(TrackStatusRequest {
1369 track_namespace,
1370 track_name,
1371 }))
1372 }
1373 MessageType::TrackStatus => {
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 let status_code = VarInt::decode(buf)?;
1378 let last_group_id = VarInt::decode(buf)?;
1379 let last_object_id = VarInt::decode(buf)?;
1380 check_track_status(status_code, last_group_id, last_object_id)?;
1381 Ok(ControlMessage::TrackStatus(TrackStatus {
1382 track_namespace,
1383 track_name,
1384 status_code,
1385 last_group_id,
1386 last_object_id,
1387 }))
1388 }
1389 MessageType::Fetch => {
1390 let subscribe_id = VarInt::decode(buf)?;
1391 if buf.remaining() < 2 {
1392 return Err(CodecError::UnexpectedEnd);
1393 }
1394 let subscriber_priority = buf.get_u8();
1395 let group_order =
1396 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1397 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1398 let fetch_type = FetchType::from_u64(fetch_type_val)
1399 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1400 let (
1401 track_namespace,
1402 track_name,
1403 start_group,
1404 start_object,
1405 end_group,
1406 end_object,
1407 joining_subscribe_id,
1408 preceding_group_offset,
1409 ) = match fetch_type {
1410 FetchType::Standalone => {
1411 let ns = TrackNamespace::decode(buf)?;
1412 let name_len = VarInt::decode(buf)?.into_inner() as usize;
1413 let name = read_bytes(buf, name_len)?;
1414 let sg = VarInt::decode(buf)?;
1415 let so = VarInt::decode(buf)?;
1416 let eg = VarInt::decode(buf)?;
1417 let eo = VarInt::decode(buf)?;
1418 (Some(ns), Some(name), Some(sg), Some(so), Some(eg), Some(eo), None, None)
1419 }
1420 FetchType::Joining => {
1421 let jsi = VarInt::decode(buf)?;
1422 let pgo = VarInt::decode(buf)?;
1423 (None, None, None, None, None, None, Some(jsi), Some(pgo))
1424 }
1425 };
1426 let parameters = decode_parameters(buf)?;
1427 Ok(ControlMessage::Fetch(Fetch {
1428 subscribe_id,
1429 subscriber_priority,
1430 group_order,
1431 fetch_type,
1432 track_namespace,
1433 track_name,
1434 start_group,
1435 start_object,
1436 end_group,
1437 end_object,
1438 joining_subscribe_id,
1439 preceding_group_offset,
1440 parameters,
1441 }))
1442 }
1443 MessageType::FetchOk => {
1444 let subscribe_id = VarInt::decode(buf)?;
1445 if buf.remaining() < 2 {
1446 return Err(CodecError::UnexpectedEnd);
1447 }
1448 let group_order = read_group_order_response(buf)?;
1449 let end_of_track = buf.get_u8();
1450 let largest_group_id = VarInt::decode(buf)?;
1451 let largest_object_id = VarInt::decode(buf)?;
1452 let parameters = decode_parameters(buf)?;
1453 Ok(ControlMessage::FetchOk(FetchOk {
1454 subscribe_id,
1455 group_order,
1456 end_of_track,
1457 largest_group_id,
1458 largest_object_id,
1459 parameters,
1460 }))
1461 }
1462 MessageType::FetchError => {
1463 let subscribe_id = VarInt::decode(buf)?;
1464 let error_code = VarInt::decode(buf)?;
1465 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1466 let reason_phrase = read_bytes(buf, reason_len)?;
1467 Ok(ControlMessage::FetchError(FetchError {
1468 subscribe_id,
1469 error_code,
1470 reason_phrase,
1471 }))
1472 }
1473 MessageType::FetchCancel => {
1474 let subscribe_id = VarInt::decode(buf)?;
1475 Ok(ControlMessage::FetchCancel(FetchCancel { subscribe_id }))
1476 }
1477 }
1478 }
1479}