1use crate::auth_token::{AuthorizationToken, AUTH_TOKEN_PARAMETER_D11};
23use crate::error::{
24 CodecError, MAX_FULL_TRACK_NAME_LENGTH, MAX_GOAWAY_URI_LENGTH, MAX_MESSAGE_LENGTH,
25 MAX_REASON_PHRASE_LENGTH,
26};
27use crate::kvp::{KeyValuePair, KvpValue};
28use crate::types::{self, *};
29pub use crate::types::{check_group_range, check_location_range, check_open_ended_group_range};
30use crate::varint::VarInt;
31use bytes::{Buf, BufMut};
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35#[repr(u64)]
36pub enum MessageType {
37 SubscribeUpdate = 0x02,
39 Subscribe = 0x03,
41 SubscribeOk = 0x04,
43 SubscribeError = 0x05,
45 Announce = 0x06,
47 AnnounceOk = 0x07,
49 AnnounceError = 0x08,
51 Unannounce = 0x09,
53 Unsubscribe = 0x0A,
55 SubscribeDone = 0x0B,
57 AnnounceCancel = 0x0C,
59 TrackStatusRequest = 0x0D,
61 TrackStatus = 0x0E,
63 GoAway = 0x10,
65 SubscribeAnnounces = 0x11,
67 SubscribeAnnouncesOk = 0x12,
69 SubscribeAnnouncesError = 0x13,
71 UnsubscribeAnnounces = 0x14,
73 MaxRequestId = 0x15,
75 Fetch = 0x16,
77 FetchCancel = 0x17,
79 FetchOk = 0x18,
81 FetchError = 0x19,
83 RequestsBlocked = 0x1A,
85 ClientSetup = 0x20,
87 ServerSetup = 0x21,
89}
90
91impl MessageType {
92 pub fn from_id(id: u64) -> Option<Self> {
94 match id {
95 0x02 => Some(MessageType::SubscribeUpdate),
96 0x03 => Some(MessageType::Subscribe),
97 0x04 => Some(MessageType::SubscribeOk),
98 0x05 => Some(MessageType::SubscribeError),
99 0x06 => Some(MessageType::Announce),
100 0x07 => Some(MessageType::AnnounceOk),
101 0x08 => Some(MessageType::AnnounceError),
102 0x09 => Some(MessageType::Unannounce),
103 0x0A => Some(MessageType::Unsubscribe),
104 0x0B => Some(MessageType::SubscribeDone),
105 0x0C => Some(MessageType::AnnounceCancel),
106 0x0D => Some(MessageType::TrackStatusRequest),
107 0x0E => Some(MessageType::TrackStatus),
108 0x10 => Some(MessageType::GoAway),
109 0x11 => Some(MessageType::SubscribeAnnounces),
110 0x12 => Some(MessageType::SubscribeAnnouncesOk),
111 0x13 => Some(MessageType::SubscribeAnnouncesError),
112 0x14 => Some(MessageType::UnsubscribeAnnounces),
113 0x15 => Some(MessageType::MaxRequestId),
114 0x16 => Some(MessageType::Fetch),
115 0x17 => Some(MessageType::FetchCancel),
116 0x18 => Some(MessageType::FetchOk),
117 0x19 => Some(MessageType::FetchError),
118 0x1A => Some(MessageType::RequestsBlocked),
119 0x20 => Some(MessageType::ClientSetup),
120 0x21 => Some(MessageType::ServerSetup),
121 _ => None,
122 }
123 }
124
125 pub fn id(&self) -> u64 {
127 *self as u64
128 }
129}
130
131#[derive(Debug, Clone, PartialEq, Eq)]
137pub struct ClientSetup {
138 pub supported_versions: Vec<VarInt>,
140 pub parameters: Vec<KeyValuePair>,
142}
143
144#[derive(Debug, Clone, PartialEq, Eq)]
146pub struct ServerSetup {
147 pub selected_version: VarInt,
149 pub parameters: Vec<KeyValuePair>,
151}
152
153#[derive(Debug, Clone, PartialEq, Eq)]
155pub struct GoAway {
156 pub new_session_uri: Vec<u8>,
158}
159
160#[derive(Debug, Clone, PartialEq, Eq)]
162pub struct MaxRequestId {
163 pub request_id: VarInt,
165}
166
167#[derive(Debug, Clone, PartialEq, Eq)]
169pub struct RequestsBlocked {
170 pub maximum_request_id: VarInt,
172}
173
174#[derive(Debug, Clone, PartialEq, Eq)]
180pub struct Subscribe {
181 pub request_id: VarInt,
183 pub track_alias: VarInt,
185 pub track_namespace: TrackNamespace,
187 pub track_name: Vec<u8>,
189 pub subscriber_priority: u8,
191 pub group_order: GroupOrder,
193 pub forward: Forward,
195 pub filter_type: VarInt,
197 pub start_group: Option<VarInt>,
199 pub start_object: Option<VarInt>,
201 pub end_group: Option<VarInt>,
203 pub parameters: Vec<KeyValuePair>,
205}
206
207#[derive(Debug, Clone, PartialEq, Eq)]
209pub struct SubscribeOk {
210 pub request_id: VarInt,
212 pub expires: VarInt,
214 pub group_order: GroupOrder,
216 pub content_exists: ContentExists,
218 pub largest_location: Option<Location>,
220 pub parameters: Vec<KeyValuePair>,
222}
223
224#[derive(Debug, Clone, PartialEq, Eq)]
226pub struct SubscribeError {
227 pub request_id: VarInt,
229 pub error_code: VarInt,
231 pub reason_phrase: Vec<u8>,
233 pub track_alias: VarInt,
235}
236
237#[derive(Debug, Clone, PartialEq, Eq)]
239pub struct SubscribeUpdate {
240 pub request_id: VarInt,
242 pub start_group: VarInt,
244 pub start_object: VarInt,
246 pub end_group: VarInt,
248 pub subscriber_priority: u8,
250 pub forward: Forward,
252 pub parameters: Vec<KeyValuePair>,
254}
255
256#[derive(Debug, Clone, PartialEq, Eq)]
258pub struct SubscribeDone {
259 pub request_id: VarInt,
261 pub status_code: VarInt,
263 pub stream_count: VarInt,
265 pub reason_phrase: Vec<u8>,
267}
268
269#[derive(Debug, Clone, PartialEq, Eq)]
271pub struct Unsubscribe {
272 pub request_id: VarInt,
274}
275
276#[derive(Debug, Clone, PartialEq, Eq)]
282pub struct Announce {
283 pub request_id: VarInt,
285 pub track_namespace: TrackNamespace,
287 pub parameters: Vec<KeyValuePair>,
289}
290
291#[derive(Debug, Clone, PartialEq, Eq)]
293pub struct AnnounceOk {
294 pub request_id: VarInt,
296}
297
298#[derive(Debug, Clone, PartialEq, Eq)]
300pub struct AnnounceError {
301 pub request_id: VarInt,
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 request_id: VarInt,
336 pub track_namespace_prefix: TrackNamespace,
338 pub parameters: Vec<KeyValuePair>,
340}
341
342#[derive(Debug, Clone, PartialEq, Eq)]
344pub struct SubscribeAnnouncesOk {
345 pub request_id: VarInt,
347}
348
349#[derive(Debug, Clone, PartialEq, Eq)]
351pub struct SubscribeAnnouncesError {
352 pub request_id: VarInt,
354 pub error_code: VarInt,
356 pub reason_phrase: Vec<u8>,
358}
359
360#[derive(Debug, Clone, PartialEq, Eq)]
362pub struct UnsubscribeAnnounces {
363 pub track_namespace_prefix: TrackNamespace,
365}
366
367#[derive(Debug, Clone, PartialEq, Eq)]
373pub struct TrackStatusRequest {
374 pub request_id: VarInt,
376 pub track_namespace: TrackNamespace,
378 pub track_name: Vec<u8>,
380 pub parameters: Vec<KeyValuePair>,
382}
383
384#[derive(Debug, Clone, PartialEq, Eq)]
386pub struct TrackStatus {
387 pub request_id: VarInt,
389 pub status_code: VarInt,
391 pub largest_location: Location,
393 pub parameters: Vec<KeyValuePair>,
395}
396
397#[derive(Debug, Clone, Copy, PartialEq, Eq)]
403#[repr(u64)]
404pub enum FetchType {
405 Standalone = 1,
407 RelativeJoining = 2,
409 AbsoluteJoining = 3,
411}
412
413impl FetchType {
414 pub fn from_u64(v: u64) -> Option<Self> {
416 match v {
417 1 => Some(FetchType::Standalone),
418 2 => Some(FetchType::RelativeJoining),
419 3 => Some(FetchType::AbsoluteJoining),
420 _ => None,
421 }
422 }
423}
424
425#[derive(Debug, Clone, PartialEq, Eq)]
427pub struct Fetch {
428 pub request_id: VarInt,
430 pub subscriber_priority: u8,
432 pub group_order: GroupOrder,
434 pub fetch_type: FetchType,
436 pub fetch_payload: FetchPayload,
438 pub parameters: Vec<KeyValuePair>,
440}
441
442#[derive(Debug, Clone, PartialEq, Eq)]
444pub enum FetchPayload {
445 Standalone {
447 track_namespace: TrackNamespace,
449 track_name: Vec<u8>,
451 start_group: VarInt,
453 start_object: VarInt,
455 end_group: VarInt,
457 end_object: VarInt,
459 },
460 Joining {
462 joining_subscribe_id: VarInt,
464 joining_start: VarInt,
466 },
467}
468
469#[derive(Debug, Clone, PartialEq, Eq)]
471pub struct FetchOk {
472 pub request_id: VarInt,
474 pub group_order: GroupOrder,
476 pub end_of_track: u8,
483 pub end_location: Location,
485 pub parameters: Vec<KeyValuePair>,
487}
488
489#[derive(Debug, Clone, PartialEq, Eq)]
491pub struct FetchError {
492 pub request_id: VarInt,
494 pub error_code: VarInt,
496 pub reason_phrase: Vec<u8>,
498}
499
500#[derive(Debug, Clone, PartialEq, Eq)]
502pub struct FetchCancel {
503 pub request_id: VarInt,
505}
506
507fn read_u8(buf: &mut impl Buf) -> Result<u8, CodecError> {
513 if !buf.has_remaining() {
514 return Err(CodecError::UnexpectedEnd);
515 }
516 Ok(buf.get_u8())
517}
518
519fn read_group_order(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
531 GroupOrder::from_u8(read_u8(buf)?).ok_or(CodecError::InvalidField)
532}
533
534fn read_forward(buf: &mut impl Buf) -> Result<Forward, CodecError> {
537 match read_u8(buf)? {
538 0 => Ok(Forward::DontForward),
539 1 => Ok(Forward::Forward),
540 other => Err(CodecError::InvalidForward(other)),
541 }
542}
543
544fn read_content_exists(buf: &mut impl Buf) -> Result<ContentExists, CodecError> {
547 match read_u8(buf)? {
548 0 => Ok(ContentExists::NoLargestLocation),
549 1 => Ok(ContentExists::HasLargestLocation),
550 other => Err(CodecError::InvalidContentExists(other)),
551 }
552}
553
554fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
565 if !buf.has_remaining() {
566 return Err(CodecError::UnexpectedEnd);
567 }
568 match GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)? {
569 GroupOrder::Publisher => Err(CodecError::InvalidField),
570 order => Ok(order),
571 }
572}
573
574fn check_filter(
578 filter_type: VarInt,
579 start_group: &Option<VarInt>,
580 start_object: &Option<VarInt>,
581 end_group: &Option<VarInt>,
582) -> Result<(), CodecError> {
583 let value = filter_type.into_inner();
584 if value == 0 || value > 4 {
585 return Err(CodecError::InvalidFilterType(value));
586 }
587 let wants_start = value == 3 || value == 4;
588 if wants_start != start_group.is_some() || wants_start != start_object.is_some() {
589 return Err(CodecError::InvalidField);
590 }
591 if (value == 4) != end_group.is_some() {
592 return Err(CodecError::InvalidField);
593 }
594 Ok(())
595}
596
597fn check_content(
598 content_exists: ContentExists,
599 largest_location: &Option<Location>,
600) -> Result<(), CodecError> {
601 if (content_exists == ContentExists::HasLargestLocation) != largest_location.is_some() {
602 return Err(CodecError::InvalidField);
603 }
604 Ok(())
605}
606
607fn check_track_status(status_code: VarInt, largest_location: Location) -> Result<(), CodecError> {
618 let code = crate::draft11::error_codes::TrackStatusCode::from_u64(status_code.into_inner())
619 .ok_or(CodecError::InvalidField)?;
620 if code.requires_zero_location()
621 && (largest_location.group.into_inner() != 0 || largest_location.object.into_inner() != 0)
622 {
623 return Err(CodecError::InvalidField);
624 }
625 Ok(())
626}
627
628fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
639 match message {
640 ControlMessage::Subscribe(m) => {
641 check_filter(m.filter_type, &m.start_group, &m.start_object, &m.end_group)
642 }
643 ControlMessage::SubscribeOk(m) => check_content(m.content_exists, &m.largest_location),
644 ControlMessage::Fetch(m) => {
645 let body_is_standalone = matches!(m.fetch_payload, FetchPayload::Standalone { .. });
646 if body_is_standalone != (m.fetch_type == FetchType::Standalone) {
647 return Err(CodecError::InvalidField);
648 }
649 Ok(())
650 }
651 _ => Ok(()),
652 }
653}
654
655fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
660 let order = match message {
661 ControlMessage::SubscribeOk(m) => m.group_order,
662 ControlMessage::FetchOk(m) => m.group_order,
663 _ => return Ok(()),
664 };
665 if order == GroupOrder::Publisher {
666 return Err(CodecError::InvalidField);
667 }
668 Ok(())
669}
670
671#[derive(Debug, Clone, PartialEq, Eq)]
673pub enum ControlMessage {
674 ClientSetup(ClientSetup),
676 ServerSetup(ServerSetup),
678 GoAway(GoAway),
680 MaxRequestId(MaxRequestId),
682 RequestsBlocked(RequestsBlocked),
684 Subscribe(Subscribe),
686 SubscribeOk(SubscribeOk),
688 SubscribeError(SubscribeError),
690 SubscribeUpdate(SubscribeUpdate),
692 SubscribeDone(SubscribeDone),
694 Unsubscribe(Unsubscribe),
696 Announce(Announce),
698 AnnounceOk(AnnounceOk),
700 AnnounceError(AnnounceError),
702 AnnounceCancel(AnnounceCancel),
704 Unannounce(Unannounce),
706 SubscribeAnnounces(SubscribeAnnounces),
708 SubscribeAnnouncesOk(SubscribeAnnouncesOk),
710 SubscribeAnnouncesError(SubscribeAnnouncesError),
712 UnsubscribeAnnounces(UnsubscribeAnnounces),
714 TrackStatusRequest(TrackStatusRequest),
716 TrackStatus(TrackStatus),
718 Fetch(Fetch),
720 FetchOk(FetchOk),
722 FetchError(FetchError),
724 FetchCancel(FetchCancel),
726}
727
728fn check_full_track_name(namespace: &TrackNamespace, track_name: &[u8]) -> Result<(), CodecError> {
729 let total = namespace.field_bytes_len().saturating_add(track_name.len());
730 if total > MAX_FULL_TRACK_NAME_LENGTH {
731 return Err(CodecError::TrackNameTooLong);
732 }
733 Ok(())
734}
735
736fn read_reason_phrase(buf: &mut impl Buf) -> Result<Vec<u8>, CodecError> {
744 let len = VarInt::decode(buf)?.into_inner() as usize;
745 if len > MAX_REASON_PHRASE_LENGTH {
746 return Err(CodecError::ReasonPhraseTooLong);
747 }
748 types::read_bytes(buf, len)
749}
750
751fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
765 match message {
766 ControlMessage::Subscribe(m) => match (&m.start_group, &m.end_group) {
767 (Some(start_group), Some(end_group)) => {
768 check_group_range(start_group.into_inner(), end_group.into_inner())
769 }
770 _ => Ok(()),
771 },
772 ControlMessage::SubscribeUpdate(m) => {
773 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
774 }
775 ControlMessage::Fetch(m) => match &m.fetch_payload {
776 FetchPayload::Standalone {
777 start_group, start_object, end_group, end_object, ..
778 } => check_location_range(
779 start_group.into_inner(),
780 start_object.into_inner(),
781 end_group.into_inner(),
782 end_object.into_inner(),
783 ),
784 FetchPayload::Joining { .. } => Ok(()),
785 },
786 _ => Ok(()),
787 }
788}
789
790const AUTHORIZATION_TOKEN: u64 = 0x01;
797
798const DELIVERY_TIMEOUT: u64 = 0x02;
800
801const MAX_CACHE_DURATION: u64 = 0x04;
803
804const SETUP_PATH: u64 = 0x01;
806
807const SETUP_MAX_REQUEST_ID: u64 = 0x02;
809
810const SETUP_MAX_AUTH_TOKEN_CACHE_SIZE: u64 = 0x04;
812
813const KNOWN_PARAMETERS: &[u64] = &[AUTHORIZATION_TOKEN, DELIVERY_TIMEOUT, MAX_CACHE_DURATION];
819
820const REPEATABLE_PARAMETERS: &[u64] = &[AUTHORIZATION_TOKEN];
826
827const KNOWN_SETUP_PARAMETERS: &[u64] =
829 &[SETUP_PATH, SETUP_MAX_REQUEST_ID, SETUP_MAX_AUTH_TOKEN_CACHE_SIZE];
830
831const REPEATABLE_SETUP_PARAMETERS: &[u64] = &[];
843
844fn check_sender_parameters(
858 parameters: &[KeyValuePair],
859 repeatable: &[u64],
860) -> Result<(), CodecError> {
861 for (i, parameter) in parameters.iter().enumerate() {
862 let key = parameter.key.into_inner();
863 if repeatable.contains(&key) {
864 continue;
865 }
866 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
867 return Err(CodecError::DuplicateParameter(key));
868 }
869 }
870 Ok(())
871}
872
873fn check_receiver_parameters(
887 parameters: &[KeyValuePair],
888 known: &[u64],
889 repeatable: &[u64],
890) -> Result<(), CodecError> {
891 for (i, parameter) in parameters.iter().enumerate() {
892 let key = parameter.key.into_inner();
893 if repeatable.contains(&key) || !known.contains(&key) {
894 continue;
895 }
896 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
897 return Err(CodecError::DuplicateParameter(key));
898 }
899 }
900 Ok(())
901}
902
903fn check_authorization_tokens(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
921 for parameter in parameters {
922 let key = parameter.key.into_inner();
923 if key != AUTH_TOKEN_PARAMETER_D11 {
924 continue;
925 }
926 match ¶meter.value {
927 KvpValue::Bytes(value) => {
928 AuthorizationToken::decode(key, value)?;
929 }
930 KvpValue::Varint(_) => {
935 return Err(CodecError::KeyValueFormatting {
936 key,
937 detail: "its value is a bare varint where the type defines a Token structure",
938 });
939 }
940 }
941 }
942 Ok(())
943}
944
945fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
947 let parameters = KeyValuePair::decode_list(buf)?;
948 check_receiver_parameters(¶meters, KNOWN_PARAMETERS, REPEATABLE_PARAMETERS)?;
949 check_authorization_tokens(¶meters)?;
950 Ok(parameters)
951}
952
953fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
963 check_sender_parameters(parameters, REPEATABLE_PARAMETERS)?;
964 check_authorization_tokens(parameters)?;
965 KeyValuePair::encode_list_checked(parameters, buf)?;
966 Ok(())
967}
968
969fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
971 let parameters = KeyValuePair::decode_list(buf)?;
972 check_receiver_parameters(¶meters, KNOWN_SETUP_PARAMETERS, REPEATABLE_SETUP_PARAMETERS)?;
973 Ok(parameters)
974}
975
976fn encode_setup_parameters(
978 parameters: &[KeyValuePair],
979 buf: &mut impl BufMut,
980) -> Result<(), CodecError> {
981 check_sender_parameters(parameters, REPEATABLE_SETUP_PARAMETERS)?;
982 KeyValuePair::encode_list_checked(parameters, buf)?;
983 Ok(())
984}
985
986impl ControlMessage {
987 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
991 check_discriminators(self)?;
992 check_group_order(self)?;
993 check_ranges(self)?;
994 let mut payload = Vec::with_capacity(256);
995 self.encode_payload(&mut payload)?;
996
997 if payload.len() > MAX_MESSAGE_LENGTH {
998 return Err(CodecError::MessageTooLong(payload.len()));
999 }
1000
1001 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
1002 buf.put_u16(payload.len() as u16);
1004 buf.put_slice(&payload);
1005 Ok(())
1006 }
1007
1008 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
1012 let type_id = VarInt::decode(buf)?.into_inner();
1013 let msg_type =
1014 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
1015 if buf.remaining() < 2 {
1017 return Err(CodecError::UnexpectedEnd);
1018 }
1019 let payload_len = buf.get_u16() as usize;
1020 if buf.remaining() < payload_len {
1021 return Err(CodecError::UnexpectedEnd);
1022 }
1023 let payload_bytes = buf.copy_to_bytes(payload_len);
1024 let mut payload = &payload_bytes[..];
1025 let msg = match Self::decode_payload(msg_type, &mut payload) {
1026 Ok(msg) => msg,
1027 Err(
1033 CodecError::UnexpectedEnd
1034 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
1035 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
1036 crate::varint::VarIntError::UnexpectedEnd,
1037 ))
1038 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
1039 ) => {
1040 return Err(CodecError::ControlMessageLengthMismatch {
1041 declared: payload_len,
1042 detail: "its fields ran past the end",
1043 });
1044 }
1045 Err(e) => return Err(e),
1046 };
1047 check_ranges(&msg)?;
1048 if payload.has_remaining() {
1053 return Err(CodecError::ControlMessageLengthMismatch {
1054 declared: payload_len,
1055 detail: "its fields left bytes unread",
1056 });
1057 }
1058 Ok(msg)
1059 }
1060
1061 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
1062 match self {
1063 ControlMessage::ClientSetup(m) => {
1064 VarInt::from_usize(m.supported_versions.len()).encode(buf);
1065 for v in &m.supported_versions {
1066 v.encode(buf);
1067 }
1068 encode_setup_parameters(&m.parameters, buf)?;
1069 }
1070 ControlMessage::ServerSetup(m) => {
1071 m.selected_version.encode(buf);
1072 encode_setup_parameters(&m.parameters, buf)?;
1073 }
1074 ControlMessage::GoAway(m) => {
1075 if m.new_session_uri.len() > MAX_GOAWAY_URI_LENGTH {
1076 return Err(CodecError::GoAwayUriTooLong);
1077 }
1078 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
1079 buf.put_slice(&m.new_session_uri);
1080 }
1081 ControlMessage::MaxRequestId(m) => {
1082 m.request_id.encode(buf);
1083 }
1084 ControlMessage::RequestsBlocked(m) => {
1085 m.maximum_request_id.encode(buf);
1086 }
1087 ControlMessage::Subscribe(m) => {
1088 m.request_id.encode(buf);
1089 m.track_alias.encode(buf);
1090 m.track_namespace.validate(TrackNamespaceRules::for_draft(11))?;
1091 m.track_namespace.encode(buf);
1092 check_full_track_name(&m.track_namespace, &m.track_name)?;
1093 VarInt::from_usize(m.track_name.len()).encode(buf);
1094 buf.put_slice(&m.track_name);
1095 buf.put_u8(m.subscriber_priority);
1096 buf.put_u8(m.group_order as u8);
1097 buf.put_u8(m.forward as u8);
1098 m.filter_type.encode(buf);
1099 if let Some(sg) = &m.start_group {
1100 sg.encode(buf);
1101 }
1102 if let Some(so) = &m.start_object {
1103 so.encode(buf);
1104 }
1105 if let Some(eg) = &m.end_group {
1106 eg.encode(buf);
1107 }
1108 encode_parameters(&m.parameters, buf)?;
1109 }
1110 ControlMessage::SubscribeOk(m) => {
1111 m.request_id.encode(buf);
1112 m.expires.encode(buf);
1113 buf.put_u8(m.group_order as u8);
1114 buf.put_u8(m.content_exists as u8);
1115 if let Some(loc) = &m.largest_location {
1116 loc.encode(buf);
1117 }
1118 encode_parameters(&m.parameters, buf)?;
1119 }
1120 ControlMessage::SubscribeError(m) => {
1121 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1122 return Err(CodecError::ReasonPhraseTooLong);
1123 }
1124 m.request_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 m.track_alias.encode(buf);
1129 }
1130 ControlMessage::SubscribeUpdate(m) => {
1131 m.request_id.encode(buf);
1132 m.start_group.encode(buf);
1133 m.start_object.encode(buf);
1134 m.end_group.encode(buf);
1135 buf.put_u8(m.subscriber_priority);
1136 buf.put_u8(m.forward as u8);
1137 encode_parameters(&m.parameters, buf)?;
1138 }
1139 ControlMessage::SubscribeDone(m) => {
1140 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1141 return Err(CodecError::ReasonPhraseTooLong);
1142 }
1143 m.request_id.encode(buf);
1144 m.status_code.encode(buf);
1145 m.stream_count.encode(buf);
1146 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1147 buf.put_slice(&m.reason_phrase);
1148 }
1149 ControlMessage::Unsubscribe(m) => {
1150 m.request_id.encode(buf);
1151 }
1152 ControlMessage::Announce(m) => {
1153 m.request_id.encode(buf);
1154 m.track_namespace.validate(TrackNamespaceRules::for_draft(11))?;
1155 m.track_namespace.encode(buf);
1156 encode_parameters(&m.parameters, buf)?;
1157 }
1158 ControlMessage::AnnounceOk(m) => {
1159 m.request_id.encode(buf);
1160 }
1161 ControlMessage::AnnounceError(m) => {
1162 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1163 return Err(CodecError::ReasonPhraseTooLong);
1164 }
1165 m.request_id.encode(buf);
1166 m.error_code.encode(buf);
1167 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1168 buf.put_slice(&m.reason_phrase);
1169 }
1170 ControlMessage::AnnounceCancel(m) => {
1171 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1172 return Err(CodecError::ReasonPhraseTooLong);
1173 }
1174 m.track_namespace.validate(TrackNamespaceRules::for_draft(11))?;
1175 m.track_namespace.encode(buf);
1176 m.error_code.encode(buf);
1177 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1178 buf.put_slice(&m.reason_phrase);
1179 }
1180 ControlMessage::Unannounce(m) => {
1181 m.track_namespace.validate(TrackNamespaceRules::for_draft(11))?;
1182 m.track_namespace.encode(buf);
1183 }
1184 ControlMessage::SubscribeAnnounces(m) => {
1185 m.request_id.encode(buf);
1186 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(11))?;
1187 m.track_namespace_prefix.encode(buf);
1188 encode_parameters(&m.parameters, buf)?;
1189 }
1190 ControlMessage::SubscribeAnnouncesOk(m) => {
1191 m.request_id.encode(buf);
1192 }
1193 ControlMessage::SubscribeAnnouncesError(m) => {
1194 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1195 return Err(CodecError::ReasonPhraseTooLong);
1196 }
1197 m.request_id.encode(buf);
1198 m.error_code.encode(buf);
1199 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1200 buf.put_slice(&m.reason_phrase);
1201 }
1202 ControlMessage::UnsubscribeAnnounces(m) => {
1203 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(11))?;
1204 m.track_namespace_prefix.encode(buf);
1205 }
1206 ControlMessage::TrackStatusRequest(m) => {
1207 m.request_id.encode(buf);
1208 m.track_namespace.validate(TrackNamespaceRules::for_draft(11))?;
1209 m.track_namespace.encode(buf);
1210 check_full_track_name(&m.track_namespace, &m.track_name)?;
1211 VarInt::from_usize(m.track_name.len()).encode(buf);
1212 buf.put_slice(&m.track_name);
1213 encode_parameters(&m.parameters, buf)?;
1214 }
1215 ControlMessage::TrackStatus(m) => {
1216 m.request_id.encode(buf);
1217 check_track_status(m.status_code, m.largest_location)?;
1218 m.status_code.encode(buf);
1219 m.largest_location.encode(buf);
1220 encode_parameters(&m.parameters, buf)?;
1221 }
1222 ControlMessage::Fetch(m) => {
1223 m.request_id.encode(buf);
1224 buf.put_u8(m.subscriber_priority);
1225 buf.put_u8(m.group_order as u8);
1226 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1227 match &m.fetch_payload {
1228 FetchPayload::Standalone {
1229 track_namespace,
1230 track_name,
1231 start_group,
1232 start_object,
1233 end_group,
1234 end_object,
1235 } => {
1236 track_namespace.validate(TrackNamespaceRules::for_draft(11))?;
1237 track_namespace.encode(buf);
1238 check_full_track_name(track_namespace, track_name)?;
1239 VarInt::from_usize(track_name.len()).encode(buf);
1240 buf.put_slice(track_name);
1241 start_group.encode(buf);
1242 start_object.encode(buf);
1243 end_group.encode(buf);
1244 end_object.encode(buf);
1245 }
1246 FetchPayload::Joining { joining_subscribe_id, joining_start } => {
1247 joining_subscribe_id.encode(buf);
1248 joining_start.encode(buf);
1249 }
1250 }
1251 encode_parameters(&m.parameters, buf)?;
1252 }
1253 ControlMessage::FetchOk(m) => {
1254 m.request_id.encode(buf);
1255 buf.put_u8(m.group_order as u8);
1256 buf.put_u8(m.end_of_track);
1257 m.end_location.encode(buf);
1258 encode_parameters(&m.parameters, buf)?;
1259 }
1260 ControlMessage::FetchError(m) => {
1261 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1262 return Err(CodecError::ReasonPhraseTooLong);
1263 }
1264 m.request_id.encode(buf);
1265 m.error_code.encode(buf);
1266 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1267 buf.put_slice(&m.reason_phrase);
1268 }
1269 ControlMessage::FetchCancel(m) => {
1270 m.request_id.encode(buf);
1271 }
1272 }
1273 Ok(())
1274 }
1275
1276 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1277 match msg_type {
1278 MessageType::ClientSetup => {
1279 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1280 if num_versions == 0 {
1290 return Err(CodecError::InvalidField);
1291 }
1292 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1293 for _ in 0..num_versions {
1294 supported_versions.push(VarInt::decode(buf)?);
1295 }
1296 let parameters = decode_setup_parameters(buf)?;
1297 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1298 }
1299 MessageType::ServerSetup => {
1300 let selected_version = VarInt::decode(buf)?;
1301 let parameters = decode_setup_parameters(buf)?;
1302 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1303 }
1304 MessageType::GoAway => {
1305 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1306 if uri_len > MAX_GOAWAY_URI_LENGTH {
1307 return Err(CodecError::GoAwayUriTooLong);
1308 }
1309 let uri = types::read_bytes(buf, uri_len)?;
1310 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1311 }
1312 MessageType::MaxRequestId => {
1313 let request_id = VarInt::decode(buf)?;
1314 Ok(ControlMessage::MaxRequestId(MaxRequestId { request_id }))
1315 }
1316 MessageType::RequestsBlocked => {
1317 let maximum_request_id = VarInt::decode(buf)?;
1318 Ok(ControlMessage::RequestsBlocked(RequestsBlocked { maximum_request_id }))
1319 }
1320 MessageType::Subscribe => {
1321 let request_id = VarInt::decode(buf)?;
1322 let track_alias = VarInt::decode(buf)?;
1323 let track_namespace = TrackNamespace::decode(buf)?;
1324 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1325 let track_name = types::read_bytes(buf, track_name_len)?;
1326 check_full_track_name(&track_namespace, &track_name)?;
1327 if buf.remaining() < 1 {
1328 return Err(CodecError::UnexpectedEnd);
1329 }
1330 let subscriber_priority = buf.get_u8();
1331 let group_order = read_group_order(buf)?;
1332 let forward = read_forward(buf)?;
1333 let filter_type = VarInt::decode(buf)?;
1334 let ft_val = filter_type.into_inner();
1335 if ft_val == 0 || ft_val > 4 {
1336 return Err(CodecError::InvalidFilterType(ft_val));
1337 }
1338 let (start_group, start_object) = if ft_val == 3 || ft_val == 4 {
1339 (Some(VarInt::decode(buf)?), Some(VarInt::decode(buf)?))
1340 } else {
1341 (None, None)
1342 };
1343 let end_group = if ft_val == 4 { Some(VarInt::decode(buf)?) } else { None };
1344 let parameters = decode_parameters(buf)?;
1345 Ok(ControlMessage::Subscribe(Subscribe {
1346 request_id,
1347 track_alias,
1348 track_namespace,
1349 track_name,
1350 subscriber_priority,
1351 group_order,
1352 forward,
1353 filter_type,
1354 start_group,
1355 start_object,
1356 end_group,
1357 parameters,
1358 }))
1359 }
1360 MessageType::SubscribeOk => {
1361 let request_id = VarInt::decode(buf)?;
1362 let expires = VarInt::decode(buf)?;
1363 let group_order = read_group_order_response(buf)?;
1364 let content_exists = read_content_exists(buf)?;
1365 let largest_location = if content_exists == ContentExists::HasLargestLocation {
1366 Some(Location::decode(buf)?)
1367 } else {
1368 None
1369 };
1370 let parameters = decode_parameters(buf)?;
1371 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1372 request_id,
1373 expires,
1374 group_order,
1375 content_exists,
1376 largest_location,
1377 parameters,
1378 }))
1379 }
1380 MessageType::SubscribeError => {
1381 let request_id = VarInt::decode(buf)?;
1382 let error_code = VarInt::decode(buf)?;
1383 let reason_phrase = read_reason_phrase(buf)?;
1384 let track_alias = VarInt::decode(buf)?;
1385 Ok(ControlMessage::SubscribeError(SubscribeError {
1386 request_id,
1387 error_code,
1388 reason_phrase,
1389 track_alias,
1390 }))
1391 }
1392 MessageType::SubscribeUpdate => {
1393 let request_id = VarInt::decode(buf)?;
1394 let start_group = VarInt::decode(buf)?;
1395 let start_object = VarInt::decode(buf)?;
1396 let end_group = VarInt::decode(buf)?;
1397 if buf.remaining() < 1 {
1398 return Err(CodecError::UnexpectedEnd);
1399 }
1400 let subscriber_priority = buf.get_u8();
1401 let forward = read_forward(buf)?;
1402 let parameters = decode_parameters(buf)?;
1403 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1404 request_id,
1405 start_group,
1406 start_object,
1407 end_group,
1408 subscriber_priority,
1409 forward,
1410 parameters,
1411 }))
1412 }
1413 MessageType::SubscribeDone => {
1414 let request_id = VarInt::decode(buf)?;
1415 let status_code = VarInt::decode(buf)?;
1416 let stream_count = VarInt::decode(buf)?;
1417 let reason_phrase = read_reason_phrase(buf)?;
1418 Ok(ControlMessage::SubscribeDone(SubscribeDone {
1419 request_id,
1420 status_code,
1421 stream_count,
1422 reason_phrase,
1423 }))
1424 }
1425 MessageType::Unsubscribe => {
1426 let request_id = VarInt::decode(buf)?;
1427 Ok(ControlMessage::Unsubscribe(Unsubscribe { request_id }))
1428 }
1429 MessageType::Announce => {
1430 let request_id = VarInt::decode(buf)?;
1431 let track_namespace = TrackNamespace::decode(buf)?;
1432 let parameters = decode_parameters(buf)?;
1433 Ok(ControlMessage::Announce(Announce { request_id, track_namespace, parameters }))
1434 }
1435 MessageType::AnnounceOk => {
1436 let request_id = VarInt::decode(buf)?;
1437 Ok(ControlMessage::AnnounceOk(AnnounceOk { request_id }))
1438 }
1439 MessageType::AnnounceError => {
1440 let request_id = VarInt::decode(buf)?;
1441 let error_code = VarInt::decode(buf)?;
1442 let reason_phrase = read_reason_phrase(buf)?;
1443 Ok(ControlMessage::AnnounceError(AnnounceError {
1444 request_id,
1445 error_code,
1446 reason_phrase,
1447 }))
1448 }
1449 MessageType::AnnounceCancel => {
1450 let track_namespace = TrackNamespace::decode(buf)?;
1451 let error_code = VarInt::decode(buf)?;
1452 let reason_phrase = read_reason_phrase(buf)?;
1453 Ok(ControlMessage::AnnounceCancel(AnnounceCancel {
1454 track_namespace,
1455 error_code,
1456 reason_phrase,
1457 }))
1458 }
1459 MessageType::Unannounce => {
1460 let track_namespace = TrackNamespace::decode(buf)?;
1461 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1462 }
1463 MessageType::SubscribeAnnounces => {
1464 let request_id = VarInt::decode(buf)?;
1465 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1466 let parameters = decode_parameters(buf)?;
1467 Ok(ControlMessage::SubscribeAnnounces(SubscribeAnnounces {
1468 request_id,
1469 track_namespace_prefix,
1470 parameters,
1471 }))
1472 }
1473 MessageType::SubscribeAnnouncesOk => {
1474 let request_id = VarInt::decode(buf)?;
1475 Ok(ControlMessage::SubscribeAnnouncesOk(SubscribeAnnouncesOk { request_id }))
1476 }
1477 MessageType::SubscribeAnnouncesError => {
1478 let request_id = VarInt::decode(buf)?;
1479 let error_code = VarInt::decode(buf)?;
1480 let reason_phrase = read_reason_phrase(buf)?;
1481 Ok(ControlMessage::SubscribeAnnouncesError(SubscribeAnnouncesError {
1482 request_id,
1483 error_code,
1484 reason_phrase,
1485 }))
1486 }
1487 MessageType::UnsubscribeAnnounces => {
1488 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1489 Ok(ControlMessage::UnsubscribeAnnounces(UnsubscribeAnnounces {
1490 track_namespace_prefix,
1491 }))
1492 }
1493 MessageType::TrackStatusRequest => {
1494 let request_id = VarInt::decode(buf)?;
1495 let track_namespace = TrackNamespace::decode(buf)?;
1496 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1497 let track_name = types::read_bytes(buf, track_name_len)?;
1498 check_full_track_name(&track_namespace, &track_name)?;
1499 let parameters = decode_parameters(buf)?;
1500 Ok(ControlMessage::TrackStatusRequest(TrackStatusRequest {
1501 request_id,
1502 track_namespace,
1503 track_name,
1504 parameters,
1505 }))
1506 }
1507 MessageType::TrackStatus => {
1508 let request_id = VarInt::decode(buf)?;
1509 let status_code = VarInt::decode(buf)?;
1510 let largest_location = Location::decode(buf)?;
1511 check_track_status(status_code, largest_location)?;
1512 let parameters = decode_parameters(buf)?;
1513 Ok(ControlMessage::TrackStatus(TrackStatus {
1514 request_id,
1515 status_code,
1516 largest_location,
1517 parameters,
1518 }))
1519 }
1520 MessageType::Fetch => {
1521 let request_id = VarInt::decode(buf)?;
1522 if buf.remaining() < 1 {
1523 return Err(CodecError::UnexpectedEnd);
1524 }
1525 let subscriber_priority = buf.get_u8();
1526 let group_order = read_group_order(buf)?;
1527 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1528 let fetch_type = FetchType::from_u64(fetch_type_val)
1529 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1530 let fetch_payload = match fetch_type {
1531 FetchType::Standalone => {
1532 let track_namespace = TrackNamespace::decode(buf)?;
1533 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1534 let track_name = types::read_bytes(buf, track_name_len)?;
1535 check_full_track_name(&track_namespace, &track_name)?;
1536 let start_group = VarInt::decode(buf)?;
1537 let start_object = VarInt::decode(buf)?;
1538 let end_group = VarInt::decode(buf)?;
1539 let end_object = VarInt::decode(buf)?;
1540 FetchPayload::Standalone {
1541 track_namespace,
1542 track_name,
1543 start_group,
1544 start_object,
1545 end_group,
1546 end_object,
1547 }
1548 }
1549 FetchType::RelativeJoining | FetchType::AbsoluteJoining => {
1550 let joining_subscribe_id = VarInt::decode(buf)?;
1551 let joining_start = VarInt::decode(buf)?;
1552 FetchPayload::Joining { joining_subscribe_id, joining_start }
1553 }
1554 };
1555 let parameters = decode_parameters(buf)?;
1556 Ok(ControlMessage::Fetch(Fetch {
1557 request_id,
1558 subscriber_priority,
1559 group_order,
1560 fetch_type,
1561 fetch_payload,
1562 parameters,
1563 }))
1564 }
1565 MessageType::FetchOk => {
1566 let request_id = VarInt::decode(buf)?;
1567 let group_order = read_group_order_response(buf)?;
1568 let end_of_track = read_u8(buf)?;
1569 let end_location = Location::decode(buf)?;
1570 let parameters = decode_parameters(buf)?;
1571 Ok(ControlMessage::FetchOk(FetchOk {
1572 request_id,
1573 group_order,
1574 end_of_track,
1575 end_location,
1576 parameters,
1577 }))
1578 }
1579 MessageType::FetchError => {
1580 let request_id = VarInt::decode(buf)?;
1581 let error_code = VarInt::decode(buf)?;
1582 let reason_phrase = read_reason_phrase(buf)?;
1583 Ok(ControlMessage::FetchError(FetchError { request_id, error_code, reason_phrase }))
1584 }
1585 MessageType::FetchCancel => {
1586 let request_id = VarInt::decode(buf)?;
1587 Ok(ControlMessage::FetchCancel(FetchCancel { request_id }))
1588 }
1589 }
1590 }
1591
1592 pub fn message_type(&self) -> MessageType {
1594 match self {
1595 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
1596 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
1597 ControlMessage::GoAway(_) => MessageType::GoAway,
1598 ControlMessage::MaxRequestId(_) => MessageType::MaxRequestId,
1599 ControlMessage::RequestsBlocked(_) => MessageType::RequestsBlocked,
1600 ControlMessage::Subscribe(_) => MessageType::Subscribe,
1601 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
1602 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
1603 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
1604 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
1605 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
1606 ControlMessage::Announce(_) => MessageType::Announce,
1607 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
1608 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
1609 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
1610 ControlMessage::Unannounce(_) => MessageType::Unannounce,
1611 ControlMessage::SubscribeAnnounces(_) => MessageType::SubscribeAnnounces,
1612 ControlMessage::SubscribeAnnouncesOk(_) => MessageType::SubscribeAnnouncesOk,
1613 ControlMessage::SubscribeAnnouncesError(_) => MessageType::SubscribeAnnouncesError,
1614 ControlMessage::UnsubscribeAnnounces(_) => MessageType::UnsubscribeAnnounces,
1615 ControlMessage::TrackStatusRequest(_) => MessageType::TrackStatusRequest,
1616 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
1617 ControlMessage::Fetch(_) => MessageType::Fetch,
1618 ControlMessage::FetchOk(_) => MessageType::FetchOk,
1619 ControlMessage::FetchError(_) => MessageType::FetchError,
1620 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
1621 }
1622 }
1623}