1use crate::error::CodecError;
2use crate::kvp::KeyValuePair;
3use crate::types::read_bytes;
4use crate::types::*;
5use crate::types::{check_location_range, check_open_ended_group_range};
6use crate::varint::VarInt;
7use bytes::{Buf, BufMut};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11#[repr(u64)]
12pub enum MessageType {
13 SubscribeUpdate = 0x02,
15 Subscribe = 0x03,
17 SubscribeOk = 0x04,
19 SubscribeError = 0x05,
21 Announce = 0x06,
23 AnnounceOk = 0x07,
25 AnnounceError = 0x08,
27 Unannounce = 0x09,
29 Unsubscribe = 0x0A,
31 SubscribeDone = 0x0B,
33 AnnounceCancel = 0x0C,
35 TrackStatusRequest = 0x0D,
37 TrackStatus = 0x0E,
39 GoAway = 0x10,
41 SubscribeAnnounces = 0x11,
43 SubscribeAnnouncesOk = 0x12,
45 SubscribeAnnouncesError = 0x13,
47 UnsubscribeAnnounces = 0x14,
49 MaxSubscribeId = 0x15,
51 Fetch = 0x16,
53 FetchCancel = 0x17,
55 FetchOk = 0x18,
57 FetchError = 0x19,
59 ClientSetup = 0x40,
61 ServerSetup = 0x41,
63}
64
65impl MessageType {
66 pub fn from_id(id: u64) -> Option<Self> {
68 match id {
69 0x02 => Some(MessageType::SubscribeUpdate),
70 0x03 => Some(MessageType::Subscribe),
71 0x04 => Some(MessageType::SubscribeOk),
72 0x05 => Some(MessageType::SubscribeError),
73 0x06 => Some(MessageType::Announce),
74 0x07 => Some(MessageType::AnnounceOk),
75 0x08 => Some(MessageType::AnnounceError),
76 0x09 => Some(MessageType::Unannounce),
77 0x0A => Some(MessageType::Unsubscribe),
78 0x0B => Some(MessageType::SubscribeDone),
79 0x0C => Some(MessageType::AnnounceCancel),
80 0x0D => Some(MessageType::TrackStatusRequest),
81 0x0E => Some(MessageType::TrackStatus),
82 0x10 => Some(MessageType::GoAway),
83 0x11 => Some(MessageType::SubscribeAnnounces),
84 0x12 => Some(MessageType::SubscribeAnnouncesOk),
85 0x13 => Some(MessageType::SubscribeAnnouncesError),
86 0x14 => Some(MessageType::UnsubscribeAnnounces),
87 0x15 => Some(MessageType::MaxSubscribeId),
88 0x16 => Some(MessageType::Fetch),
89 0x17 => Some(MessageType::FetchCancel),
90 0x18 => Some(MessageType::FetchOk),
91 0x19 => Some(MessageType::FetchError),
92 0x40 => Some(MessageType::ClientSetup),
93 0x41 => Some(MessageType::ServerSetup),
94 _ => None,
95 }
96 }
97
98 pub fn id(&self) -> u64 {
100 *self as u64
101 }
102
103 pub fn name(&self) -> &'static str {
106 match self {
107 MessageType::SubscribeUpdate => "subscribe_update",
108 MessageType::Subscribe => "subscribe",
109 MessageType::SubscribeOk => "subscribe_ok",
110 MessageType::SubscribeError => "subscribe_error",
111 MessageType::Announce => "announce",
112 MessageType::AnnounceOk => "announce_ok",
113 MessageType::AnnounceError => "announce_error",
114 MessageType::Unannounce => "unannounce",
115 MessageType::Unsubscribe => "unsubscribe",
116 MessageType::SubscribeDone => "subscribe_done",
117 MessageType::AnnounceCancel => "announce_cancel",
118 MessageType::TrackStatusRequest => "track_status_request",
119 MessageType::TrackStatus => "track_status",
120 MessageType::GoAway => "goaway",
121 MessageType::SubscribeAnnounces => "subscribe_announces",
122 MessageType::SubscribeAnnouncesOk => "subscribe_announces_ok",
123 MessageType::SubscribeAnnouncesError => "subscribe_announces_error",
124 MessageType::UnsubscribeAnnounces => "unsubscribe_announces",
125 MessageType::MaxSubscribeId => "max_subscribe_id",
126 MessageType::Fetch => "fetch",
127 MessageType::FetchCancel => "fetch_cancel",
128 MessageType::FetchOk => "fetch_ok",
129 MessageType::FetchError => "fetch_error",
130 MessageType::ClientSetup => "client_setup",
131 MessageType::ServerSetup => "server_setup",
132 }
133 }
134}
135
136#[derive(Debug, Clone, PartialEq, Eq)]
142pub struct ClientSetup {
143 pub supported_versions: Vec<VarInt>,
145 pub parameters: Vec<KeyValuePair>,
147}
148
149#[derive(Debug, Clone, PartialEq, Eq)]
151pub struct ServerSetup {
152 pub selected_version: VarInt,
154 pub parameters: Vec<KeyValuePair>,
156}
157
158#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct GoAway {
161 pub new_session_uri: Vec<u8>,
163}
164
165#[derive(Debug, Clone, PartialEq, Eq)]
167pub struct MaxSubscribeId {
168 pub subscribe_id: VarInt,
170}
171
172#[derive(Debug, Clone, PartialEq, Eq)]
178pub struct Subscribe {
179 pub subscribe_id: VarInt,
181 pub track_alias: VarInt,
183 pub track_namespace: TrackNamespace,
185 pub track_name: Vec<u8>,
187 pub subscriber_priority: u8,
189 pub group_order: GroupOrder,
191 pub filter_type: FilterType,
193 pub start_location: Option<Location>,
195 pub end_group: Option<VarInt>,
197 pub end_object: Option<VarInt>,
199 pub parameters: Vec<KeyValuePair>,
201}
202
203#[derive(Debug, Clone, PartialEq, Eq)]
205pub struct SubscribeOk {
206 pub subscribe_id: VarInt,
208 pub expires: VarInt,
210 pub group_order: GroupOrder,
212 pub content_exists: ContentExists,
214 pub largest_group_id: Option<VarInt>,
216 pub largest_object_id: Option<VarInt>,
218 pub parameters: Vec<KeyValuePair>,
220}
221
222#[derive(Debug, Clone, PartialEq, Eq)]
224pub struct SubscribeError {
225 pub subscribe_id: VarInt,
227 pub error_code: VarInt,
229 pub reason_phrase: Vec<u8>,
231 pub track_alias: VarInt,
233}
234
235#[derive(Debug, Clone, PartialEq, Eq)]
237pub struct SubscribeUpdate {
238 pub subscribe_id: VarInt,
240 pub start_group: VarInt,
242 pub start_object: VarInt,
244 pub end_group: VarInt,
246 pub end_object: VarInt,
248 pub subscriber_priority: u8,
250 pub parameters: Vec<KeyValuePair>,
252}
253
254#[derive(Debug, Clone, PartialEq, Eq)]
256pub struct SubscribeDone {
257 pub subscribe_id: VarInt,
259 pub status_code: VarInt,
261 pub reason_phrase: Vec<u8>,
263 pub content_exists: ContentExists,
265 pub final_group: Option<VarInt>,
267 pub final_object: Option<VarInt>,
269}
270
271#[derive(Debug, Clone, PartialEq, Eq)]
273pub struct Unsubscribe {
274 pub subscribe_id: VarInt,
276}
277
278#[derive(Debug, Clone, PartialEq, Eq)]
284pub struct Announce {
285 pub track_namespace: TrackNamespace,
287 pub parameters: Vec<KeyValuePair>,
289}
290
291#[derive(Debug, Clone, PartialEq, Eq)]
293pub struct AnnounceOk {
294 pub track_namespace: TrackNamespace,
296}
297
298#[derive(Debug, Clone, PartialEq, Eq)]
300pub struct AnnounceError {
301 pub track_namespace: TrackNamespace,
303 pub error_code: VarInt,
305 pub reason_phrase: Vec<u8>,
307}
308
309#[derive(Debug, Clone, PartialEq, Eq)]
311pub struct AnnounceCancel {
312 pub track_namespace: TrackNamespace,
314 pub error_code: VarInt,
316 pub reason_phrase: Vec<u8>,
318}
319
320#[derive(Debug, Clone, PartialEq, Eq)]
322pub struct Unannounce {
323 pub track_namespace: TrackNamespace,
325}
326
327#[derive(Debug, Clone, PartialEq, Eq)]
333pub struct SubscribeAnnounces {
334 pub track_namespace_prefix: TrackNamespace,
336 pub parameters: Vec<KeyValuePair>,
338}
339
340#[derive(Debug, Clone, PartialEq, Eq)]
342pub struct SubscribeAnnouncesOk {
343 pub track_namespace_prefix: TrackNamespace,
345}
346
347#[derive(Debug, Clone, PartialEq, Eq)]
349pub struct SubscribeAnnouncesError {
350 pub track_namespace_prefix: TrackNamespace,
352 pub error_code: VarInt,
354 pub reason_phrase: Vec<u8>,
356}
357
358#[derive(Debug, Clone, PartialEq, Eq)]
360pub struct UnsubscribeAnnounces {
361 pub track_namespace_prefix: TrackNamespace,
363}
364
365#[derive(Debug, Clone, PartialEq, Eq)]
371pub struct TrackStatusRequest {
372 pub track_namespace: TrackNamespace,
374 pub track_name: Vec<u8>,
376}
377
378#[derive(Debug, Clone, PartialEq, Eq)]
380pub struct TrackStatus {
381 pub track_namespace: TrackNamespace,
383 pub track_name: Vec<u8>,
385 pub status_code: VarInt,
387 pub last_group_id: VarInt,
389 pub last_object_id: VarInt,
391}
392
393#[derive(Debug, Clone, PartialEq, Eq)]
399pub struct Fetch {
400 pub subscribe_id: VarInt,
402 pub track_namespace: TrackNamespace,
404 pub track_name: Vec<u8>,
406 pub subscriber_priority: u8,
408 pub group_order: GroupOrder,
410 pub start_group: VarInt,
412 pub start_object: VarInt,
414 pub end_group: VarInt,
416 pub end_object: VarInt,
418 pub parameters: Vec<KeyValuePair>,
420}
421
422#[derive(Debug, Clone, PartialEq, Eq)]
424pub struct FetchOk {
425 pub subscribe_id: VarInt,
427 pub group_order: GroupOrder,
429 pub end_of_track: u8,
431 pub largest_group_id: Option<VarInt>,
433 pub largest_object_id: Option<VarInt>,
435 pub parameters: Vec<KeyValuePair>,
437}
438
439#[derive(Debug, Clone, PartialEq, Eq)]
441pub struct FetchError {
442 pub subscribe_id: VarInt,
444 pub error_code: VarInt,
446 pub reason_phrase: Vec<u8>,
448}
449
450#[derive(Debug, Clone, PartialEq, Eq)]
452pub struct FetchCancel {
453 pub subscribe_id: VarInt,
455}
456
457fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
472 if !buf.has_remaining() {
473 return Err(CodecError::UnexpectedEnd);
474 }
475 match GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)? {
476 GroupOrder::Publisher => Err(CodecError::InvalidField),
477 order => Ok(order),
478 }
479}
480
481fn check_track_status(
492 status_code: VarInt,
493 last_group_id: VarInt,
494 last_object_id: VarInt,
495) -> Result<(), CodecError> {
496 let code = crate::draft07::error_codes::TrackStatusCode::from_u64(status_code.into_inner())
497 .ok_or(CodecError::InvalidField)?;
498 if code.requires_zero_location()
499 && (last_group_id.into_inner() != 0 || last_object_id.into_inner() != 0)
500 {
501 return Err(CodecError::InvalidField);
502 }
503 Ok(())
504}
505
506fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
517 match message {
518 ControlMessage::Subscribe(m) => {
519 let wants_start =
520 matches!(m.filter_type, FilterType::AbsoluteStart | FilterType::AbsoluteRange);
521 if wants_start != m.start_location.is_some() {
522 return Err(CodecError::InvalidField);
523 }
524 let wants_end = m.filter_type == FilterType::AbsoluteRange;
525 if wants_end != m.end_group.is_some() || wants_end != m.end_object.is_some() {
526 return Err(CodecError::InvalidField);
527 }
528 Ok(())
529 }
530 ControlMessage::SubscribeOk(m) => {
531 let has = m.content_exists == ContentExists::HasLargestLocation;
532 if has != m.largest_group_id.is_some() || has != m.largest_object_id.is_some() {
533 return Err(CodecError::InvalidField);
534 }
535 Ok(())
536 }
537 _ => Ok(()),
538 }
539}
540
541fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
546 let order = match message {
547 ControlMessage::SubscribeOk(m) => m.group_order,
548 ControlMessage::FetchOk(m) => m.group_order,
549 _ => return Ok(()),
550 };
551 if order == GroupOrder::Publisher {
552 return Err(CodecError::InvalidField);
553 }
554 Ok(())
555}
556
557#[derive(Debug, Clone, PartialEq, Eq)]
559pub enum ControlMessage {
560 ClientSetup(ClientSetup),
562 ServerSetup(ServerSetup),
564 GoAway(GoAway),
566 MaxSubscribeId(MaxSubscribeId),
568 Subscribe(Subscribe),
570 SubscribeOk(SubscribeOk),
572 SubscribeError(SubscribeError),
574 SubscribeUpdate(SubscribeUpdate),
576 SubscribeDone(SubscribeDone),
578 Unsubscribe(Unsubscribe),
580 Announce(Announce),
582 AnnounceOk(AnnounceOk),
584 AnnounceError(AnnounceError),
586 AnnounceCancel(AnnounceCancel),
588 Unannounce(Unannounce),
590 SubscribeAnnounces(SubscribeAnnounces),
592 SubscribeAnnouncesOk(SubscribeAnnouncesOk),
594 SubscribeAnnouncesError(SubscribeAnnouncesError),
596 UnsubscribeAnnounces(UnsubscribeAnnounces),
598 TrackStatusRequest(TrackStatusRequest),
600 TrackStatus(TrackStatus),
602 Fetch(Fetch),
604 FetchOk(FetchOk),
606 FetchError(FetchError),
608 FetchCancel(FetchCancel),
610}
611
612fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
626 match message {
627 ControlMessage::Subscribe(m) => match (&m.start_location, &m.end_group, &m.end_object) {
628 (Some(start), Some(end_group), Some(end_object)) => check_location_range(
629 start.group.into_inner(),
630 start.object.into_inner(),
631 end_group.into_inner(),
632 end_object.into_inner(),
633 ),
634 _ => Ok(()),
635 },
636 ControlMessage::SubscribeUpdate(m) => {
637 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
638 }
639 ControlMessage::Fetch(m) => check_location_range(
640 m.start_group.into_inner(),
641 m.start_object.into_inner(),
642 m.end_group.into_inner(),
643 m.end_object.into_inner(),
644 ),
645 _ => Ok(()),
646 }
647}
648
649fn check_no_duplicate_parameters(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
660 for (i, parameter) in parameters.iter().enumerate() {
661 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
662 return Err(CodecError::DuplicateParameter(parameter.key.into_inner()));
663 }
664 }
665 Ok(())
666}
667
668const SETUP_VARINT_PARAMETERS: &[u64] = &[0x00, 0x02];
675
676const VERSION_VARINT_PARAMETERS: &[u64] = &[0x03, 0x04];
689
690fn check_parameter_lengths(
708 parameters: &[KeyValuePair],
709 varint_typed: &[u64],
710) -> Result<(), CodecError> {
711 for parameter in parameters {
712 let key = parameter.key.into_inner();
713 if !varint_typed.contains(&key) {
714 continue;
715 }
716 if let crate::kvp::KvpValue::Bytes(bytes) = ¶meter.value {
717 let mut cursor = &bytes[..];
718 let one_varint = VarInt::decode(&mut cursor).is_ok() && !cursor.has_remaining();
719 if !one_varint {
720 return Err(CodecError::ParameterLengthMismatch(key));
721 }
722 }
723 }
724 Ok(())
725}
726
727fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
730 let parameters = KeyValuePair::decode_list_d07(buf)?;
731 check_no_duplicate_parameters(¶meters)?;
732 check_parameter_lengths(¶meters, VERSION_VARINT_PARAMETERS)?;
733 Ok(parameters)
734}
735
736fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
739 check_no_duplicate_parameters(parameters)?;
740 check_parameter_lengths(parameters, VERSION_VARINT_PARAMETERS)?;
741 KeyValuePair::encode_list_d07(parameters, buf);
742 Ok(())
743}
744
745fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
751 let parameters = KeyValuePair::decode_list_d07(buf)?;
752 check_no_duplicate_parameters(¶meters)?;
753 check_parameter_lengths(¶meters, SETUP_VARINT_PARAMETERS)?;
754 Ok(parameters)
755}
756
757fn encode_setup_parameters(
759 parameters: &[KeyValuePair],
760 buf: &mut impl BufMut,
761) -> Result<(), CodecError> {
762 check_no_duplicate_parameters(parameters)?;
763 check_parameter_lengths(parameters, SETUP_VARINT_PARAMETERS)?;
764 KeyValuePair::encode_list_d07(parameters, buf);
765 Ok(())
766}
767
768impl ControlMessage {
769 pub fn message_type(&self) -> MessageType {
771 match self {
772 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
773 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
774 ControlMessage::GoAway(_) => MessageType::GoAway,
775 ControlMessage::MaxSubscribeId(_) => MessageType::MaxSubscribeId,
776 ControlMessage::Subscribe(_) => MessageType::Subscribe,
777 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
778 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
779 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
780 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
781 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
782 ControlMessage::Announce(_) => MessageType::Announce,
783 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
784 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
785 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
786 ControlMessage::Unannounce(_) => MessageType::Unannounce,
787 ControlMessage::SubscribeAnnounces(_) => MessageType::SubscribeAnnounces,
788 ControlMessage::SubscribeAnnouncesOk(_) => MessageType::SubscribeAnnouncesOk,
789 ControlMessage::SubscribeAnnouncesError(_) => MessageType::SubscribeAnnouncesError,
790 ControlMessage::UnsubscribeAnnounces(_) => MessageType::UnsubscribeAnnounces,
791 ControlMessage::TrackStatusRequest(_) => MessageType::TrackStatusRequest,
792 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
793 ControlMessage::Fetch(_) => MessageType::Fetch,
794 ControlMessage::FetchOk(_) => MessageType::FetchOk,
795 ControlMessage::FetchError(_) => MessageType::FetchError,
796 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
797 }
798 }
799
800 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
802 check_discriminators(self)?;
803 check_group_order(self)?;
804 check_ranges(self)?;
805 let mut payload = Vec::with_capacity(256);
806 self.encode_payload(&mut payload)?;
807
808 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
816 VarInt::from_usize(payload.len()).encode(buf);
817 buf.put_slice(&payload);
818 Ok(())
819 }
820
821 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
823 let type_id = VarInt::decode(buf)?.into_inner();
824 let msg_type =
825 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
826 let payload_len = VarInt::decode(buf)?.into_inner() as usize;
827 if buf.remaining() < payload_len {
828 return Err(CodecError::UnexpectedEnd);
829 }
830 let payload_bytes = buf.copy_to_bytes(payload_len);
831 let mut payload = &payload_bytes[..];
832 let msg = match Self::decode_payload(msg_type, &mut payload) {
833 Ok(msg) => msg,
834 Err(
840 CodecError::UnexpectedEnd
841 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
842 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
843 crate::varint::VarIntError::UnexpectedEnd,
844 ))
845 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
846 ) => {
847 return Err(CodecError::ControlMessageLengthMismatch {
848 declared: payload_len,
849 detail: "its fields ran past the end",
850 });
851 }
852 Err(e) => return Err(e),
853 };
854 check_ranges(&msg)?;
855 if payload.has_remaining() {
860 return Err(CodecError::ControlMessageLengthMismatch {
861 declared: payload_len,
862 detail: "its fields left bytes unread",
863 });
864 }
865 Ok(msg)
866 }
867
868 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
869 match self {
870 ControlMessage::ClientSetup(m) => {
871 VarInt::from_usize(m.supported_versions.len()).encode(buf);
872 for v in &m.supported_versions {
873 v.encode(buf);
874 }
875 encode_setup_parameters(&m.parameters, buf)?;
876 }
877 ControlMessage::ServerSetup(m) => {
878 m.selected_version.encode(buf);
879 encode_setup_parameters(&m.parameters, buf)?;
880 }
881 ControlMessage::GoAway(m) => {
882 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
883 buf.put_slice(&m.new_session_uri);
884 }
885 ControlMessage::MaxSubscribeId(m) => {
886 m.subscribe_id.encode(buf);
887 }
888 ControlMessage::Subscribe(m) => {
889 m.subscribe_id.encode(buf);
890 m.track_alias.encode(buf);
891 m.track_namespace.validate(TrackNamespaceRules::for_draft(7))?;
892 m.track_namespace.encode(buf);
893 VarInt::from_usize(m.track_name.len()).encode(buf);
894 buf.put_slice(&m.track_name);
895 buf.put_u8(m.subscriber_priority);
896 buf.put_u8(m.group_order as u8);
897 buf.put_u8(m.filter_type as u8);
898 if let Some(loc) = &m.start_location {
899 loc.encode(buf);
900 }
901 if let Some(eg) = &m.end_group {
902 eg.encode(buf);
903 }
904 if let Some(eo) = &m.end_object {
905 eo.encode(buf);
906 }
907 encode_parameters(&m.parameters, buf)?;
908 }
909 ControlMessage::SubscribeOk(m) => {
910 m.subscribe_id.encode(buf);
911 m.expires.encode(buf);
912 buf.put_u8(m.group_order as u8);
913 buf.put_u8(m.content_exists as u8);
914 if let Some(gid) = &m.largest_group_id {
915 gid.encode(buf);
916 }
917 if let Some(oid) = &m.largest_object_id {
918 oid.encode(buf);
919 }
920 encode_parameters(&m.parameters, buf)?;
921 }
922 ControlMessage::SubscribeError(m) => {
923 m.subscribe_id.encode(buf);
924 m.error_code.encode(buf);
925 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
926 buf.put_slice(&m.reason_phrase);
927 m.track_alias.encode(buf);
928 }
929 ControlMessage::SubscribeUpdate(m) => {
930 m.subscribe_id.encode(buf);
931 m.start_group.encode(buf);
932 m.start_object.encode(buf);
933 m.end_group.encode(buf);
934 m.end_object.encode(buf);
935 buf.put_u8(m.subscriber_priority);
936 encode_parameters(&m.parameters, buf)?;
937 }
938 ControlMessage::SubscribeDone(m) => {
939 m.subscribe_id.encode(buf);
940 m.status_code.encode(buf);
941 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
942 buf.put_slice(&m.reason_phrase);
943 buf.put_u8(m.content_exists as u8);
944 if let Some(fg) = &m.final_group {
945 fg.encode(buf);
946 }
947 if let Some(fo) = &m.final_object {
948 fo.encode(buf);
949 }
950 }
951 ControlMessage::Unsubscribe(m) => {
952 m.subscribe_id.encode(buf);
953 }
954 ControlMessage::Announce(m) => {
955 m.track_namespace.validate(TrackNamespaceRules::for_draft(7))?;
956 m.track_namespace.encode(buf);
957 encode_parameters(&m.parameters, buf)?;
958 }
959 ControlMessage::AnnounceOk(m) => {
960 m.track_namespace.validate(TrackNamespaceRules::for_draft(7))?;
961 m.track_namespace.encode(buf);
962 }
963 ControlMessage::AnnounceError(m) => {
964 m.track_namespace.validate(TrackNamespaceRules::for_draft(7))?;
965 m.track_namespace.encode(buf);
966 m.error_code.encode(buf);
967 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
968 buf.put_slice(&m.reason_phrase);
969 }
970 ControlMessage::AnnounceCancel(m) => {
971 m.track_namespace.validate(TrackNamespaceRules::for_draft(7))?;
972 m.track_namespace.encode(buf);
973 m.error_code.encode(buf);
974 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
975 buf.put_slice(&m.reason_phrase);
976 }
977 ControlMessage::Unannounce(m) => {
978 m.track_namespace.validate(TrackNamespaceRules::for_draft(7))?;
979 m.track_namespace.encode(buf);
980 }
981 ControlMessage::SubscribeAnnounces(m) => {
982 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(7))?;
983 m.track_namespace_prefix.encode(buf);
984 encode_parameters(&m.parameters, buf)?;
985 }
986 ControlMessage::SubscribeAnnouncesOk(m) => {
987 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(7))?;
988 m.track_namespace_prefix.encode(buf);
989 }
990 ControlMessage::SubscribeAnnouncesError(m) => {
991 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(7))?;
992 m.track_namespace_prefix.encode(buf);
993 m.error_code.encode(buf);
994 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
995 buf.put_slice(&m.reason_phrase);
996 }
997 ControlMessage::UnsubscribeAnnounces(m) => {
998 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(7))?;
999 m.track_namespace_prefix.encode(buf);
1000 }
1001 ControlMessage::TrackStatusRequest(m) => {
1002 m.track_namespace.validate(TrackNamespaceRules::for_draft(7))?;
1003 m.track_namespace.encode(buf);
1004 VarInt::from_usize(m.track_name.len()).encode(buf);
1005 buf.put_slice(&m.track_name);
1006 }
1007 ControlMessage::TrackStatus(m) => {
1008 m.track_namespace.validate(TrackNamespaceRules::for_draft(7))?;
1009 m.track_namespace.encode(buf);
1010 VarInt::from_usize(m.track_name.len()).encode(buf);
1011 buf.put_slice(&m.track_name);
1012 check_track_status(m.status_code, m.last_group_id, m.last_object_id)?;
1013 m.status_code.encode(buf);
1014 m.last_group_id.encode(buf);
1015 m.last_object_id.encode(buf);
1016 }
1017 ControlMessage::Fetch(m) => {
1018 m.subscribe_id.encode(buf);
1019 m.track_namespace.validate(TrackNamespaceRules::for_draft(7))?;
1020 m.track_namespace.encode(buf);
1021 VarInt::from_usize(m.track_name.len()).encode(buf);
1022 buf.put_slice(&m.track_name);
1023 buf.put_u8(m.subscriber_priority);
1024 buf.put_u8(m.group_order as u8);
1025 m.start_group.encode(buf);
1026 m.start_object.encode(buf);
1027 m.end_group.encode(buf);
1028 m.end_object.encode(buf);
1029 encode_parameters(&m.parameters, buf)?;
1030 }
1031 ControlMessage::FetchOk(m) => {
1032 m.subscribe_id.encode(buf);
1033 buf.put_u8(m.group_order as u8);
1034 buf.put_u8(m.end_of_track);
1035 if let Some(gid) = &m.largest_group_id {
1036 gid.encode(buf);
1037 }
1038 if let Some(oid) = &m.largest_object_id {
1039 oid.encode(buf);
1040 }
1041 encode_parameters(&m.parameters, buf)?;
1042 }
1043 ControlMessage::FetchError(m) => {
1044 m.subscribe_id.encode(buf);
1045 m.error_code.encode(buf);
1046 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1047 buf.put_slice(&m.reason_phrase);
1048 }
1049 ControlMessage::FetchCancel(m) => {
1050 m.subscribe_id.encode(buf);
1051 }
1052 }
1053 Ok(())
1054 }
1055
1056 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1057 match msg_type {
1058 MessageType::ClientSetup => {
1059 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1060 if num_versions == 0 {
1070 return Err(CodecError::InvalidField);
1071 }
1072 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1073 for _ in 0..num_versions {
1074 supported_versions.push(VarInt::decode(buf)?);
1075 }
1076 let parameters = decode_setup_parameters(buf)?;
1077 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1078 }
1079 MessageType::ServerSetup => {
1080 let selected_version = VarInt::decode(buf)?;
1081 let parameters = decode_setup_parameters(buf)?;
1082 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1083 }
1084 MessageType::GoAway => {
1085 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1086 let uri = read_bytes(buf, uri_len)?;
1087 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1088 }
1089 MessageType::MaxSubscribeId => {
1090 let subscribe_id = VarInt::decode(buf)?;
1091 Ok(ControlMessage::MaxSubscribeId(MaxSubscribeId { subscribe_id }))
1092 }
1093 MessageType::Subscribe => {
1094 let subscribe_id = VarInt::decode(buf)?;
1095 let track_alias = VarInt::decode(buf)?;
1096 let track_namespace = TrackNamespace::decode(buf)?;
1097 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1098 let track_name = read_bytes(buf, track_name_len)?;
1099 if buf.remaining() < 3 {
1100 return Err(CodecError::UnexpectedEnd);
1101 }
1102 let subscriber_priority = buf.get_u8();
1103 let group_order =
1104 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1105 let filter_val = buf.get_u8();
1106 let filter_type = FilterType::from_u8(filter_val)
1107 .ok_or(CodecError::InvalidFilterType(filter_val as u64))?;
1108 let start_location = match filter_type {
1109 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1110 Some(Location::decode(buf)?)
1111 }
1112 _ => None,
1113 };
1114 let (end_group, end_object) = match filter_type {
1115 FilterType::AbsoluteRange => {
1116 let eg = VarInt::decode(buf)?;
1117 let eo = VarInt::decode(buf)?;
1118 (Some(eg), Some(eo))
1119 }
1120 _ => (None, None),
1121 };
1122 let parameters = decode_parameters(buf)?;
1123 Ok(ControlMessage::Subscribe(Subscribe {
1124 subscribe_id,
1125 track_alias,
1126 track_namespace,
1127 track_name,
1128 subscriber_priority,
1129 group_order,
1130 filter_type,
1131 start_location,
1132 end_group,
1133 end_object,
1134 parameters,
1135 }))
1136 }
1137 MessageType::SubscribeOk => {
1138 let subscribe_id = VarInt::decode(buf)?;
1139 let expires = VarInt::decode(buf)?;
1140 if buf.remaining() < 2 {
1141 return Err(CodecError::UnexpectedEnd);
1142 }
1143 let group_order = read_group_order_response(buf)?;
1144 let content_exists_val = buf.get_u8();
1145 let content_exists = match content_exists_val {
1146 0 => ContentExists::NoLargestLocation,
1147 1 => ContentExists::HasLargestLocation,
1148 other => return Err(CodecError::InvalidContentExists(other)),
1149 };
1150 let (largest_group_id, largest_object_id) =
1151 if content_exists == ContentExists::HasLargestLocation {
1152 let gid = VarInt::decode(buf)?;
1153 let oid = VarInt::decode(buf)?;
1154 (Some(gid), Some(oid))
1155 } else {
1156 (None, None)
1157 };
1158 let parameters = decode_parameters(buf)?;
1159 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1160 subscribe_id,
1161 expires,
1162 group_order,
1163 content_exists,
1164 largest_group_id,
1165 largest_object_id,
1166 parameters,
1167 }))
1168 }
1169 MessageType::SubscribeError => {
1170 let subscribe_id = VarInt::decode(buf)?;
1171 let error_code = VarInt::decode(buf)?;
1172 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1173 let reason_phrase = read_bytes(buf, reason_len)?;
1174 let track_alias = VarInt::decode(buf)?;
1175 Ok(ControlMessage::SubscribeError(SubscribeError {
1176 subscribe_id,
1177 error_code,
1178 reason_phrase,
1179 track_alias,
1180 }))
1181 }
1182 MessageType::SubscribeUpdate => {
1183 let subscribe_id = VarInt::decode(buf)?;
1184 let start_group = VarInt::decode(buf)?;
1185 let start_object = VarInt::decode(buf)?;
1186 let end_group = VarInt::decode(buf)?;
1187 let end_object = VarInt::decode(buf)?;
1188 if buf.remaining() < 1 {
1189 return Err(CodecError::UnexpectedEnd);
1190 }
1191 let subscriber_priority = buf.get_u8();
1192 let parameters = decode_parameters(buf)?;
1193 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1194 subscribe_id,
1195 start_group,
1196 start_object,
1197 end_group,
1198 end_object,
1199 subscriber_priority,
1200 parameters,
1201 }))
1202 }
1203 MessageType::SubscribeDone => {
1204 let subscribe_id = VarInt::decode(buf)?;
1205 let status_code = VarInt::decode(buf)?;
1206 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1207 let reason_phrase = read_bytes(buf, reason_len)?;
1208 if buf.remaining() < 1 {
1209 return Err(CodecError::UnexpectedEnd);
1210 }
1211 let content_exists_val = buf.get_u8();
1212 let content_exists = match content_exists_val {
1213 0 => ContentExists::NoLargestLocation,
1214 1 => ContentExists::HasLargestLocation,
1215 other => return Err(CodecError::InvalidContentExists(other)),
1216 };
1217 let (final_group, final_object) =
1218 if content_exists == ContentExists::HasLargestLocation {
1219 let fg = VarInt::decode(buf)?;
1220 let fo = VarInt::decode(buf)?;
1221 (Some(fg), Some(fo))
1222 } else {
1223 (None, None)
1224 };
1225 Ok(ControlMessage::SubscribeDone(SubscribeDone {
1226 subscribe_id,
1227 status_code,
1228 reason_phrase,
1229 content_exists,
1230 final_group,
1231 final_object,
1232 }))
1233 }
1234 MessageType::Unsubscribe => {
1235 let subscribe_id = VarInt::decode(buf)?;
1236 Ok(ControlMessage::Unsubscribe(Unsubscribe { subscribe_id }))
1237 }
1238 MessageType::Announce => {
1239 let track_namespace = TrackNamespace::decode(buf)?;
1240 let parameters = decode_parameters(buf)?;
1241 Ok(ControlMessage::Announce(Announce { track_namespace, parameters }))
1242 }
1243 MessageType::AnnounceOk => {
1244 let track_namespace = TrackNamespace::decode(buf)?;
1245 Ok(ControlMessage::AnnounceOk(AnnounceOk { track_namespace }))
1246 }
1247 MessageType::AnnounceError => {
1248 let track_namespace = TrackNamespace::decode(buf)?;
1249 let error_code = VarInt::decode(buf)?;
1250 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1251 let reason_phrase = read_bytes(buf, reason_len)?;
1252 Ok(ControlMessage::AnnounceError(AnnounceError {
1253 track_namespace,
1254 error_code,
1255 reason_phrase,
1256 }))
1257 }
1258 MessageType::AnnounceCancel => {
1259 let track_namespace = TrackNamespace::decode(buf)?;
1260 let error_code = 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::AnnounceCancel(AnnounceCancel {
1264 track_namespace,
1265 error_code,
1266 reason_phrase,
1267 }))
1268 }
1269 MessageType::Unannounce => {
1270 let track_namespace = TrackNamespace::decode(buf)?;
1271 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1272 }
1273 MessageType::SubscribeAnnounces => {
1274 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1275 let parameters = decode_parameters(buf)?;
1276 Ok(ControlMessage::SubscribeAnnounces(SubscribeAnnounces {
1277 track_namespace_prefix,
1278 parameters,
1279 }))
1280 }
1281 MessageType::SubscribeAnnouncesOk => {
1282 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1283 Ok(ControlMessage::SubscribeAnnouncesOk(SubscribeAnnouncesOk {
1284 track_namespace_prefix,
1285 }))
1286 }
1287 MessageType::SubscribeAnnouncesError => {
1288 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1289 let error_code = VarInt::decode(buf)?;
1290 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1291 let reason_phrase = read_bytes(buf, reason_len)?;
1292 Ok(ControlMessage::SubscribeAnnouncesError(SubscribeAnnouncesError {
1293 track_namespace_prefix,
1294 error_code,
1295 reason_phrase,
1296 }))
1297 }
1298 MessageType::UnsubscribeAnnounces => {
1299 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1300 Ok(ControlMessage::UnsubscribeAnnounces(UnsubscribeAnnounces {
1301 track_namespace_prefix,
1302 }))
1303 }
1304 MessageType::TrackStatusRequest => {
1305 let track_namespace = TrackNamespace::decode(buf)?;
1306 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1307 let track_name = read_bytes(buf, track_name_len)?;
1308 Ok(ControlMessage::TrackStatusRequest(TrackStatusRequest {
1309 track_namespace,
1310 track_name,
1311 }))
1312 }
1313 MessageType::TrackStatus => {
1314 let track_namespace = TrackNamespace::decode(buf)?;
1315 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1316 let track_name = read_bytes(buf, track_name_len)?;
1317 let status_code = VarInt::decode(buf)?;
1318 let last_group_id = VarInt::decode(buf)?;
1319 let last_object_id = VarInt::decode(buf)?;
1320 check_track_status(status_code, last_group_id, last_object_id)?;
1321 Ok(ControlMessage::TrackStatus(TrackStatus {
1322 track_namespace,
1323 track_name,
1324 status_code,
1325 last_group_id,
1326 last_object_id,
1327 }))
1328 }
1329 MessageType::Fetch => {
1330 let subscribe_id = VarInt::decode(buf)?;
1331 let track_namespace = TrackNamespace::decode(buf)?;
1332 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1333 let track_name = read_bytes(buf, track_name_len)?;
1334 if buf.remaining() < 2 {
1335 return Err(CodecError::UnexpectedEnd);
1336 }
1337 let subscriber_priority = buf.get_u8();
1338 let group_order =
1339 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1340 let start_group = VarInt::decode(buf)?;
1341 let start_object = VarInt::decode(buf)?;
1342 let end_group = VarInt::decode(buf)?;
1343 let end_object = VarInt::decode(buf)?;
1344 let parameters = decode_parameters(buf)?;
1345 Ok(ControlMessage::Fetch(Fetch {
1346 subscribe_id,
1347 track_namespace,
1348 track_name,
1349 subscriber_priority,
1350 group_order,
1351 start_group,
1352 start_object,
1353 end_group,
1354 end_object,
1355 parameters,
1356 }))
1357 }
1358 MessageType::FetchOk => {
1359 let subscribe_id = VarInt::decode(buf)?;
1360 if buf.remaining() < 2 {
1361 return Err(CodecError::UnexpectedEnd);
1362 }
1363 let group_order = read_group_order_response(buf)?;
1364 let end_of_track = buf.get_u8();
1365 let largest_group_id = Some(VarInt::decode(buf)?);
1366 let largest_object_id = Some(VarInt::decode(buf)?);
1367 let parameters = decode_parameters(buf)?;
1368 Ok(ControlMessage::FetchOk(FetchOk {
1369 subscribe_id,
1370 group_order,
1371 end_of_track,
1372 largest_group_id,
1373 largest_object_id,
1374 parameters,
1375 }))
1376 }
1377 MessageType::FetchError => {
1378 let subscribe_id = VarInt::decode(buf)?;
1379 let error_code = VarInt::decode(buf)?;
1380 let reason_len = VarInt::decode(buf)?.into_inner() as usize;
1381 let reason_phrase = read_bytes(buf, reason_len)?;
1382 Ok(ControlMessage::FetchError(FetchError {
1383 subscribe_id,
1384 error_code,
1385 reason_phrase,
1386 }))
1387 }
1388 MessageType::FetchCancel => {
1389 let subscribe_id = VarInt::decode(buf)?;
1390 Ok(ControlMessage::FetchCancel(FetchCancel { subscribe_id }))
1391 }
1392 }
1393 }
1394}