1use crate::error::CodecError;
11use crate::kvp::KeyValuePair;
12use crate::types::read_bytes;
13use crate::types::*;
14use crate::types::{check_group_range, check_location_range, check_open_ended_group_range};
15use crate::varint::VarInt;
16use bytes::{Buf, BufMut};
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20#[repr(u64)]
21pub enum MessageType {
22 SubscribeUpdate = 0x02,
24 Subscribe = 0x03,
26 SubscribeOk = 0x04,
28 SubscribeError = 0x05,
30 Announce = 0x06,
32 AnnounceOk = 0x07,
34 AnnounceError = 0x08,
36 Unannounce = 0x09,
38 Unsubscribe = 0x0A,
40 SubscribeDone = 0x0B,
42 AnnounceCancel = 0x0C,
44 TrackStatusRequest = 0x0D,
46 TrackStatus = 0x0E,
48 GoAway = 0x10,
50 SubscribeAnnounces = 0x11,
52 SubscribeAnnouncesOk = 0x12,
54 SubscribeAnnouncesError = 0x13,
56 UnsubscribeAnnounces = 0x14,
58 MaxSubscribeId = 0x15,
60 Fetch = 0x16,
62 FetchCancel = 0x17,
64 FetchOk = 0x18,
66 FetchError = 0x19,
68 SubscribesBlocked = 0x1A,
70 ClientSetup = 0x40,
72 ServerSetup = 0x41,
74}
75
76impl MessageType {
77 pub fn from_id(id: u64) -> Option<Self> {
79 match id {
80 0x02 => Some(MessageType::SubscribeUpdate),
81 0x03 => Some(MessageType::Subscribe),
82 0x04 => Some(MessageType::SubscribeOk),
83 0x05 => Some(MessageType::SubscribeError),
84 0x06 => Some(MessageType::Announce),
85 0x07 => Some(MessageType::AnnounceOk),
86 0x08 => Some(MessageType::AnnounceError),
87 0x09 => Some(MessageType::Unannounce),
88 0x0A => Some(MessageType::Unsubscribe),
89 0x0B => Some(MessageType::SubscribeDone),
90 0x0C => Some(MessageType::AnnounceCancel),
91 0x0D => Some(MessageType::TrackStatusRequest),
92 0x0E => Some(MessageType::TrackStatus),
93 0x10 => Some(MessageType::GoAway),
94 0x11 => Some(MessageType::SubscribeAnnounces),
95 0x12 => Some(MessageType::SubscribeAnnouncesOk),
96 0x13 => Some(MessageType::SubscribeAnnouncesError),
97 0x14 => Some(MessageType::UnsubscribeAnnounces),
98 0x15 => Some(MessageType::MaxSubscribeId),
99 0x16 => Some(MessageType::Fetch),
100 0x17 => Some(MessageType::FetchCancel),
101 0x18 => Some(MessageType::FetchOk),
102 0x19 => Some(MessageType::FetchError),
103 0x1A => Some(MessageType::SubscribesBlocked),
104 0x40 => Some(MessageType::ClientSetup),
105 0x41 => Some(MessageType::ServerSetup),
106 _ => None,
107 }
108 }
109
110 pub fn id(&self) -> u64 {
112 *self as u64
113 }
114}
115
116#[derive(Debug, Clone, PartialEq, Eq)]
122pub struct ClientSetup {
123 pub supported_versions: Vec<VarInt>,
125 pub parameters: Vec<KeyValuePair>,
127}
128
129#[derive(Debug, Clone, PartialEq, Eq)]
131pub struct ServerSetup {
132 pub selected_version: VarInt,
134 pub parameters: Vec<KeyValuePair>,
136}
137
138#[derive(Debug, Clone, PartialEq, Eq)]
140pub struct GoAway {
141 pub new_session_uri: Vec<u8>,
143}
144
145#[derive(Debug, Clone, PartialEq, Eq)]
147pub struct MaxSubscribeId {
148 pub subscribe_id: VarInt,
150}
151
152#[derive(Debug, Clone, PartialEq, Eq)]
154pub struct SubscribesBlocked {
155 pub maximum_subscribe_id: VarInt,
157}
158
159#[derive(Debug, Clone, PartialEq, Eq)]
168pub struct Subscribe {
169 pub subscribe_id: VarInt,
171 pub track_alias: VarInt,
173 pub track_namespace: TrackNamespace,
175 pub track_name: Vec<u8>,
177 pub subscriber_priority: u8,
179 pub group_order: GroupOrder,
181 pub filter_type: FilterType,
183 pub start_location: Option<Location>,
185 pub end_group: Option<VarInt>,
187 pub parameters: Vec<KeyValuePair>,
189}
190
191#[derive(Debug, Clone, PartialEq, Eq)]
193pub struct SubscribeOk {
194 pub subscribe_id: VarInt,
196 pub expires: VarInt,
198 pub group_order: GroupOrder,
200 pub content_exists: ContentExists,
202 pub largest_group_id: Option<VarInt>,
204 pub largest_object_id: Option<VarInt>,
206 pub parameters: Vec<KeyValuePair>,
208}
209
210#[derive(Debug, Clone, PartialEq, Eq)]
212pub struct SubscribeError {
213 pub subscribe_id: VarInt,
215 pub error_code: VarInt,
217 pub reason_phrase: Vec<u8>,
219 pub track_alias: VarInt,
221}
222
223#[derive(Debug, Clone, PartialEq, Eq)]
225pub struct SubscribeUpdate {
226 pub subscribe_id: VarInt,
228 pub start_group: VarInt,
230 pub start_object: VarInt,
232 pub end_group: VarInt,
234 pub subscriber_priority: u8,
236 pub parameters: Vec<KeyValuePair>,
238}
239
240#[derive(Debug, Clone, PartialEq, Eq)]
242pub struct SubscribeDone {
243 pub subscribe_id: VarInt,
245 pub status_code: VarInt,
247 pub stream_count: VarInt,
249 pub reason_phrase: Vec<u8>,
251}
252
253#[derive(Debug, Clone, PartialEq, Eq)]
255pub struct Unsubscribe {
256 pub subscribe_id: VarInt,
258}
259
260#[derive(Debug, Clone, PartialEq, Eq)]
266pub struct Announce {
267 pub track_namespace: TrackNamespace,
269 pub parameters: Vec<KeyValuePair>,
271}
272
273#[derive(Debug, Clone, PartialEq, Eq)]
275pub struct AnnounceOk {
276 pub track_namespace: TrackNamespace,
278}
279
280#[derive(Debug, Clone, PartialEq, Eq)]
282pub struct AnnounceError {
283 pub track_namespace: TrackNamespace,
285 pub error_code: VarInt,
287 pub reason_phrase: Vec<u8>,
289}
290
291#[derive(Debug, Clone, PartialEq, Eq)]
293pub struct AnnounceCancel {
294 pub track_namespace: TrackNamespace,
296 pub error_code: VarInt,
298 pub reason_phrase: Vec<u8>,
300}
301
302#[derive(Debug, Clone, PartialEq, Eq)]
304pub struct Unannounce {
305 pub track_namespace: TrackNamespace,
307}
308
309#[derive(Debug, Clone, PartialEq, Eq)]
315pub struct SubscribeAnnounces {
316 pub track_namespace_prefix: TrackNamespace,
318 pub parameters: Vec<KeyValuePair>,
320}
321
322#[derive(Debug, Clone, PartialEq, Eq)]
324pub struct SubscribeAnnouncesOk {
325 pub track_namespace_prefix: TrackNamespace,
327}
328
329#[derive(Debug, Clone, PartialEq, Eq)]
331pub struct SubscribeAnnouncesError {
332 pub track_namespace_prefix: TrackNamespace,
334 pub error_code: VarInt,
336 pub reason_phrase: Vec<u8>,
338}
339
340#[derive(Debug, Clone, PartialEq, Eq)]
342pub struct UnsubscribeAnnounces {
343 pub track_namespace_prefix: TrackNamespace,
345}
346
347#[derive(Debug, Clone, PartialEq, Eq)]
353pub struct TrackStatusRequest {
354 pub track_namespace: TrackNamespace,
356 pub track_name: Vec<u8>,
358}
359
360#[derive(Debug, Clone, PartialEq, Eq)]
362pub struct TrackStatus {
363 pub track_namespace: TrackNamespace,
365 pub track_name: Vec<u8>,
367 pub status_code: VarInt,
369 pub last_group_id: VarInt,
371 pub last_object_id: VarInt,
373}
374
375#[derive(Debug, Clone, Copy, PartialEq, Eq)]
381#[repr(u64)]
382pub enum FetchType {
383 Standalone = 1,
385 Joining = 2,
387}
388
389impl FetchType {
390 pub fn from_u64(v: u64) -> Option<Self> {
392 match v {
393 1 => Some(FetchType::Standalone),
394 2 => Some(FetchType::Joining),
395 _ => None,
396 }
397 }
398}
399
400#[derive(Debug, Clone, PartialEq, Eq)]
402pub struct Fetch {
403 pub subscribe_id: VarInt,
405 pub subscriber_priority: u8,
407 pub group_order: GroupOrder,
409 pub fetch_type: FetchType,
411 pub track_namespace: Option<TrackNamespace>,
413 pub track_name: Option<Vec<u8>>,
415 pub start_group: Option<VarInt>,
417 pub start_object: Option<VarInt>,
419 pub end_group: Option<VarInt>,
421 pub end_object: Option<VarInt>,
423 pub joining_subscribe_id: Option<VarInt>,
425 pub preceding_group_offset: Option<VarInt>,
427 pub parameters: Vec<KeyValuePair>,
429}
430
431#[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::draft10::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 if m.filter_type == FilterType::NextGroupStart {
530 return Err(CodecError::InvalidField);
531 }
532 let wants_start =
533 matches!(m.filter_type, FilterType::AbsoluteStart | FilterType::AbsoluteRange);
534 if wants_start != m.start_location.is_some() {
535 return Err(CodecError::InvalidField);
536 }
537 if (m.filter_type == FilterType::AbsoluteRange) != m.end_group.is_some() {
538 return Err(CodecError::InvalidField);
539 }
540 Ok(())
541 }
542 ControlMessage::SubscribeOk(m) => {
543 let has = m.content_exists == ContentExists::HasLargestLocation;
544 if has != m.largest_group_id.is_some() || has != m.largest_object_id.is_some() {
545 return Err(CodecError::InvalidField);
546 }
547 Ok(())
548 }
549 ControlMessage::Fetch(m) => {
550 let standalone = m.fetch_type == FetchType::Standalone;
551 let standalone_fields = [
552 m.track_namespace.is_some(),
553 m.track_name.is_some(),
554 m.start_group.is_some(),
555 m.start_object.is_some(),
556 m.end_group.is_some(),
557 m.end_object.is_some(),
558 ];
559 if standalone_fields.iter().any(|present| *present != standalone) {
560 return Err(CodecError::InvalidField);
561 }
562 let joining_fields =
563 [m.joining_subscribe_id.is_some(), m.preceding_group_offset.is_some()];
564 if joining_fields.contains(&standalone) {
565 return Err(CodecError::InvalidField);
566 }
567 Ok(())
568 }
569 _ => Ok(()),
570 }
571}
572
573fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
578 let order = match message {
579 ControlMessage::SubscribeOk(m) => m.group_order,
580 ControlMessage::FetchOk(m) => m.group_order,
581 _ => return Ok(()),
582 };
583 if order == GroupOrder::Publisher {
584 return Err(CodecError::InvalidField);
585 }
586 Ok(())
587}
588
589#[derive(Debug, Clone, PartialEq, Eq)]
591pub enum ControlMessage {
592 ClientSetup(ClientSetup),
594 ServerSetup(ServerSetup),
596 GoAway(GoAway),
598 MaxSubscribeId(MaxSubscribeId),
600 SubscribesBlocked(SubscribesBlocked),
602 Subscribe(Subscribe),
604 SubscribeOk(SubscribeOk),
606 SubscribeError(SubscribeError),
608 SubscribeUpdate(SubscribeUpdate),
610 SubscribeDone(SubscribeDone),
612 Unsubscribe(Unsubscribe),
614 Announce(Announce),
616 AnnounceOk(AnnounceOk),
618 AnnounceError(AnnounceError),
620 AnnounceCancel(AnnounceCancel),
622 Unannounce(Unannounce),
624 SubscribeAnnounces(SubscribeAnnounces),
626 SubscribeAnnouncesOk(SubscribeAnnouncesOk),
628 SubscribeAnnouncesError(SubscribeAnnouncesError),
630 UnsubscribeAnnounces(UnsubscribeAnnounces),
632 TrackStatusRequest(TrackStatusRequest),
634 TrackStatus(TrackStatus),
636 Fetch(Fetch),
638 FetchOk(FetchOk),
640 FetchError(FetchError),
642 FetchCancel(FetchCancel),
644}
645
646fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
660 match message {
661 ControlMessage::Subscribe(m) => match (&m.start_location, &m.end_group) {
662 (Some(start), Some(end_group)) => {
663 check_group_range(start.group.into_inner(), end_group.into_inner())
664 }
665 _ => Ok(()),
666 },
667 ControlMessage::SubscribeUpdate(m) => {
668 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
669 }
670 ControlMessage::Fetch(m) => {
671 match (&m.start_group, &m.start_object, &m.end_group, &m.end_object) {
672 (Some(start_group), Some(start_object), Some(end_group), Some(end_object)) => {
673 check_location_range(
674 start_group.into_inner(),
675 start_object.into_inner(),
676 end_group.into_inner(),
677 end_object.into_inner(),
678 )
679 }
680 _ => Ok(()),
681 }
682 }
683 _ => Ok(()),
684 }
685}
686
687fn check_no_duplicate_parameters(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
698 for (i, parameter) in parameters.iter().enumerate() {
699 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
700 return Err(CodecError::DuplicateParameter(parameter.key.into_inner()));
701 }
702 }
703 Ok(())
704}
705
706const SETUP_VARINT_PARAMETERS: &[u64] = &[0x02];
713
714const VERSION_VARINT_PARAMETERS: &[u64] = &[0x03, 0x04];
727
728fn check_parameter_lengths(
746 parameters: &[KeyValuePair],
747 varint_typed: &[u64],
748) -> Result<(), CodecError> {
749 for parameter in parameters {
750 let key = parameter.key.into_inner();
751 if !varint_typed.contains(&key) {
752 continue;
753 }
754 if let crate::kvp::KvpValue::Bytes(bytes) = ¶meter.value {
755 let mut cursor = &bytes[..];
756 let one_varint = VarInt::decode(&mut cursor).is_ok() && !cursor.has_remaining();
757 if !one_varint {
758 return Err(CodecError::ParameterLengthMismatch(key));
759 }
760 }
761 }
762 Ok(())
763}
764
765fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
768 let parameters = KeyValuePair::decode_list_d07(buf)?;
769 check_no_duplicate_parameters(¶meters)?;
770 check_parameter_lengths(¶meters, VERSION_VARINT_PARAMETERS)?;
771 Ok(parameters)
772}
773
774fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
777 check_no_duplicate_parameters(parameters)?;
778 check_parameter_lengths(parameters, VERSION_VARINT_PARAMETERS)?;
779 KeyValuePair::encode_list_d07(parameters, buf);
780 Ok(())
781}
782
783fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
789 let parameters = KeyValuePair::decode_list_d07(buf)?;
790 check_no_duplicate_parameters(¶meters)?;
791 check_parameter_lengths(¶meters, SETUP_VARINT_PARAMETERS)?;
792 Ok(parameters)
793}
794
795fn encode_setup_parameters(
797 parameters: &[KeyValuePair],
798 buf: &mut impl BufMut,
799) -> Result<(), CodecError> {
800 check_no_duplicate_parameters(parameters)?;
801 check_parameter_lengths(parameters, SETUP_VARINT_PARAMETERS)?;
802 KeyValuePair::encode_list_d07(parameters, buf);
803 Ok(())
804}
805
806impl ControlMessage {
807 pub fn message_type(&self) -> MessageType {
809 match self {
810 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
811 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
812 ControlMessage::GoAway(_) => MessageType::GoAway,
813 ControlMessage::MaxSubscribeId(_) => MessageType::MaxSubscribeId,
814 ControlMessage::SubscribesBlocked(_) => MessageType::SubscribesBlocked,
815 ControlMessage::Subscribe(_) => MessageType::Subscribe,
816 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
817 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
818 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
819 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
820 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
821 ControlMessage::Announce(_) => MessageType::Announce,
822 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
823 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
824 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
825 ControlMessage::Unannounce(_) => MessageType::Unannounce,
826 ControlMessage::SubscribeAnnounces(_) => MessageType::SubscribeAnnounces,
827 ControlMessage::SubscribeAnnouncesOk(_) => MessageType::SubscribeAnnouncesOk,
828 ControlMessage::SubscribeAnnouncesError(_) => MessageType::SubscribeAnnouncesError,
829 ControlMessage::UnsubscribeAnnounces(_) => MessageType::UnsubscribeAnnounces,
830 ControlMessage::TrackStatusRequest(_) => MessageType::TrackStatusRequest,
831 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
832 ControlMessage::Fetch(_) => MessageType::Fetch,
833 ControlMessage::FetchOk(_) => MessageType::FetchOk,
834 ControlMessage::FetchError(_) => MessageType::FetchError,
835 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
836 }
837 }
838
839 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
841 check_discriminators(self)?;
842 check_group_order(self)?;
843 check_ranges(self)?;
844 let mut payload = Vec::with_capacity(256);
845 self.encode_payload(&mut payload)?;
846
847 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
855 VarInt::from_usize(payload.len()).encode(buf);
856 buf.put_slice(&payload);
857 Ok(())
858 }
859
860 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
862 let type_id = VarInt::decode(buf)?.into_inner();
863 let msg_type =
864 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
865 let payload_len = VarInt::decode(buf)?.into_inner() as usize;
866 if buf.remaining() < payload_len {
867 return Err(CodecError::UnexpectedEnd);
868 }
869 let payload_bytes = buf.copy_to_bytes(payload_len);
870 let mut payload = &payload_bytes[..];
871 let msg = match Self::decode_payload(msg_type, &mut payload) {
872 Ok(msg) => msg,
873 Err(
879 CodecError::UnexpectedEnd
880 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
881 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
882 crate::varint::VarIntError::UnexpectedEnd,
883 ))
884 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
885 ) => {
886 return Err(CodecError::ControlMessageLengthMismatch {
887 declared: payload_len,
888 detail: "its fields ran past the end",
889 });
890 }
891 Err(e) => return Err(e),
892 };
893 check_ranges(&msg)?;
894 if payload.has_remaining() {
899 return Err(CodecError::ControlMessageLengthMismatch {
900 declared: payload_len,
901 detail: "its fields left bytes unread",
902 });
903 }
904 Ok(msg)
905 }
906
907 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
908 match self {
909 ControlMessage::ClientSetup(m) => {
910 VarInt::from_usize(m.supported_versions.len()).encode(buf);
911 for v in &m.supported_versions {
912 v.encode(buf);
913 }
914 encode_setup_parameters(&m.parameters, buf)?;
915 }
916 ControlMessage::ServerSetup(m) => {
917 m.selected_version.encode(buf);
918 encode_setup_parameters(&m.parameters, buf)?;
919 }
920 ControlMessage::GoAway(m) => {
921 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
922 buf.put_slice(&m.new_session_uri);
923 }
924 ControlMessage::MaxSubscribeId(m) => {
925 m.subscribe_id.encode(buf);
926 }
927 ControlMessage::SubscribesBlocked(m) => {
928 m.maximum_subscribe_id.encode(buf);
929 }
930 ControlMessage::Subscribe(m) => {
931 m.subscribe_id.encode(buf);
932 m.track_alias.encode(buf);
933 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
934 m.track_namespace.encode(buf);
935 VarInt::from_usize(m.track_name.len()).encode(buf);
936 buf.put_slice(&m.track_name);
937 buf.put_u8(m.subscriber_priority);
938 buf.put_u8(m.group_order as u8);
939 VarInt::from_usize(m.filter_type as usize).encode(buf);
940 if let Some(loc) = &m.start_location {
941 loc.encode(buf);
942 }
943 if let Some(eg) = &m.end_group {
944 eg.encode(buf);
945 }
946 encode_parameters(&m.parameters, buf)?;
947 }
948 ControlMessage::SubscribeOk(m) => {
949 m.subscribe_id.encode(buf);
950 m.expires.encode(buf);
951 buf.put_u8(m.group_order as u8);
952 buf.put_u8(m.content_exists as u8);
953 if let Some(gid) = &m.largest_group_id {
954 gid.encode(buf);
955 }
956 if let Some(oid) = &m.largest_object_id {
957 oid.encode(buf);
958 }
959 encode_parameters(&m.parameters, buf)?;
960 }
961 ControlMessage::SubscribeError(m) => {
962 m.subscribe_id.encode(buf);
963 m.error_code.encode(buf);
964 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
965 buf.put_slice(&m.reason_phrase);
966 m.track_alias.encode(buf);
967 }
968 ControlMessage::SubscribeUpdate(m) => {
969 m.subscribe_id.encode(buf);
970 m.start_group.encode(buf);
971 m.start_object.encode(buf);
972 m.end_group.encode(buf);
973 buf.put_u8(m.subscriber_priority);
974 encode_parameters(&m.parameters, buf)?;
975 }
976 ControlMessage::SubscribeDone(m) => {
977 m.subscribe_id.encode(buf);
978 m.status_code.encode(buf);
979 m.stream_count.encode(buf);
980 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
981 buf.put_slice(&m.reason_phrase);
982 }
983 ControlMessage::Unsubscribe(m) => {
984 m.subscribe_id.encode(buf);
985 }
986 ControlMessage::Announce(m) => {
987 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
988 m.track_namespace.encode(buf);
989 encode_parameters(&m.parameters, buf)?;
990 }
991 ControlMessage::AnnounceOk(m) => {
992 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
993 m.track_namespace.encode(buf);
994 }
995 ControlMessage::AnnounceError(m) => {
996 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
997 m.track_namespace.encode(buf);
998 m.error_code.encode(buf);
999 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1000 buf.put_slice(&m.reason_phrase);
1001 }
1002 ControlMessage::AnnounceCancel(m) => {
1003 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
1004 m.track_namespace.encode(buf);
1005 m.error_code.encode(buf);
1006 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1007 buf.put_slice(&m.reason_phrase);
1008 }
1009 ControlMessage::Unannounce(m) => {
1010 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
1011 m.track_namespace.encode(buf);
1012 }
1013 ControlMessage::SubscribeAnnounces(m) => {
1014 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(10))?;
1015 m.track_namespace_prefix.encode(buf);
1016 encode_parameters(&m.parameters, buf)?;
1017 }
1018 ControlMessage::SubscribeAnnouncesOk(m) => {
1019 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(10))?;
1020 m.track_namespace_prefix.encode(buf);
1021 }
1022 ControlMessage::SubscribeAnnouncesError(m) => {
1023 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(10))?;
1024 m.track_namespace_prefix.encode(buf);
1025 m.error_code.encode(buf);
1026 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1027 buf.put_slice(&m.reason_phrase);
1028 }
1029 ControlMessage::UnsubscribeAnnounces(m) => {
1030 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(10))?;
1031 m.track_namespace_prefix.encode(buf);
1032 }
1033 ControlMessage::TrackStatusRequest(m) => {
1034 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
1035 m.track_namespace.encode(buf);
1036 VarInt::from_usize(m.track_name.len()).encode(buf);
1037 buf.put_slice(&m.track_name);
1038 }
1039 ControlMessage::TrackStatus(m) => {
1040 m.track_namespace.validate(TrackNamespaceRules::for_draft(10))?;
1041 m.track_namespace.encode(buf);
1042 VarInt::from_usize(m.track_name.len()).encode(buf);
1043 buf.put_slice(&m.track_name);
1044 check_track_status(m.status_code, m.last_group_id, m.last_object_id)?;
1045 m.status_code.encode(buf);
1046 m.last_group_id.encode(buf);
1047 m.last_object_id.encode(buf);
1048 }
1049 ControlMessage::Fetch(m) => {
1050 m.subscribe_id.encode(buf);
1051 buf.put_u8(m.subscriber_priority);
1052 buf.put_u8(m.group_order as u8);
1053 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1054 match m.fetch_type {
1055 FetchType::Standalone => {
1056 if let Some(ns) = &m.track_namespace {
1057 ns.encode(buf);
1058 }
1059 if let Some(name) = &m.track_name {
1060 VarInt::from_usize(name.len()).encode(buf);
1061 buf.put_slice(name);
1062 }
1063 if let Some(sg) = &m.start_group {
1064 sg.encode(buf);
1065 }
1066 if let Some(so) = &m.start_object {
1067 so.encode(buf);
1068 }
1069 if let Some(eg) = &m.end_group {
1070 eg.encode(buf);
1071 }
1072 if let Some(eo) = &m.end_object {
1073 eo.encode(buf);
1074 }
1075 }
1076 FetchType::Joining => {
1077 if let Some(jsi) = &m.joining_subscribe_id {
1078 jsi.encode(buf);
1079 }
1080 if let Some(pgo) = &m.preceding_group_offset {
1081 pgo.encode(buf);
1082 }
1083 }
1084 }
1085 encode_parameters(&m.parameters, buf)?;
1086 }
1087 ControlMessage::FetchOk(m) => {
1088 m.subscribe_id.encode(buf);
1089 buf.put_u8(m.group_order as u8);
1090 buf.put_u8(m.end_of_track);
1091 m.largest_group_id.encode(buf);
1092 m.largest_object_id.encode(buf);
1093 encode_parameters(&m.parameters, buf)?;
1094 }
1095 ControlMessage::FetchError(m) => {
1096 m.subscribe_id.encode(buf);
1097 m.error_code.encode(buf);
1098 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1099 buf.put_slice(&m.reason_phrase);
1100 }
1101 ControlMessage::FetchCancel(m) => {
1102 m.subscribe_id.encode(buf);
1103 }
1104 }
1105 Ok(())
1106 }
1107
1108 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1109 match msg_type {
1110 MessageType::ClientSetup => {
1111 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1112 if num_versions == 0 {
1122 return Err(CodecError::InvalidField);
1123 }
1124 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1125 for _ in 0..num_versions {
1126 supported_versions.push(VarInt::decode(buf)?);
1127 }
1128 let parameters = decode_setup_parameters(buf)?;
1129 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1130 }
1131 MessageType::ServerSetup => {
1132 let selected_version = VarInt::decode(buf)?;
1133 let parameters = decode_setup_parameters(buf)?;
1134 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1135 }
1136 MessageType::GoAway => {
1137 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1138 let uri = read_bytes(buf, uri_len)?;
1139 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1140 }
1141 MessageType::MaxSubscribeId => {
1142 let subscribe_id = VarInt::decode(buf)?;
1143 Ok(ControlMessage::MaxSubscribeId(MaxSubscribeId { subscribe_id }))
1144 }
1145 MessageType::SubscribesBlocked => {
1146 let maximum_subscribe_id = VarInt::decode(buf)?;
1147 Ok(ControlMessage::SubscribesBlocked(SubscribesBlocked { maximum_subscribe_id }))
1148 }
1149 MessageType::Subscribe => {
1150 let subscribe_id = VarInt::decode(buf)?;
1151 let track_alias = VarInt::decode(buf)?;
1152 let track_namespace = TrackNamespace::decode(buf)?;
1153 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1154 let track_name = read_bytes(buf, track_name_len)?;
1155 if buf.remaining() < 2 {
1156 return Err(CodecError::UnexpectedEnd);
1157 }
1158 let subscriber_priority = buf.get_u8();
1159 let group_order =
1160 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1161 let filter_val = VarInt::decode(buf)?.into_inner();
1162 if filter_val == 1 {
1165 return Err(CodecError::InvalidFilterType(filter_val));
1166 }
1167 let filter_type = FilterType::from_u64(filter_val)
1168 .ok_or(CodecError::InvalidFilterType(filter_val))?;
1169 let start_location = match filter_type {
1170 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1171 Some(Location::decode(buf)?)
1172 }
1173 _ => None,
1174 };
1175 let end_group = match filter_type {
1176 FilterType::AbsoluteRange => Some(VarInt::decode(buf)?),
1177 _ => None,
1178 };
1179 let parameters = decode_parameters(buf)?;
1180 Ok(ControlMessage::Subscribe(Subscribe {
1181 subscribe_id,
1182 track_alias,
1183 track_namespace,
1184 track_name,
1185 subscriber_priority,
1186 group_order,
1187 filter_type,
1188 start_location,
1189 end_group,
1190 parameters,
1191 }))
1192 }
1193 MessageType::SubscribeOk => {
1194 let subscribe_id = VarInt::decode(buf)?;
1195 let expires = VarInt::decode(buf)?;
1196 if buf.remaining() < 2 {
1197 return Err(CodecError::UnexpectedEnd);
1198 }
1199 let group_order = read_group_order_response(buf)?;
1200 let content_exists_val = buf.get_u8();
1201 let content_exists = match content_exists_val {
1202 0 => ContentExists::NoLargestLocation,
1203 1 => ContentExists::HasLargestLocation,
1204 other => return Err(CodecError::InvalidContentExists(other)),
1205 };
1206 let (largest_group_id, largest_object_id) =
1207 if content_exists == ContentExists::HasLargestLocation {
1208 let gid = VarInt::decode(buf)?;
1209 let oid = VarInt::decode(buf)?;
1210 (Some(gid), Some(oid))
1211 } else {
1212 (None, None)
1213 };
1214 let parameters = decode_parameters(buf)?;
1215 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1216 subscribe_id,
1217 expires,
1218 group_order,
1219 content_exists,
1220 largest_group_id,
1221 largest_object_id,
1222 parameters,
1223 }))
1224 }
1225 MessageType::SubscribeError => {
1226 let subscribe_id = VarInt::decode(buf)?;
1227 let error_code = VarInt::decode(buf)?;
1228 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1229 let reason_phrase = read_bytes(buf, reason_len)?;
1230 let track_alias = VarInt::decode(buf)?;
1231 Ok(ControlMessage::SubscribeError(SubscribeError {
1232 subscribe_id,
1233 error_code,
1234 reason_phrase,
1235 track_alias,
1236 }))
1237 }
1238 MessageType::SubscribeUpdate => {
1239 let subscribe_id = VarInt::decode(buf)?;
1240 let start_group = VarInt::decode(buf)?;
1241 let start_object = VarInt::decode(buf)?;
1242 let end_group = VarInt::decode(buf)?;
1243 if buf.remaining() < 1 {
1244 return Err(CodecError::UnexpectedEnd);
1245 }
1246 let subscriber_priority = buf.get_u8();
1247 let parameters = decode_parameters(buf)?;
1248 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1249 subscribe_id,
1250 start_group,
1251 start_object,
1252 end_group,
1253 subscriber_priority,
1254 parameters,
1255 }))
1256 }
1257 MessageType::SubscribeDone => {
1258 let subscribe_id = VarInt::decode(buf)?;
1259 let status_code = VarInt::decode(buf)?;
1260 let stream_count = VarInt::decode(buf)?;
1261 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1262 let reason_phrase = read_bytes(buf, reason_len)?;
1263 Ok(ControlMessage::SubscribeDone(SubscribeDone {
1264 subscribe_id,
1265 status_code,
1266 stream_count,
1267 reason_phrase,
1268 }))
1269 }
1270 MessageType::Unsubscribe => {
1271 let subscribe_id = VarInt::decode(buf)?;
1272 Ok(ControlMessage::Unsubscribe(Unsubscribe { subscribe_id }))
1273 }
1274 MessageType::Announce => {
1275 let track_namespace = TrackNamespace::decode(buf)?;
1276 let parameters = decode_parameters(buf)?;
1277 Ok(ControlMessage::Announce(Announce { track_namespace, parameters }))
1278 }
1279 MessageType::AnnounceOk => {
1280 let track_namespace = TrackNamespace::decode(buf)?;
1281 Ok(ControlMessage::AnnounceOk(AnnounceOk { track_namespace }))
1282 }
1283 MessageType::AnnounceError => {
1284 let track_namespace = TrackNamespace::decode(buf)?;
1285 let error_code = VarInt::decode(buf)?;
1286 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1287 let reason_phrase = read_bytes(buf, reason_len)?;
1288 Ok(ControlMessage::AnnounceError(AnnounceError {
1289 track_namespace,
1290 error_code,
1291 reason_phrase,
1292 }))
1293 }
1294 MessageType::AnnounceCancel => {
1295 let track_namespace = TrackNamespace::decode(buf)?;
1296 let error_code = VarInt::decode(buf)?;
1297 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1298 let reason_phrase = read_bytes(buf, reason_len)?;
1299 Ok(ControlMessage::AnnounceCancel(AnnounceCancel {
1300 track_namespace,
1301 error_code,
1302 reason_phrase,
1303 }))
1304 }
1305 MessageType::Unannounce => {
1306 let track_namespace = TrackNamespace::decode(buf)?;
1307 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1308 }
1309 MessageType::SubscribeAnnounces => {
1310 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1311 let parameters = decode_parameters(buf)?;
1312 Ok(ControlMessage::SubscribeAnnounces(SubscribeAnnounces {
1313 track_namespace_prefix,
1314 parameters,
1315 }))
1316 }
1317 MessageType::SubscribeAnnouncesOk => {
1318 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1319 Ok(ControlMessage::SubscribeAnnouncesOk(SubscribeAnnouncesOk {
1320 track_namespace_prefix,
1321 }))
1322 }
1323 MessageType::SubscribeAnnouncesError => {
1324 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1325 let error_code = VarInt::decode(buf)?;
1326 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1327 let reason_phrase = read_bytes(buf, reason_len)?;
1328 Ok(ControlMessage::SubscribeAnnouncesError(SubscribeAnnouncesError {
1329 track_namespace_prefix,
1330 error_code,
1331 reason_phrase,
1332 }))
1333 }
1334 MessageType::UnsubscribeAnnounces => {
1335 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1336 Ok(ControlMessage::UnsubscribeAnnounces(UnsubscribeAnnounces {
1337 track_namespace_prefix,
1338 }))
1339 }
1340 MessageType::TrackStatusRequest => {
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 Ok(ControlMessage::TrackStatusRequest(TrackStatusRequest {
1345 track_namespace,
1346 track_name,
1347 }))
1348 }
1349 MessageType::TrackStatus => {
1350 let track_namespace = TrackNamespace::decode(buf)?;
1351 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1352 let track_name = read_bytes(buf, track_name_len)?;
1353 let status_code = VarInt::decode(buf)?;
1354 let last_group_id = VarInt::decode(buf)?;
1355 let last_object_id = VarInt::decode(buf)?;
1356 check_track_status(status_code, last_group_id, last_object_id)?;
1357 Ok(ControlMessage::TrackStatus(TrackStatus {
1358 track_namespace,
1359 track_name,
1360 status_code,
1361 last_group_id,
1362 last_object_id,
1363 }))
1364 }
1365 MessageType::Fetch => {
1366 let subscribe_id = VarInt::decode(buf)?;
1367 if buf.remaining() < 2 {
1368 return Err(CodecError::UnexpectedEnd);
1369 }
1370 let subscriber_priority = buf.get_u8();
1371 let group_order =
1372 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1373 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1374 let fetch_type = FetchType::from_u64(fetch_type_val)
1375 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1376 let (
1377 track_namespace,
1378 track_name,
1379 start_group,
1380 start_object,
1381 end_group,
1382 end_object,
1383 joining_subscribe_id,
1384 preceding_group_offset,
1385 ) = match fetch_type {
1386 FetchType::Standalone => {
1387 let ns = TrackNamespace::decode(buf)?;
1388 let name_len = VarInt::decode(buf)?.into_inner() as usize;
1389 let name = read_bytes(buf, name_len)?;
1390 let sg = VarInt::decode(buf)?;
1391 let so = VarInt::decode(buf)?;
1392 let eg = VarInt::decode(buf)?;
1393 let eo = VarInt::decode(buf)?;
1394 (Some(ns), Some(name), Some(sg), Some(so), Some(eg), Some(eo), None, None)
1395 }
1396 FetchType::Joining => {
1397 let jsi = VarInt::decode(buf)?;
1398 let pgo = VarInt::decode(buf)?;
1399 (None, None, None, None, None, None, Some(jsi), Some(pgo))
1400 }
1401 };
1402 let parameters = decode_parameters(buf)?;
1403 Ok(ControlMessage::Fetch(Fetch {
1404 subscribe_id,
1405 subscriber_priority,
1406 group_order,
1407 fetch_type,
1408 track_namespace,
1409 track_name,
1410 start_group,
1411 start_object,
1412 end_group,
1413 end_object,
1414 joining_subscribe_id,
1415 preceding_group_offset,
1416 parameters,
1417 }))
1418 }
1419 MessageType::FetchOk => {
1420 let subscribe_id = VarInt::decode(buf)?;
1421 if buf.remaining() < 2 {
1422 return Err(CodecError::UnexpectedEnd);
1423 }
1424 let group_order = read_group_order_response(buf)?;
1425 let end_of_track = buf.get_u8();
1426 let largest_group_id = VarInt::decode(buf)?;
1427 let largest_object_id = VarInt::decode(buf)?;
1428 let parameters = decode_parameters(buf)?;
1429 Ok(ControlMessage::FetchOk(FetchOk {
1430 subscribe_id,
1431 group_order,
1432 end_of_track,
1433 largest_group_id,
1434 largest_object_id,
1435 parameters,
1436 }))
1437 }
1438 MessageType::FetchError => {
1439 let subscribe_id = VarInt::decode(buf)?;
1440 let error_code = VarInt::decode(buf)?;
1441 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1442 let reason_phrase = read_bytes(buf, reason_len)?;
1443 Ok(ControlMessage::FetchError(FetchError {
1444 subscribe_id,
1445 error_code,
1446 reason_phrase,
1447 }))
1448 }
1449 MessageType::FetchCancel => {
1450 let subscribe_id = VarInt::decode(buf)?;
1451 Ok(ControlMessage::FetchCancel(FetchCancel { subscribe_id }))
1452 }
1453 }
1454 }
1455}