1use crate::auth_token::{AuthorizationToken, AUTH_TOKEN_PARAMETER};
2use crate::error::{
3 CodecError, MAX_FULL_TRACK_NAME_LENGTH, MAX_GOAWAY_URI_LENGTH, MAX_MESSAGE_LENGTH,
4 MAX_REASON_PHRASE_LENGTH,
5};
6use crate::kvp::{KeyValuePair, KvpValue};
7use crate::types::*;
8pub use crate::types::{check_group_range, check_location_range, check_open_ended_group_range};
9use crate::varint::VarInt;
10use bytes::{Buf, BufMut};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14#[repr(u64)]
15pub enum MessageType {
16 SubscribeUpdate = 0x02,
18 Subscribe = 0x03,
20 SubscribeOk = 0x04,
22 SubscribeError = 0x05,
24 PublishNamespace = 0x06,
26 PublishNamespaceOk = 0x07,
28 PublishNamespaceError = 0x08,
30 PublishNamespaceDone = 0x09,
32 Unsubscribe = 0x0A,
34 PublishDone = 0x0B,
36 PublishNamespaceCancel = 0x0C,
38 TrackStatus = 0x0D,
40 TrackStatusOk = 0x0E,
42 TrackStatusError = 0x0F,
44 GoAway = 0x10,
46 SubscribeNamespace = 0x11,
48 SubscribeNamespaceOk = 0x12,
50 SubscribeNamespaceError = 0x13,
52 UnsubscribeNamespace = 0x14,
54 MaxRequestId = 0x15,
56 Fetch = 0x16,
58 FetchCancel = 0x17,
60 FetchOk = 0x18,
62 FetchError = 0x19,
64 RequestsBlocked = 0x1A,
66 Publish = 0x1D,
68 PublishOk = 0x1E,
70 PublishError = 0x1F,
72 ClientSetup = 0x20,
74 ServerSetup = 0x21,
76}
77
78impl MessageType {
79 pub fn from_id(id: u64) -> Option<Self> {
81 match id {
82 0x02 => Some(MessageType::SubscribeUpdate),
83 0x03 => Some(MessageType::Subscribe),
84 0x04 => Some(MessageType::SubscribeOk),
85 0x05 => Some(MessageType::SubscribeError),
86 0x06 => Some(MessageType::PublishNamespace),
87 0x07 => Some(MessageType::PublishNamespaceOk),
88 0x08 => Some(MessageType::PublishNamespaceError),
89 0x09 => Some(MessageType::PublishNamespaceDone),
90 0x0A => Some(MessageType::Unsubscribe),
91 0x0B => Some(MessageType::PublishDone),
92 0x0C => Some(MessageType::PublishNamespaceCancel),
93 0x0D => Some(MessageType::TrackStatus),
94 0x0E => Some(MessageType::TrackStatusOk),
95 0x0F => Some(MessageType::TrackStatusError),
96 0x10 => Some(MessageType::GoAway),
97 0x11 => Some(MessageType::SubscribeNamespace),
98 0x12 => Some(MessageType::SubscribeNamespaceOk),
99 0x13 => Some(MessageType::SubscribeNamespaceError),
100 0x14 => Some(MessageType::UnsubscribeNamespace),
101 0x15 => Some(MessageType::MaxRequestId),
102 0x16 => Some(MessageType::Fetch),
103 0x17 => Some(MessageType::FetchCancel),
104 0x18 => Some(MessageType::FetchOk),
105 0x19 => Some(MessageType::FetchError),
106 0x1A => Some(MessageType::RequestsBlocked),
107 0x1D => Some(MessageType::Publish),
108 0x1E => Some(MessageType::PublishOk),
109 0x1F => Some(MessageType::PublishError),
110 0x20 => Some(MessageType::ClientSetup),
111 0x21 => Some(MessageType::ServerSetup),
112 _ => None,
113 }
114 }
115
116 pub fn id(&self) -> u64 {
118 *self as u64
119 }
120
121 pub fn name(&self) -> &'static str {
124 match self {
125 MessageType::SubscribeUpdate => "subscribe_update",
126 MessageType::Subscribe => "subscribe",
127 MessageType::SubscribeOk => "subscribe_ok",
128 MessageType::SubscribeError => "subscribe_error",
129 MessageType::PublishNamespace => "publish_namespace",
130 MessageType::PublishNamespaceOk => "publish_namespace_ok",
131 MessageType::PublishNamespaceError => "publish_namespace_error",
132 MessageType::PublishNamespaceDone => "publish_namespace_done",
133 MessageType::Unsubscribe => "unsubscribe",
134 MessageType::PublishDone => "publish_done",
135 MessageType::PublishNamespaceCancel => "publish_namespace_cancel",
136 MessageType::TrackStatus => "track_status",
137 MessageType::TrackStatusOk => "track_status_ok",
138 MessageType::TrackStatusError => "track_status_error",
139 MessageType::GoAway => "goaway",
140 MessageType::SubscribeNamespace => "subscribe_namespace",
141 MessageType::SubscribeNamespaceOk => "subscribe_namespace_ok",
142 MessageType::SubscribeNamespaceError => "subscribe_namespace_error",
143 MessageType::UnsubscribeNamespace => "unsubscribe_namespace",
144 MessageType::MaxRequestId => "max_request_id",
145 MessageType::Fetch => "fetch",
146 MessageType::FetchCancel => "fetch_cancel",
147 MessageType::FetchOk => "fetch_ok",
148 MessageType::FetchError => "fetch_error",
149 MessageType::RequestsBlocked => "requests_blocked",
150 MessageType::Publish => "publish",
151 MessageType::PublishOk => "publish_ok",
152 MessageType::PublishError => "publish_error",
153 MessageType::ClientSetup => "client_setup",
154 MessageType::ServerSetup => "server_setup",
155 }
156 }
157}
158
159#[derive(Debug, Clone, PartialEq, Eq)]
165pub struct ClientSetup {
166 pub supported_versions: Vec<VarInt>,
168 pub parameters: Vec<KeyValuePair>,
170}
171
172#[derive(Debug, Clone, PartialEq, Eq)]
174pub struct ServerSetup {
175 pub selected_version: VarInt,
177 pub parameters: Vec<KeyValuePair>,
179}
180
181#[derive(Debug, Clone, PartialEq, Eq)]
183pub struct GoAway {
184 pub new_session_uri: Vec<u8>,
186}
187
188#[derive(Debug, Clone, PartialEq, Eq)]
190pub struct MaxRequestId {
191 pub request_id: VarInt,
193}
194
195#[derive(Debug, Clone, PartialEq, Eq)]
197pub struct RequestsBlocked {
198 pub maximum_request_id: VarInt,
200}
201
202#[derive(Debug, Clone, PartialEq, Eq)]
208pub struct Subscribe {
209 pub request_id: VarInt,
211 pub track_namespace: TrackNamespace,
213 pub track_name: Vec<u8>,
215 pub subscriber_priority: u8,
217 pub group_order: GroupOrder,
219 pub forward: Forward,
221 pub filter_type: FilterType,
223 pub start_location: Option<Location>,
225 pub end_group: Option<VarInt>,
227 pub parameters: Vec<KeyValuePair>,
229}
230
231#[derive(Debug, Clone, PartialEq, Eq)]
233pub struct SubscribeOk {
234 pub request_id: VarInt,
236 pub track_alias: VarInt,
238 pub expires: VarInt,
240 pub group_order: GroupOrder,
242 pub content_exists: ContentExists,
244 pub largest_location: Option<Location>,
246 pub parameters: Vec<KeyValuePair>,
248}
249
250#[derive(Debug, Clone, PartialEq, Eq)]
252pub struct SubscribeError {
253 pub request_id: VarInt,
255 pub error_code: VarInt,
257 pub reason_phrase: Vec<u8>,
259}
260
261#[derive(Debug, Clone, PartialEq, Eq)]
263pub struct SubscribeUpdate {
264 pub request_id: VarInt,
266 pub subscription_request_id: VarInt,
268 pub start_location: Location,
270 pub end_group: VarInt,
272 pub subscriber_priority: u8,
274 pub forward: Forward,
276 pub parameters: Vec<KeyValuePair>,
278}
279
280#[derive(Debug, Clone, PartialEq, Eq)]
282pub struct Unsubscribe {
283 pub request_id: VarInt,
285}
286
287#[derive(Debug, Clone, PartialEq, Eq)]
293pub struct Publish {
294 pub request_id: VarInt,
296 pub track_namespace: TrackNamespace,
298 pub track_name: Vec<u8>,
300 pub track_alias: VarInt,
302 pub group_order: GroupOrder,
304 pub content_exists: ContentExists,
306 pub largest_location: Option<Location>,
308 pub forward: Forward,
310 pub parameters: Vec<KeyValuePair>,
312}
313
314#[derive(Debug, Clone, PartialEq, Eq)]
316pub struct PublishOk {
317 pub request_id: VarInt,
319 pub forward: Forward,
321 pub subscriber_priority: u8,
323 pub group_order: GroupOrder,
325 pub filter_type: FilterType,
327 pub start_location: Option<Location>,
329 pub end_group: Option<VarInt>,
331 pub parameters: Vec<KeyValuePair>,
333}
334
335#[derive(Debug, Clone, PartialEq, Eq)]
337pub struct PublishError {
338 pub request_id: VarInt,
340 pub error_code: VarInt,
342 pub reason_phrase: Vec<u8>,
344}
345
346#[derive(Debug, Clone, PartialEq, Eq)]
348pub struct PublishDone {
349 pub request_id: VarInt,
351 pub status_code: VarInt,
353 pub stream_count: VarInt,
355 pub reason_phrase: Vec<u8>,
357}
358
359#[derive(Debug, Clone, PartialEq, Eq)]
365pub struct PublishNamespace {
366 pub request_id: VarInt,
368 pub track_namespace: TrackNamespace,
370 pub parameters: Vec<KeyValuePair>,
372}
373
374#[derive(Debug, Clone, PartialEq, Eq)]
376pub struct PublishNamespaceOk {
377 pub request_id: VarInt,
379}
380
381#[derive(Debug, Clone, PartialEq, Eq)]
383pub struct PublishNamespaceError {
384 pub request_id: VarInt,
386 pub error_code: VarInt,
388 pub reason_phrase: Vec<u8>,
390}
391
392#[derive(Debug, Clone, PartialEq, Eq)]
394pub struct PublishNamespaceDone {
395 pub track_namespace: TrackNamespace,
397}
398
399#[derive(Debug, Clone, PartialEq, Eq)]
401pub struct PublishNamespaceCancel {
402 pub track_namespace: TrackNamespace,
404 pub error_code: VarInt,
406 pub reason_phrase: Vec<u8>,
408}
409
410#[derive(Debug, Clone, PartialEq, Eq)]
416pub struct SubscribeNamespace {
417 pub request_id: VarInt,
419 pub track_namespace: TrackNamespace,
421 pub parameters: Vec<KeyValuePair>,
423}
424
425#[derive(Debug, Clone, PartialEq, Eq)]
427pub struct SubscribeNamespaceOk {
428 pub request_id: VarInt,
430}
431
432#[derive(Debug, Clone, PartialEq, Eq)]
434pub struct SubscribeNamespaceError {
435 pub request_id: VarInt,
437 pub error_code: VarInt,
439 pub reason_phrase: Vec<u8>,
441}
442
443#[derive(Debug, Clone, PartialEq, Eq)]
445pub struct UnsubscribeNamespace {
446 pub track_namespace_prefix: TrackNamespace,
448}
449
450#[derive(Debug, Clone, Copy, PartialEq, Eq)]
456#[repr(u64)]
457pub enum FetchType {
458 Standalone = 1,
460 RelativeJoining = 2,
462 AbsoluteJoining = 3,
464}
465
466impl FetchType {
467 pub fn from_u64(v: u64) -> Option<Self> {
469 match v {
470 1 => Some(FetchType::Standalone),
471 2 => Some(FetchType::RelativeJoining),
472 3 => Some(FetchType::AbsoluteJoining),
473 _ => None,
474 }
475 }
476}
477
478#[derive(Debug, Clone, PartialEq, Eq)]
480pub enum FetchPayload {
481 Standalone {
483 track_namespace: TrackNamespace,
485 track_name: Vec<u8>,
487 start_group: VarInt,
489 start_object: VarInt,
491 end_group: VarInt,
493 end_object: VarInt,
495 },
496 Joining {
498 joining_request_id: VarInt,
504 joining_start: VarInt,
506 },
507}
508
509#[derive(Debug, Clone, PartialEq, Eq)]
511pub struct Fetch {
512 pub request_id: VarInt,
514 pub subscriber_priority: u8,
516 pub group_order: GroupOrder,
518 pub fetch_type: FetchType,
520 pub fetch_payload: FetchPayload,
522 pub parameters: Vec<KeyValuePair>,
524}
525
526#[derive(Debug, Clone, PartialEq, Eq)]
528pub struct FetchOk {
529 pub request_id: VarInt,
531 pub group_order: GroupOrder,
533 pub end_of_track: u8,
535 pub end_location: Location,
537 pub parameters: Vec<KeyValuePair>,
539}
540
541#[derive(Debug, Clone, PartialEq, Eq)]
543pub struct FetchError {
544 pub request_id: VarInt,
546 pub error_code: VarInt,
548 pub reason_phrase: Vec<u8>,
550}
551
552#[derive(Debug, Clone, PartialEq, Eq)]
554pub struct FetchCancel {
555 pub request_id: VarInt,
557}
558
559#[derive(Debug, Clone, PartialEq, Eq)]
565pub struct TrackStatus {
566 pub request_id: VarInt,
568 pub track_namespace: TrackNamespace,
570 pub track_name: Vec<u8>,
572 pub subscriber_priority: u8,
574 pub group_order: GroupOrder,
576 pub forward: Forward,
578 pub filter_type: FilterType,
580 pub start_location: Option<Location>,
582 pub end_group: Option<VarInt>,
584 pub parameters: Vec<KeyValuePair>,
586}
587
588#[derive(Debug, Clone, PartialEq, Eq)]
590pub struct TrackStatusOk {
591 pub request_id: VarInt,
593 pub track_alias: VarInt,
595 pub expires: VarInt,
597 pub group_order: GroupOrder,
599 pub content_exists: ContentExists,
601 pub largest_location: Option<Location>,
603 pub parameters: Vec<KeyValuePair>,
605}
606
607#[derive(Debug, Clone, PartialEq, Eq)]
609pub struct TrackStatusError {
610 pub request_id: VarInt,
612 pub error_code: VarInt,
614 pub reason_phrase: Vec<u8>,
616}
617
618#[derive(Debug, Clone, PartialEq, Eq)]
624pub enum ControlMessage {
625 ClientSetup(ClientSetup),
627 ServerSetup(ServerSetup),
629 GoAway(GoAway),
631 MaxRequestId(MaxRequestId),
633 RequestsBlocked(RequestsBlocked),
635 Subscribe(Subscribe),
637 SubscribeOk(SubscribeOk),
639 SubscribeError(SubscribeError),
641 SubscribeUpdate(SubscribeUpdate),
643 Unsubscribe(Unsubscribe),
645 Publish(Publish),
647 PublishOk(PublishOk),
649 PublishError(PublishError),
651 PublishDone(PublishDone),
653 PublishNamespace(PublishNamespace),
655 PublishNamespaceOk(PublishNamespaceOk),
657 PublishNamespaceError(PublishNamespaceError),
659 PublishNamespaceDone(PublishNamespaceDone),
661 PublishNamespaceCancel(PublishNamespaceCancel),
663 SubscribeNamespace(SubscribeNamespace),
665 SubscribeNamespaceOk(SubscribeNamespaceOk),
667 SubscribeNamespaceError(SubscribeNamespaceError),
669 UnsubscribeNamespace(UnsubscribeNamespace),
671 Fetch(Fetch),
673 FetchOk(FetchOk),
675 FetchError(FetchError),
677 FetchCancel(FetchCancel),
679 TrackStatus(TrackStatus),
681 TrackStatusOk(TrackStatusOk),
683 TrackStatusError(TrackStatusError),
685}
686
687fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
704 if !buf.has_remaining() {
705 return Err(CodecError::UnexpectedEnd);
706 }
707 match GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)? {
708 GroupOrder::Publisher => Err(CodecError::InvalidField),
709 order => Ok(order),
710 }
711}
712
713fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
718 let order = match message {
719 ControlMessage::SubscribeOk(m) => m.group_order,
720 ControlMessage::TrackStatusOk(m) => m.group_order,
721 ControlMessage::FetchOk(m) => m.group_order,
722 ControlMessage::Publish(m) => m.group_order,
723 ControlMessage::PublishOk(m) => m.group_order,
724 _ => return Ok(()),
725 };
726 if order == GroupOrder::Publisher {
727 return Err(CodecError::InvalidField);
728 }
729 Ok(())
730}
731
732fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
768 match message {
769 ControlMessage::Fetch(m) => {
770 let body_is_standalone = matches!(m.fetch_payload, FetchPayload::Standalone { .. });
771 if body_is_standalone != (m.fetch_type == FetchType::Standalone) {
772 return Err(CodecError::InvalidField);
773 }
774 }
775 ControlMessage::Subscribe(m) => {
776 let wants_start =
777 matches!(m.filter_type, FilterType::AbsoluteStart | FilterType::AbsoluteRange);
778 if wants_start != m.start_location.is_some() {
779 return Err(CodecError::InvalidField);
780 }
781 if (m.filter_type == FilterType::AbsoluteRange) != m.end_group.is_some() {
782 return Err(CodecError::InvalidField);
783 }
784 }
785 ControlMessage::SubscribeOk(m) => {
786 let has_location = m.content_exists == ContentExists::HasLargestLocation;
787 if has_location != m.largest_location.is_some() {
788 return Err(CodecError::InvalidField);
789 }
790 }
791 _ => {}
792 }
793 Ok(())
794}
795
796fn read_reason_phrase(buf: &mut impl Buf) -> Result<Vec<u8>, CodecError> {
812 let len = VarInt::decode(buf)?.into_inner() as usize;
813 if len > MAX_REASON_PHRASE_LENGTH {
814 return Err(CodecError::ReasonPhraseTooLong);
815 }
816 read_bytes(buf, len)
817}
818
819fn check_full_track_name(namespace: &TrackNamespace, track_name: &[u8]) -> Result<(), CodecError> {
820 let total = namespace.field_bytes_len().saturating_add(track_name.len());
821 if total > MAX_FULL_TRACK_NAME_LENGTH {
822 return Err(CodecError::TrackNameTooLong);
823 }
824 Ok(())
825}
826
827fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
841 match message {
842 ControlMessage::Subscribe(m) => match (&m.start_location, &m.end_group) {
843 (Some(start), Some(end_group)) => {
844 check_group_range(start.group.into_inner(), end_group.into_inner())
845 }
846 _ => Ok(()),
847 },
848 ControlMessage::SubscribeUpdate(m) => check_open_ended_group_range(
849 m.start_location.group.into_inner(),
850 m.end_group.into_inner(),
851 ),
852 ControlMessage::Fetch(m) => match &m.fetch_payload {
853 FetchPayload::Standalone {
854 start_group, start_object, end_group, end_object, ..
855 } => check_location_range(
856 start_group.into_inner(),
857 start_object.into_inner(),
858 end_group.into_inner(),
859 end_object.into_inner(),
860 ),
861 FetchPayload::Joining { .. } => Ok(()),
862 },
863 _ => Ok(()),
864 }
865}
866
867const REPEATABLE_PARAMETER: u64 = 0x03;
879
880const KNOWN_VERSION_SPECIFIC_PARAMETERS: &[u64] = &[0x02, 0x03, 0x04];
892
893const KNOWN_SETUP_PARAMETERS: &[u64] = &[0x01, 0x02, 0x03, 0x04, 0x05];
906
907fn check_no_duplicate_parameters_sent(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
919 for (i, parameter) in parameters.iter().enumerate() {
920 let key = parameter.key.into_inner();
921 if key == REPEATABLE_PARAMETER {
922 continue;
923 }
924 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
925 return Err(CodecError::DuplicateParameter(key));
926 }
927 }
928 Ok(())
929}
930
931fn check_no_duplicate_parameters_received(
949 parameters: &[KeyValuePair],
950 known: &[u64],
951) -> Result<(), CodecError> {
952 for (i, parameter) in parameters.iter().enumerate() {
953 let key = parameter.key.into_inner();
954 if key == REPEATABLE_PARAMETER || !known.contains(&key) {
955 continue;
956 }
957 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
958 return Err(CodecError::DuplicateParameter(key));
959 }
960 }
961 Ok(())
962}
963
964fn check_authorization_tokens(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
979 for parameter in parameters {
980 let key = parameter.key.into_inner();
981 if key != AUTH_TOKEN_PARAMETER {
982 continue;
983 }
984 match ¶meter.value {
985 KvpValue::Bytes(value) => {
986 AuthorizationToken::decode(key, value)?;
987 }
988 KvpValue::Varint(_) => {
993 return Err(CodecError::KeyValueFormatting {
994 key,
995 detail: "its value is a bare varint where the type defines a Token structure",
996 });
997 }
998 }
999 }
1000 Ok(())
1001}
1002
1003fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
1005 let parameters = KeyValuePair::decode_list(buf)?;
1006 check_no_duplicate_parameters_received(¶meters, KNOWN_VERSION_SPECIFIC_PARAMETERS)?;
1007 check_authorization_tokens(¶meters)?;
1008 Ok(parameters)
1009}
1010
1011fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
1016 let parameters = KeyValuePair::decode_list(buf)?;
1017 check_no_duplicate_parameters_received(¶meters, KNOWN_SETUP_PARAMETERS)?;
1018 check_authorization_tokens(¶meters)?;
1019 Ok(parameters)
1020}
1021
1022fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
1034 check_no_duplicate_parameters_sent(parameters)?;
1035 check_authorization_tokens(parameters)?;
1036 KeyValuePair::encode_list_checked(parameters, buf)?;
1037 Ok(())
1038}
1039
1040impl ControlMessage {
1041 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
1045 check_discriminators(self)?;
1046 check_group_order(self)?;
1047 check_ranges(self)?;
1048 let mut payload = Vec::with_capacity(256);
1049 self.encode_payload(&mut payload)?;
1050
1051 if payload.len() > MAX_MESSAGE_LENGTH {
1052 return Err(CodecError::MessageTooLong(payload.len()));
1053 }
1054
1055 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
1056 buf.put_u16(payload.len() as u16);
1058 buf.put_slice(&payload);
1059 Ok(())
1060 }
1061
1062 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
1066 let type_id = VarInt::decode(buf)?.into_inner();
1067 let msg_type =
1068 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
1069 if buf.remaining() < 2 {
1071 return Err(CodecError::UnexpectedEnd);
1072 }
1073 let payload_len = buf.get_u16() as usize;
1074 if buf.remaining() < payload_len {
1075 return Err(CodecError::UnexpectedEnd);
1076 }
1077 let payload_bytes = buf.copy_to_bytes(payload_len);
1078 let mut payload = &payload_bytes[..];
1079 let msg = match Self::decode_payload(msg_type, &mut payload) {
1080 Ok(msg) => msg,
1081 Err(
1087 CodecError::UnexpectedEnd
1088 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
1089 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
1090 crate::varint::VarIntError::UnexpectedEnd,
1091 ))
1092 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
1093 ) => {
1094 return Err(CodecError::ControlMessageLengthMismatch {
1095 declared: payload_len,
1096 detail: "its fields ran past the end",
1097 });
1098 }
1099 Err(e) => return Err(e),
1100 };
1101 check_ranges(&msg)?;
1102 if payload.has_remaining() {
1107 return Err(CodecError::ControlMessageLengthMismatch {
1108 declared: payload_len,
1109 detail: "its fields left bytes unread",
1110 });
1111 }
1112 Ok(msg)
1113 }
1114
1115 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
1116 match self {
1117 ControlMessage::ClientSetup(m) => {
1118 VarInt::from_usize(m.supported_versions.len()).encode(buf);
1119 for v in &m.supported_versions {
1120 v.encode(buf);
1121 }
1122 encode_parameters(&m.parameters, buf)?;
1123 }
1124 ControlMessage::ServerSetup(m) => {
1125 m.selected_version.encode(buf);
1126 encode_parameters(&m.parameters, buf)?;
1127 }
1128 ControlMessage::GoAway(m) => {
1129 if m.new_session_uri.len() > MAX_GOAWAY_URI_LENGTH {
1130 return Err(CodecError::GoAwayUriTooLong);
1131 }
1132 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
1133 buf.put_slice(&m.new_session_uri);
1134 }
1135 ControlMessage::MaxRequestId(m) => {
1136 m.request_id.encode(buf);
1137 }
1138 ControlMessage::RequestsBlocked(m) => {
1139 m.maximum_request_id.encode(buf);
1140 }
1141 ControlMessage::Subscribe(m) => {
1142 check_full_track_name(&m.track_namespace, &m.track_name)?;
1143 m.request_id.encode(buf);
1144 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1145 m.track_namespace.encode(buf);
1146 VarInt::from_usize(m.track_name.len()).encode(buf);
1147 buf.put_slice(&m.track_name);
1148 buf.put_u8(m.subscriber_priority);
1149 buf.put_u8(m.group_order as u8);
1150 buf.put_u8(m.forward as u8);
1151 VarInt::from_u64(m.filter_type as u64).unwrap().encode(buf);
1152 if let Some(loc) = &m.start_location {
1153 loc.encode(buf);
1154 }
1155 if let Some(eg) = &m.end_group {
1156 eg.encode(buf);
1157 }
1158 encode_parameters(&m.parameters, buf)?;
1159 }
1160 ControlMessage::SubscribeOk(m) => {
1161 m.request_id.encode(buf);
1162 m.track_alias.encode(buf);
1163 m.expires.encode(buf);
1164 buf.put_u8(m.group_order as u8);
1165 buf.put_u8(m.content_exists as u8);
1166 if let Some(loc) = &m.largest_location {
1167 loc.encode(buf);
1168 }
1169 encode_parameters(&m.parameters, buf)?;
1170 }
1171 ControlMessage::SubscribeError(m) => {
1172 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1173 return Err(CodecError::ReasonPhraseTooLong);
1174 }
1175 m.request_id.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::SubscribeUpdate(m) => {
1181 m.request_id.encode(buf);
1182 m.subscription_request_id.encode(buf);
1183 m.start_location.encode(buf);
1184 m.end_group.encode(buf);
1185 buf.put_u8(m.subscriber_priority);
1186 buf.put_u8(m.forward as u8);
1187 encode_parameters(&m.parameters, buf)?;
1188 }
1189 ControlMessage::Unsubscribe(m) => {
1190 m.request_id.encode(buf);
1191 }
1192 ControlMessage::Publish(m) => {
1193 check_full_track_name(&m.track_namespace, &m.track_name)?;
1194 m.request_id.encode(buf);
1195 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1196 m.track_namespace.encode(buf);
1197 VarInt::from_usize(m.track_name.len()).encode(buf);
1198 buf.put_slice(&m.track_name);
1199 m.track_alias.encode(buf);
1200 buf.put_u8(m.group_order as u8);
1201 buf.put_u8(m.content_exists as u8);
1202 if let Some(loc) = &m.largest_location {
1203 loc.encode(buf);
1204 }
1205 buf.put_u8(m.forward as u8);
1206 encode_parameters(&m.parameters, buf)?;
1207 }
1208 ControlMessage::PublishOk(m) => {
1209 m.request_id.encode(buf);
1210 buf.put_u8(m.forward as u8);
1211 buf.put_u8(m.subscriber_priority);
1212 buf.put_u8(m.group_order as u8);
1213 VarInt::from_u64(m.filter_type as u64).unwrap().encode(buf);
1214 if let Some(loc) = &m.start_location {
1215 loc.encode(buf);
1216 }
1217 if let Some(eg) = &m.end_group {
1218 eg.encode(buf);
1219 }
1220 encode_parameters(&m.parameters, buf)?;
1221 }
1222 ControlMessage::PublishError(m) => {
1223 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1224 return Err(CodecError::ReasonPhraseTooLong);
1225 }
1226 m.request_id.encode(buf);
1227 m.error_code.encode(buf);
1228 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1229 buf.put_slice(&m.reason_phrase);
1230 }
1231 ControlMessage::PublishDone(m) => {
1232 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1233 return Err(CodecError::ReasonPhraseTooLong);
1234 }
1235 m.request_id.encode(buf);
1236 m.status_code.encode(buf);
1237 m.stream_count.encode(buf);
1238 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1239 buf.put_slice(&m.reason_phrase);
1240 }
1241 ControlMessage::PublishNamespace(m) => {
1242 m.request_id.encode(buf);
1243 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1244 m.track_namespace.encode(buf);
1245 encode_parameters(&m.parameters, buf)?;
1246 }
1247 ControlMessage::PublishNamespaceOk(m) => {
1248 m.request_id.encode(buf);
1249 }
1250 ControlMessage::PublishNamespaceError(m) => {
1251 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1252 return Err(CodecError::ReasonPhraseTooLong);
1253 }
1254 m.request_id.encode(buf);
1255 m.error_code.encode(buf);
1256 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1257 buf.put_slice(&m.reason_phrase);
1258 }
1259 ControlMessage::PublishNamespaceDone(m) => {
1260 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1261 m.track_namespace.encode(buf);
1262 }
1263 ControlMessage::PublishNamespaceCancel(m) => {
1264 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1265 return Err(CodecError::ReasonPhraseTooLong);
1266 }
1267 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1268 m.track_namespace.encode(buf);
1269 m.error_code.encode(buf);
1270 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1271 buf.put_slice(&m.reason_phrase);
1272 }
1273 ControlMessage::SubscribeNamespace(m) => {
1274 m.request_id.encode(buf);
1275 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1276 m.track_namespace.encode(buf);
1277 encode_parameters(&m.parameters, buf)?;
1278 }
1279 ControlMessage::SubscribeNamespaceOk(m) => {
1280 m.request_id.encode(buf);
1281 }
1282 ControlMessage::SubscribeNamespaceError(m) => {
1283 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1284 return Err(CodecError::ReasonPhraseTooLong);
1285 }
1286 m.request_id.encode(buf);
1287 m.error_code.encode(buf);
1288 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1289 buf.put_slice(&m.reason_phrase);
1290 }
1291 ControlMessage::UnsubscribeNamespace(m) => {
1292 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(14))?;
1293 m.track_namespace_prefix.encode(buf);
1294 }
1295 ControlMessage::Fetch(m) => {
1296 m.request_id.encode(buf);
1297 buf.put_u8(m.subscriber_priority);
1298 buf.put_u8(m.group_order as u8);
1299 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1300 match &m.fetch_payload {
1301 FetchPayload::Standalone {
1302 track_namespace,
1303 track_name,
1304 start_group,
1305 start_object,
1306 end_group,
1307 end_object,
1308 } => {
1309 check_full_track_name(track_namespace, track_name)?;
1310 track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1311 track_namespace.encode(buf);
1312 VarInt::from_usize(track_name.len()).encode(buf);
1313 buf.put_slice(track_name);
1314 start_group.encode(buf);
1315 start_object.encode(buf);
1316 end_group.encode(buf);
1317 end_object.encode(buf);
1318 }
1319 FetchPayload::Joining { joining_request_id, joining_start } => {
1320 joining_request_id.encode(buf);
1321 joining_start.encode(buf);
1322 }
1323 }
1324 encode_parameters(&m.parameters, buf)?;
1325 }
1326 ControlMessage::FetchOk(m) => {
1327 m.request_id.encode(buf);
1328 buf.put_u8(m.group_order as u8);
1329 buf.put_u8(m.end_of_track);
1330 m.end_location.encode(buf);
1331 encode_parameters(&m.parameters, buf)?;
1332 }
1333 ControlMessage::FetchError(m) => {
1334 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1335 return Err(CodecError::ReasonPhraseTooLong);
1336 }
1337 m.request_id.encode(buf);
1338 m.error_code.encode(buf);
1339 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1340 buf.put_slice(&m.reason_phrase);
1341 }
1342 ControlMessage::FetchCancel(m) => {
1343 m.request_id.encode(buf);
1344 }
1345 ControlMessage::TrackStatus(m) => {
1346 check_full_track_name(&m.track_namespace, &m.track_name)?;
1347 m.request_id.encode(buf);
1348 m.track_namespace.validate(TrackNamespaceRules::for_draft(14))?;
1349 m.track_namespace.encode(buf);
1350 VarInt::from_usize(m.track_name.len()).encode(buf);
1351 buf.put_slice(&m.track_name);
1352 buf.put_u8(m.subscriber_priority);
1353 buf.put_u8(m.group_order as u8);
1354 buf.put_u8(m.forward as u8);
1355 VarInt::from_u64(m.filter_type as u64).unwrap().encode(buf);
1356 if let Some(loc) = &m.start_location {
1357 loc.encode(buf);
1358 }
1359 if let Some(eg) = &m.end_group {
1360 eg.encode(buf);
1361 }
1362 encode_parameters(&m.parameters, buf)?;
1363 }
1364 ControlMessage::TrackStatusOk(m) => {
1365 m.request_id.encode(buf);
1366 m.track_alias.encode(buf);
1367 m.expires.encode(buf);
1368 buf.put_u8(m.group_order as u8);
1369 buf.put_u8(m.content_exists as u8);
1370 if let Some(loc) = &m.largest_location {
1371 loc.encode(buf);
1372 }
1373 encode_parameters(&m.parameters, buf)?;
1374 }
1375 ControlMessage::TrackStatusError(m) => {
1376 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1377 return Err(CodecError::ReasonPhraseTooLong);
1378 }
1379 m.request_id.encode(buf);
1380 m.error_code.encode(buf);
1381 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1382 buf.put_slice(&m.reason_phrase);
1383 }
1384 }
1385 Ok(())
1386 }
1387
1388 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1389 match msg_type {
1390 MessageType::ClientSetup => {
1391 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1392 if num_versions == 0 {
1402 return Err(CodecError::InvalidField);
1403 }
1404 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1405 for _ in 0..num_versions {
1406 supported_versions.push(VarInt::decode(buf)?);
1407 }
1408 let parameters = decode_setup_parameters(buf)?;
1409 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1410 }
1411 MessageType::ServerSetup => {
1412 let selected_version = VarInt::decode(buf)?;
1413 let parameters = decode_setup_parameters(buf)?;
1414 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1415 }
1416 MessageType::GoAway => {
1417 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1418 if uri_len > MAX_GOAWAY_URI_LENGTH {
1424 return Err(CodecError::GoAwayUriTooLong);
1425 }
1426 let uri = read_bytes(buf, uri_len)?;
1427 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1428 }
1429 MessageType::MaxRequestId => {
1430 let request_id = VarInt::decode(buf)?;
1431 Ok(ControlMessage::MaxRequestId(MaxRequestId { request_id }))
1432 }
1433 MessageType::RequestsBlocked => {
1434 let maximum_request_id = VarInt::decode(buf)?;
1435 Ok(ControlMessage::RequestsBlocked(RequestsBlocked { maximum_request_id }))
1436 }
1437 MessageType::Subscribe => {
1438 let request_id = VarInt::decode(buf)?;
1439 let track_namespace = TrackNamespace::decode(buf)?;
1440 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1441 let track_name = read_bytes(buf, track_name_len)?;
1442 check_full_track_name(&track_namespace, &track_name)?;
1443 if buf.remaining() < 3 {
1444 return Err(CodecError::UnexpectedEnd);
1445 }
1446 let subscriber_priority = buf.get_u8();
1447 let group_order =
1448 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1449 let forward_val = buf.get_u8();
1450 let forward = match forward_val {
1451 0 => Forward::DontForward,
1452 1 => Forward::Forward,
1453 other => return Err(CodecError::InvalidForward(other)),
1454 };
1455 let filter_val = VarInt::decode(buf)?.into_inner();
1461 let filter_type = FilterType::from_u64(filter_val)
1462 .ok_or(CodecError::InvalidFilterType(filter_val))?;
1463 let start_location = match filter_type {
1464 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1465 Some(Location::decode(buf)?)
1466 }
1467 _ => None,
1468 };
1469 let end_group = match filter_type {
1470 FilterType::AbsoluteRange => Some(VarInt::decode(buf)?),
1471 _ => None,
1472 };
1473 let parameters = decode_parameters(buf)?;
1474 Ok(ControlMessage::Subscribe(Subscribe {
1475 request_id,
1476 track_namespace,
1477 track_name,
1478 subscriber_priority,
1479 group_order,
1480 forward,
1481 filter_type,
1482 start_location,
1483 end_group,
1484 parameters,
1485 }))
1486 }
1487 MessageType::SubscribeOk => {
1488 let request_id = VarInt::decode(buf)?;
1489 let track_alias = VarInt::decode(buf)?;
1490 let expires = VarInt::decode(buf)?;
1491 if buf.remaining() < 2 {
1492 return Err(CodecError::UnexpectedEnd);
1493 }
1494 let group_order = read_group_order_response(buf)?;
1495 let content_exists_val = buf.get_u8();
1496 let content_exists = match content_exists_val {
1497 0 => ContentExists::NoLargestLocation,
1498 1 => ContentExists::HasLargestLocation,
1499 other => return Err(CodecError::InvalidContentExists(other)),
1500 };
1501 let largest_location = if content_exists == ContentExists::HasLargestLocation {
1502 Some(Location::decode(buf)?)
1503 } else {
1504 None
1505 };
1506 let parameters = decode_parameters(buf)?;
1507 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1508 request_id,
1509 track_alias,
1510 expires,
1511 group_order,
1512 content_exists,
1513 largest_location,
1514 parameters,
1515 }))
1516 }
1517 MessageType::SubscribeError => {
1518 let request_id = VarInt::decode(buf)?;
1519 let error_code = VarInt::decode(buf)?;
1520 let reason_phrase = read_reason_phrase(buf)?;
1521 Ok(ControlMessage::SubscribeError(SubscribeError {
1522 request_id,
1523 error_code,
1524 reason_phrase,
1525 }))
1526 }
1527 MessageType::SubscribeUpdate => {
1528 let request_id = VarInt::decode(buf)?;
1529 let subscription_request_id = VarInt::decode(buf)?;
1530 let start_location = Location::decode(buf)?;
1531 let end_group = VarInt::decode(buf)?;
1532 if buf.remaining() < 2 {
1533 return Err(CodecError::UnexpectedEnd);
1534 }
1535 let subscriber_priority = buf.get_u8();
1536 let forward_val = buf.get_u8();
1537 let forward = match forward_val {
1538 0 => Forward::DontForward,
1539 1 => Forward::Forward,
1540 other => return Err(CodecError::InvalidForward(other)),
1541 };
1542 let parameters = decode_parameters(buf)?;
1543 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1544 request_id,
1545 subscription_request_id,
1546 start_location,
1547 end_group,
1548 subscriber_priority,
1549 forward,
1550 parameters,
1551 }))
1552 }
1553 MessageType::Unsubscribe => {
1554 let request_id = VarInt::decode(buf)?;
1555 Ok(ControlMessage::Unsubscribe(Unsubscribe { request_id }))
1556 }
1557 MessageType::Publish => {
1558 let request_id = VarInt::decode(buf)?;
1559 let track_namespace = TrackNamespace::decode(buf)?;
1560 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1561 let track_name = read_bytes(buf, track_name_len)?;
1562 check_full_track_name(&track_namespace, &track_name)?;
1563 let track_alias = VarInt::decode(buf)?;
1564 if buf.remaining() < 2 {
1565 return Err(CodecError::UnexpectedEnd);
1566 }
1567 let group_order = read_group_order_response(buf)?;
1568 let content_exists_val = buf.get_u8();
1569 let content_exists = match content_exists_val {
1570 0 => ContentExists::NoLargestLocation,
1571 1 => ContentExists::HasLargestLocation,
1572 other => return Err(CodecError::InvalidContentExists(other)),
1573 };
1574 let largest_location = if content_exists == ContentExists::HasLargestLocation {
1575 Some(Location::decode(buf)?)
1576 } else {
1577 None
1578 };
1579 if buf.remaining() < 1 {
1580 return Err(CodecError::UnexpectedEnd);
1581 }
1582 let forward_val = buf.get_u8();
1583 let forward = match forward_val {
1584 0 => Forward::DontForward,
1585 1 => Forward::Forward,
1586 other => return Err(CodecError::InvalidForward(other)),
1587 };
1588 let parameters = decode_parameters(buf)?;
1589 Ok(ControlMessage::Publish(Publish {
1590 request_id,
1591 track_namespace,
1592 track_name,
1593 track_alias,
1594 group_order,
1595 content_exists,
1596 largest_location,
1597 forward,
1598 parameters,
1599 }))
1600 }
1601 MessageType::PublishOk => {
1602 let request_id = VarInt::decode(buf)?;
1603 if buf.remaining() < 3 {
1604 return Err(CodecError::UnexpectedEnd);
1605 }
1606 let forward_val = buf.get_u8();
1607 let forward = match forward_val {
1608 0 => Forward::DontForward,
1609 1 => Forward::Forward,
1610 other => return Err(CodecError::InvalidForward(other)),
1611 };
1612 let subscriber_priority = buf.get_u8();
1613 let group_order = read_group_order_response(buf)?;
1614 let filter_val = VarInt::decode(buf)?.into_inner();
1615 let filter_type = FilterType::from_u64(filter_val)
1616 .ok_or(CodecError::InvalidFilterType(filter_val))?;
1617 let start_location = match filter_type {
1618 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1619 Some(Location::decode(buf)?)
1620 }
1621 _ => None,
1622 };
1623 let end_group = match filter_type {
1624 FilterType::AbsoluteRange => Some(VarInt::decode(buf)?),
1625 _ => None,
1626 };
1627 let parameters = decode_parameters(buf)?;
1628 Ok(ControlMessage::PublishOk(PublishOk {
1629 request_id,
1630 forward,
1631 subscriber_priority,
1632 group_order,
1633 filter_type,
1634 start_location,
1635 end_group,
1636 parameters,
1637 }))
1638 }
1639 MessageType::PublishError => {
1640 let request_id = VarInt::decode(buf)?;
1641 let error_code = VarInt::decode(buf)?;
1642 let reason_phrase = read_reason_phrase(buf)?;
1643 Ok(ControlMessage::PublishError(PublishError {
1644 request_id,
1645 error_code,
1646 reason_phrase,
1647 }))
1648 }
1649 MessageType::PublishDone => {
1650 let request_id = VarInt::decode(buf)?;
1651 let status_code = VarInt::decode(buf)?;
1652 let stream_count = VarInt::decode(buf)?;
1653 let reason_phrase = read_reason_phrase(buf)?;
1654 Ok(ControlMessage::PublishDone(PublishDone {
1655 request_id,
1656 status_code,
1657 stream_count,
1658 reason_phrase,
1659 }))
1660 }
1661 MessageType::PublishNamespace => {
1662 let request_id = VarInt::decode(buf)?;
1663 let track_namespace = TrackNamespace::decode(buf)?;
1664 let parameters = decode_parameters(buf)?;
1665 Ok(ControlMessage::PublishNamespace(PublishNamespace {
1666 request_id,
1667 track_namespace,
1668 parameters,
1669 }))
1670 }
1671 MessageType::PublishNamespaceOk => {
1672 let request_id = VarInt::decode(buf)?;
1673 Ok(ControlMessage::PublishNamespaceOk(PublishNamespaceOk { request_id }))
1674 }
1675 MessageType::PublishNamespaceError => {
1676 let request_id = VarInt::decode(buf)?;
1677 let error_code = VarInt::decode(buf)?;
1678 let reason_phrase = read_reason_phrase(buf)?;
1679 Ok(ControlMessage::PublishNamespaceError(PublishNamespaceError {
1680 request_id,
1681 error_code,
1682 reason_phrase,
1683 }))
1684 }
1685 MessageType::PublishNamespaceDone => {
1686 let track_namespace = TrackNamespace::decode(buf)?;
1687 Ok(ControlMessage::PublishNamespaceDone(PublishNamespaceDone { track_namespace }))
1688 }
1689 MessageType::PublishNamespaceCancel => {
1690 let track_namespace = TrackNamespace::decode(buf)?;
1691 let error_code = VarInt::decode(buf)?;
1692 let reason_phrase = read_reason_phrase(buf)?;
1693 Ok(ControlMessage::PublishNamespaceCancel(PublishNamespaceCancel {
1694 track_namespace,
1695 error_code,
1696 reason_phrase,
1697 }))
1698 }
1699 MessageType::SubscribeNamespace => {
1700 let request_id = VarInt::decode(buf)?;
1701 let track_namespace = TrackNamespace::decode(buf)?;
1702 let parameters = decode_parameters(buf)?;
1703 Ok(ControlMessage::SubscribeNamespace(SubscribeNamespace {
1704 request_id,
1705 track_namespace,
1706 parameters,
1707 }))
1708 }
1709 MessageType::SubscribeNamespaceOk => {
1710 let request_id = VarInt::decode(buf)?;
1711 Ok(ControlMessage::SubscribeNamespaceOk(SubscribeNamespaceOk { request_id }))
1712 }
1713 MessageType::SubscribeNamespaceError => {
1714 let request_id = VarInt::decode(buf)?;
1715 let error_code = VarInt::decode(buf)?;
1716 let reason_phrase = read_reason_phrase(buf)?;
1717 Ok(ControlMessage::SubscribeNamespaceError(SubscribeNamespaceError {
1718 request_id,
1719 error_code,
1720 reason_phrase,
1721 }))
1722 }
1723 MessageType::UnsubscribeNamespace => {
1724 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1725 Ok(ControlMessage::UnsubscribeNamespace(UnsubscribeNamespace {
1726 track_namespace_prefix,
1727 }))
1728 }
1729 MessageType::Fetch => {
1730 let request_id = VarInt::decode(buf)?;
1731 if buf.remaining() < 2 {
1732 return Err(CodecError::UnexpectedEnd);
1733 }
1734 let subscriber_priority = buf.get_u8();
1735 let group_order =
1736 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1737 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1738 let fetch_type = FetchType::from_u64(fetch_type_val)
1739 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1740 let fetch_payload = match fetch_type {
1741 FetchType::Standalone => {
1742 let track_namespace = TrackNamespace::decode(buf)?;
1743 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1744 let track_name = read_bytes(buf, track_name_len)?;
1745 check_full_track_name(&track_namespace, &track_name)?;
1746 let start_group = VarInt::decode(buf)?;
1747 let start_object = VarInt::decode(buf)?;
1748 let end_group = VarInt::decode(buf)?;
1749 let end_object = VarInt::decode(buf)?;
1750 FetchPayload::Standalone {
1751 track_namespace,
1752 track_name,
1753 start_group,
1754 start_object,
1755 end_group,
1756 end_object,
1757 }
1758 }
1759 FetchType::RelativeJoining | FetchType::AbsoluteJoining => {
1760 let joining_request_id = VarInt::decode(buf)?;
1761 let joining_start = VarInt::decode(buf)?;
1762 FetchPayload::Joining { joining_request_id, joining_start }
1763 }
1764 };
1765 let parameters = decode_parameters(buf)?;
1766 Ok(ControlMessage::Fetch(Fetch {
1767 request_id,
1768 subscriber_priority,
1769 group_order,
1770 fetch_type,
1771 fetch_payload,
1772 parameters,
1773 }))
1774 }
1775 MessageType::FetchOk => {
1776 let request_id = VarInt::decode(buf)?;
1777 if buf.remaining() < 2 {
1778 return Err(CodecError::UnexpectedEnd);
1779 }
1780 let group_order = read_group_order_response(buf)?;
1781 let end_of_track = buf.get_u8();
1785 let end_location = Location::decode(buf)?;
1786 let parameters = decode_parameters(buf)?;
1787 Ok(ControlMessage::FetchOk(FetchOk {
1788 request_id,
1789 group_order,
1790 end_of_track,
1791 end_location,
1792 parameters,
1793 }))
1794 }
1795 MessageType::FetchError => {
1796 let request_id = VarInt::decode(buf)?;
1797 let error_code = VarInt::decode(buf)?;
1798 let reason_phrase = read_reason_phrase(buf)?;
1799 Ok(ControlMessage::FetchError(FetchError { request_id, error_code, reason_phrase }))
1800 }
1801 MessageType::FetchCancel => {
1802 let request_id = VarInt::decode(buf)?;
1803 Ok(ControlMessage::FetchCancel(FetchCancel { request_id }))
1804 }
1805 MessageType::TrackStatus => {
1806 let request_id = VarInt::decode(buf)?;
1807 let track_namespace = TrackNamespace::decode(buf)?;
1808 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1809 let track_name = read_bytes(buf, track_name_len)?;
1810 check_full_track_name(&track_namespace, &track_name)?;
1811 if buf.remaining() < 3 {
1812 return Err(CodecError::UnexpectedEnd);
1813 }
1814 let subscriber_priority = buf.get_u8();
1815 let group_order =
1816 GroupOrder::from_u8(buf.get_u8()).ok_or(CodecError::InvalidField)?;
1817 let forward_val = buf.get_u8();
1818 let forward = match forward_val {
1819 0 => Forward::DontForward,
1820 1 => Forward::Forward,
1821 other => return Err(CodecError::InvalidForward(other)),
1822 };
1823 let filter_val = VarInt::decode(buf)?.into_inner();
1829 let filter_type = FilterType::from_u64(filter_val)
1830 .ok_or(CodecError::InvalidFilterType(filter_val))?;
1831 let start_location = match filter_type {
1832 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
1833 Some(Location::decode(buf)?)
1834 }
1835 _ => None,
1836 };
1837 let end_group = match filter_type {
1838 FilterType::AbsoluteRange => Some(VarInt::decode(buf)?),
1839 _ => None,
1840 };
1841 let parameters = decode_parameters(buf)?;
1842 Ok(ControlMessage::TrackStatus(TrackStatus {
1843 request_id,
1844 track_namespace,
1845 track_name,
1846 subscriber_priority,
1847 group_order,
1848 forward,
1849 filter_type,
1850 start_location,
1851 end_group,
1852 parameters,
1853 }))
1854 }
1855 MessageType::TrackStatusOk => {
1856 let request_id = VarInt::decode(buf)?;
1857 let track_alias = VarInt::decode(buf)?;
1858 let expires = VarInt::decode(buf)?;
1859 if buf.remaining() < 2 {
1860 return Err(CodecError::UnexpectedEnd);
1861 }
1862 let group_order = read_group_order_response(buf)?;
1863 let content_exists_val = buf.get_u8();
1864 let content_exists = match content_exists_val {
1865 0 => ContentExists::NoLargestLocation,
1866 1 => ContentExists::HasLargestLocation,
1867 other => return Err(CodecError::InvalidContentExists(other)),
1868 };
1869 let largest_location = if content_exists == ContentExists::HasLargestLocation {
1870 Some(Location::decode(buf)?)
1871 } else {
1872 None
1873 };
1874 let parameters = decode_parameters(buf)?;
1875 Ok(ControlMessage::TrackStatusOk(TrackStatusOk {
1876 request_id,
1877 track_alias,
1878 expires,
1879 group_order,
1880 content_exists,
1881 largest_location,
1882 parameters,
1883 }))
1884 }
1885 MessageType::TrackStatusError => {
1886 let request_id = VarInt::decode(buf)?;
1887 let error_code = VarInt::decode(buf)?;
1888 let reason_phrase = read_reason_phrase(buf)?;
1889 Ok(ControlMessage::TrackStatusError(TrackStatusError {
1890 request_id,
1891 error_code,
1892 reason_phrase,
1893 }))
1894 }
1895 }
1896 }
1897
1898 pub fn message_type(&self) -> MessageType {
1900 match self {
1901 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
1902 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
1903 ControlMessage::GoAway(_) => MessageType::GoAway,
1904 ControlMessage::MaxRequestId(_) => MessageType::MaxRequestId,
1905 ControlMessage::RequestsBlocked(_) => MessageType::RequestsBlocked,
1906 ControlMessage::Subscribe(_) => MessageType::Subscribe,
1907 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
1908 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
1909 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
1910 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
1911 ControlMessage::Publish(_) => MessageType::Publish,
1912 ControlMessage::PublishOk(_) => MessageType::PublishOk,
1913 ControlMessage::PublishError(_) => MessageType::PublishError,
1914 ControlMessage::PublishDone(_) => MessageType::PublishDone,
1915 ControlMessage::PublishNamespace(_) => MessageType::PublishNamespace,
1916 ControlMessage::PublishNamespaceOk(_) => MessageType::PublishNamespaceOk,
1917 ControlMessage::PublishNamespaceError(_) => MessageType::PublishNamespaceError,
1918 ControlMessage::PublishNamespaceDone(_) => MessageType::PublishNamespaceDone,
1919 ControlMessage::PublishNamespaceCancel(_) => MessageType::PublishNamespaceCancel,
1920 ControlMessage::SubscribeNamespace(_) => MessageType::SubscribeNamespace,
1921 ControlMessage::SubscribeNamespaceOk(_) => MessageType::SubscribeNamespaceOk,
1922 ControlMessage::SubscribeNamespaceError(_) => MessageType::SubscribeNamespaceError,
1923 ControlMessage::UnsubscribeNamespace(_) => MessageType::UnsubscribeNamespace,
1924 ControlMessage::Fetch(_) => MessageType::Fetch,
1925 ControlMessage::FetchOk(_) => MessageType::FetchOk,
1926 ControlMessage::FetchError(_) => MessageType::FetchError,
1927 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
1928 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
1929 ControlMessage::TrackStatusOk(_) => MessageType::TrackStatusOk,
1930 ControlMessage::TrackStatusError(_) => MessageType::TrackStatusError,
1931 }
1932 }
1933}