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 pub fn name(&self) -> &'static str {
114 match self {
115 MessageType::SubscribeUpdate => "subscribe_update",
116 MessageType::Subscribe => "subscribe",
117 MessageType::SubscribeOk => "subscribe_ok",
118 MessageType::SubscribeError => "subscribe_error",
119 MessageType::Announce => "announce",
120 MessageType::AnnounceOk => "announce_ok",
121 MessageType::AnnounceError => "announce_error",
122 MessageType::Unannounce => "unannounce",
123 MessageType::Unsubscribe => "unsubscribe",
124 MessageType::SubscribeDone => "subscribe_done",
125 MessageType::AnnounceCancel => "announce_cancel",
126 MessageType::TrackStatusRequest => "track_status_request",
127 MessageType::TrackStatus => "track_status",
128 MessageType::GoAway => "goaway",
129 MessageType::SubscribeAnnounces => "subscribe_announces",
130 MessageType::SubscribeAnnouncesOk => "subscribe_announces_ok",
131 MessageType::SubscribeAnnouncesError => "subscribe_announces_error",
132 MessageType::UnsubscribeAnnounces => "unsubscribe_announces",
133 MessageType::MaxSubscribeId => "max_subscribe_id",
134 MessageType::Fetch => "fetch",
135 MessageType::FetchCancel => "fetch_cancel",
136 MessageType::FetchOk => "fetch_ok",
137 MessageType::FetchError => "fetch_error",
138 MessageType::SubscribesBlocked => "subscribes_blocked",
139 MessageType::ClientSetup => "client_setup",
140 MessageType::ServerSetup => "server_setup",
141 }
142 }
143}
144
145#[derive(Debug, Clone, PartialEq, Eq)]
151pub struct ClientSetup {
152 pub supported_versions: Vec<VarInt>,
154 pub parameters: Vec<KeyValuePair>,
156}
157
158#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct ServerSetup {
161 pub selected_version: VarInt,
163 pub parameters: Vec<KeyValuePair>,
165}
166
167#[derive(Debug, Clone, PartialEq, Eq)]
169pub struct GoAway {
170 pub new_session_uri: Vec<u8>,
172}
173
174#[derive(Debug, Clone, PartialEq, Eq)]
176pub struct MaxSubscribeId {
177 pub subscribe_id: VarInt,
179}
180
181#[derive(Debug, Clone, PartialEq, Eq)]
183pub struct SubscribesBlocked {
184 pub maximum_subscribe_id: VarInt,
186}
187
188#[derive(Debug, Clone, PartialEq, Eq)]
196pub struct Subscribe {
197 pub subscribe_id: VarInt,
199 pub track_alias: VarInt,
201 pub track_namespace: TrackNamespace,
203 pub track_name: Vec<u8>,
205 pub subscriber_priority: u8,
207 pub group_order: GroupOrder,
209 pub filter_type: FilterType,
211 pub start_location: Option<Location>,
213 pub end_group: Option<VarInt>,
215 pub parameters: Vec<KeyValuePair>,
217}
218
219#[derive(Debug, Clone, PartialEq, Eq)]
221pub struct SubscribeOk {
222 pub subscribe_id: VarInt,
224 pub expires: VarInt,
226 pub group_order: GroupOrder,
228 pub content_exists: ContentExists,
230 pub largest_group_id: Option<VarInt>,
232 pub largest_object_id: Option<VarInt>,
234 pub parameters: Vec<KeyValuePair>,
236}
237
238#[derive(Debug, Clone, PartialEq, Eq)]
240pub struct SubscribeError {
241 pub subscribe_id: VarInt,
243 pub error_code: VarInt,
245 pub reason_phrase: Vec<u8>,
247 pub track_alias: VarInt,
249}
250
251#[derive(Debug, Clone, PartialEq, Eq)]
253pub struct SubscribeUpdate {
254 pub subscribe_id: VarInt,
256 pub start_group: VarInt,
258 pub start_object: VarInt,
260 pub end_group: VarInt,
262 pub subscriber_priority: u8,
264 pub parameters: Vec<KeyValuePair>,
266}
267
268#[derive(Debug, Clone, PartialEq, Eq)]
270pub struct SubscribeDone {
271 pub subscribe_id: VarInt,
273 pub status_code: VarInt,
275 pub stream_count: VarInt,
277 pub reason_phrase: Vec<u8>,
279}
280
281#[derive(Debug, Clone, PartialEq, Eq)]
283pub struct Unsubscribe {
284 pub subscribe_id: VarInt,
286}
287
288#[derive(Debug, Clone, PartialEq, Eq)]
294pub struct Announce {
295 pub track_namespace: TrackNamespace,
297 pub parameters: Vec<KeyValuePair>,
299}
300
301#[derive(Debug, Clone, PartialEq, Eq)]
303pub struct AnnounceOk {
304 pub track_namespace: TrackNamespace,
306}
307
308#[derive(Debug, Clone, PartialEq, Eq)]
310pub struct AnnounceError {
311 pub track_namespace: TrackNamespace,
313 pub error_code: VarInt,
315 pub reason_phrase: Vec<u8>,
317}
318
319#[derive(Debug, Clone, PartialEq, Eq)]
321pub struct AnnounceCancel {
322 pub track_namespace: TrackNamespace,
324 pub error_code: VarInt,
326 pub reason_phrase: Vec<u8>,
328}
329
330#[derive(Debug, Clone, PartialEq, Eq)]
332pub struct Unannounce {
333 pub track_namespace: TrackNamespace,
335}
336
337#[derive(Debug, Clone, PartialEq, Eq)]
343pub struct SubscribeAnnounces {
344 pub track_namespace_prefix: TrackNamespace,
346 pub parameters: Vec<KeyValuePair>,
348}
349
350#[derive(Debug, Clone, PartialEq, Eq)]
352pub struct SubscribeAnnouncesOk {
353 pub track_namespace_prefix: TrackNamespace,
355}
356
357#[derive(Debug, Clone, PartialEq, Eq)]
359pub struct SubscribeAnnouncesError {
360 pub track_namespace_prefix: TrackNamespace,
362 pub error_code: VarInt,
364 pub reason_phrase: Vec<u8>,
366}
367
368#[derive(Debug, Clone, PartialEq, Eq)]
370pub struct UnsubscribeAnnounces {
371 pub track_namespace_prefix: TrackNamespace,
373}
374
375#[derive(Debug, Clone, PartialEq, Eq)]
381pub struct TrackStatusRequest {
382 pub track_namespace: TrackNamespace,
384 pub track_name: Vec<u8>,
386}
387
388#[derive(Debug, Clone, PartialEq, Eq)]
390pub struct TrackStatus {
391 pub track_namespace: TrackNamespace,
393 pub track_name: Vec<u8>,
395 pub status_code: VarInt,
397 pub last_group_id: VarInt,
399 pub last_object_id: VarInt,
401}
402
403#[derive(Debug, Clone, Copy, PartialEq, Eq)]
409#[repr(u64)]
410pub enum FetchType {
411 Standalone = 1,
413 Joining = 2,
415}
416
417impl FetchType {
418 pub fn from_u64(v: u64) -> Option<Self> {
420 match v {
421 1 => Some(FetchType::Standalone),
422 2 => Some(FetchType::Joining),
423 _ => None,
424 }
425 }
426}
427
428#[derive(Debug, Clone, PartialEq, Eq)]
430pub struct Fetch {
431 pub subscribe_id: VarInt,
433 pub subscriber_priority: u8,
435 pub group_order: GroupOrder,
437 pub fetch_type: FetchType,
439 pub track_namespace: Option<TrackNamespace>,
441 pub track_name: Option<Vec<u8>>,
443 pub start_group: Option<VarInt>,
445 pub start_object: Option<VarInt>,
447 pub end_group: Option<VarInt>,
449 pub end_object: Option<VarInt>,
451 pub joining_subscribe_id: Option<VarInt>,
453 pub preceding_group_offset: Option<VarInt>,
455 pub parameters: Vec<KeyValuePair>,
457}
458
459#[derive(Debug, Clone, PartialEq, Eq)]
461pub struct FetchOk {
462 pub subscribe_id: VarInt,
464 pub group_order: GroupOrder,
466 pub end_of_track: u8,
468 pub largest_group_id: VarInt,
470 pub largest_object_id: VarInt,
472 pub parameters: Vec<KeyValuePair>,
474}
475
476#[derive(Debug, Clone, PartialEq, Eq)]
478pub struct FetchError {
479 pub subscribe_id: VarInt,
481 pub error_code: VarInt,
483 pub reason_phrase: Vec<u8>,
485}
486
487#[derive(Debug, Clone, PartialEq, Eq)]
489pub struct FetchCancel {
490 pub subscribe_id: VarInt,
492}
493
494fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
509 if !buf.has_remaining() {
510 return Err(CodecError::UnexpectedEnd);
511 }
512 match GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)? {
513 GroupOrder::Publisher => Err(CodecError::InvalidField),
514 order => Ok(order),
515 }
516}
517
518fn check_track_status(
529 status_code: VarInt,
530 last_group_id: VarInt,
531 last_object_id: VarInt,
532) -> Result<(), CodecError> {
533 let code = crate::draft09::error_codes::TrackStatusCode::from_u64(status_code.into_inner())
534 .ok_or(CodecError::InvalidField)?;
535 if code.requires_zero_location()
536 && (last_group_id.into_inner() != 0 || last_object_id.into_inner() != 0)
537 {
538 return Err(CodecError::InvalidField);
539 }
540 Ok(())
541}
542
543fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
554 match message {
555 ControlMessage::Subscribe(m) => {
556 if m.filter_type == FilterType::NextGroupStart {
558 return Err(CodecError::InvalidField);
559 }
560 let wants_start =
561 matches!(m.filter_type, FilterType::AbsoluteStart | FilterType::AbsoluteRange);
562 if wants_start != m.start_location.is_some() {
563 return Err(CodecError::InvalidField);
564 }
565 if (m.filter_type == FilterType::AbsoluteRange) != m.end_group.is_some() {
566 return Err(CodecError::InvalidField);
567 }
568 Ok(())
569 }
570 ControlMessage::SubscribeOk(m) => {
571 let has = m.content_exists == ContentExists::HasLargestLocation;
572 if has != m.largest_group_id.is_some() || has != m.largest_object_id.is_some() {
573 return Err(CodecError::InvalidField);
574 }
575 Ok(())
576 }
577 ControlMessage::Fetch(m) => {
578 let standalone = m.fetch_type == FetchType::Standalone;
579 let standalone_fields = [
580 m.track_namespace.is_some(),
581 m.track_name.is_some(),
582 m.start_group.is_some(),
583 m.start_object.is_some(),
584 m.end_group.is_some(),
585 m.end_object.is_some(),
586 ];
587 if standalone_fields.iter().any(|present| *present != standalone) {
588 return Err(CodecError::InvalidField);
589 }
590 let joining_fields =
591 [m.joining_subscribe_id.is_some(), m.preceding_group_offset.is_some()];
592 if joining_fields.contains(&standalone) {
593 return Err(CodecError::InvalidField);
594 }
595 Ok(())
596 }
597 _ => Ok(()),
598 }
599}
600
601fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
606 let order = match message {
607 ControlMessage::SubscribeOk(m) => m.group_order,
608 ControlMessage::FetchOk(m) => m.group_order,
609 _ => return Ok(()),
610 };
611 if order == GroupOrder::Publisher {
612 return Err(CodecError::InvalidField);
613 }
614 Ok(())
615}
616
617#[derive(Debug, Clone, PartialEq, Eq)]
619pub enum ControlMessage {
620 ClientSetup(ClientSetup),
622 ServerSetup(ServerSetup),
624 GoAway(GoAway),
626 MaxSubscribeId(MaxSubscribeId),
628 SubscribesBlocked(SubscribesBlocked),
630 Subscribe(Subscribe),
632 SubscribeOk(SubscribeOk),
634 SubscribeError(SubscribeError),
636 SubscribeUpdate(SubscribeUpdate),
638 SubscribeDone(SubscribeDone),
640 Unsubscribe(Unsubscribe),
642 Announce(Announce),
644 AnnounceOk(AnnounceOk),
646 AnnounceError(AnnounceError),
648 AnnounceCancel(AnnounceCancel),
650 Unannounce(Unannounce),
652 SubscribeAnnounces(SubscribeAnnounces),
654 SubscribeAnnouncesOk(SubscribeAnnouncesOk),
656 SubscribeAnnouncesError(SubscribeAnnouncesError),
658 UnsubscribeAnnounces(UnsubscribeAnnounces),
660 TrackStatusRequest(TrackStatusRequest),
662 TrackStatus(TrackStatus),
664 Fetch(Fetch),
666 FetchOk(FetchOk),
668 FetchError(FetchError),
670 FetchCancel(FetchCancel),
672}
673
674fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
688 match message {
689 ControlMessage::Subscribe(m) => match (&m.start_location, &m.end_group) {
690 (Some(start), Some(end_group)) => {
691 check_group_range(start.group.into_inner(), end_group.into_inner())
692 }
693 _ => Ok(()),
694 },
695 ControlMessage::SubscribeUpdate(m) => {
696 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
697 }
698 ControlMessage::Fetch(m) => {
699 match (&m.start_group, &m.start_object, &m.end_group, &m.end_object) {
700 (Some(start_group), Some(start_object), Some(end_group), Some(end_object)) => {
701 check_location_range(
702 start_group.into_inner(),
703 start_object.into_inner(),
704 end_group.into_inner(),
705 end_object.into_inner(),
706 )
707 }
708 _ => Ok(()),
709 }
710 }
711 _ => Ok(()),
712 }
713}
714
715fn check_no_duplicate_parameters(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
726 for (i, parameter) in parameters.iter().enumerate() {
727 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
728 return Err(CodecError::DuplicateParameter(parameter.key.into_inner()));
729 }
730 }
731 Ok(())
732}
733
734const SETUP_VARINT_PARAMETERS: &[u64] = &[0x02];
741
742const VERSION_VARINT_PARAMETERS: &[u64] = &[0x03, 0x04];
755
756fn check_parameter_lengths(
774 parameters: &[KeyValuePair],
775 varint_typed: &[u64],
776) -> Result<(), CodecError> {
777 for parameter in parameters {
778 let key = parameter.key.into_inner();
779 if !varint_typed.contains(&key) {
780 continue;
781 }
782 if let crate::kvp::KvpValue::Bytes(bytes) = ¶meter.value {
783 let mut cursor = &bytes[..];
784 let one_varint = VarInt::decode(&mut cursor).is_ok() && !cursor.has_remaining();
785 if !one_varint {
786 return Err(CodecError::ParameterLengthMismatch(key));
787 }
788 }
789 }
790 Ok(())
791}
792
793fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
796 let parameters = KeyValuePair::decode_list_d07(buf)?;
797 check_no_duplicate_parameters(¶meters)?;
798 check_parameter_lengths(¶meters, VERSION_VARINT_PARAMETERS)?;
799 Ok(parameters)
800}
801
802fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
805 check_no_duplicate_parameters(parameters)?;
806 check_parameter_lengths(parameters, VERSION_VARINT_PARAMETERS)?;
807 KeyValuePair::encode_list_d07(parameters, buf);
808 Ok(())
809}
810
811fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
817 let parameters = KeyValuePair::decode_list_d07(buf)?;
818 check_no_duplicate_parameters(¶meters)?;
819 check_parameter_lengths(¶meters, SETUP_VARINT_PARAMETERS)?;
820 Ok(parameters)
821}
822
823fn encode_setup_parameters(
825 parameters: &[KeyValuePair],
826 buf: &mut impl BufMut,
827) -> Result<(), CodecError> {
828 check_no_duplicate_parameters(parameters)?;
829 check_parameter_lengths(parameters, SETUP_VARINT_PARAMETERS)?;
830 KeyValuePair::encode_list_d07(parameters, buf);
831 Ok(())
832}
833
834impl ControlMessage {
835 pub fn message_type(&self) -> MessageType {
837 match self {
838 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
839 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
840 ControlMessage::GoAway(_) => MessageType::GoAway,
841 ControlMessage::MaxSubscribeId(_) => MessageType::MaxSubscribeId,
842 ControlMessage::SubscribesBlocked(_) => MessageType::SubscribesBlocked,
843 ControlMessage::Subscribe(_) => MessageType::Subscribe,
844 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
845 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
846 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
847 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
848 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
849 ControlMessage::Announce(_) => MessageType::Announce,
850 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
851 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
852 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
853 ControlMessage::Unannounce(_) => MessageType::Unannounce,
854 ControlMessage::SubscribeAnnounces(_) => MessageType::SubscribeAnnounces,
855 ControlMessage::SubscribeAnnouncesOk(_) => MessageType::SubscribeAnnouncesOk,
856 ControlMessage::SubscribeAnnouncesError(_) => MessageType::SubscribeAnnouncesError,
857 ControlMessage::UnsubscribeAnnounces(_) => MessageType::UnsubscribeAnnounces,
858 ControlMessage::TrackStatusRequest(_) => MessageType::TrackStatusRequest,
859 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
860 ControlMessage::Fetch(_) => MessageType::Fetch,
861 ControlMessage::FetchOk(_) => MessageType::FetchOk,
862 ControlMessage::FetchError(_) => MessageType::FetchError,
863 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
864 }
865 }
866
867 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
869 check_discriminators(self)?;
870 check_group_order(self)?;
871 check_ranges(self)?;
872 let mut payload = Vec::with_capacity(256);
873 self.encode_payload(&mut payload)?;
874
875 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
883 VarInt::from_usize(payload.len()).encode(buf);
884 buf.put_slice(&payload);
885 Ok(())
886 }
887
888 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
890 let type_id = VarInt::decode(buf)?.into_inner();
891 let msg_type =
892 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
893 let payload_len = VarInt::decode(buf)?.into_inner() as usize;
894 if buf.remaining() < payload_len {
895 return Err(CodecError::UnexpectedEnd);
896 }
897 let payload_bytes = buf.copy_to_bytes(payload_len);
898 let mut payload = &payload_bytes[..];
899 let msg = match Self::decode_payload(msg_type, &mut payload) {
900 Ok(msg) => msg,
901 Err(
907 CodecError::UnexpectedEnd
908 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
909 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
910 crate::varint::VarIntError::UnexpectedEnd,
911 ))
912 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
913 ) => {
914 return Err(CodecError::ControlMessageLengthMismatch {
915 declared: payload_len,
916 detail: "its fields ran past the end",
917 });
918 }
919 Err(e) => return Err(e),
920 };
921 check_ranges(&msg)?;
922 if payload.has_remaining() {
927 return Err(CodecError::ControlMessageLengthMismatch {
928 declared: payload_len,
929 detail: "its fields left bytes unread",
930 });
931 }
932 Ok(msg)
933 }
934
935 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
936 match self {
937 ControlMessage::ClientSetup(m) => {
938 VarInt::from_usize(m.supported_versions.len()).encode(buf);
939 for v in &m.supported_versions {
940 v.encode(buf);
941 }
942 encode_setup_parameters(&m.parameters, buf)?;
943 }
944 ControlMessage::ServerSetup(m) => {
945 m.selected_version.encode(buf);
946 encode_setup_parameters(&m.parameters, buf)?;
947 }
948 ControlMessage::GoAway(m) => {
949 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
950 buf.put_slice(&m.new_session_uri);
951 }
952 ControlMessage::MaxSubscribeId(m) => {
953 m.subscribe_id.encode(buf);
954 }
955 ControlMessage::SubscribesBlocked(m) => {
956 m.maximum_subscribe_id.encode(buf);
957 }
958 ControlMessage::Subscribe(m) => {
959 m.subscribe_id.encode(buf);
960 m.track_alias.encode(buf);
961 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
962 m.track_namespace.encode(buf);
963 VarInt::from_usize(m.track_name.len()).encode(buf);
964 buf.put_slice(&m.track_name);
965 buf.put_u8(m.subscriber_priority);
966 buf.put_u8(m.group_order as u8);
967 VarInt::from_usize(m.filter_type as usize).encode(buf);
968 if let Some(loc) = &m.start_location {
969 loc.encode(buf);
970 }
971 if let Some(eg) = &m.end_group {
972 eg.encode(buf);
973 }
974 encode_parameters(&m.parameters, buf)?;
975 }
976 ControlMessage::SubscribeOk(m) => {
977 m.subscribe_id.encode(buf);
978 m.expires.encode(buf);
979 buf.put_u8(m.group_order as u8);
980 buf.put_u8(m.content_exists as u8);
981 if let Some(gid) = &m.largest_group_id {
982 gid.encode(buf);
983 }
984 if let Some(oid) = &m.largest_object_id {
985 oid.encode(buf);
986 }
987 encode_parameters(&m.parameters, buf)?;
988 }
989 ControlMessage::SubscribeError(m) => {
990 m.subscribe_id.encode(buf);
991 m.error_code.encode(buf);
992 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
993 buf.put_slice(&m.reason_phrase);
994 m.track_alias.encode(buf);
995 }
996 ControlMessage::SubscribeUpdate(m) => {
997 m.subscribe_id.encode(buf);
998 m.start_group.encode(buf);
999 m.start_object.encode(buf);
1000 m.end_group.encode(buf);
1001 buf.put_u8(m.subscriber_priority);
1002 encode_parameters(&m.parameters, buf)?;
1003 }
1004 ControlMessage::SubscribeDone(m) => {
1005 m.subscribe_id.encode(buf);
1006 m.status_code.encode(buf);
1007 m.stream_count.encode(buf);
1008 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1009 buf.put_slice(&m.reason_phrase);
1010 }
1011 ControlMessage::Unsubscribe(m) => {
1012 m.subscribe_id.encode(buf);
1013 }
1014 ControlMessage::Announce(m) => {
1015 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
1016 m.track_namespace.encode(buf);
1017 encode_parameters(&m.parameters, buf)?;
1018 }
1019 ControlMessage::AnnounceOk(m) => {
1020 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
1021 m.track_namespace.encode(buf);
1022 }
1023 ControlMessage::AnnounceError(m) => {
1024 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
1025 m.track_namespace.encode(buf);
1026 m.error_code.encode(buf);
1027 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1028 buf.put_slice(&m.reason_phrase);
1029 }
1030 ControlMessage::AnnounceCancel(m) => {
1031 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
1032 m.track_namespace.encode(buf);
1033 m.error_code.encode(buf);
1034 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1035 buf.put_slice(&m.reason_phrase);
1036 }
1037 ControlMessage::Unannounce(m) => {
1038 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
1039 m.track_namespace.encode(buf);
1040 }
1041 ControlMessage::SubscribeAnnounces(m) => {
1042 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(9))?;
1043 m.track_namespace_prefix.encode(buf);
1044 encode_parameters(&m.parameters, buf)?;
1045 }
1046 ControlMessage::SubscribeAnnouncesOk(m) => {
1047 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(9))?;
1048 m.track_namespace_prefix.encode(buf);
1049 }
1050 ControlMessage::SubscribeAnnouncesError(m) => {
1051 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(9))?;
1052 m.track_namespace_prefix.encode(buf);
1053 m.error_code.encode(buf);
1054 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1055 buf.put_slice(&m.reason_phrase);
1056 }
1057 ControlMessage::UnsubscribeAnnounces(m) => {
1058 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(9))?;
1059 m.track_namespace_prefix.encode(buf);
1060 }
1061 ControlMessage::TrackStatusRequest(m) => {
1062 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
1063 m.track_namespace.encode(buf);
1064 VarInt::from_usize(m.track_name.len()).encode(buf);
1065 buf.put_slice(&m.track_name);
1066 }
1067 ControlMessage::TrackStatus(m) => {
1068 m.track_namespace.validate(TrackNamespaceRules::for_draft(9))?;
1069 m.track_namespace.encode(buf);
1070 VarInt::from_usize(m.track_name.len()).encode(buf);
1071 buf.put_slice(&m.track_name);
1072 check_track_status(m.status_code, m.last_group_id, m.last_object_id)?;
1073 m.status_code.encode(buf);
1074 m.last_group_id.encode(buf);
1075 m.last_object_id.encode(buf);
1076 }
1077 ControlMessage::Fetch(m) => {
1078 m.subscribe_id.encode(buf);
1079 buf.put_u8(m.subscriber_priority);
1080 buf.put_u8(m.group_order as u8);
1081 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1082 match m.fetch_type {
1083 FetchType::Standalone => {
1084 if let Some(ns) = &m.track_namespace {
1085 ns.encode(buf);
1086 }
1087 if let Some(name) = &m.track_name {
1088 VarInt::from_usize(name.len()).encode(buf);
1089 buf.put_slice(name);
1090 }
1091 if let Some(sg) = &m.start_group {
1092 sg.encode(buf);
1093 }
1094 if let Some(so) = &m.start_object {
1095 so.encode(buf);
1096 }
1097 if let Some(eg) = &m.end_group {
1098 eg.encode(buf);
1099 }
1100 if let Some(eo) = &m.end_object {
1101 eo.encode(buf);
1102 }
1103 }
1104 FetchType::Joining => {
1105 if let Some(jsi) = &m.joining_subscribe_id {
1106 jsi.encode(buf);
1107 }
1108 if let Some(pgo) = &m.preceding_group_offset {
1109 pgo.encode(buf);
1110 }
1111 }
1112 }
1113 encode_parameters(&m.parameters, buf)?;
1114 }
1115 ControlMessage::FetchOk(m) => {
1116 m.subscribe_id.encode(buf);
1117 buf.put_u8(m.group_order as u8);
1118 buf.put_u8(m.end_of_track);
1119 m.largest_group_id.encode(buf);
1120 m.largest_object_id.encode(buf);
1121 encode_parameters(&m.parameters, buf)?;
1122 }
1123 ControlMessage::FetchError(m) => {
1124 m.subscribe_id.encode(buf);
1125 m.error_code.encode(buf);
1126 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1127 buf.put_slice(&m.reason_phrase);
1128 }
1129 ControlMessage::FetchCancel(m) => {
1130 m.subscribe_id.encode(buf);
1131 }
1132 }
1133 Ok(())
1134 }
1135
1136 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1137 match msg_type {
1138 MessageType::ClientSetup => {
1139 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1140 if num_versions == 0 {
1150 return Err(CodecError::InvalidField);
1151 }
1152 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1153 for _ in 0..num_versions {
1154 supported_versions.push(VarInt::decode(buf)?);
1155 }
1156 let parameters = decode_setup_parameters(buf)?;
1157 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1158 }
1159 MessageType::ServerSetup => {
1160 let selected_version = VarInt::decode(buf)?;
1161 let parameters = decode_setup_parameters(buf)?;
1162 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1163 }
1164 MessageType::GoAway => {
1165 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1166 let uri = read_bytes(buf, uri_len)?;
1167 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1168 }
1169 MessageType::MaxSubscribeId => {
1170 let subscribe_id = VarInt::decode(buf)?;
1171 Ok(ControlMessage::MaxSubscribeId(MaxSubscribeId { subscribe_id }))
1172 }
1173 MessageType::SubscribesBlocked => {
1174 let maximum_subscribe_id = VarInt::decode(buf)?;
1175 Ok(ControlMessage::SubscribesBlocked(SubscribesBlocked { maximum_subscribe_id }))
1176 }
1177 MessageType::Subscribe => {
1178 let subscribe_id = VarInt::decode(buf)?;
1179 let track_alias = VarInt::decode(buf)?;
1180 let track_namespace = TrackNamespace::decode(buf)?;
1181 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1182 let track_name = read_bytes(buf, track_name_len)?;
1183 if buf.remaining() < 2 {
1184 return Err(CodecError::UnexpectedEnd);
1185 }
1186 let subscriber_priority = buf.get_u8();
1187 let group_order =
1188 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1189 let filter_val = VarInt::decode(buf)?.into_inner();
1190 if filter_val == 1 {
1192 return Err(CodecError::InvalidFilterType(filter_val));
1193 }
1194 let filter_type = FilterType::from_u64(filter_val)
1195 .ok_or(CodecError::InvalidFilterType(filter_val))?;
1196 let start_location = match filter_type {
1197 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1198 Some(Location::decode(buf)?)
1199 }
1200 _ => None,
1201 };
1202 let end_group = match filter_type {
1203 FilterType::AbsoluteRange => Some(VarInt::decode(buf)?),
1204 _ => None,
1205 };
1206 let parameters = decode_parameters(buf)?;
1207 Ok(ControlMessage::Subscribe(Subscribe {
1208 subscribe_id,
1209 track_alias,
1210 track_namespace,
1211 track_name,
1212 subscriber_priority,
1213 group_order,
1214 filter_type,
1215 start_location,
1216 end_group,
1217 parameters,
1218 }))
1219 }
1220 MessageType::SubscribeOk => {
1221 let subscribe_id = VarInt::decode(buf)?;
1222 let expires = VarInt::decode(buf)?;
1223 if buf.remaining() < 2 {
1224 return Err(CodecError::UnexpectedEnd);
1225 }
1226 let group_order = read_group_order_response(buf)?;
1227 let content_exists_val = buf.get_u8();
1228 let content_exists = match content_exists_val {
1229 0 => ContentExists::NoLargestLocation,
1230 1 => ContentExists::HasLargestLocation,
1231 other => return Err(CodecError::InvalidContentExists(other)),
1232 };
1233 let (largest_group_id, largest_object_id) =
1234 if content_exists == ContentExists::HasLargestLocation {
1235 let gid = VarInt::decode(buf)?;
1236 let oid = VarInt::decode(buf)?;
1237 (Some(gid), Some(oid))
1238 } else {
1239 (None, None)
1240 };
1241 let parameters = decode_parameters(buf)?;
1242 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1243 subscribe_id,
1244 expires,
1245 group_order,
1246 content_exists,
1247 largest_group_id,
1248 largest_object_id,
1249 parameters,
1250 }))
1251 }
1252 MessageType::SubscribeError => {
1253 let subscribe_id = VarInt::decode(buf)?;
1254 let error_code = VarInt::decode(buf)?;
1255 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1256 let reason_phrase = read_bytes(buf, reason_len)?;
1257 let track_alias = VarInt::decode(buf)?;
1258 Ok(ControlMessage::SubscribeError(SubscribeError {
1259 subscribe_id,
1260 error_code,
1261 reason_phrase,
1262 track_alias,
1263 }))
1264 }
1265 MessageType::SubscribeUpdate => {
1266 let subscribe_id = VarInt::decode(buf)?;
1267 let start_group = VarInt::decode(buf)?;
1268 let start_object = VarInt::decode(buf)?;
1269 let end_group = VarInt::decode(buf)?;
1270 if buf.remaining() < 1 {
1271 return Err(CodecError::UnexpectedEnd);
1272 }
1273 let subscriber_priority = buf.get_u8();
1274 let parameters = decode_parameters(buf)?;
1275 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1276 subscribe_id,
1277 start_group,
1278 start_object,
1279 end_group,
1280 subscriber_priority,
1281 parameters,
1282 }))
1283 }
1284 MessageType::SubscribeDone => {
1285 let subscribe_id = VarInt::decode(buf)?;
1286 let status_code = VarInt::decode(buf)?;
1287 let stream_count = 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::SubscribeDone(SubscribeDone {
1291 subscribe_id,
1292 status_code,
1293 stream_count,
1294 reason_phrase,
1295 }))
1296 }
1297 MessageType::Unsubscribe => {
1298 let subscribe_id = VarInt::decode(buf)?;
1299 Ok(ControlMessage::Unsubscribe(Unsubscribe { subscribe_id }))
1300 }
1301 MessageType::Announce => {
1302 let track_namespace = TrackNamespace::decode(buf)?;
1303 let parameters = decode_parameters(buf)?;
1304 Ok(ControlMessage::Announce(Announce { track_namespace, parameters }))
1305 }
1306 MessageType::AnnounceOk => {
1307 let track_namespace = TrackNamespace::decode(buf)?;
1308 Ok(ControlMessage::AnnounceOk(AnnounceOk { track_namespace }))
1309 }
1310 MessageType::AnnounceError => {
1311 let track_namespace = TrackNamespace::decode(buf)?;
1312 let error_code = VarInt::decode(buf)?;
1313 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1314 let reason_phrase = read_bytes(buf, reason_len)?;
1315 Ok(ControlMessage::AnnounceError(AnnounceError {
1316 track_namespace,
1317 error_code,
1318 reason_phrase,
1319 }))
1320 }
1321 MessageType::AnnounceCancel => {
1322 let track_namespace = TrackNamespace::decode(buf)?;
1323 let error_code = VarInt::decode(buf)?;
1324 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1325 let reason_phrase = read_bytes(buf, reason_len)?;
1326 Ok(ControlMessage::AnnounceCancel(AnnounceCancel {
1327 track_namespace,
1328 error_code,
1329 reason_phrase,
1330 }))
1331 }
1332 MessageType::Unannounce => {
1333 let track_namespace = TrackNamespace::decode(buf)?;
1334 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1335 }
1336 MessageType::SubscribeAnnounces => {
1337 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1338 let parameters = decode_parameters(buf)?;
1339 Ok(ControlMessage::SubscribeAnnounces(SubscribeAnnounces {
1340 track_namespace_prefix,
1341 parameters,
1342 }))
1343 }
1344 MessageType::SubscribeAnnouncesOk => {
1345 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1346 Ok(ControlMessage::SubscribeAnnouncesOk(SubscribeAnnouncesOk {
1347 track_namespace_prefix,
1348 }))
1349 }
1350 MessageType::SubscribeAnnouncesError => {
1351 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1352 let error_code = VarInt::decode(buf)?;
1353 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1354 let reason_phrase = read_bytes(buf, reason_len)?;
1355 Ok(ControlMessage::SubscribeAnnouncesError(SubscribeAnnouncesError {
1356 track_namespace_prefix,
1357 error_code,
1358 reason_phrase,
1359 }))
1360 }
1361 MessageType::UnsubscribeAnnounces => {
1362 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1363 Ok(ControlMessage::UnsubscribeAnnounces(UnsubscribeAnnounces {
1364 track_namespace_prefix,
1365 }))
1366 }
1367 MessageType::TrackStatusRequest => {
1368 let track_namespace = TrackNamespace::decode(buf)?;
1369 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1370 let track_name = read_bytes(buf, track_name_len)?;
1371 Ok(ControlMessage::TrackStatusRequest(TrackStatusRequest {
1372 track_namespace,
1373 track_name,
1374 }))
1375 }
1376 MessageType::TrackStatus => {
1377 let track_namespace = TrackNamespace::decode(buf)?;
1378 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1379 let track_name = read_bytes(buf, track_name_len)?;
1380 let status_code = VarInt::decode(buf)?;
1381 let last_group_id = VarInt::decode(buf)?;
1382 let last_object_id = VarInt::decode(buf)?;
1383 check_track_status(status_code, last_group_id, last_object_id)?;
1384 Ok(ControlMessage::TrackStatus(TrackStatus {
1385 track_namespace,
1386 track_name,
1387 status_code,
1388 last_group_id,
1389 last_object_id,
1390 }))
1391 }
1392 MessageType::Fetch => {
1393 let subscribe_id = VarInt::decode(buf)?;
1394 if buf.remaining() < 2 {
1395 return Err(CodecError::UnexpectedEnd);
1396 }
1397 let subscriber_priority = buf.get_u8();
1398 let group_order =
1399 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1400 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1401 let fetch_type = FetchType::from_u64(fetch_type_val)
1402 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1403 let (
1404 track_namespace,
1405 track_name,
1406 start_group,
1407 start_object,
1408 end_group,
1409 end_object,
1410 joining_subscribe_id,
1411 preceding_group_offset,
1412 ) = match fetch_type {
1413 FetchType::Standalone => {
1414 let ns = TrackNamespace::decode(buf)?;
1415 let name_len = VarInt::decode(buf)?.into_inner() as usize;
1416 let name = read_bytes(buf, name_len)?;
1417 let sg = VarInt::decode(buf)?;
1418 let so = VarInt::decode(buf)?;
1419 let eg = VarInt::decode(buf)?;
1420 let eo = VarInt::decode(buf)?;
1421 (Some(ns), Some(name), Some(sg), Some(so), Some(eg), Some(eo), None, None)
1422 }
1423 FetchType::Joining => {
1424 let jsi = VarInt::decode(buf)?;
1425 let pgo = VarInt::decode(buf)?;
1426 (None, None, None, None, None, None, Some(jsi), Some(pgo))
1427 }
1428 };
1429 let parameters = decode_parameters(buf)?;
1430 Ok(ControlMessage::Fetch(Fetch {
1431 subscribe_id,
1432 subscriber_priority,
1433 group_order,
1434 fetch_type,
1435 track_namespace,
1436 track_name,
1437 start_group,
1438 start_object,
1439 end_group,
1440 end_object,
1441 joining_subscribe_id,
1442 preceding_group_offset,
1443 parameters,
1444 }))
1445 }
1446 MessageType::FetchOk => {
1447 let subscribe_id = VarInt::decode(buf)?;
1448 if buf.remaining() < 2 {
1449 return Err(CodecError::UnexpectedEnd);
1450 }
1451 let group_order = read_group_order_response(buf)?;
1452 let end_of_track = buf.get_u8();
1453 let largest_group_id = VarInt::decode(buf)?;
1454 let largest_object_id = VarInt::decode(buf)?;
1455 let parameters = decode_parameters(buf)?;
1456 Ok(ControlMessage::FetchOk(FetchOk {
1457 subscribe_id,
1458 group_order,
1459 end_of_track,
1460 largest_group_id,
1461 largest_object_id,
1462 parameters,
1463 }))
1464 }
1465 MessageType::FetchError => {
1466 let subscribe_id = VarInt::decode(buf)?;
1467 let error_code = VarInt::decode(buf)?;
1468 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1469 let reason_phrase = read_bytes(buf, reason_len)?;
1470 Ok(ControlMessage::FetchError(FetchError {
1471 subscribe_id,
1472 error_code,
1473 reason_phrase,
1474 }))
1475 }
1476 MessageType::FetchCancel => {
1477 let subscribe_id = VarInt::decode(buf)?;
1478 Ok(ControlMessage::FetchCancel(FetchCancel { subscribe_id }))
1479 }
1480 }
1481 }
1482}