1use crate::error::CodecError;
7use crate::kvp::KeyValuePair;
8use crate::types::read_bytes;
9use crate::types::*;
10use crate::types::{check_group_range, check_location_range, check_open_ended_group_range};
11use crate::varint::VarInt;
12use bytes::{Buf, BufMut};
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16#[repr(u64)]
17pub enum MessageType {
18 SubscribeUpdate = 0x02,
20 Subscribe = 0x03,
22 SubscribeOk = 0x04,
24 SubscribeError = 0x05,
26 Announce = 0x06,
28 AnnounceOk = 0x07,
30 AnnounceError = 0x08,
32 Unannounce = 0x09,
34 Unsubscribe = 0x0A,
36 SubscribeDone = 0x0B,
38 AnnounceCancel = 0x0C,
40 TrackStatusRequest = 0x0D,
42 TrackStatus = 0x0E,
44 GoAway = 0x10,
46 SubscribeAnnounces = 0x11,
48 SubscribeAnnouncesOk = 0x12,
50 SubscribeAnnouncesError = 0x13,
52 UnsubscribeAnnounces = 0x14,
54 MaxSubscribeId = 0x15,
56 Fetch = 0x16,
58 FetchCancel = 0x17,
60 FetchOk = 0x18,
62 FetchError = 0x19,
64 SubscribesBlocked = 0x1A,
66 ClientSetup = 0x40,
68 ServerSetup = 0x41,
70}
71
72impl MessageType {
73 pub fn from_id(id: u64) -> Option<Self> {
75 match id {
76 0x02 => Some(MessageType::SubscribeUpdate),
77 0x03 => Some(MessageType::Subscribe),
78 0x04 => Some(MessageType::SubscribeOk),
79 0x05 => Some(MessageType::SubscribeError),
80 0x06 => Some(MessageType::Announce),
81 0x07 => Some(MessageType::AnnounceOk),
82 0x08 => Some(MessageType::AnnounceError),
83 0x09 => Some(MessageType::Unannounce),
84 0x0A => Some(MessageType::Unsubscribe),
85 0x0B => Some(MessageType::SubscribeDone),
86 0x0C => Some(MessageType::AnnounceCancel),
87 0x0D => Some(MessageType::TrackStatusRequest),
88 0x0E => Some(MessageType::TrackStatus),
89 0x10 => Some(MessageType::GoAway),
90 0x11 => Some(MessageType::SubscribeAnnounces),
91 0x12 => Some(MessageType::SubscribeAnnouncesOk),
92 0x13 => Some(MessageType::SubscribeAnnouncesError),
93 0x14 => Some(MessageType::UnsubscribeAnnounces),
94 0x15 => Some(MessageType::MaxSubscribeId),
95 0x16 => Some(MessageType::Fetch),
96 0x17 => Some(MessageType::FetchCancel),
97 0x18 => Some(MessageType::FetchOk),
98 0x19 => Some(MessageType::FetchError),
99 0x1A => Some(MessageType::SubscribesBlocked),
100 0x40 => Some(MessageType::ClientSetup),
101 0x41 => Some(MessageType::ServerSetup),
102 _ => None,
103 }
104 }
105
106 pub fn id(&self) -> u64 {
108 *self as u64
109 }
110}
111
112#[derive(Debug, Clone, PartialEq, Eq)]
118pub struct ClientSetup {
119 pub supported_versions: Vec<VarInt>,
121 pub parameters: Vec<KeyValuePair>,
123}
124
125#[derive(Debug, Clone, PartialEq, Eq)]
127pub struct ServerSetup {
128 pub selected_version: VarInt,
130 pub parameters: Vec<KeyValuePair>,
132}
133
134#[derive(Debug, Clone, PartialEq, Eq)]
136pub struct GoAway {
137 pub new_session_uri: Vec<u8>,
139}
140
141#[derive(Debug, Clone, PartialEq, Eq)]
143pub struct MaxSubscribeId {
144 pub subscribe_id: VarInt,
146}
147
148#[derive(Debug, Clone, PartialEq, Eq)]
150pub struct SubscribesBlocked {
151 pub maximum_subscribe_id: VarInt,
153}
154
155#[derive(Debug, Clone, PartialEq, Eq)]
163pub struct Subscribe {
164 pub subscribe_id: VarInt,
166 pub track_alias: VarInt,
168 pub track_namespace: TrackNamespace,
170 pub track_name: Vec<u8>,
172 pub subscriber_priority: u8,
174 pub group_order: GroupOrder,
176 pub filter_type: FilterType,
178 pub start_location: Option<Location>,
180 pub end_group: Option<VarInt>,
182 pub parameters: Vec<KeyValuePair>,
184}
185
186#[derive(Debug, Clone, PartialEq, Eq)]
188pub struct SubscribeOk {
189 pub subscribe_id: VarInt,
191 pub expires: VarInt,
193 pub group_order: GroupOrder,
195 pub content_exists: ContentExists,
197 pub largest_group_id: Option<VarInt>,
199 pub largest_object_id: Option<VarInt>,
201 pub parameters: Vec<KeyValuePair>,
203}
204
205#[derive(Debug, Clone, PartialEq, Eq)]
207pub struct SubscribeError {
208 pub subscribe_id: VarInt,
210 pub error_code: VarInt,
212 pub reason_phrase: Vec<u8>,
214 pub track_alias: VarInt,
216}
217
218#[derive(Debug, Clone, PartialEq, Eq)]
220pub struct SubscribeUpdate {
221 pub subscribe_id: VarInt,
223 pub start_group: VarInt,
225 pub start_object: VarInt,
227 pub end_group: VarInt,
229 pub subscriber_priority: u8,
231 pub parameters: Vec<KeyValuePair>,
233}
234
235#[derive(Debug, Clone, PartialEq, Eq)]
237pub struct SubscribeDone {
238 pub subscribe_id: VarInt,
240 pub status_code: VarInt,
242 pub stream_count: VarInt,
244 pub reason_phrase: Vec<u8>,
246}
247
248#[derive(Debug, Clone, PartialEq, Eq)]
250pub struct Unsubscribe {
251 pub subscribe_id: VarInt,
253}
254
255#[derive(Debug, Clone, PartialEq, Eq)]
261pub struct Announce {
262 pub track_namespace: TrackNamespace,
264 pub parameters: Vec<KeyValuePair>,
266}
267
268#[derive(Debug, Clone, PartialEq, Eq)]
270pub struct AnnounceOk {
271 pub track_namespace: TrackNamespace,
273}
274
275#[derive(Debug, Clone, PartialEq, Eq)]
277pub struct AnnounceError {
278 pub track_namespace: TrackNamespace,
280 pub error_code: VarInt,
282 pub reason_phrase: Vec<u8>,
284}
285
286#[derive(Debug, Clone, PartialEq, Eq)]
288pub struct AnnounceCancel {
289 pub track_namespace: TrackNamespace,
291 pub error_code: VarInt,
293 pub reason_phrase: Vec<u8>,
295}
296
297#[derive(Debug, Clone, PartialEq, Eq)]
299pub struct Unannounce {
300 pub track_namespace: TrackNamespace,
302}
303
304#[derive(Debug, Clone, PartialEq, Eq)]
310pub struct SubscribeAnnounces {
311 pub track_namespace_prefix: TrackNamespace,
313 pub parameters: Vec<KeyValuePair>,
315}
316
317#[derive(Debug, Clone, PartialEq, Eq)]
319pub struct SubscribeAnnouncesOk {
320 pub track_namespace_prefix: TrackNamespace,
322}
323
324#[derive(Debug, Clone, PartialEq, Eq)]
326pub struct SubscribeAnnouncesError {
327 pub track_namespace_prefix: TrackNamespace,
329 pub error_code: VarInt,
331 pub reason_phrase: Vec<u8>,
333}
334
335#[derive(Debug, Clone, PartialEq, Eq)]
337pub struct UnsubscribeAnnounces {
338 pub track_namespace_prefix: TrackNamespace,
340}
341
342#[derive(Debug, Clone, PartialEq, Eq)]
348pub struct TrackStatusRequest {
349 pub track_namespace: TrackNamespace,
351 pub track_name: Vec<u8>,
353}
354
355#[derive(Debug, Clone, PartialEq, Eq)]
357pub struct TrackStatus {
358 pub track_namespace: TrackNamespace,
360 pub track_name: Vec<u8>,
362 pub status_code: VarInt,
364 pub last_group_id: VarInt,
366 pub last_object_id: VarInt,
368}
369
370#[derive(Debug, Clone, Copy, PartialEq, Eq)]
376#[repr(u64)]
377pub enum FetchType {
378 Standalone = 1,
380 Joining = 2,
382}
383
384impl FetchType {
385 pub fn from_u64(v: u64) -> Option<Self> {
387 match v {
388 1 => Some(FetchType::Standalone),
389 2 => Some(FetchType::Joining),
390 _ => None,
391 }
392 }
393}
394
395#[derive(Debug, Clone, PartialEq, Eq)]
397pub struct Fetch {
398 pub subscribe_id: VarInt,
400 pub subscriber_priority: u8,
402 pub group_order: GroupOrder,
404 pub fetch_type: FetchType,
406 pub track_namespace: Option<TrackNamespace>,
408 pub track_name: Option<Vec<u8>>,
410 pub start_group: Option<VarInt>,
412 pub start_object: Option<VarInt>,
414 pub end_group: Option<VarInt>,
416 pub end_object: Option<VarInt>,
418 pub joining_subscribe_id: Option<VarInt>,
420 pub preceding_group_offset: Option<VarInt>,
422 pub parameters: Vec<KeyValuePair>,
424}
425
426#[derive(Debug, Clone, PartialEq, Eq)]
428pub struct FetchOk {
429 pub subscribe_id: VarInt,
431 pub group_order: GroupOrder,
433 pub end_of_track: u8,
435 pub largest_group_id: VarInt,
437 pub largest_object_id: VarInt,
439 pub parameters: Vec<KeyValuePair>,
441}
442
443#[derive(Debug, Clone, PartialEq, Eq)]
445pub struct FetchError {
446 pub subscribe_id: VarInt,
448 pub error_code: VarInt,
450 pub reason_phrase: Vec<u8>,
452}
453
454#[derive(Debug, Clone, PartialEq, Eq)]
456pub struct FetchCancel {
457 pub subscribe_id: VarInt,
459}
460
461fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
476 if !buf.has_remaining() {
477 return Err(CodecError::UnexpectedEnd);
478 }
479 match GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)? {
480 GroupOrder::Publisher => Err(CodecError::InvalidField),
481 order => Ok(order),
482 }
483}
484
485fn check_track_status(
496 status_code: VarInt,
497 last_group_id: VarInt,
498 last_object_id: VarInt,
499) -> Result<(), CodecError> {
500 let code = crate::draft09::error_codes::TrackStatusCode::from_u64(status_code.into_inner())
501 .ok_or(CodecError::InvalidField)?;
502 if code.requires_zero_location()
503 && (last_group_id.into_inner() != 0 || last_object_id.into_inner() != 0)
504 {
505 return Err(CodecError::InvalidField);
506 }
507 Ok(())
508}
509
510fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
521 match message {
522 ControlMessage::Subscribe(m) => {
523 if m.filter_type == FilterType::NextGroupStart {
525 return Err(CodecError::InvalidField);
526 }
527 let wants_start =
528 matches!(m.filter_type, FilterType::AbsoluteStart | FilterType::AbsoluteRange);
529 if wants_start != m.start_location.is_some() {
530 return Err(CodecError::InvalidField);
531 }
532 if (m.filter_type == FilterType::AbsoluteRange) != m.end_group.is_some() {
533 return Err(CodecError::InvalidField);
534 }
535 Ok(())
536 }
537 ControlMessage::SubscribeOk(m) => {
538 let has = m.content_exists == ContentExists::HasLargestLocation;
539 if has != m.largest_group_id.is_some() || has != m.largest_object_id.is_some() {
540 return Err(CodecError::InvalidField);
541 }
542 Ok(())
543 }
544 ControlMessage::Fetch(m) => {
545 let standalone = m.fetch_type == FetchType::Standalone;
546 let standalone_fields = [
547 m.track_namespace.is_some(),
548 m.track_name.is_some(),
549 m.start_group.is_some(),
550 m.start_object.is_some(),
551 m.end_group.is_some(),
552 m.end_object.is_some(),
553 ];
554 if standalone_fields.iter().any(|present| *present != standalone) {
555 return Err(CodecError::InvalidField);
556 }
557 let joining_fields =
558 [m.joining_subscribe_id.is_some(), m.preceding_group_offset.is_some()];
559 if joining_fields.contains(&standalone) {
560 return Err(CodecError::InvalidField);
561 }
562 Ok(())
563 }
564 _ => Ok(()),
565 }
566}
567
568fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
573 let order = match message {
574 ControlMessage::SubscribeOk(m) => m.group_order,
575 ControlMessage::FetchOk(m) => m.group_order,
576 _ => return Ok(()),
577 };
578 if order == GroupOrder::Publisher {
579 return Err(CodecError::InvalidField);
580 }
581 Ok(())
582}
583
584#[derive(Debug, Clone, PartialEq, Eq)]
586pub enum ControlMessage {
587 ClientSetup(ClientSetup),
589 ServerSetup(ServerSetup),
591 GoAway(GoAway),
593 MaxSubscribeId(MaxSubscribeId),
595 SubscribesBlocked(SubscribesBlocked),
597 Subscribe(Subscribe),
599 SubscribeOk(SubscribeOk),
601 SubscribeError(SubscribeError),
603 SubscribeUpdate(SubscribeUpdate),
605 SubscribeDone(SubscribeDone),
607 Unsubscribe(Unsubscribe),
609 Announce(Announce),
611 AnnounceOk(AnnounceOk),
613 AnnounceError(AnnounceError),
615 AnnounceCancel(AnnounceCancel),
617 Unannounce(Unannounce),
619 SubscribeAnnounces(SubscribeAnnounces),
621 SubscribeAnnouncesOk(SubscribeAnnouncesOk),
623 SubscribeAnnouncesError(SubscribeAnnouncesError),
625 UnsubscribeAnnounces(UnsubscribeAnnounces),
627 TrackStatusRequest(TrackStatusRequest),
629 TrackStatus(TrackStatus),
631 Fetch(Fetch),
633 FetchOk(FetchOk),
635 FetchError(FetchError),
637 FetchCancel(FetchCancel),
639}
640
641fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
655 match message {
656 ControlMessage::Subscribe(m) => match (&m.start_location, &m.end_group) {
657 (Some(start), Some(end_group)) => {
658 check_group_range(start.group.into_inner(), end_group.into_inner())
659 }
660 _ => Ok(()),
661 },
662 ControlMessage::SubscribeUpdate(m) => {
663 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
664 }
665 ControlMessage::Fetch(m) => {
666 match (&m.start_group, &m.start_object, &m.end_group, &m.end_object) {
667 (Some(start_group), Some(start_object), Some(end_group), Some(end_object)) => {
668 check_location_range(
669 start_group.into_inner(),
670 start_object.into_inner(),
671 end_group.into_inner(),
672 end_object.into_inner(),
673 )
674 }
675 _ => Ok(()),
676 }
677 }
678 _ => Ok(()),
679 }
680}
681
682fn check_no_duplicate_parameters(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
693 for (i, parameter) in parameters.iter().enumerate() {
694 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
695 return Err(CodecError::DuplicateParameter(parameter.key.into_inner()));
696 }
697 }
698 Ok(())
699}
700
701const SETUP_VARINT_PARAMETERS: &[u64] = &[0x02];
708
709const VERSION_VARINT_PARAMETERS: &[u64] = &[0x03, 0x04];
722
723fn check_parameter_lengths(
741 parameters: &[KeyValuePair],
742 varint_typed: &[u64],
743) -> Result<(), CodecError> {
744 for parameter in parameters {
745 let key = parameter.key.into_inner();
746 if !varint_typed.contains(&key) {
747 continue;
748 }
749 if let crate::kvp::KvpValue::Bytes(bytes) = ¶meter.value {
750 let mut cursor = &bytes[..];
751 let one_varint = VarInt::decode(&mut cursor).is_ok() && !cursor.has_remaining();
752 if !one_varint {
753 return Err(CodecError::ParameterLengthMismatch(key));
754 }
755 }
756 }
757 Ok(())
758}
759
760fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
763 let parameters = KeyValuePair::decode_list_d07(buf)?;
764 check_no_duplicate_parameters(¶meters)?;
765 check_parameter_lengths(¶meters, VERSION_VARINT_PARAMETERS)?;
766 Ok(parameters)
767}
768
769fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
772 check_no_duplicate_parameters(parameters)?;
773 check_parameter_lengths(parameters, VERSION_VARINT_PARAMETERS)?;
774 KeyValuePair::encode_list_d07(parameters, buf);
775 Ok(())
776}
777
778fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
784 let parameters = KeyValuePair::decode_list_d07(buf)?;
785 check_no_duplicate_parameters(¶meters)?;
786 check_parameter_lengths(¶meters, SETUP_VARINT_PARAMETERS)?;
787 Ok(parameters)
788}
789
790fn encode_setup_parameters(
792 parameters: &[KeyValuePair],
793 buf: &mut impl BufMut,
794) -> Result<(), CodecError> {
795 check_no_duplicate_parameters(parameters)?;
796 check_parameter_lengths(parameters, SETUP_VARINT_PARAMETERS)?;
797 KeyValuePair::encode_list_d07(parameters, buf);
798 Ok(())
799}
800
801impl ControlMessage {
802 pub fn message_type(&self) -> MessageType {
804 match self {
805 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
806 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
807 ControlMessage::GoAway(_) => MessageType::GoAway,
808 ControlMessage::MaxSubscribeId(_) => MessageType::MaxSubscribeId,
809 ControlMessage::SubscribesBlocked(_) => MessageType::SubscribesBlocked,
810 ControlMessage::Subscribe(_) => MessageType::Subscribe,
811 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
812 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
813 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
814 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
815 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
816 ControlMessage::Announce(_) => MessageType::Announce,
817 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
818 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
819 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
820 ControlMessage::Unannounce(_) => MessageType::Unannounce,
821 ControlMessage::SubscribeAnnounces(_) => MessageType::SubscribeAnnounces,
822 ControlMessage::SubscribeAnnouncesOk(_) => MessageType::SubscribeAnnouncesOk,
823 ControlMessage::SubscribeAnnouncesError(_) => MessageType::SubscribeAnnouncesError,
824 ControlMessage::UnsubscribeAnnounces(_) => MessageType::UnsubscribeAnnounces,
825 ControlMessage::TrackStatusRequest(_) => MessageType::TrackStatusRequest,
826 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
827 ControlMessage::Fetch(_) => MessageType::Fetch,
828 ControlMessage::FetchOk(_) => MessageType::FetchOk,
829 ControlMessage::FetchError(_) => MessageType::FetchError,
830 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
831 }
832 }
833
834 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
836 check_discriminators(self)?;
837 check_group_order(self)?;
838 check_ranges(self)?;
839 let mut payload = Vec::with_capacity(256);
840 self.encode_payload(&mut payload)?;
841
842 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
850 VarInt::from_usize(payload.len()).encode(buf);
851 buf.put_slice(&payload);
852 Ok(())
853 }
854
855 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
857 let type_id = VarInt::decode(buf)?.into_inner();
858 let msg_type =
859 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
860 let payload_len = VarInt::decode(buf)?.into_inner() as usize;
861 if buf.remaining() < payload_len {
862 return Err(CodecError::UnexpectedEnd);
863 }
864 let payload_bytes = buf.copy_to_bytes(payload_len);
865 let mut payload = &payload_bytes[..];
866 let msg = match Self::decode_payload(msg_type, &mut payload) {
867 Ok(msg) => msg,
868 Err(
874 CodecError::UnexpectedEnd
875 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
876 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
877 crate::varint::VarIntError::UnexpectedEnd,
878 ))
879 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
880 ) => {
881 return Err(CodecError::ControlMessageLengthMismatch {
882 declared: payload_len,
883 detail: "its fields ran past the end",
884 });
885 }
886 Err(e) => return Err(e),
887 };
888 check_ranges(&msg)?;
889 if payload.has_remaining() {
894 return Err(CodecError::ControlMessageLengthMismatch {
895 declared: payload_len,
896 detail: "its fields left bytes unread",
897 });
898 }
899 Ok(msg)
900 }
901
902 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
903 match self {
904 ControlMessage::ClientSetup(m) => {
905 VarInt::from_usize(m.supported_versions.len()).encode(buf);
906 for v in &m.supported_versions {
907 v.encode(buf);
908 }
909 encode_setup_parameters(&m.parameters, buf)?;
910 }
911 ControlMessage::ServerSetup(m) => {
912 m.selected_version.encode(buf);
913 encode_setup_parameters(&m.parameters, buf)?;
914 }
915 ControlMessage::GoAway(m) => {
916 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
917 buf.put_slice(&m.new_session_uri);
918 }
919 ControlMessage::MaxSubscribeId(m) => {
920 m.subscribe_id.encode(buf);
921 }
922 ControlMessage::SubscribesBlocked(m) => {
923 m.maximum_subscribe_id.encode(buf);
924 }
925 ControlMessage::Subscribe(m) => {
926 m.subscribe_id.encode(buf);
927 m.track_alias.encode(buf);
928 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
929 m.track_namespace.encode(buf);
930 VarInt::from_usize(m.track_name.len()).encode(buf);
931 buf.put_slice(&m.track_name);
932 buf.put_u8(m.subscriber_priority);
933 buf.put_u8(m.group_order as u8);
934 VarInt::from_usize(m.filter_type as usize).encode(buf);
935 if let Some(loc) = &m.start_location {
936 loc.encode(buf);
937 }
938 if let Some(eg) = &m.end_group {
939 eg.encode(buf);
940 }
941 encode_parameters(&m.parameters, buf)?;
942 }
943 ControlMessage::SubscribeOk(m) => {
944 m.subscribe_id.encode(buf);
945 m.expires.encode(buf);
946 buf.put_u8(m.group_order as u8);
947 buf.put_u8(m.content_exists as u8);
948 if let Some(gid) = &m.largest_group_id {
949 gid.encode(buf);
950 }
951 if let Some(oid) = &m.largest_object_id {
952 oid.encode(buf);
953 }
954 encode_parameters(&m.parameters, buf)?;
955 }
956 ControlMessage::SubscribeError(m) => {
957 m.subscribe_id.encode(buf);
958 m.error_code.encode(buf);
959 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
960 buf.put_slice(&m.reason_phrase);
961 m.track_alias.encode(buf);
962 }
963 ControlMessage::SubscribeUpdate(m) => {
964 m.subscribe_id.encode(buf);
965 m.start_group.encode(buf);
966 m.start_object.encode(buf);
967 m.end_group.encode(buf);
968 buf.put_u8(m.subscriber_priority);
969 encode_parameters(&m.parameters, buf)?;
970 }
971 ControlMessage::SubscribeDone(m) => {
972 m.subscribe_id.encode(buf);
973 m.status_code.encode(buf);
974 m.stream_count.encode(buf);
975 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
976 buf.put_slice(&m.reason_phrase);
977 }
978 ControlMessage::Unsubscribe(m) => {
979 m.subscribe_id.encode(buf);
980 }
981 ControlMessage::Announce(m) => {
982 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
983 m.track_namespace.encode(buf);
984 encode_parameters(&m.parameters, buf)?;
985 }
986 ControlMessage::AnnounceOk(m) => {
987 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
988 m.track_namespace.encode(buf);
989 }
990 ControlMessage::AnnounceError(m) => {
991 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
992 m.track_namespace.encode(buf);
993 m.error_code.encode(buf);
994 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
995 buf.put_slice(&m.reason_phrase);
996 }
997 ControlMessage::AnnounceCancel(m) => {
998 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
999 m.track_namespace.encode(buf);
1000 m.error_code.encode(buf);
1001 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1002 buf.put_slice(&m.reason_phrase);
1003 }
1004 ControlMessage::Unannounce(m) => {
1005 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
1006 m.track_namespace.encode(buf);
1007 }
1008 ControlMessage::SubscribeAnnounces(m) => {
1009 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(9))?;
1010 m.track_namespace_prefix.encode(buf);
1011 encode_parameters(&m.parameters, buf)?;
1012 }
1013 ControlMessage::SubscribeAnnouncesOk(m) => {
1014 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(9))?;
1015 m.track_namespace_prefix.encode(buf);
1016 }
1017 ControlMessage::SubscribeAnnouncesError(m) => {
1018 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(9))?;
1019 m.track_namespace_prefix.encode(buf);
1020 m.error_code.encode(buf);
1021 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1022 buf.put_slice(&m.reason_phrase);
1023 }
1024 ControlMessage::UnsubscribeAnnounces(m) => {
1025 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(9))?;
1026 m.track_namespace_prefix.encode(buf);
1027 }
1028 ControlMessage::TrackStatusRequest(m) => {
1029 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
1030 m.track_namespace.encode(buf);
1031 VarInt::from_usize(m.track_name.len()).encode(buf);
1032 buf.put_slice(&m.track_name);
1033 }
1034 ControlMessage::TrackStatus(m) => {
1035 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
1036 m.track_namespace.encode(buf);
1037 VarInt::from_usize(m.track_name.len()).encode(buf);
1038 buf.put_slice(&m.track_name);
1039 check_track_status(m.status_code, m.last_group_id, m.last_object_id)?;
1040 m.status_code.encode(buf);
1041 m.last_group_id.encode(buf);
1042 m.last_object_id.encode(buf);
1043 }
1044 ControlMessage::Fetch(m) => {
1045 m.subscribe_id.encode(buf);
1046 buf.put_u8(m.subscriber_priority);
1047 buf.put_u8(m.group_order as u8);
1048 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1049 match m.fetch_type {
1050 FetchType::Standalone => {
1051 if let Some(ns) = &m.track_namespace {
1052 ns.encode(buf);
1053 }
1054 if let Some(name) = &m.track_name {
1055 VarInt::from_usize(name.len()).encode(buf);
1056 buf.put_slice(name);
1057 }
1058 if let Some(sg) = &m.start_group {
1059 sg.encode(buf);
1060 }
1061 if let Some(so) = &m.start_object {
1062 so.encode(buf);
1063 }
1064 if let Some(eg) = &m.end_group {
1065 eg.encode(buf);
1066 }
1067 if let Some(eo) = &m.end_object {
1068 eo.encode(buf);
1069 }
1070 }
1071 FetchType::Joining => {
1072 if let Some(jsi) = &m.joining_subscribe_id {
1073 jsi.encode(buf);
1074 }
1075 if let Some(pgo) = &m.preceding_group_offset {
1076 pgo.encode(buf);
1077 }
1078 }
1079 }
1080 encode_parameters(&m.parameters, buf)?;
1081 }
1082 ControlMessage::FetchOk(m) => {
1083 m.subscribe_id.encode(buf);
1084 buf.put_u8(m.group_order as u8);
1085 buf.put_u8(m.end_of_track);
1086 m.largest_group_id.encode(buf);
1087 m.largest_object_id.encode(buf);
1088 encode_parameters(&m.parameters, buf)?;
1089 }
1090 ControlMessage::FetchError(m) => {
1091 m.subscribe_id.encode(buf);
1092 m.error_code.encode(buf);
1093 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1094 buf.put_slice(&m.reason_phrase);
1095 }
1096 ControlMessage::FetchCancel(m) => {
1097 m.subscribe_id.encode(buf);
1098 }
1099 }
1100 Ok(())
1101 }
1102
1103 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1104 match msg_type {
1105 MessageType::ClientSetup => {
1106 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1107 if num_versions == 0 {
1117 return Err(CodecError::InvalidField);
1118 }
1119 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1120 for _ in 0..num_versions {
1121 supported_versions.push(VarInt::decode(buf)?);
1122 }
1123 let parameters = decode_setup_parameters(buf)?;
1124 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1125 }
1126 MessageType::ServerSetup => {
1127 let selected_version = VarInt::decode(buf)?;
1128 let parameters = decode_setup_parameters(buf)?;
1129 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1130 }
1131 MessageType::GoAway => {
1132 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1133 let uri = read_bytes(buf, uri_len)?;
1134 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1135 }
1136 MessageType::MaxSubscribeId => {
1137 let subscribe_id = VarInt::decode(buf)?;
1138 Ok(ControlMessage::MaxSubscribeId(MaxSubscribeId { subscribe_id }))
1139 }
1140 MessageType::SubscribesBlocked => {
1141 let maximum_subscribe_id = VarInt::decode(buf)?;
1142 Ok(ControlMessage::SubscribesBlocked(SubscribesBlocked { maximum_subscribe_id }))
1143 }
1144 MessageType::Subscribe => {
1145 let subscribe_id = VarInt::decode(buf)?;
1146 let track_alias = VarInt::decode(buf)?;
1147 let track_namespace = TrackNamespace::decode(buf)?;
1148 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1149 let track_name = read_bytes(buf, track_name_len)?;
1150 if buf.remaining() < 2 {
1151 return Err(CodecError::UnexpectedEnd);
1152 }
1153 let subscriber_priority = buf.get_u8();
1154 let group_order =
1155 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1156 let filter_val = VarInt::decode(buf)?.into_inner();
1157 if filter_val == 1 {
1159 return Err(CodecError::InvalidFilterType(filter_val));
1160 }
1161 let filter_type = FilterType::from_u64(filter_val)
1162 .ok_or(CodecError::InvalidFilterType(filter_val))?;
1163 let start_location = match filter_type {
1164 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1165 Some(Location::decode(buf)?)
1166 }
1167 _ => None,
1168 };
1169 let end_group = match filter_type {
1170 FilterType::AbsoluteRange => Some(VarInt::decode(buf)?),
1171 _ => None,
1172 };
1173 let parameters = decode_parameters(buf)?;
1174 Ok(ControlMessage::Subscribe(Subscribe {
1175 subscribe_id,
1176 track_alias,
1177 track_namespace,
1178 track_name,
1179 subscriber_priority,
1180 group_order,
1181 filter_type,
1182 start_location,
1183 end_group,
1184 parameters,
1185 }))
1186 }
1187 MessageType::SubscribeOk => {
1188 let subscribe_id = VarInt::decode(buf)?;
1189 let expires = VarInt::decode(buf)?;
1190 if buf.remaining() < 2 {
1191 return Err(CodecError::UnexpectedEnd);
1192 }
1193 let group_order = read_group_order_response(buf)?;
1194 let content_exists_val = buf.get_u8();
1195 let content_exists = match content_exists_val {
1196 0 => ContentExists::NoLargestLocation,
1197 1 => ContentExists::HasLargestLocation,
1198 other => return Err(CodecError::InvalidContentExists(other)),
1199 };
1200 let (largest_group_id, largest_object_id) =
1201 if content_exists == ContentExists::HasLargestLocation {
1202 let gid = VarInt::decode(buf)?;
1203 let oid = VarInt::decode(buf)?;
1204 (Some(gid), Some(oid))
1205 } else {
1206 (None, None)
1207 };
1208 let parameters = decode_parameters(buf)?;
1209 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1210 subscribe_id,
1211 expires,
1212 group_order,
1213 content_exists,
1214 largest_group_id,
1215 largest_object_id,
1216 parameters,
1217 }))
1218 }
1219 MessageType::SubscribeError => {
1220 let subscribe_id = VarInt::decode(buf)?;
1221 let error_code = VarInt::decode(buf)?;
1222 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1223 let reason_phrase = read_bytes(buf, reason_len)?;
1224 let track_alias = VarInt::decode(buf)?;
1225 Ok(ControlMessage::SubscribeError(SubscribeError {
1226 subscribe_id,
1227 error_code,
1228 reason_phrase,
1229 track_alias,
1230 }))
1231 }
1232 MessageType::SubscribeUpdate => {
1233 let subscribe_id = VarInt::decode(buf)?;
1234 let start_group = VarInt::decode(buf)?;
1235 let start_object = VarInt::decode(buf)?;
1236 let end_group = VarInt::decode(buf)?;
1237 if buf.remaining() < 1 {
1238 return Err(CodecError::UnexpectedEnd);
1239 }
1240 let subscriber_priority = buf.get_u8();
1241 let parameters = decode_parameters(buf)?;
1242 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1243 subscribe_id,
1244 start_group,
1245 start_object,
1246 end_group,
1247 subscriber_priority,
1248 parameters,
1249 }))
1250 }
1251 MessageType::SubscribeDone => {
1252 let subscribe_id = VarInt::decode(buf)?;
1253 let status_code = VarInt::decode(buf)?;
1254 let stream_count = VarInt::decode(buf)?;
1255 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1256 let reason_phrase = read_bytes(buf, reason_len)?;
1257 Ok(ControlMessage::SubscribeDone(SubscribeDone {
1258 subscribe_id,
1259 status_code,
1260 stream_count,
1261 reason_phrase,
1262 }))
1263 }
1264 MessageType::Unsubscribe => {
1265 let subscribe_id = VarInt::decode(buf)?;
1266 Ok(ControlMessage::Unsubscribe(Unsubscribe { subscribe_id }))
1267 }
1268 MessageType::Announce => {
1269 let track_namespace = TrackNamespace::decode(buf)?;
1270 let parameters = decode_parameters(buf)?;
1271 Ok(ControlMessage::Announce(Announce { track_namespace, parameters }))
1272 }
1273 MessageType::AnnounceOk => {
1274 let track_namespace = TrackNamespace::decode(buf)?;
1275 Ok(ControlMessage::AnnounceOk(AnnounceOk { track_namespace }))
1276 }
1277 MessageType::AnnounceError => {
1278 let track_namespace = TrackNamespace::decode(buf)?;
1279 let error_code = VarInt::decode(buf)?;
1280 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1281 let reason_phrase = read_bytes(buf, reason_len)?;
1282 Ok(ControlMessage::AnnounceError(AnnounceError {
1283 track_namespace,
1284 error_code,
1285 reason_phrase,
1286 }))
1287 }
1288 MessageType::AnnounceCancel => {
1289 let track_namespace = TrackNamespace::decode(buf)?;
1290 let error_code = VarInt::decode(buf)?;
1291 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1292 let reason_phrase = read_bytes(buf, reason_len)?;
1293 Ok(ControlMessage::AnnounceCancel(AnnounceCancel {
1294 track_namespace,
1295 error_code,
1296 reason_phrase,
1297 }))
1298 }
1299 MessageType::Unannounce => {
1300 let track_namespace = TrackNamespace::decode(buf)?;
1301 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1302 }
1303 MessageType::SubscribeAnnounces => {
1304 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1305 let parameters = decode_parameters(buf)?;
1306 Ok(ControlMessage::SubscribeAnnounces(SubscribeAnnounces {
1307 track_namespace_prefix,
1308 parameters,
1309 }))
1310 }
1311 MessageType::SubscribeAnnouncesOk => {
1312 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1313 Ok(ControlMessage::SubscribeAnnouncesOk(SubscribeAnnouncesOk {
1314 track_namespace_prefix,
1315 }))
1316 }
1317 MessageType::SubscribeAnnouncesError => {
1318 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1319 let error_code = VarInt::decode(buf)?;
1320 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1321 let reason_phrase = read_bytes(buf, reason_len)?;
1322 Ok(ControlMessage::SubscribeAnnouncesError(SubscribeAnnouncesError {
1323 track_namespace_prefix,
1324 error_code,
1325 reason_phrase,
1326 }))
1327 }
1328 MessageType::UnsubscribeAnnounces => {
1329 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1330 Ok(ControlMessage::UnsubscribeAnnounces(UnsubscribeAnnounces {
1331 track_namespace_prefix,
1332 }))
1333 }
1334 MessageType::TrackStatusRequest => {
1335 let track_namespace = TrackNamespace::decode(buf)?;
1336 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1337 let track_name = read_bytes(buf, track_name_len)?;
1338 Ok(ControlMessage::TrackStatusRequest(TrackStatusRequest {
1339 track_namespace,
1340 track_name,
1341 }))
1342 }
1343 MessageType::TrackStatus => {
1344 let track_namespace = TrackNamespace::decode(buf)?;
1345 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1346 let track_name = read_bytes(buf, track_name_len)?;
1347 let status_code = VarInt::decode(buf)?;
1348 let last_group_id = VarInt::decode(buf)?;
1349 let last_object_id = VarInt::decode(buf)?;
1350 check_track_status(status_code, last_group_id, last_object_id)?;
1351 Ok(ControlMessage::TrackStatus(TrackStatus {
1352 track_namespace,
1353 track_name,
1354 status_code,
1355 last_group_id,
1356 last_object_id,
1357 }))
1358 }
1359 MessageType::Fetch => {
1360 let subscribe_id = VarInt::decode(buf)?;
1361 if buf.remaining() < 2 {
1362 return Err(CodecError::UnexpectedEnd);
1363 }
1364 let subscriber_priority = buf.get_u8();
1365 let group_order =
1366 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1367 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1368 let fetch_type = FetchType::from_u64(fetch_type_val)
1369 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1370 let (
1371 track_namespace,
1372 track_name,
1373 start_group,
1374 start_object,
1375 end_group,
1376 end_object,
1377 joining_subscribe_id,
1378 preceding_group_offset,
1379 ) = match fetch_type {
1380 FetchType::Standalone => {
1381 let ns = TrackNamespace::decode(buf)?;
1382 let name_len = VarInt::decode(buf)?.into_inner() as usize;
1383 let name = read_bytes(buf, name_len)?;
1384 let sg = VarInt::decode(buf)?;
1385 let so = VarInt::decode(buf)?;
1386 let eg = VarInt::decode(buf)?;
1387 let eo = VarInt::decode(buf)?;
1388 (Some(ns), Some(name), Some(sg), Some(so), Some(eg), Some(eo), None, None)
1389 }
1390 FetchType::Joining => {
1391 let jsi = VarInt::decode(buf)?;
1392 let pgo = VarInt::decode(buf)?;
1393 (None, None, None, None, None, None, Some(jsi), Some(pgo))
1394 }
1395 };
1396 let parameters = decode_parameters(buf)?;
1397 Ok(ControlMessage::Fetch(Fetch {
1398 subscribe_id,
1399 subscriber_priority,
1400 group_order,
1401 fetch_type,
1402 track_namespace,
1403 track_name,
1404 start_group,
1405 start_object,
1406 end_group,
1407 end_object,
1408 joining_subscribe_id,
1409 preceding_group_offset,
1410 parameters,
1411 }))
1412 }
1413 MessageType::FetchOk => {
1414 let subscribe_id = VarInt::decode(buf)?;
1415 if buf.remaining() < 2 {
1416 return Err(CodecError::UnexpectedEnd);
1417 }
1418 let group_order = read_group_order_response(buf)?;
1419 let end_of_track = buf.get_u8();
1420 let largest_group_id = VarInt::decode(buf)?;
1421 let largest_object_id = VarInt::decode(buf)?;
1422 let parameters = decode_parameters(buf)?;
1423 Ok(ControlMessage::FetchOk(FetchOk {
1424 subscribe_id,
1425 group_order,
1426 end_of_track,
1427 largest_group_id,
1428 largest_object_id,
1429 parameters,
1430 }))
1431 }
1432 MessageType::FetchError => {
1433 let subscribe_id = VarInt::decode(buf)?;
1434 let error_code = VarInt::decode(buf)?;
1435 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1436 let reason_phrase = read_bytes(buf, reason_len)?;
1437 Ok(ControlMessage::FetchError(FetchError {
1438 subscribe_id,
1439 error_code,
1440 reason_phrase,
1441 }))
1442 }
1443 MessageType::FetchCancel => {
1444 let subscribe_id = VarInt::decode(buf)?;
1445 Ok(ControlMessage::FetchCancel(FetchCancel { subscribe_id }))
1446 }
1447 }
1448 }
1449}