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
109#[derive(Debug, Clone, PartialEq, Eq)]
115pub struct ClientSetup {
116 pub supported_versions: Vec<VarInt>,
118 pub parameters: Vec<KeyValuePair>,
120}
121
122#[derive(Debug, Clone, PartialEq, Eq)]
124pub struct ServerSetup {
125 pub selected_version: VarInt,
127 pub parameters: Vec<KeyValuePair>,
129}
130
131#[derive(Debug, Clone, PartialEq, Eq)]
133pub struct GoAway {
134 pub new_session_uri: Vec<u8>,
136}
137
138#[derive(Debug, Clone, PartialEq, Eq)]
140pub struct MaxSubscribeId {
141 pub subscribe_id: VarInt,
143}
144
145#[derive(Debug, Clone, PartialEq, Eq)]
147pub struct SubscribesBlocked {
148 pub maximum_subscribe_id: VarInt,
150}
151
152#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct Subscribe {
161 pub subscribe_id: VarInt,
163 pub track_alias: VarInt,
165 pub track_namespace: TrackNamespace,
167 pub track_name: Vec<u8>,
169 pub subscriber_priority: u8,
171 pub group_order: GroupOrder,
173 pub filter_type: FilterType,
175 pub start_location: Option<Location>,
177 pub end_group: Option<VarInt>,
179 pub parameters: Vec<KeyValuePair>,
181}
182
183#[derive(Debug, Clone, PartialEq, Eq)]
185pub struct SubscribeOk {
186 pub subscribe_id: VarInt,
188 pub expires: VarInt,
190 pub group_order: GroupOrder,
192 pub content_exists: ContentExists,
194 pub largest_group_id: Option<VarInt>,
196 pub largest_object_id: Option<VarInt>,
198 pub parameters: Vec<KeyValuePair>,
200}
201
202#[derive(Debug, Clone, PartialEq, Eq)]
204pub struct SubscribeError {
205 pub subscribe_id: VarInt,
207 pub error_code: VarInt,
209 pub reason_phrase: Vec<u8>,
211 pub track_alias: VarInt,
213}
214
215#[derive(Debug, Clone, PartialEq, Eq)]
219pub struct SubscribeUpdate {
220 pub subscribe_id: VarInt,
222 pub start_group: VarInt,
224 pub start_object: VarInt,
226 pub end_group: VarInt,
228 pub subscriber_priority: u8,
230 pub parameters: Vec<KeyValuePair>,
232}
233
234#[derive(Debug, Clone, PartialEq, Eq)]
238pub struct SubscribeDone {
239 pub subscribe_id: VarInt,
241 pub status_code: VarInt,
243 pub stream_count: VarInt,
245 pub reason_phrase: Vec<u8>,
247}
248
249#[derive(Debug, Clone, PartialEq, Eq)]
251pub struct Unsubscribe {
252 pub subscribe_id: VarInt,
254}
255
256#[derive(Debug, Clone, PartialEq, Eq)]
262pub struct Announce {
263 pub track_namespace: TrackNamespace,
265 pub parameters: Vec<KeyValuePair>,
267}
268
269#[derive(Debug, Clone, PartialEq, Eq)]
271pub struct AnnounceOk {
272 pub track_namespace: TrackNamespace,
274}
275
276#[derive(Debug, Clone, PartialEq, Eq)]
278pub struct AnnounceError {
279 pub track_namespace: TrackNamespace,
281 pub error_code: VarInt,
283 pub reason_phrase: Vec<u8>,
285}
286
287#[derive(Debug, Clone, PartialEq, Eq)]
289pub struct AnnounceCancel {
290 pub track_namespace: TrackNamespace,
292 pub error_code: VarInt,
294 pub reason_phrase: Vec<u8>,
296}
297
298#[derive(Debug, Clone, PartialEq, Eq)]
300pub struct Unannounce {
301 pub track_namespace: TrackNamespace,
303}
304
305#[derive(Debug, Clone, PartialEq, Eq)]
311pub struct SubscribeAnnounces {
312 pub track_namespace_prefix: TrackNamespace,
314 pub parameters: Vec<KeyValuePair>,
316}
317
318#[derive(Debug, Clone, PartialEq, Eq)]
320pub struct SubscribeAnnouncesOk {
321 pub track_namespace_prefix: TrackNamespace,
323}
324
325#[derive(Debug, Clone, PartialEq, Eq)]
327pub struct SubscribeAnnouncesError {
328 pub track_namespace_prefix: TrackNamespace,
330 pub error_code: VarInt,
332 pub reason_phrase: Vec<u8>,
334}
335
336#[derive(Debug, Clone, PartialEq, Eq)]
338pub struct UnsubscribeAnnounces {
339 pub track_namespace_prefix: TrackNamespace,
341}
342
343#[derive(Debug, Clone, PartialEq, Eq)]
349pub struct TrackStatusRequest {
350 pub track_namespace: TrackNamespace,
352 pub track_name: Vec<u8>,
354}
355
356#[derive(Debug, Clone, PartialEq, Eq)]
358pub struct TrackStatus {
359 pub track_namespace: TrackNamespace,
361 pub track_name: Vec<u8>,
363 pub status_code: VarInt,
365 pub last_group_id: VarInt,
367 pub last_object_id: VarInt,
369}
370
371#[derive(Debug, Clone, Copy, PartialEq, Eq)]
377#[repr(u64)]
378pub enum FetchType {
379 Standalone = 1,
381 Joining = 2,
383}
384
385impl FetchType {
386 pub fn from_u64(v: u64) -> Option<Self> {
388 match v {
389 1 => Some(FetchType::Standalone),
390 2 => Some(FetchType::Joining),
391 _ => None,
392 }
393 }
394}
395
396#[derive(Debug, Clone, PartialEq, Eq)]
400pub struct Fetch {
401 pub subscribe_id: VarInt,
403 pub subscriber_priority: u8,
405 pub group_order: GroupOrder,
407 pub fetch_type: FetchType,
409 pub track_namespace: Option<TrackNamespace>,
411 pub track_name: Option<Vec<u8>>,
413 pub start_group: Option<VarInt>,
415 pub start_object: Option<VarInt>,
417 pub end_group: Option<VarInt>,
419 pub end_object: Option<VarInt>,
421 pub joining_subscribe_id: Option<VarInt>,
423 pub preceding_group_offset: Option<VarInt>,
425 pub parameters: Vec<KeyValuePair>,
427}
428
429#[derive(Debug, Clone, PartialEq, Eq)]
433pub struct FetchOk {
434 pub subscribe_id: VarInt,
436 pub group_order: GroupOrder,
438 pub end_of_track: u8,
440 pub largest_group_id: VarInt,
442 pub largest_object_id: VarInt,
444 pub parameters: Vec<KeyValuePair>,
446}
447
448#[derive(Debug, Clone, PartialEq, Eq)]
450pub struct FetchError {
451 pub subscribe_id: VarInt,
453 pub error_code: VarInt,
455 pub reason_phrase: Vec<u8>,
457}
458
459#[derive(Debug, Clone, PartialEq, Eq)]
461pub struct FetchCancel {
462 pub subscribe_id: VarInt,
464}
465
466fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
481 if !buf.has_remaining() {
482 return Err(CodecError::UnexpectedEnd);
483 }
484 match GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)? {
485 GroupOrder::Publisher => Err(CodecError::InvalidField),
486 order => Ok(order),
487 }
488}
489
490fn check_track_status(
501 status_code: VarInt,
502 last_group_id: VarInt,
503 last_object_id: VarInt,
504) -> Result<(), CodecError> {
505 let code = crate::draft08::error_codes::TrackStatusCode::from_u64(status_code.into_inner())
506 .ok_or(CodecError::InvalidField)?;
507 if code.requires_zero_location()
508 && (last_group_id.into_inner() != 0 || last_object_id.into_inner() != 0)
509 {
510 return Err(CodecError::InvalidField);
511 }
512 Ok(())
513}
514
515fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
526 match message {
527 ControlMessage::Subscribe(m) => {
528 let wants_start =
529 matches!(m.filter_type, FilterType::AbsoluteStart | FilterType::AbsoluteRange);
530 if wants_start != m.start_location.is_some() {
531 return Err(CodecError::InvalidField);
532 }
533 if (m.filter_type == FilterType::AbsoluteRange) != m.end_group.is_some() {
534 return Err(CodecError::InvalidField);
535 }
536 Ok(())
537 }
538 ControlMessage::SubscribeOk(m) => {
539 let has = m.content_exists == ContentExists::HasLargestLocation;
540 if has != m.largest_group_id.is_some() || has != m.largest_object_id.is_some() {
541 return Err(CodecError::InvalidField);
542 }
543 Ok(())
544 }
545 ControlMessage::Fetch(m) => {
546 let standalone = m.fetch_type == FetchType::Standalone;
547 let standalone_fields = [
548 m.track_namespace.is_some(),
549 m.track_name.is_some(),
550 m.start_group.is_some(),
551 m.start_object.is_some(),
552 m.end_group.is_some(),
553 m.end_object.is_some(),
554 ];
555 if standalone_fields.iter().any(|present| *present != standalone) {
556 return Err(CodecError::InvalidField);
557 }
558 let joining_fields =
559 [m.joining_subscribe_id.is_some(), m.preceding_group_offset.is_some()];
560 if joining_fields.contains(&standalone) {
561 return Err(CodecError::InvalidField);
562 }
563 Ok(())
564 }
565 _ => Ok(()),
566 }
567}
568
569fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
574 let order = match message {
575 ControlMessage::SubscribeOk(m) => m.group_order,
576 ControlMessage::FetchOk(m) => m.group_order,
577 _ => return Ok(()),
578 };
579 if order == GroupOrder::Publisher {
580 return Err(CodecError::InvalidField);
581 }
582 Ok(())
583}
584
585#[derive(Debug, Clone, PartialEq, Eq)]
587pub enum ControlMessage {
588 ClientSetup(ClientSetup),
590 ServerSetup(ServerSetup),
592 GoAway(GoAway),
594 MaxSubscribeId(MaxSubscribeId),
596 SubscribesBlocked(SubscribesBlocked),
598 Subscribe(Subscribe),
600 SubscribeOk(SubscribeOk),
602 SubscribeError(SubscribeError),
604 SubscribeUpdate(SubscribeUpdate),
606 SubscribeDone(SubscribeDone),
608 Unsubscribe(Unsubscribe),
610 Announce(Announce),
612 AnnounceOk(AnnounceOk),
614 AnnounceError(AnnounceError),
616 AnnounceCancel(AnnounceCancel),
618 Unannounce(Unannounce),
620 SubscribeAnnounces(SubscribeAnnounces),
622 SubscribeAnnouncesOk(SubscribeAnnouncesOk),
624 SubscribeAnnouncesError(SubscribeAnnouncesError),
626 UnsubscribeAnnounces(UnsubscribeAnnounces),
628 TrackStatusRequest(TrackStatusRequest),
630 TrackStatus(TrackStatus),
632 Fetch(Fetch),
634 FetchOk(FetchOk),
636 FetchError(FetchError),
638 FetchCancel(FetchCancel),
640}
641
642fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
656 match message {
657 ControlMessage::Subscribe(m) => match (&m.start_location, &m.end_group) {
658 (Some(start), Some(end_group)) => {
659 check_group_range(start.group.into_inner(), end_group.into_inner())
660 }
661 _ => Ok(()),
662 },
663 ControlMessage::SubscribeUpdate(m) => {
664 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
665 }
666 ControlMessage::Fetch(m) => {
667 match (&m.start_group, &m.start_object, &m.end_group, &m.end_object) {
668 (Some(start_group), Some(start_object), Some(end_group), Some(end_object)) => {
669 check_location_range(
670 start_group.into_inner(),
671 start_object.into_inner(),
672 end_group.into_inner(),
673 end_object.into_inner(),
674 )
675 }
676 _ => Ok(()),
677 }
678 }
679 _ => Ok(()),
680 }
681}
682
683fn check_no_duplicate_parameters(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
694 for (i, parameter) in parameters.iter().enumerate() {
695 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
696 return Err(CodecError::DuplicateParameter(parameter.key.into_inner()));
697 }
698 }
699 Ok(())
700}
701
702const SETUP_VARINT_PARAMETERS: &[u64] = &[0x02];
709
710const VERSION_VARINT_PARAMETERS: &[u64] = &[0x03, 0x04];
723
724fn check_parameter_lengths(
742 parameters: &[KeyValuePair],
743 varint_typed: &[u64],
744) -> Result<(), CodecError> {
745 for parameter in parameters {
746 let key = parameter.key.into_inner();
747 if !varint_typed.contains(&key) {
748 continue;
749 }
750 if let crate::kvp::KvpValue::Bytes(bytes) = ¶meter.value {
751 let mut cursor = &bytes[..];
752 let one_varint = VarInt::decode(&mut cursor).is_ok() && !cursor.has_remaining();
753 if !one_varint {
754 return Err(CodecError::ParameterLengthMismatch(key));
755 }
756 }
757 }
758 Ok(())
759}
760
761fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
764 let parameters = KeyValuePair::decode_list_d07(buf)?;
765 check_no_duplicate_parameters(¶meters)?;
766 check_parameter_lengths(¶meters, VERSION_VARINT_PARAMETERS)?;
767 Ok(parameters)
768}
769
770fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
773 check_no_duplicate_parameters(parameters)?;
774 check_parameter_lengths(parameters, VERSION_VARINT_PARAMETERS)?;
775 KeyValuePair::encode_list_d07(parameters, buf);
776 Ok(())
777}
778
779fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
785 let parameters = KeyValuePair::decode_list_d07(buf)?;
786 check_no_duplicate_parameters(¶meters)?;
787 check_parameter_lengths(¶meters, SETUP_VARINT_PARAMETERS)?;
788 Ok(parameters)
789}
790
791fn encode_setup_parameters(
793 parameters: &[KeyValuePair],
794 buf: &mut impl BufMut,
795) -> Result<(), CodecError> {
796 check_no_duplicate_parameters(parameters)?;
797 check_parameter_lengths(parameters, SETUP_VARINT_PARAMETERS)?;
798 KeyValuePair::encode_list_d07(parameters, buf);
799 Ok(())
800}
801
802impl ControlMessage {
803 pub fn message_type(&self) -> MessageType {
805 match self {
806 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
807 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
808 ControlMessage::GoAway(_) => MessageType::GoAway,
809 ControlMessage::MaxSubscribeId(_) => MessageType::MaxSubscribeId,
810 ControlMessage::SubscribesBlocked(_) => MessageType::SubscribesBlocked,
811 ControlMessage::Subscribe(_) => MessageType::Subscribe,
812 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
813 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
814 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
815 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
816 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
817 ControlMessage::Announce(_) => MessageType::Announce,
818 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
819 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
820 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
821 ControlMessage::Unannounce(_) => MessageType::Unannounce,
822 ControlMessage::SubscribeAnnounces(_) => MessageType::SubscribeAnnounces,
823 ControlMessage::SubscribeAnnouncesOk(_) => MessageType::SubscribeAnnouncesOk,
824 ControlMessage::SubscribeAnnouncesError(_) => MessageType::SubscribeAnnouncesError,
825 ControlMessage::UnsubscribeAnnounces(_) => MessageType::UnsubscribeAnnounces,
826 ControlMessage::TrackStatusRequest(_) => MessageType::TrackStatusRequest,
827 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
828 ControlMessage::Fetch(_) => MessageType::Fetch,
829 ControlMessage::FetchOk(_) => MessageType::FetchOk,
830 ControlMessage::FetchError(_) => MessageType::FetchError,
831 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
832 }
833 }
834
835 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
837 check_discriminators(self)?;
838 check_group_order(self)?;
839 check_ranges(self)?;
840 let mut payload = Vec::with_capacity(256);
841 self.encode_payload(&mut payload)?;
842
843 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
851 VarInt::from_usize(payload.len()).encode(buf);
852 buf.put_slice(&payload);
853 Ok(())
854 }
855
856 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
858 let type_id = VarInt::decode(buf)?.into_inner();
859 let msg_type =
860 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
861 let payload_len = VarInt::decode(buf)?.into_inner() as usize;
862 if buf.remaining() < payload_len {
863 return Err(CodecError::UnexpectedEnd);
864 }
865 let payload_bytes = buf.copy_to_bytes(payload_len);
866 let mut payload = &payload_bytes[..];
867 let msg = match Self::decode_payload(msg_type, &mut payload) {
868 Ok(msg) => msg,
869 Err(
875 CodecError::UnexpectedEnd
876 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
877 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
878 crate::varint::VarIntError::UnexpectedEnd,
879 ))
880 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
881 ) => {
882 return Err(CodecError::ControlMessageLengthMismatch {
883 declared: payload_len,
884 detail: "its fields ran past the end",
885 });
886 }
887 Err(e) => return Err(e),
888 };
889 check_ranges(&msg)?;
890 if payload.has_remaining() {
895 return Err(CodecError::ControlMessageLengthMismatch {
896 declared: payload_len,
897 detail: "its fields left bytes unread",
898 });
899 }
900 Ok(msg)
901 }
902
903 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
904 match self {
905 ControlMessage::ClientSetup(m) => {
906 VarInt::from_usize(m.supported_versions.len()).encode(buf);
907 for v in &m.supported_versions {
908 v.encode(buf);
909 }
910 encode_setup_parameters(&m.parameters, buf)?;
911 }
912 ControlMessage::ServerSetup(m) => {
913 m.selected_version.encode(buf);
914 encode_setup_parameters(&m.parameters, buf)?;
915 }
916 ControlMessage::GoAway(m) => {
917 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
918 buf.put_slice(&m.new_session_uri);
919 }
920 ControlMessage::MaxSubscribeId(m) => {
921 m.subscribe_id.encode(buf);
922 }
923 ControlMessage::SubscribesBlocked(m) => {
924 m.maximum_subscribe_id.encode(buf);
925 }
926 ControlMessage::Subscribe(m) => {
927 m.subscribe_id.encode(buf);
928 m.track_alias.encode(buf);
929 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
930 m.track_namespace.encode(buf);
931 VarInt::from_usize(m.track_name.len()).encode(buf);
932 buf.put_slice(&m.track_name);
933 buf.put_u8(m.subscriber_priority);
934 buf.put_u8(m.group_order as u8);
935 VarInt::from_usize(m.filter_type as usize).encode(buf);
936 if let Some(loc) = &m.start_location {
937 loc.encode(buf);
938 }
939 if let Some(eg) = &m.end_group {
940 eg.encode(buf);
941 }
942 encode_parameters(&m.parameters, buf)?;
943 }
944 ControlMessage::SubscribeOk(m) => {
945 m.subscribe_id.encode(buf);
946 m.expires.encode(buf);
947 buf.put_u8(m.group_order as u8);
948 buf.put_u8(m.content_exists as u8);
949 if let Some(gid) = &m.largest_group_id {
950 gid.encode(buf);
951 }
952 if let Some(oid) = &m.largest_object_id {
953 oid.encode(buf);
954 }
955 encode_parameters(&m.parameters, buf)?;
956 }
957 ControlMessage::SubscribeError(m) => {
958 m.subscribe_id.encode(buf);
959 m.error_code.encode(buf);
960 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
961 buf.put_slice(&m.reason_phrase);
962 m.track_alias.encode(buf);
963 }
964 ControlMessage::SubscribeUpdate(m) => {
965 m.subscribe_id.encode(buf);
966 m.start_group.encode(buf);
967 m.start_object.encode(buf);
968 m.end_group.encode(buf);
969 buf.put_u8(m.subscriber_priority);
970 encode_parameters(&m.parameters, buf)?;
971 }
972 ControlMessage::SubscribeDone(m) => {
973 m.subscribe_id.encode(buf);
974 m.status_code.encode(buf);
975 m.stream_count.encode(buf);
976 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
977 buf.put_slice(&m.reason_phrase);
978 }
979 ControlMessage::Unsubscribe(m) => {
980 m.subscribe_id.encode(buf);
981 }
982 ControlMessage::Announce(m) => {
983 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
984 m.track_namespace.encode(buf);
985 encode_parameters(&m.parameters, buf)?;
986 }
987 ControlMessage::AnnounceOk(m) => {
988 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
989 m.track_namespace.encode(buf);
990 }
991 ControlMessage::AnnounceError(m) => {
992 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
993 m.track_namespace.encode(buf);
994 m.error_code.encode(buf);
995 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
996 buf.put_slice(&m.reason_phrase);
997 }
998 ControlMessage::AnnounceCancel(m) => {
999 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
1000 m.track_namespace.encode(buf);
1001 m.error_code.encode(buf);
1002 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1003 buf.put_slice(&m.reason_phrase);
1004 }
1005 ControlMessage::Unannounce(m) => {
1006 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
1007 m.track_namespace.encode(buf);
1008 }
1009 ControlMessage::SubscribeAnnounces(m) => {
1010 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(8))?;
1011 m.track_namespace_prefix.encode(buf);
1012 encode_parameters(&m.parameters, buf)?;
1013 }
1014 ControlMessage::SubscribeAnnouncesOk(m) => {
1015 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(8))?;
1016 m.track_namespace_prefix.encode(buf);
1017 }
1018 ControlMessage::SubscribeAnnouncesError(m) => {
1019 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(8))?;
1020 m.track_namespace_prefix.encode(buf);
1021 m.error_code.encode(buf);
1022 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1023 buf.put_slice(&m.reason_phrase);
1024 }
1025 ControlMessage::UnsubscribeAnnounces(m) => {
1026 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(8))?;
1027 m.track_namespace_prefix.encode(buf);
1028 }
1029 ControlMessage::TrackStatusRequest(m) => {
1030 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
1031 m.track_namespace.encode(buf);
1032 VarInt::from_usize(m.track_name.len()).encode(buf);
1033 buf.put_slice(&m.track_name);
1034 }
1035 ControlMessage::TrackStatus(m) => {
1036 m.track_namespace.validate(TrackNamespaceRules::for_draft(8))?;
1037 m.track_namespace.encode(buf);
1038 VarInt::from_usize(m.track_name.len()).encode(buf);
1039 buf.put_slice(&m.track_name);
1040 check_track_status(m.status_code, m.last_group_id, m.last_object_id)?;
1041 m.status_code.encode(buf);
1042 m.last_group_id.encode(buf);
1043 m.last_object_id.encode(buf);
1044 }
1045 ControlMessage::Fetch(m) => {
1046 m.subscribe_id.encode(buf);
1047 buf.put_u8(m.subscriber_priority);
1048 buf.put_u8(m.group_order as u8);
1049 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1050 match m.fetch_type {
1051 FetchType::Standalone => {
1052 if let Some(ns) = &m.track_namespace {
1053 ns.encode(buf);
1054 }
1055 if let Some(name) = &m.track_name {
1056 VarInt::from_usize(name.len()).encode(buf);
1057 buf.put_slice(name);
1058 }
1059 if let Some(sg) = &m.start_group {
1060 sg.encode(buf);
1061 }
1062 if let Some(so) = &m.start_object {
1063 so.encode(buf);
1064 }
1065 if let Some(eg) = &m.end_group {
1066 eg.encode(buf);
1067 }
1068 if let Some(eo) = &m.end_object {
1069 eo.encode(buf);
1070 }
1071 }
1072 FetchType::Joining => {
1073 if let Some(jsi) = &m.joining_subscribe_id {
1074 jsi.encode(buf);
1075 }
1076 if let Some(pgo) = &m.preceding_group_offset {
1077 pgo.encode(buf);
1078 }
1079 }
1080 }
1081 encode_parameters(&m.parameters, buf)?;
1082 }
1083 ControlMessage::FetchOk(m) => {
1084 m.subscribe_id.encode(buf);
1085 buf.put_u8(m.group_order as u8);
1086 buf.put_u8(m.end_of_track);
1087 m.largest_group_id.encode(buf);
1088 m.largest_object_id.encode(buf);
1089 encode_parameters(&m.parameters, buf)?;
1090 }
1091 ControlMessage::FetchError(m) => {
1092 m.subscribe_id.encode(buf);
1093 m.error_code.encode(buf);
1094 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1095 buf.put_slice(&m.reason_phrase);
1096 }
1097 ControlMessage::FetchCancel(m) => {
1098 m.subscribe_id.encode(buf);
1099 }
1100 }
1101 Ok(())
1102 }
1103
1104 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1105 match msg_type {
1106 MessageType::ClientSetup => {
1107 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1108 if num_versions == 0 {
1118 return Err(CodecError::InvalidField);
1119 }
1120 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1121 for _ in 0..num_versions {
1122 supported_versions.push(VarInt::decode(buf)?);
1123 }
1124 let parameters = decode_setup_parameters(buf)?;
1125 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1126 }
1127 MessageType::ServerSetup => {
1128 let selected_version = VarInt::decode(buf)?;
1129 let parameters = decode_setup_parameters(buf)?;
1130 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1131 }
1132 MessageType::GoAway => {
1133 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1134 let uri = read_bytes(buf, uri_len)?;
1135 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1136 }
1137 MessageType::MaxSubscribeId => {
1138 let subscribe_id = VarInt::decode(buf)?;
1139 Ok(ControlMessage::MaxSubscribeId(MaxSubscribeId { subscribe_id }))
1140 }
1141 MessageType::SubscribesBlocked => {
1142 let maximum_subscribe_id = VarInt::decode(buf)?;
1143 Ok(ControlMessage::SubscribesBlocked(SubscribesBlocked { maximum_subscribe_id }))
1144 }
1145 MessageType::Subscribe => {
1146 let subscribe_id = VarInt::decode(buf)?;
1147 let track_alias = VarInt::decode(buf)?;
1148 let track_namespace = TrackNamespace::decode(buf)?;
1149 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1150 let track_name = read_bytes(buf, track_name_len)?;
1151 if buf.remaining() < 2 {
1152 return Err(CodecError::UnexpectedEnd);
1153 }
1154 let subscriber_priority = buf.get_u8();
1155 let group_order =
1156 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1157 let filter_val = VarInt::decode(buf)?.into_inner();
1158 let filter_type = FilterType::from_u64(filter_val)
1159 .ok_or(CodecError::InvalidFilterType(filter_val))?;
1160 let start_location = match filter_type {
1161 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1162 Some(Location::decode(buf)?)
1163 }
1164 _ => None,
1165 };
1166 let end_group = match filter_type {
1167 FilterType::AbsoluteRange => Some(VarInt::decode(buf)?),
1168 _ => None,
1169 };
1170 let parameters = decode_parameters(buf)?;
1171 Ok(ControlMessage::Subscribe(Subscribe {
1172 subscribe_id,
1173 track_alias,
1174 track_namespace,
1175 track_name,
1176 subscriber_priority,
1177 group_order,
1178 filter_type,
1179 start_location,
1180 end_group,
1181 parameters,
1182 }))
1183 }
1184 MessageType::SubscribeOk => {
1185 let subscribe_id = VarInt::decode(buf)?;
1186 let expires = VarInt::decode(buf)?;
1187 if buf.remaining() < 2 {
1188 return Err(CodecError::UnexpectedEnd);
1189 }
1190 let group_order = read_group_order_response(buf)?;
1191 let content_exists_val = buf.get_u8();
1192 let content_exists = match content_exists_val {
1193 0 => ContentExists::NoLargestLocation,
1194 1 => ContentExists::HasLargestLocation,
1195 other => return Err(CodecError::InvalidContentExists(other)),
1196 };
1197 let (largest_group_id, largest_object_id) =
1198 if content_exists == ContentExists::HasLargestLocation {
1199 let gid = VarInt::decode(buf)?;
1200 let oid = VarInt::decode(buf)?;
1201 (Some(gid), Some(oid))
1202 } else {
1203 (None, None)
1204 };
1205 let parameters = decode_parameters(buf)?;
1206 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1207 subscribe_id,
1208 expires,
1209 group_order,
1210 content_exists,
1211 largest_group_id,
1212 largest_object_id,
1213 parameters,
1214 }))
1215 }
1216 MessageType::SubscribeError => {
1217 let subscribe_id = VarInt::decode(buf)?;
1218 let error_code = VarInt::decode(buf)?;
1219 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1220 let reason_phrase = read_bytes(buf, reason_len)?;
1221 let track_alias = VarInt::decode(buf)?;
1222 Ok(ControlMessage::SubscribeError(SubscribeError {
1223 subscribe_id,
1224 error_code,
1225 reason_phrase,
1226 track_alias,
1227 }))
1228 }
1229 MessageType::SubscribeUpdate => {
1230 let subscribe_id = VarInt::decode(buf)?;
1231 let start_group = VarInt::decode(buf)?;
1232 let start_object = VarInt::decode(buf)?;
1233 let end_group = VarInt::decode(buf)?;
1234 if buf.remaining() < 1 {
1235 return Err(CodecError::UnexpectedEnd);
1236 }
1237 let subscriber_priority = buf.get_u8();
1238 let parameters = decode_parameters(buf)?;
1239 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1240 subscribe_id,
1241 start_group,
1242 start_object,
1243 end_group,
1244 subscriber_priority,
1245 parameters,
1246 }))
1247 }
1248 MessageType::SubscribeDone => {
1249 let subscribe_id = VarInt::decode(buf)?;
1250 let status_code = VarInt::decode(buf)?;
1251 let stream_count = VarInt::decode(buf)?;
1252 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1253 let reason_phrase = read_bytes(buf, reason_len)?;
1254 Ok(ControlMessage::SubscribeDone(SubscribeDone {
1255 subscribe_id,
1256 status_code,
1257 stream_count,
1258 reason_phrase,
1259 }))
1260 }
1261 MessageType::Unsubscribe => {
1262 let subscribe_id = VarInt::decode(buf)?;
1263 Ok(ControlMessage::Unsubscribe(Unsubscribe { subscribe_id }))
1264 }
1265 MessageType::Announce => {
1266 let track_namespace = TrackNamespace::decode(buf)?;
1267 let parameters = decode_parameters(buf)?;
1268 Ok(ControlMessage::Announce(Announce { track_namespace, parameters }))
1269 }
1270 MessageType::AnnounceOk => {
1271 let track_namespace = TrackNamespace::decode(buf)?;
1272 Ok(ControlMessage::AnnounceOk(AnnounceOk { track_namespace }))
1273 }
1274 MessageType::AnnounceError => {
1275 let track_namespace = TrackNamespace::decode(buf)?;
1276 let error_code = VarInt::decode(buf)?;
1277 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1278 let reason_phrase = read_bytes(buf, reason_len)?;
1279 Ok(ControlMessage::AnnounceError(AnnounceError {
1280 track_namespace,
1281 error_code,
1282 reason_phrase,
1283 }))
1284 }
1285 MessageType::AnnounceCancel => {
1286 let track_namespace = TrackNamespace::decode(buf)?;
1287 let error_code = VarInt::decode(buf)?;
1288 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1289 let reason_phrase = read_bytes(buf, reason_len)?;
1290 Ok(ControlMessage::AnnounceCancel(AnnounceCancel {
1291 track_namespace,
1292 error_code,
1293 reason_phrase,
1294 }))
1295 }
1296 MessageType::Unannounce => {
1297 let track_namespace = TrackNamespace::decode(buf)?;
1298 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1299 }
1300 MessageType::SubscribeAnnounces => {
1301 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1302 let parameters = decode_parameters(buf)?;
1303 Ok(ControlMessage::SubscribeAnnounces(SubscribeAnnounces {
1304 track_namespace_prefix,
1305 parameters,
1306 }))
1307 }
1308 MessageType::SubscribeAnnouncesOk => {
1309 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1310 Ok(ControlMessage::SubscribeAnnouncesOk(SubscribeAnnouncesOk {
1311 track_namespace_prefix,
1312 }))
1313 }
1314 MessageType::SubscribeAnnouncesError => {
1315 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1316 let error_code = VarInt::decode(buf)?;
1317 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1318 let reason_phrase = read_bytes(buf, reason_len)?;
1319 Ok(ControlMessage::SubscribeAnnouncesError(SubscribeAnnouncesError {
1320 track_namespace_prefix,
1321 error_code,
1322 reason_phrase,
1323 }))
1324 }
1325 MessageType::UnsubscribeAnnounces => {
1326 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1327 Ok(ControlMessage::UnsubscribeAnnounces(UnsubscribeAnnounces {
1328 track_namespace_prefix,
1329 }))
1330 }
1331 MessageType::TrackStatusRequest => {
1332 let track_namespace = TrackNamespace::decode(buf)?;
1333 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1334 let track_name = read_bytes(buf, track_name_len)?;
1335 Ok(ControlMessage::TrackStatusRequest(TrackStatusRequest {
1336 track_namespace,
1337 track_name,
1338 }))
1339 }
1340 MessageType::TrackStatus => {
1341 let track_namespace = TrackNamespace::decode(buf)?;
1342 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1343 let track_name = read_bytes(buf, track_name_len)?;
1344 let status_code = VarInt::decode(buf)?;
1345 let last_group_id = VarInt::decode(buf)?;
1346 let last_object_id = VarInt::decode(buf)?;
1347 check_track_status(status_code, last_group_id, last_object_id)?;
1348 Ok(ControlMessage::TrackStatus(TrackStatus {
1349 track_namespace,
1350 track_name,
1351 status_code,
1352 last_group_id,
1353 last_object_id,
1354 }))
1355 }
1356 MessageType::Fetch => {
1357 let subscribe_id = VarInt::decode(buf)?;
1358 if buf.remaining() < 2 {
1359 return Err(CodecError::UnexpectedEnd);
1360 }
1361 let subscriber_priority = buf.get_u8();
1362 let group_order =
1363 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1364 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1365 let fetch_type = FetchType::from_u64(fetch_type_val)
1366 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1367 let (
1368 track_namespace,
1369 track_name,
1370 start_group,
1371 start_object,
1372 end_group,
1373 end_object,
1374 joining_subscribe_id,
1375 preceding_group_offset,
1376 ) = match fetch_type {
1377 FetchType::Standalone => {
1378 let ns = TrackNamespace::decode(buf)?;
1379 let name_len = VarInt::decode(buf)?.into_inner() as usize;
1380 let name = read_bytes(buf, name_len)?;
1381 let sg = VarInt::decode(buf)?;
1382 let so = VarInt::decode(buf)?;
1383 let eg = VarInt::decode(buf)?;
1384 let eo = VarInt::decode(buf)?;
1385 (Some(ns), Some(name), Some(sg), Some(so), Some(eg), Some(eo), None, None)
1386 }
1387 FetchType::Joining => {
1388 let jsi = VarInt::decode(buf)?;
1389 let pgo = VarInt::decode(buf)?;
1390 (None, None, None, None, None, None, Some(jsi), Some(pgo))
1391 }
1392 };
1393 let parameters = decode_parameters(buf)?;
1394 Ok(ControlMessage::Fetch(Fetch {
1395 subscribe_id,
1396 subscriber_priority,
1397 group_order,
1398 fetch_type,
1399 track_namespace,
1400 track_name,
1401 start_group,
1402 start_object,
1403 end_group,
1404 end_object,
1405 joining_subscribe_id,
1406 preceding_group_offset,
1407 parameters,
1408 }))
1409 }
1410 MessageType::FetchOk => {
1411 let subscribe_id = VarInt::decode(buf)?;
1412 if buf.remaining() < 2 {
1413 return Err(CodecError::UnexpectedEnd);
1414 }
1415 let group_order = read_group_order_response(buf)?;
1416 let end_of_track = buf.get_u8();
1417 let largest_group_id = VarInt::decode(buf)?;
1418 let largest_object_id = VarInt::decode(buf)?;
1419 let parameters = decode_parameters(buf)?;
1420 Ok(ControlMessage::FetchOk(FetchOk {
1421 subscribe_id,
1422 group_order,
1423 end_of_track,
1424 largest_group_id,
1425 largest_object_id,
1426 parameters,
1427 }))
1428 }
1429 MessageType::FetchError => {
1430 let subscribe_id = VarInt::decode(buf)?;
1431 let error_code = VarInt::decode(buf)?;
1432 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1433 let reason_phrase = read_bytes(buf, reason_len)?;
1434 Ok(ControlMessage::FetchError(FetchError {
1435 subscribe_id,
1436 error_code,
1437 reason_phrase,
1438 }))
1439 }
1440 MessageType::FetchCancel => {
1441 let subscribe_id = VarInt::decode(buf)?;
1442 Ok(ControlMessage::FetchCancel(FetchCancel { subscribe_id }))
1443 }
1444 }
1445 }
1446}