1use crate::auth_token::{AuthorizationToken, AUTH_TOKEN_PARAMETER};
16use crate::error::{
17 CodecError, MAX_FULL_TRACK_NAME_LENGTH, MAX_GOAWAY_URI_LENGTH, MAX_MESSAGE_LENGTH,
18 MAX_REASON_PHRASE_LENGTH,
19};
20use crate::kvp::{KeyValuePair, KvpValue};
21use crate::subscription_filter::{SubscriptionFilter, SUBSCRIPTION_FILTER_PARAMETER};
22pub use crate::types::check_location_range;
23use crate::types::*;
24use crate::varint::VarInt;
25use bytes::{Buf, BufMut};
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28#[repr(u64)]
29pub enum MessageType {
30 SubscribeUpdate = 0x02,
31 Subscribe = 0x03,
32 SubscribeOk = 0x04,
33 RequestError = 0x05,
34 PublishNamespace = 0x06,
35 RequestOk = 0x07,
36 PublishNamespaceDone = 0x09,
37 Unsubscribe = 0x0A,
38 PublishDone = 0x0B,
39 PublishNamespaceCancel = 0x0C,
40 TrackStatus = 0x0D,
41 GoAway = 0x10,
42 SubscribeNamespace = 0x11,
43 UnsubscribeNamespace = 0x14,
44 MaxRequestId = 0x15,
45 Fetch = 0x16,
46 FetchCancel = 0x17,
47 FetchOk = 0x18,
48 RequestsBlocked = 0x1A,
49 Publish = 0x1D,
50 PublishOk = 0x1E,
51 ClientSetup = 0x20,
52 ServerSetup = 0x21,
53}
54
55impl MessageType {
56 pub fn from_id(id: u64) -> Option<Self> {
57 match id {
58 0x02 => Some(MessageType::SubscribeUpdate),
59 0x03 => Some(MessageType::Subscribe),
60 0x04 => Some(MessageType::SubscribeOk),
61 0x05 => Some(MessageType::RequestError),
62 0x06 => Some(MessageType::PublishNamespace),
63 0x07 => Some(MessageType::RequestOk),
64 0x09 => Some(MessageType::PublishNamespaceDone),
65 0x0A => Some(MessageType::Unsubscribe),
66 0x0B => Some(MessageType::PublishDone),
67 0x0C => Some(MessageType::PublishNamespaceCancel),
68 0x0D => Some(MessageType::TrackStatus),
69 0x10 => Some(MessageType::GoAway),
70 0x11 => Some(MessageType::SubscribeNamespace),
71 0x14 => Some(MessageType::UnsubscribeNamespace),
72 0x15 => Some(MessageType::MaxRequestId),
73 0x16 => Some(MessageType::Fetch),
74 0x17 => Some(MessageType::FetchCancel),
75 0x18 => Some(MessageType::FetchOk),
76 0x1A => Some(MessageType::RequestsBlocked),
77 0x1D => Some(MessageType::Publish),
78 0x1E => Some(MessageType::PublishOk),
79 0x20 => Some(MessageType::ClientSetup),
80 0x21 => Some(MessageType::ServerSetup),
81 _ => None,
82 }
83 }
84
85 pub fn id(&self) -> u64 {
86 *self as u64
87 }
88}
89
90#[derive(Debug, Clone, PartialEq, Eq)]
96pub struct ClientSetup {
97 pub parameters: Vec<KeyValuePair>,
98}
99
100#[derive(Debug, Clone, PartialEq, Eq)]
102pub struct ServerSetup {
103 pub parameters: Vec<KeyValuePair>,
104}
105
106#[derive(Debug, Clone, PartialEq, Eq)]
107pub struct GoAway {
108 pub new_session_uri: Vec<u8>,
109}
110
111#[derive(Debug, Clone, PartialEq, Eq)]
112pub struct MaxRequestId {
113 pub request_id: VarInt,
114}
115
116#[derive(Debug, Clone, PartialEq, Eq)]
117pub struct RequestsBlocked {
118 pub maximum_request_id: VarInt,
119}
120
121#[derive(Debug, Clone, PartialEq, Eq)]
127pub struct RequestOk {
128 pub request_id: VarInt,
129 pub parameters: Vec<KeyValuePair>,
130}
131
132#[derive(Debug, Clone, PartialEq, Eq)]
134pub struct RequestError {
135 pub request_id: VarInt,
136 pub error_code: VarInt,
137 pub reason_phrase: Vec<u8>,
138}
139
140#[derive(Debug, Clone, PartialEq, Eq)]
146pub struct Subscribe {
147 pub request_id: VarInt,
148 pub track_namespace: TrackNamespace,
149 pub track_name: Vec<u8>,
150 pub parameters: Vec<KeyValuePair>,
151}
152
153#[derive(Debug, Clone, PartialEq, Eq)]
155pub struct SubscribeOk {
156 pub request_id: VarInt,
157 pub track_alias: VarInt,
158 pub parameters: Vec<KeyValuePair>,
159}
160
161#[derive(Debug, Clone, PartialEq, Eq)]
163pub struct SubscribeUpdate {
164 pub request_id: VarInt,
165 pub subscription_request_id: VarInt,
166 pub parameters: Vec<KeyValuePair>,
167}
168
169#[derive(Debug, Clone, PartialEq, Eq)]
170pub struct Unsubscribe {
171 pub request_id: VarInt,
172}
173
174#[derive(Debug, Clone, PartialEq, Eq)]
180pub struct Publish {
181 pub request_id: VarInt,
182 pub track_namespace: TrackNamespace,
183 pub track_name: Vec<u8>,
184 pub track_alias: VarInt,
185 pub parameters: Vec<KeyValuePair>,
186}
187
188#[derive(Debug, Clone, PartialEq, Eq)]
190pub struct PublishOk {
191 pub request_id: VarInt,
192 pub parameters: Vec<KeyValuePair>,
193}
194
195#[derive(Debug, Clone, PartialEq, Eq)]
197pub struct PublishDone {
198 pub request_id: VarInt,
199 pub status_code: VarInt,
200 pub stream_count: VarInt,
201 pub reason_phrase: Vec<u8>,
202}
203
204#[derive(Debug, Clone, PartialEq, Eq)]
210pub struct PublishNamespace {
211 pub request_id: VarInt,
212 pub track_namespace: TrackNamespace,
213 pub parameters: Vec<KeyValuePair>,
214}
215
216#[derive(Debug, Clone, PartialEq, Eq)]
218pub struct PublishNamespaceDone {
219 pub track_namespace: TrackNamespace,
220}
221
222#[derive(Debug, Clone, PartialEq, Eq)]
224pub struct PublishNamespaceCancel {
225 pub track_namespace: TrackNamespace,
226 pub error_code: VarInt,
227 pub reason_phrase: Vec<u8>,
228}
229
230#[derive(Debug, Clone, PartialEq, Eq)]
235pub struct SubscribeNamespace {
236 pub request_id: VarInt,
237 pub namespace_prefix: TrackNamespace,
238 pub parameters: Vec<KeyValuePair>,
239}
240
241#[derive(Debug, Clone, PartialEq, Eq)]
243pub struct UnsubscribeNamespace {
244 pub request_id: VarInt,
245}
246
247#[derive(Debug, Clone, PartialEq, Eq)]
253pub struct TrackStatus {
254 pub request_id: VarInt,
255 pub track_namespace: TrackNamespace,
256 pub track_name: Vec<u8>,
257 pub parameters: Vec<KeyValuePair>,
258}
259
260#[derive(Debug, Clone, Copy, PartialEq, Eq)]
265#[repr(u64)]
266pub enum FetchType {
267 Standalone = 1,
269 RelativeJoining = 2,
271 AbsoluteJoining = 3,
273}
274
275impl FetchType {
276 pub fn from_u64(v: u64) -> Option<Self> {
278 match v {
279 1 => Some(FetchType::Standalone),
280 2 => Some(FetchType::RelativeJoining),
281 3 => Some(FetchType::AbsoluteJoining),
282 _ => None,
283 }
284 }
285}
286
287#[derive(Debug, Clone, PartialEq, Eq)]
288pub struct Fetch {
289 pub request_id: VarInt,
290 pub fetch_type: FetchType,
291 pub fetch_payload: FetchPayload,
292 pub parameters: Vec<KeyValuePair>,
293}
294
295#[derive(Debug, Clone, PartialEq, Eq)]
296pub enum FetchPayload {
297 Standalone {
298 track_namespace: TrackNamespace,
299 track_name: Vec<u8>,
300 start_group: VarInt,
301 start_object: VarInt,
302 end_group: VarInt,
303 end_object: VarInt,
304 },
305 Joining {
306 joining_request_id: VarInt,
307 joining_start: VarInt,
308 },
309}
310
311#[derive(Debug, Clone, PartialEq, Eq)]
312pub struct FetchOk {
313 pub request_id: VarInt,
314 pub end_of_track: u8,
321 pub end_group: VarInt,
322 pub end_object: VarInt,
323 pub parameters: Vec<KeyValuePair>,
324}
325
326#[derive(Debug, Clone, PartialEq, Eq)]
327pub struct FetchCancel {
328 pub request_id: VarInt,
329}
330
331fn read_u8(buf: &mut impl Buf) -> Result<u8, CodecError> {
337 if !buf.has_remaining() {
338 return Err(CodecError::UnexpectedEnd);
339 }
340 Ok(buf.get_u8())
341}
342
343#[derive(Debug, Clone, PartialEq, Eq)]
344pub enum ControlMessage {
345 ClientSetup(ClientSetup),
346 ServerSetup(ServerSetup),
347 GoAway(GoAway),
348 MaxRequestId(MaxRequestId),
349 RequestsBlocked(RequestsBlocked),
350 RequestOk(RequestOk),
351 RequestError(RequestError),
352 Subscribe(Subscribe),
353 SubscribeOk(SubscribeOk),
354 SubscribeUpdate(SubscribeUpdate),
355 Unsubscribe(Unsubscribe),
356 Publish(Publish),
357 PublishOk(PublishOk),
358 PublishDone(PublishDone),
359 PublishNamespace(PublishNamespace),
360 PublishNamespaceDone(PublishNamespaceDone),
361 PublishNamespaceCancel(PublishNamespaceCancel),
362 SubscribeNamespace(SubscribeNamespace),
363 UnsubscribeNamespace(UnsubscribeNamespace),
364 TrackStatus(TrackStatus),
365 Fetch(Fetch),
366 FetchOk(FetchOk),
367 FetchCancel(FetchCancel),
368}
369
370fn check_full_track_name(namespace: &TrackNamespace, track_name: &[u8]) -> Result<(), CodecError> {
371 let total = namespace.field_bytes_len().saturating_add(track_name.len());
372 if total > MAX_FULL_TRACK_NAME_LENGTH {
373 return Err(CodecError::TrackNameTooLong);
374 }
375 Ok(())
376}
377
378fn read_reason_phrase(buf: &mut impl Buf) -> Result<Vec<u8>, CodecError> {
386 let len = VarInt::decode(buf)?.into_inner() as usize;
387 if len > MAX_REASON_PHRASE_LENGTH {
388 return Err(CodecError::ReasonPhraseTooLong);
389 }
390 read_bytes(buf, len)
391}
392
393fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
409 match message {
410 ControlMessage::Fetch(m) => match &m.fetch_payload {
411 FetchPayload::Standalone {
412 start_group, start_object, end_group, end_object, ..
413 } => check_location_range(
414 start_group.into_inner(),
415 start_object.into_inner(),
416 end_group.into_inner(),
417 end_object.into_inner(),
418 ),
419 FetchPayload::Joining { .. } => Ok(()),
420 },
421 _ => Ok(()),
422 }
423}
424
425fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
456 if let ControlMessage::Fetch(m) = message {
457 let body_is_standalone = matches!(m.fetch_payload, FetchPayload::Standalone { .. });
458 if body_is_standalone != (m.fetch_type == FetchType::Standalone) {
459 return Err(CodecError::InvalidField);
460 }
461 }
462 Ok(())
463}
464
465const REPEATABLE_PARAMETER: u64 = 0x03;
487
488const KNOWN_VERSION_SPECIFIC_PARAMETERS: &[u64] =
504 &[0x02, 0x03, 0x04, 0x08, 0x09, 0x0E, 0x10, 0x20, 0x21, 0x22, 0x30, 0x32];
505
506const KNOWN_SETUP_PARAMETERS: &[u64] = &[0x01, 0x02, 0x03, 0x04, 0x05, 0x07];
520
521fn check_no_duplicate_parameters_sent(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
533 for (i, parameter) in parameters.iter().enumerate() {
534 let key = parameter.key.into_inner();
535 if key == REPEATABLE_PARAMETER {
536 continue;
537 }
538 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
539 return Err(CodecError::DuplicateParameter(key));
540 }
541 }
542 Ok(())
543}
544
545fn check_no_duplicate_parameters_received(
563 parameters: &[KeyValuePair],
564 known: &[u64],
565) -> Result<(), CodecError> {
566 for (i, parameter) in parameters.iter().enumerate() {
567 let key = parameter.key.into_inner();
568 if key == REPEATABLE_PARAMETER || !known.contains(&key) {
569 continue;
570 }
571 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
572 return Err(CodecError::DuplicateParameter(key));
573 }
574 }
575 Ok(())
576}
577
578fn check_authorization_tokens(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
593 for parameter in parameters {
594 let key = parameter.key.into_inner();
595 if key != AUTH_TOKEN_PARAMETER {
596 continue;
597 }
598 match ¶meter.value {
599 KvpValue::Bytes(value) => {
600 AuthorizationToken::decode(key, value)?;
601 }
602 KvpValue::Varint(_) => {
607 return Err(CodecError::KeyValueFormatting {
608 key,
609 detail: "its value is a bare varint where the type defines a Token structure",
610 });
611 }
612 }
613 }
614 Ok(())
615}
616
617fn parameter_value_in_range(key: u64, value: u64) -> bool {
642 match key {
643 0x10 | 0x30 => value <= 1,
645 0x20 => value <= 255,
647 0x22 => value == 1 || value == 2,
649 _ => true,
650 }
651}
652
653fn check_parameter_value_ranges(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
660 for parameter in parameters {
661 if let KvpValue::Varint(value) = ¶meter.value {
662 let key = parameter.key.into_inner();
663 let value = value.into_inner();
664 if !parameter_value_in_range(key, value) {
665 return Err(CodecError::ParameterValueOutOfRange { key, value });
666 }
667 }
668 }
669 Ok(())
670}
671
672fn check_subscription_filters(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
694 for parameter in parameters {
695 if parameter.key.into_inner() != SUBSCRIPTION_FILTER_PARAMETER {
696 continue;
697 }
698 match ¶meter.value {
699 KvpValue::Bytes(value) => {
700 SubscriptionFilter::decode(value)?;
701 }
702 KvpValue::Varint(_) => {
706 return Err(CodecError::SubscriptionFilterMalformed {
707 detail: "its value is a bare varint where the type defines a filter",
708 });
709 }
710 }
711 }
712 Ok(())
713}
714
715fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
717 let parameters = KeyValuePair::decode_list(buf)?;
718 check_no_duplicate_parameters_received(¶meters, KNOWN_VERSION_SPECIFIC_PARAMETERS)?;
719 check_authorization_tokens(¶meters)?;
720 check_parameter_value_ranges(¶meters)?;
721 check_subscription_filters(¶meters)?;
722 Ok(parameters)
723}
724
725fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
730 let parameters = KeyValuePair::decode_list(buf)?;
731 check_no_duplicate_parameters_received(¶meters, KNOWN_SETUP_PARAMETERS)?;
732 check_authorization_tokens(¶meters)?;
733 Ok(parameters)
734}
735
736fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
747 check_no_duplicate_parameters_sent(parameters)?;
748 check_authorization_tokens(parameters)?;
749 check_parameter_value_ranges(parameters)?;
750 check_subscription_filters(parameters)?;
751 KeyValuePair::encode_list_checked(parameters, buf)?;
752 Ok(())
753}
754
755fn encode_setup_parameters(
762 parameters: &[KeyValuePair],
763 buf: &mut impl BufMut,
764) -> Result<(), CodecError> {
765 check_no_duplicate_parameters_sent(parameters)?;
766 check_authorization_tokens(parameters)?;
767 KeyValuePair::encode_list_checked(parameters, buf)?;
768 Ok(())
769}
770
771impl ControlMessage {
772 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
773 check_discriminators(self)?;
774 check_ranges(self)?;
775 let mut payload = Vec::with_capacity(256);
776 self.encode_payload(&mut payload)?;
777
778 if payload.len() > MAX_MESSAGE_LENGTH {
779 return Err(CodecError::MessageTooLong(payload.len()));
780 }
781
782 let msg_type = self.message_type();
783 VarInt::from_usize(msg_type.id() as usize).encode(buf);
784 buf.put_u16(payload.len() as u16);
786 buf.put_slice(&payload);
787 Ok(())
788 }
789
790 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
791 let type_id = VarInt::decode(buf)?.into_inner();
792 let msg_type =
793 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
794 if buf.remaining() < 2 {
796 return Err(CodecError::UnexpectedEnd);
797 }
798 let payload_len = buf.get_u16() as usize;
799 if buf.remaining() < payload_len {
800 return Err(CodecError::UnexpectedEnd);
801 }
802 let payload_bytes = buf.copy_to_bytes(payload_len);
803 let mut payload = &payload_bytes[..];
804 let msg = match Self::decode_payload(msg_type, &mut payload) {
805 Ok(msg) => msg,
806 Err(
812 CodecError::UnexpectedEnd
813 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
814 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
815 crate::varint::VarIntError::UnexpectedEnd,
816 ))
817 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
818 ) => {
819 return Err(CodecError::ControlMessageLengthMismatch {
820 declared: payload_len,
821 detail: "its fields ran past the end",
822 });
823 }
824 Err(e) => return Err(e),
825 };
826 check_ranges(&msg)?;
827 if payload.has_remaining() {
838 return Err(CodecError::ControlMessageLengthMismatch {
839 declared: payload_len,
840 detail: "its fields left bytes unread",
841 });
842 }
843 Ok(msg)
844 }
845
846 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
847 match self {
848 ControlMessage::ClientSetup(m) => {
849 encode_setup_parameters(&m.parameters, buf)?;
850 }
851 ControlMessage::ServerSetup(m) => {
852 encode_setup_parameters(&m.parameters, buf)?;
853 }
854 ControlMessage::GoAway(m) => {
855 if m.new_session_uri.len() > MAX_GOAWAY_URI_LENGTH {
856 return Err(CodecError::GoAwayUriTooLong);
857 }
858 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
859 buf.put_slice(&m.new_session_uri);
860 }
861 ControlMessage::MaxRequestId(m) => {
862 m.request_id.encode(buf);
863 }
864 ControlMessage::RequestsBlocked(m) => {
865 m.maximum_request_id.encode(buf);
866 }
867 ControlMessage::RequestOk(m) => {
868 m.request_id.encode(buf);
869 encode_parameters(&m.parameters, buf)?;
870 }
871 ControlMessage::RequestError(m) => {
872 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
873 return Err(CodecError::ReasonPhraseTooLong);
874 }
875 m.request_id.encode(buf);
876 m.error_code.encode(buf);
877 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
878 buf.put_slice(&m.reason_phrase);
879 }
880 ControlMessage::Subscribe(m) => {
881 m.request_id.encode(buf);
882 m.track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
883 m.track_namespace.encode(buf);
884 check_full_track_name(&m.track_namespace, &m.track_name)?;
885 VarInt::from_usize(m.track_name.len()).encode(buf);
886 buf.put_slice(&m.track_name);
887 encode_parameters(&m.parameters, buf)?;
888 }
889 ControlMessage::SubscribeOk(m) => {
890 m.request_id.encode(buf);
891 m.track_alias.encode(buf);
892 encode_parameters(&m.parameters, buf)?;
893 }
894 ControlMessage::SubscribeUpdate(m) => {
895 m.request_id.encode(buf);
896 m.subscription_request_id.encode(buf);
897 encode_parameters(&m.parameters, buf)?;
898 }
899 ControlMessage::Unsubscribe(m) => {
900 m.request_id.encode(buf);
901 }
902 ControlMessage::Publish(m) => {
903 m.request_id.encode(buf);
904 m.track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
905 m.track_namespace.encode(buf);
906 check_full_track_name(&m.track_namespace, &m.track_name)?;
907 VarInt::from_usize(m.track_name.len()).encode(buf);
908 buf.put_slice(&m.track_name);
909 m.track_alias.encode(buf);
910 encode_parameters(&m.parameters, buf)?;
911 }
912 ControlMessage::PublishOk(m) => {
913 m.request_id.encode(buf);
914 encode_parameters(&m.parameters, buf)?;
915 }
916 ControlMessage::PublishDone(m) => {
917 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
918 return Err(CodecError::ReasonPhraseTooLong);
919 }
920 m.request_id.encode(buf);
921 m.status_code.encode(buf);
922 m.stream_count.encode(buf);
923 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
924 buf.put_slice(&m.reason_phrase);
925 }
926 ControlMessage::PublishNamespace(m) => {
927 m.request_id.encode(buf);
928 m.track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
929 m.track_namespace.encode(buf);
930 encode_parameters(&m.parameters, buf)?;
931 }
932 ControlMessage::PublishNamespaceDone(m) => {
933 m.track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
934 m.track_namespace.encode(buf);
935 }
936 ControlMessage::PublishNamespaceCancel(m) => {
937 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
938 return Err(CodecError::ReasonPhraseTooLong);
939 }
940 m.track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
941 m.track_namespace.encode(buf);
942 m.error_code.encode(buf);
943 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
944 buf.put_slice(&m.reason_phrase);
945 }
946 ControlMessage::SubscribeNamespace(m) => {
947 m.request_id.encode(buf);
948 m.namespace_prefix.validate(TrackNamespaceRules::for_draft(15))?;
949 m.namespace_prefix.encode(buf);
950 encode_parameters(&m.parameters, buf)?;
951 }
952 ControlMessage::UnsubscribeNamespace(m) => {
953 m.request_id.encode(buf);
954 }
955 ControlMessage::TrackStatus(m) => {
956 m.request_id.encode(buf);
957 m.track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
958 m.track_namespace.encode(buf);
959 check_full_track_name(&m.track_namespace, &m.track_name)?;
960 VarInt::from_usize(m.track_name.len()).encode(buf);
961 buf.put_slice(&m.track_name);
962 encode_parameters(&m.parameters, buf)?;
963 }
964 ControlMessage::Fetch(m) => {
965 m.request_id.encode(buf);
966 VarInt::from_usize(m.fetch_type as usize).encode(buf);
967 match &m.fetch_payload {
968 FetchPayload::Standalone {
969 track_namespace,
970 track_name,
971 start_group,
972 start_object,
973 end_group,
974 end_object,
975 } => {
976 track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
977 track_namespace.encode(buf);
978 check_full_track_name(track_namespace, track_name)?;
979 VarInt::from_usize(track_name.len()).encode(buf);
980 buf.put_slice(track_name);
981 start_group.encode(buf);
982 start_object.encode(buf);
983 end_group.encode(buf);
984 end_object.encode(buf);
985 }
986 FetchPayload::Joining { joining_request_id, joining_start } => {
987 joining_request_id.encode(buf);
988 joining_start.encode(buf);
989 }
990 }
991 encode_parameters(&m.parameters, buf)?;
992 }
993 ControlMessage::FetchOk(m) => {
994 m.request_id.encode(buf);
995 buf.put_u8(m.end_of_track);
996 m.end_group.encode(buf);
997 m.end_object.encode(buf);
998 encode_parameters(&m.parameters, buf)?;
999 }
1000 ControlMessage::FetchCancel(m) => {
1001 m.request_id.encode(buf);
1002 }
1003 }
1004 Ok(())
1005 }
1006
1007 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1008 match msg_type {
1009 MessageType::ClientSetup => {
1010 let parameters = decode_setup_parameters(buf)?;
1011 Ok(ControlMessage::ClientSetup(ClientSetup { parameters }))
1012 }
1013 MessageType::ServerSetup => {
1014 let parameters = decode_setup_parameters(buf)?;
1015 Ok(ControlMessage::ServerSetup(ServerSetup { parameters }))
1016 }
1017 MessageType::GoAway => {
1018 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1019 if uri_len > MAX_GOAWAY_URI_LENGTH {
1020 return Err(CodecError::GoAwayUriTooLong);
1021 }
1022 let uri = read_bytes(buf, uri_len)?;
1023 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1024 }
1025 MessageType::MaxRequestId => {
1026 let request_id = VarInt::decode(buf)?;
1027 Ok(ControlMessage::MaxRequestId(MaxRequestId { request_id }))
1028 }
1029 MessageType::RequestsBlocked => {
1030 let maximum_request_id = VarInt::decode(buf)?;
1031 Ok(ControlMessage::RequestsBlocked(RequestsBlocked { maximum_request_id }))
1032 }
1033 MessageType::RequestOk => {
1034 let request_id = VarInt::decode(buf)?;
1035 let parameters = decode_parameters(buf)?;
1036 Ok(ControlMessage::RequestOk(RequestOk { request_id, parameters }))
1037 }
1038 MessageType::RequestError => {
1039 let request_id = VarInt::decode(buf)?;
1040 let error_code = VarInt::decode(buf)?;
1041 let reason_phrase = read_reason_phrase(buf)?;
1042 Ok(ControlMessage::RequestError(RequestError {
1043 request_id,
1044 error_code,
1045 reason_phrase,
1046 }))
1047 }
1048 MessageType::Subscribe => {
1049 let request_id = VarInt::decode(buf)?;
1050 let track_namespace = TrackNamespace::decode(buf)?;
1051 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1052 let track_name = read_bytes(buf, track_name_len)?;
1053 check_full_track_name(&track_namespace, &track_name)?;
1054 let parameters = decode_parameters(buf)?;
1055 Ok(ControlMessage::Subscribe(Subscribe {
1056 request_id,
1057 track_namespace,
1058 track_name,
1059 parameters,
1060 }))
1061 }
1062 MessageType::SubscribeOk => {
1063 let request_id = VarInt::decode(buf)?;
1064 let track_alias = VarInt::decode(buf)?;
1065 let parameters = decode_parameters(buf)?;
1066 Ok(ControlMessage::SubscribeOk(SubscribeOk { request_id, track_alias, parameters }))
1067 }
1068 MessageType::SubscribeUpdate => {
1069 let request_id = VarInt::decode(buf)?;
1070 let subscription_request_id = VarInt::decode(buf)?;
1071 let parameters = decode_parameters(buf)?;
1072 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1073 request_id,
1074 subscription_request_id,
1075 parameters,
1076 }))
1077 }
1078 MessageType::Unsubscribe => {
1079 let request_id = VarInt::decode(buf)?;
1080 Ok(ControlMessage::Unsubscribe(Unsubscribe { request_id }))
1081 }
1082 MessageType::Publish => {
1083 let request_id = VarInt::decode(buf)?;
1084 let track_namespace = TrackNamespace::decode(buf)?;
1085 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1086 let track_name = read_bytes(buf, track_name_len)?;
1087 check_full_track_name(&track_namespace, &track_name)?;
1088 let track_alias = VarInt::decode(buf)?;
1089 let parameters = decode_parameters(buf)?;
1090 Ok(ControlMessage::Publish(Publish {
1091 request_id,
1092 track_namespace,
1093 track_name,
1094 track_alias,
1095 parameters,
1096 }))
1097 }
1098 MessageType::PublishOk => {
1099 let request_id = VarInt::decode(buf)?;
1100 let parameters = decode_parameters(buf)?;
1101 Ok(ControlMessage::PublishOk(PublishOk { request_id, parameters }))
1102 }
1103 MessageType::PublishDone => {
1104 let request_id = VarInt::decode(buf)?;
1105 let status_code = VarInt::decode(buf)?;
1106 let stream_count = VarInt::decode(buf)?;
1107 let reason_phrase = read_reason_phrase(buf)?;
1108 Ok(ControlMessage::PublishDone(PublishDone {
1109 request_id,
1110 status_code,
1111 stream_count,
1112 reason_phrase,
1113 }))
1114 }
1115 MessageType::PublishNamespace => {
1116 let request_id = VarInt::decode(buf)?;
1117 let track_namespace = TrackNamespace::decode(buf)?;
1118 let parameters = decode_parameters(buf)?;
1119 Ok(ControlMessage::PublishNamespace(PublishNamespace {
1120 request_id,
1121 track_namespace,
1122 parameters,
1123 }))
1124 }
1125 MessageType::PublishNamespaceDone => {
1126 let track_namespace = TrackNamespace::decode(buf)?;
1127 Ok(ControlMessage::PublishNamespaceDone(PublishNamespaceDone { track_namespace }))
1128 }
1129 MessageType::PublishNamespaceCancel => {
1130 let track_namespace = TrackNamespace::decode(buf)?;
1131 let error_code = VarInt::decode(buf)?;
1132 let reason_phrase = read_reason_phrase(buf)?;
1133 Ok(ControlMessage::PublishNamespaceCancel(PublishNamespaceCancel {
1134 track_namespace,
1135 error_code,
1136 reason_phrase,
1137 }))
1138 }
1139 MessageType::SubscribeNamespace => {
1140 let request_id = VarInt::decode(buf)?;
1141 let namespace_prefix = TrackNamespace::decode(buf)?;
1142 let parameters = decode_parameters(buf)?;
1143 Ok(ControlMessage::SubscribeNamespace(SubscribeNamespace {
1144 request_id,
1145 namespace_prefix,
1146 parameters,
1147 }))
1148 }
1149 MessageType::UnsubscribeNamespace => {
1150 let request_id = VarInt::decode(buf)?;
1151 Ok(ControlMessage::UnsubscribeNamespace(UnsubscribeNamespace { request_id }))
1152 }
1153 MessageType::TrackStatus => {
1154 let request_id = VarInt::decode(buf)?;
1155 let track_namespace = TrackNamespace::decode(buf)?;
1156 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1157 let track_name = read_bytes(buf, track_name_len)?;
1158 check_full_track_name(&track_namespace, &track_name)?;
1159 let parameters = decode_parameters(buf)?;
1160 Ok(ControlMessage::TrackStatus(TrackStatus {
1161 request_id,
1162 track_namespace,
1163 track_name,
1164 parameters,
1165 }))
1166 }
1167 MessageType::Fetch => {
1168 let request_id = VarInt::decode(buf)?;
1169 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1170 let fetch_type = FetchType::from_u64(fetch_type_val)
1171 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1172 let fetch_payload = match fetch_type {
1173 FetchType::Standalone => {
1174 let track_namespace = TrackNamespace::decode(buf)?;
1175 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1176 let track_name = read_bytes(buf, track_name_len)?;
1177 check_full_track_name(&track_namespace, &track_name)?;
1178 let start_group = VarInt::decode(buf)?;
1179 let start_object = VarInt::decode(buf)?;
1180 let end_group = VarInt::decode(buf)?;
1181 let end_object = VarInt::decode(buf)?;
1182 FetchPayload::Standalone {
1183 track_namespace,
1184 track_name,
1185 start_group,
1186 start_object,
1187 end_group,
1188 end_object,
1189 }
1190 }
1191 FetchType::RelativeJoining | FetchType::AbsoluteJoining => {
1192 let joining_request_id = VarInt::decode(buf)?;
1193 let joining_start = VarInt::decode(buf)?;
1194 FetchPayload::Joining { joining_request_id, joining_start }
1195 }
1196 };
1197 let parameters = decode_parameters(buf)?;
1198 Ok(ControlMessage::Fetch(Fetch {
1199 request_id,
1200 fetch_type,
1201 fetch_payload,
1202 parameters,
1203 }))
1204 }
1205 MessageType::FetchOk => {
1206 let request_id = VarInt::decode(buf)?;
1207 let end_of_track = read_u8(buf)?;
1208 let end_group = VarInt::decode(buf)?;
1209 let end_object = VarInt::decode(buf)?;
1210 let parameters = decode_parameters(buf)?;
1211 Ok(ControlMessage::FetchOk(FetchOk {
1212 request_id,
1213 end_of_track,
1214 end_group,
1215 end_object,
1216 parameters,
1217 }))
1218 }
1219 MessageType::FetchCancel => {
1220 let request_id = VarInt::decode(buf)?;
1221 Ok(ControlMessage::FetchCancel(FetchCancel { request_id }))
1222 }
1223 }
1224 }
1225
1226 pub fn message_type(&self) -> MessageType {
1227 match self {
1228 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
1229 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
1230 ControlMessage::GoAway(_) => MessageType::GoAway,
1231 ControlMessage::MaxRequestId(_) => MessageType::MaxRequestId,
1232 ControlMessage::RequestsBlocked(_) => MessageType::RequestsBlocked,
1233 ControlMessage::RequestOk(_) => MessageType::RequestOk,
1234 ControlMessage::RequestError(_) => MessageType::RequestError,
1235 ControlMessage::Subscribe(_) => MessageType::Subscribe,
1236 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
1237 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
1238 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
1239 ControlMessage::Publish(_) => MessageType::Publish,
1240 ControlMessage::PublishOk(_) => MessageType::PublishOk,
1241 ControlMessage::PublishDone(_) => MessageType::PublishDone,
1242 ControlMessage::PublishNamespace(_) => MessageType::PublishNamespace,
1243 ControlMessage::PublishNamespaceDone(_) => MessageType::PublishNamespaceDone,
1244 ControlMessage::PublishNamespaceCancel(_) => MessageType::PublishNamespaceCancel,
1245 ControlMessage::SubscribeNamespace(_) => MessageType::SubscribeNamespace,
1246 ControlMessage::UnsubscribeNamespace(_) => MessageType::UnsubscribeNamespace,
1247 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
1248 ControlMessage::Fetch(_) => MessageType::Fetch,
1249 ControlMessage::FetchOk(_) => MessageType::FetchOk,
1250 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
1251 }
1252 }
1253}