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 pub fn name(&self) -> &'static str {
92 match self {
93 MessageType::SubscribeUpdate => "subscribe_update",
94 MessageType::Subscribe => "subscribe",
95 MessageType::SubscribeOk => "subscribe_ok",
96 MessageType::RequestError => "request_error",
97 MessageType::PublishNamespace => "publish_namespace",
98 MessageType::RequestOk => "request_ok",
99 MessageType::PublishNamespaceDone => "publish_namespace_done",
100 MessageType::Unsubscribe => "unsubscribe",
101 MessageType::PublishDone => "publish_done",
102 MessageType::PublishNamespaceCancel => "publish_namespace_cancel",
103 MessageType::TrackStatus => "track_status",
104 MessageType::GoAway => "goaway",
105 MessageType::SubscribeNamespace => "subscribe_namespace",
106 MessageType::UnsubscribeNamespace => "unsubscribe_namespace",
107 MessageType::MaxRequestId => "max_request_id",
108 MessageType::Fetch => "fetch",
109 MessageType::FetchCancel => "fetch_cancel",
110 MessageType::FetchOk => "fetch_ok",
111 MessageType::RequestsBlocked => "requests_blocked",
112 MessageType::Publish => "publish",
113 MessageType::PublishOk => "publish_ok",
114 MessageType::ClientSetup => "client_setup",
115 MessageType::ServerSetup => "server_setup",
116 }
117 }
118}
119
120#[derive(Debug, Clone, PartialEq, Eq)]
126pub struct ClientSetup {
127 pub parameters: Vec<KeyValuePair>,
128}
129
130#[derive(Debug, Clone, PartialEq, Eq)]
132pub struct ServerSetup {
133 pub parameters: Vec<KeyValuePair>,
134}
135
136#[derive(Debug, Clone, PartialEq, Eq)]
137pub struct GoAway {
138 pub new_session_uri: Vec<u8>,
139}
140
141#[derive(Debug, Clone, PartialEq, Eq)]
142pub struct MaxRequestId {
143 pub request_id: VarInt,
144}
145
146#[derive(Debug, Clone, PartialEq, Eq)]
147pub struct RequestsBlocked {
148 pub maximum_request_id: VarInt,
149}
150
151#[derive(Debug, Clone, PartialEq, Eq)]
157pub struct RequestOk {
158 pub request_id: VarInt,
159 pub parameters: Vec<KeyValuePair>,
160}
161
162#[derive(Debug, Clone, PartialEq, Eq)]
164pub struct RequestError {
165 pub request_id: VarInt,
166 pub error_code: VarInt,
167 pub reason_phrase: Vec<u8>,
168}
169
170#[derive(Debug, Clone, PartialEq, Eq)]
176pub struct Subscribe {
177 pub request_id: VarInt,
178 pub track_namespace: TrackNamespace,
179 pub track_name: Vec<u8>,
180 pub parameters: Vec<KeyValuePair>,
181}
182
183#[derive(Debug, Clone, PartialEq, Eq)]
185pub struct SubscribeOk {
186 pub request_id: VarInt,
187 pub track_alias: VarInt,
188 pub parameters: Vec<KeyValuePair>,
189}
190
191#[derive(Debug, Clone, PartialEq, Eq)]
193pub struct SubscribeUpdate {
194 pub request_id: VarInt,
195 pub subscription_request_id: VarInt,
196 pub parameters: Vec<KeyValuePair>,
197}
198
199#[derive(Debug, Clone, PartialEq, Eq)]
200pub struct Unsubscribe {
201 pub request_id: VarInt,
202}
203
204#[derive(Debug, Clone, PartialEq, Eq)]
210pub struct Publish {
211 pub request_id: VarInt,
212 pub track_namespace: TrackNamespace,
213 pub track_name: Vec<u8>,
214 pub track_alias: VarInt,
215 pub parameters: Vec<KeyValuePair>,
216}
217
218#[derive(Debug, Clone, PartialEq, Eq)]
220pub struct PublishOk {
221 pub request_id: VarInt,
222 pub parameters: Vec<KeyValuePair>,
223}
224
225#[derive(Debug, Clone, PartialEq, Eq)]
228pub struct PublishDone {
229 pub request_id: VarInt,
230 pub status_code: VarInt,
231 pub stream_count: VarInt,
232 pub reason_phrase: Vec<u8>,
233}
234
235#[derive(Debug, Clone, PartialEq, Eq)]
241pub struct PublishNamespace {
242 pub request_id: VarInt,
243 pub track_namespace: TrackNamespace,
244 pub parameters: Vec<KeyValuePair>,
245}
246
247#[derive(Debug, Clone, PartialEq, Eq)]
249pub struct PublishNamespaceDone {
250 pub track_namespace: TrackNamespace,
251}
252
253#[derive(Debug, Clone, PartialEq, Eq)]
255pub struct PublishNamespaceCancel {
256 pub track_namespace: TrackNamespace,
257 pub error_code: VarInt,
258 pub reason_phrase: Vec<u8>,
259}
260
261#[derive(Debug, Clone, PartialEq, Eq)]
266pub struct SubscribeNamespace {
267 pub request_id: VarInt,
268 pub namespace_prefix: TrackNamespace,
269 pub parameters: Vec<KeyValuePair>,
270}
271
272#[derive(Debug, Clone, PartialEq, Eq)]
274pub struct UnsubscribeNamespace {
275 pub request_id: VarInt,
276}
277
278#[derive(Debug, Clone, PartialEq, Eq)]
284pub struct TrackStatus {
285 pub request_id: VarInt,
286 pub track_namespace: TrackNamespace,
287 pub track_name: Vec<u8>,
288 pub parameters: Vec<KeyValuePair>,
289}
290
291#[derive(Debug, Clone, Copy, PartialEq, Eq)]
296#[repr(u64)]
297pub enum FetchType {
298 Standalone = 1,
300 RelativeJoining = 2,
302 AbsoluteJoining = 3,
304}
305
306impl FetchType {
307 pub fn from_u64(v: u64) -> Option<Self> {
309 match v {
310 1 => Some(FetchType::Standalone),
311 2 => Some(FetchType::RelativeJoining),
312 3 => Some(FetchType::AbsoluteJoining),
313 _ => None,
314 }
315 }
316}
317
318#[derive(Debug, Clone, PartialEq, Eq)]
319pub struct Fetch {
320 pub request_id: VarInt,
321 pub fetch_type: FetchType,
322 pub fetch_payload: FetchPayload,
323 pub parameters: Vec<KeyValuePair>,
324}
325
326#[derive(Debug, Clone, PartialEq, Eq)]
327pub enum FetchPayload {
328 Standalone {
329 track_namespace: TrackNamespace,
330 track_name: Vec<u8>,
331 start_group: VarInt,
332 start_object: VarInt,
333 end_group: VarInt,
334 end_object: VarInt,
335 },
336 Joining {
337 joining_request_id: VarInt,
338 joining_start: VarInt,
339 },
340}
341
342#[derive(Debug, Clone, PartialEq, Eq)]
343pub struct FetchOk {
344 pub request_id: VarInt,
345 pub end_of_track: u8,
352 pub end_group: VarInt,
353 pub end_object: VarInt,
354 pub parameters: Vec<KeyValuePair>,
355}
356
357#[derive(Debug, Clone, PartialEq, Eq)]
358pub struct FetchCancel {
359 pub request_id: VarInt,
360}
361
362fn read_u8(buf: &mut impl Buf) -> Result<u8, CodecError> {
368 if !buf.has_remaining() {
369 return Err(CodecError::UnexpectedEnd);
370 }
371 Ok(buf.get_u8())
372}
373
374#[derive(Debug, Clone, PartialEq, Eq)]
375pub enum ControlMessage {
376 ClientSetup(ClientSetup),
377 ServerSetup(ServerSetup),
378 GoAway(GoAway),
379 MaxRequestId(MaxRequestId),
380 RequestsBlocked(RequestsBlocked),
381 RequestOk(RequestOk),
382 RequestError(RequestError),
383 Subscribe(Subscribe),
384 SubscribeOk(SubscribeOk),
385 SubscribeUpdate(SubscribeUpdate),
386 Unsubscribe(Unsubscribe),
387 Publish(Publish),
388 PublishOk(PublishOk),
389 PublishDone(PublishDone),
390 PublishNamespace(PublishNamespace),
391 PublishNamespaceDone(PublishNamespaceDone),
392 PublishNamespaceCancel(PublishNamespaceCancel),
393 SubscribeNamespace(SubscribeNamespace),
394 UnsubscribeNamespace(UnsubscribeNamespace),
395 TrackStatus(TrackStatus),
396 Fetch(Fetch),
397 FetchOk(FetchOk),
398 FetchCancel(FetchCancel),
399}
400
401fn check_full_track_name(namespace: &TrackNamespace, track_name: &[u8]) -> Result<(), CodecError> {
402 let total = namespace.field_bytes_len().saturating_add(track_name.len());
403 if total > MAX_FULL_TRACK_NAME_LENGTH {
404 return Err(CodecError::TrackNameTooLong);
405 }
406 Ok(())
407}
408
409fn read_reason_phrase(buf: &mut impl Buf) -> Result<Vec<u8>, CodecError> {
417 let len = VarInt::decode(buf)?.into_inner() as usize;
418 if len > MAX_REASON_PHRASE_LENGTH {
419 return Err(CodecError::ReasonPhraseTooLong);
420 }
421 read_bytes(buf, len)
422}
423
424fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
440 match message {
441 ControlMessage::Fetch(m) => match &m.fetch_payload {
442 FetchPayload::Standalone {
443 start_group, start_object, end_group, end_object, ..
444 } => check_location_range(
445 start_group.into_inner(),
446 start_object.into_inner(),
447 end_group.into_inner(),
448 end_object.into_inner(),
449 ),
450 FetchPayload::Joining { .. } => Ok(()),
451 },
452 _ => Ok(()),
453 }
454}
455
456fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
487 if let ControlMessage::Fetch(m) = message {
488 let body_is_standalone = matches!(m.fetch_payload, FetchPayload::Standalone { .. });
489 if body_is_standalone != (m.fetch_type == FetchType::Standalone) {
490 return Err(CodecError::InvalidField);
491 }
492 }
493 Ok(())
494}
495
496const REPEATABLE_PARAMETER: u64 = 0x03;
518
519const KNOWN_VERSION_SPECIFIC_PARAMETERS: &[u64] =
535 &[0x02, 0x03, 0x04, 0x08, 0x09, 0x0E, 0x10, 0x20, 0x21, 0x22, 0x30, 0x32];
536
537const KNOWN_SETUP_PARAMETERS: &[u64] = &[0x01, 0x02, 0x03, 0x04, 0x05, 0x07];
551
552fn check_no_duplicate_parameters_sent(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
564 for (i, parameter) in parameters.iter().enumerate() {
565 let key = parameter.key.into_inner();
566 if key == REPEATABLE_PARAMETER {
567 continue;
568 }
569 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
570 return Err(CodecError::DuplicateParameter(key));
571 }
572 }
573 Ok(())
574}
575
576fn check_no_duplicate_parameters_received(
594 parameters: &[KeyValuePair],
595 known: &[u64],
596) -> Result<(), CodecError> {
597 for (i, parameter) in parameters.iter().enumerate() {
598 let key = parameter.key.into_inner();
599 if key == REPEATABLE_PARAMETER || !known.contains(&key) {
600 continue;
601 }
602 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
603 return Err(CodecError::DuplicateParameter(key));
604 }
605 }
606 Ok(())
607}
608
609fn check_authorization_tokens(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
624 for parameter in parameters {
625 let key = parameter.key.into_inner();
626 if key != AUTH_TOKEN_PARAMETER {
627 continue;
628 }
629 match ¶meter.value {
630 KvpValue::Bytes(value) => {
631 AuthorizationToken::decode(key, value)?;
632 }
633 KvpValue::Varint(_) => {
638 return Err(CodecError::KeyValueFormatting {
639 key,
640 detail: "its value is a bare varint where the type defines a Token structure",
641 });
642 }
643 }
644 }
645 Ok(())
646}
647
648fn parameter_value_in_range(key: u64, value: u64) -> bool {
673 match key {
674 0x10 | 0x30 => value <= 1,
676 0x20 => value <= 255,
678 0x22 => value == 1 || value == 2,
680 _ => true,
681 }
682}
683
684fn check_parameter_value_ranges(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
691 for parameter in parameters {
692 if let KvpValue::Varint(value) = ¶meter.value {
693 let key = parameter.key.into_inner();
694 let value = value.into_inner();
695 if !parameter_value_in_range(key, value) {
696 return Err(CodecError::ParameterValueOutOfRange { key, value });
697 }
698 }
699 }
700 Ok(())
701}
702
703fn check_subscription_filters(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
725 for parameter in parameters {
726 if parameter.key.into_inner() != SUBSCRIPTION_FILTER_PARAMETER {
727 continue;
728 }
729 match ¶meter.value {
730 KvpValue::Bytes(value) => {
731 SubscriptionFilter::decode(value)?;
732 }
733 KvpValue::Varint(_) => {
737 return Err(CodecError::SubscriptionFilterMalformed {
738 detail: "its value is a bare varint where the type defines a filter",
739 });
740 }
741 }
742 }
743 Ok(())
744}
745
746fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
748 let parameters = KeyValuePair::decode_list(buf)?;
749 check_no_duplicate_parameters_received(¶meters, KNOWN_VERSION_SPECIFIC_PARAMETERS)?;
750 check_authorization_tokens(¶meters)?;
751 check_parameter_value_ranges(¶meters)?;
752 check_subscription_filters(¶meters)?;
753 Ok(parameters)
754}
755
756fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
761 let parameters = KeyValuePair::decode_list(buf)?;
762 check_no_duplicate_parameters_received(¶meters, KNOWN_SETUP_PARAMETERS)?;
763 check_authorization_tokens(¶meters)?;
764 Ok(parameters)
765}
766
767fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
778 check_no_duplicate_parameters_sent(parameters)?;
779 check_authorization_tokens(parameters)?;
780 check_parameter_value_ranges(parameters)?;
781 check_subscription_filters(parameters)?;
782 KeyValuePair::encode_list_checked(parameters, buf)?;
783 Ok(())
784}
785
786fn encode_setup_parameters(
793 parameters: &[KeyValuePair],
794 buf: &mut impl BufMut,
795) -> Result<(), CodecError> {
796 check_no_duplicate_parameters_sent(parameters)?;
797 check_authorization_tokens(parameters)?;
798 KeyValuePair::encode_list_checked(parameters, buf)?;
799 Ok(())
800}
801
802impl ControlMessage {
803 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
804 check_discriminators(self)?;
805 check_ranges(self)?;
806 let mut payload = Vec::with_capacity(256);
807 self.encode_payload(&mut payload)?;
808
809 if payload.len() > MAX_MESSAGE_LENGTH {
810 return Err(CodecError::MessageTooLong(payload.len()));
811 }
812
813 let msg_type = self.message_type();
814 VarInt::from_usize(msg_type.id() as usize).encode(buf);
815 buf.put_u16(payload.len() as u16);
817 buf.put_slice(&payload);
818 Ok(())
819 }
820
821 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
822 let type_id = VarInt::decode(buf)?.into_inner();
823 let msg_type =
824 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
825 if buf.remaining() < 2 {
827 return Err(CodecError::UnexpectedEnd);
828 }
829 let payload_len = buf.get_u16() as usize;
830 if buf.remaining() < payload_len {
831 return Err(CodecError::UnexpectedEnd);
832 }
833 let payload_bytes = buf.copy_to_bytes(payload_len);
834 let mut payload = &payload_bytes[..];
835 let msg = match Self::decode_payload(msg_type, &mut payload) {
836 Ok(msg) => msg,
837 Err(
843 CodecError::UnexpectedEnd
844 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
845 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
846 crate::varint::VarIntError::UnexpectedEnd,
847 ))
848 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
849 ) => {
850 return Err(CodecError::ControlMessageLengthMismatch {
851 declared: payload_len,
852 detail: "its fields ran past the end",
853 });
854 }
855 Err(e) => return Err(e),
856 };
857 check_ranges(&msg)?;
858 if payload.has_remaining() {
869 return Err(CodecError::ControlMessageLengthMismatch {
870 declared: payload_len,
871 detail: "its fields left bytes unread",
872 });
873 }
874 Ok(msg)
875 }
876
877 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
878 match self {
879 ControlMessage::ClientSetup(m) => {
880 encode_setup_parameters(&m.parameters, buf)?;
881 }
882 ControlMessage::ServerSetup(m) => {
883 encode_setup_parameters(&m.parameters, buf)?;
884 }
885 ControlMessage::GoAway(m) => {
886 if m.new_session_uri.len() > MAX_GOAWAY_URI_LENGTH {
887 return Err(CodecError::GoAwayUriTooLong);
888 }
889 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
890 buf.put_slice(&m.new_session_uri);
891 }
892 ControlMessage::MaxRequestId(m) => {
893 m.request_id.encode(buf);
894 }
895 ControlMessage::RequestsBlocked(m) => {
896 m.maximum_request_id.encode(buf);
897 }
898 ControlMessage::RequestOk(m) => {
899 m.request_id.encode(buf);
900 encode_parameters(&m.parameters, buf)?;
901 }
902 ControlMessage::RequestError(m) => {
903 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
904 return Err(CodecError::ReasonPhraseTooLong);
905 }
906 m.request_id.encode(buf);
907 m.error_code.encode(buf);
908 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
909 buf.put_slice(&m.reason_phrase);
910 }
911 ControlMessage::Subscribe(m) => {
912 m.request_id.encode(buf);
913 m.track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
914 m.track_namespace.encode(buf);
915 check_full_track_name(&m.track_namespace, &m.track_name)?;
916 VarInt::from_usize(m.track_name.len()).encode(buf);
917 buf.put_slice(&m.track_name);
918 encode_parameters(&m.parameters, buf)?;
919 }
920 ControlMessage::SubscribeOk(m) => {
921 m.request_id.encode(buf);
922 m.track_alias.encode(buf);
923 encode_parameters(&m.parameters, buf)?;
924 }
925 ControlMessage::SubscribeUpdate(m) => {
926 m.request_id.encode(buf);
927 m.subscription_request_id.encode(buf);
928 encode_parameters(&m.parameters, buf)?;
929 }
930 ControlMessage::Unsubscribe(m) => {
931 m.request_id.encode(buf);
932 }
933 ControlMessage::Publish(m) => {
934 m.request_id.encode(buf);
935 m.track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
936 m.track_namespace.encode(buf);
937 check_full_track_name(&m.track_namespace, &m.track_name)?;
938 VarInt::from_usize(m.track_name.len()).encode(buf);
939 buf.put_slice(&m.track_name);
940 m.track_alias.encode(buf);
941 encode_parameters(&m.parameters, buf)?;
942 }
943 ControlMessage::PublishOk(m) => {
944 m.request_id.encode(buf);
945 encode_parameters(&m.parameters, buf)?;
946 }
947 ControlMessage::PublishDone(m) => {
948 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
949 return Err(CodecError::ReasonPhraseTooLong);
950 }
951 m.request_id.encode(buf);
952 m.status_code.encode(buf);
953 m.stream_count.encode(buf);
954 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
955 buf.put_slice(&m.reason_phrase);
956 }
957 ControlMessage::PublishNamespace(m) => {
958 m.request_id.encode(buf);
959 m.track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
960 m.track_namespace.encode(buf);
961 encode_parameters(&m.parameters, buf)?;
962 }
963 ControlMessage::PublishNamespaceDone(m) => {
964 m.track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
965 m.track_namespace.encode(buf);
966 }
967 ControlMessage::PublishNamespaceCancel(m) => {
968 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
969 return Err(CodecError::ReasonPhraseTooLong);
970 }
971 m.track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
972 m.track_namespace.encode(buf);
973 m.error_code.encode(buf);
974 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
975 buf.put_slice(&m.reason_phrase);
976 }
977 ControlMessage::SubscribeNamespace(m) => {
978 m.request_id.encode(buf);
979 m.namespace_prefix.validate(TrackNamespaceRules::for_draft(15))?;
980 m.namespace_prefix.encode(buf);
981 encode_parameters(&m.parameters, buf)?;
982 }
983 ControlMessage::UnsubscribeNamespace(m) => {
984 m.request_id.encode(buf);
985 }
986 ControlMessage::TrackStatus(m) => {
987 m.request_id.encode(buf);
988 m.track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
989 m.track_namespace.encode(buf);
990 check_full_track_name(&m.track_namespace, &m.track_name)?;
991 VarInt::from_usize(m.track_name.len()).encode(buf);
992 buf.put_slice(&m.track_name);
993 encode_parameters(&m.parameters, buf)?;
994 }
995 ControlMessage::Fetch(m) => {
996 m.request_id.encode(buf);
997 VarInt::from_usize(m.fetch_type as usize).encode(buf);
998 match &m.fetch_payload {
999 FetchPayload::Standalone {
1000 track_namespace,
1001 track_name,
1002 start_group,
1003 start_object,
1004 end_group,
1005 end_object,
1006 } => {
1007 track_namespace.validate(TrackNamespaceRules::for_draft(15))?;
1008 track_namespace.encode(buf);
1009 check_full_track_name(track_namespace, track_name)?;
1010 VarInt::from_usize(track_name.len()).encode(buf);
1011 buf.put_slice(track_name);
1012 start_group.encode(buf);
1013 start_object.encode(buf);
1014 end_group.encode(buf);
1015 end_object.encode(buf);
1016 }
1017 FetchPayload::Joining { joining_request_id, joining_start } => {
1018 joining_request_id.encode(buf);
1019 joining_start.encode(buf);
1020 }
1021 }
1022 encode_parameters(&m.parameters, buf)?;
1023 }
1024 ControlMessage::FetchOk(m) => {
1025 m.request_id.encode(buf);
1026 buf.put_u8(m.end_of_track);
1027 m.end_group.encode(buf);
1028 m.end_object.encode(buf);
1029 encode_parameters(&m.parameters, buf)?;
1030 }
1031 ControlMessage::FetchCancel(m) => {
1032 m.request_id.encode(buf);
1033 }
1034 }
1035 Ok(())
1036 }
1037
1038 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1039 match msg_type {
1040 MessageType::ClientSetup => {
1041 let parameters = decode_setup_parameters(buf)?;
1042 Ok(ControlMessage::ClientSetup(ClientSetup { parameters }))
1043 }
1044 MessageType::ServerSetup => {
1045 let parameters = decode_setup_parameters(buf)?;
1046 Ok(ControlMessage::ServerSetup(ServerSetup { parameters }))
1047 }
1048 MessageType::GoAway => {
1049 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1050 if uri_len > MAX_GOAWAY_URI_LENGTH {
1051 return Err(CodecError::GoAwayUriTooLong);
1052 }
1053 let uri = read_bytes(buf, uri_len)?;
1054 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1055 }
1056 MessageType::MaxRequestId => {
1057 let request_id = VarInt::decode(buf)?;
1058 Ok(ControlMessage::MaxRequestId(MaxRequestId { request_id }))
1059 }
1060 MessageType::RequestsBlocked => {
1061 let maximum_request_id = VarInt::decode(buf)?;
1062 Ok(ControlMessage::RequestsBlocked(RequestsBlocked { maximum_request_id }))
1063 }
1064 MessageType::RequestOk => {
1065 let request_id = VarInt::decode(buf)?;
1066 let parameters = decode_parameters(buf)?;
1067 Ok(ControlMessage::RequestOk(RequestOk { request_id, parameters }))
1068 }
1069 MessageType::RequestError => {
1070 let request_id = VarInt::decode(buf)?;
1071 let error_code = VarInt::decode(buf)?;
1072 let reason_phrase = read_reason_phrase(buf)?;
1073 Ok(ControlMessage::RequestError(RequestError {
1074 request_id,
1075 error_code,
1076 reason_phrase,
1077 }))
1078 }
1079 MessageType::Subscribe => {
1080 let request_id = VarInt::decode(buf)?;
1081 let track_namespace = TrackNamespace::decode(buf)?;
1082 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1083 let track_name = read_bytes(buf, track_name_len)?;
1084 check_full_track_name(&track_namespace, &track_name)?;
1085 let parameters = decode_parameters(buf)?;
1086 Ok(ControlMessage::Subscribe(Subscribe {
1087 request_id,
1088 track_namespace,
1089 track_name,
1090 parameters,
1091 }))
1092 }
1093 MessageType::SubscribeOk => {
1094 let request_id = VarInt::decode(buf)?;
1095 let track_alias = VarInt::decode(buf)?;
1096 let parameters = decode_parameters(buf)?;
1097 Ok(ControlMessage::SubscribeOk(SubscribeOk { request_id, track_alias, parameters }))
1098 }
1099 MessageType::SubscribeUpdate => {
1100 let request_id = VarInt::decode(buf)?;
1101 let subscription_request_id = VarInt::decode(buf)?;
1102 let parameters = decode_parameters(buf)?;
1103 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1104 request_id,
1105 subscription_request_id,
1106 parameters,
1107 }))
1108 }
1109 MessageType::Unsubscribe => {
1110 let request_id = VarInt::decode(buf)?;
1111 Ok(ControlMessage::Unsubscribe(Unsubscribe { request_id }))
1112 }
1113 MessageType::Publish => {
1114 let request_id = VarInt::decode(buf)?;
1115 let track_namespace = TrackNamespace::decode(buf)?;
1116 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1117 let track_name = read_bytes(buf, track_name_len)?;
1118 check_full_track_name(&track_namespace, &track_name)?;
1119 let track_alias = VarInt::decode(buf)?;
1120 let parameters = decode_parameters(buf)?;
1121 Ok(ControlMessage::Publish(Publish {
1122 request_id,
1123 track_namespace,
1124 track_name,
1125 track_alias,
1126 parameters,
1127 }))
1128 }
1129 MessageType::PublishOk => {
1130 let request_id = VarInt::decode(buf)?;
1131 let parameters = decode_parameters(buf)?;
1132 Ok(ControlMessage::PublishOk(PublishOk { request_id, parameters }))
1133 }
1134 MessageType::PublishDone => {
1135 let request_id = VarInt::decode(buf)?;
1136 let status_code = VarInt::decode(buf)?;
1137 let stream_count = VarInt::decode(buf)?;
1138 let reason_phrase = read_reason_phrase(buf)?;
1139 Ok(ControlMessage::PublishDone(PublishDone {
1140 request_id,
1141 status_code,
1142 stream_count,
1143 reason_phrase,
1144 }))
1145 }
1146 MessageType::PublishNamespace => {
1147 let request_id = VarInt::decode(buf)?;
1148 let track_namespace = TrackNamespace::decode(buf)?;
1149 let parameters = decode_parameters(buf)?;
1150 Ok(ControlMessage::PublishNamespace(PublishNamespace {
1151 request_id,
1152 track_namespace,
1153 parameters,
1154 }))
1155 }
1156 MessageType::PublishNamespaceDone => {
1157 let track_namespace = TrackNamespace::decode(buf)?;
1158 Ok(ControlMessage::PublishNamespaceDone(PublishNamespaceDone { track_namespace }))
1159 }
1160 MessageType::PublishNamespaceCancel => {
1161 let track_namespace = TrackNamespace::decode(buf)?;
1162 let error_code = VarInt::decode(buf)?;
1163 let reason_phrase = read_reason_phrase(buf)?;
1164 Ok(ControlMessage::PublishNamespaceCancel(PublishNamespaceCancel {
1165 track_namespace,
1166 error_code,
1167 reason_phrase,
1168 }))
1169 }
1170 MessageType::SubscribeNamespace => {
1171 let request_id = VarInt::decode(buf)?;
1172 let namespace_prefix = TrackNamespace::decode(buf)?;
1173 let parameters = decode_parameters(buf)?;
1174 Ok(ControlMessage::SubscribeNamespace(SubscribeNamespace {
1175 request_id,
1176 namespace_prefix,
1177 parameters,
1178 }))
1179 }
1180 MessageType::UnsubscribeNamespace => {
1181 let request_id = VarInt::decode(buf)?;
1182 Ok(ControlMessage::UnsubscribeNamespace(UnsubscribeNamespace { request_id }))
1183 }
1184 MessageType::TrackStatus => {
1185 let request_id = VarInt::decode(buf)?;
1186 let track_namespace = TrackNamespace::decode(buf)?;
1187 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1188 let track_name = read_bytes(buf, track_name_len)?;
1189 check_full_track_name(&track_namespace, &track_name)?;
1190 let parameters = decode_parameters(buf)?;
1191 Ok(ControlMessage::TrackStatus(TrackStatus {
1192 request_id,
1193 track_namespace,
1194 track_name,
1195 parameters,
1196 }))
1197 }
1198 MessageType::Fetch => {
1199 let request_id = VarInt::decode(buf)?;
1200 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1201 let fetch_type = FetchType::from_u64(fetch_type_val)
1202 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1203 let fetch_payload = match fetch_type {
1204 FetchType::Standalone => {
1205 let track_namespace = TrackNamespace::decode(buf)?;
1206 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1207 let track_name = read_bytes(buf, track_name_len)?;
1208 check_full_track_name(&track_namespace, &track_name)?;
1209 let start_group = VarInt::decode(buf)?;
1210 let start_object = VarInt::decode(buf)?;
1211 let end_group = VarInt::decode(buf)?;
1212 let end_object = VarInt::decode(buf)?;
1213 FetchPayload::Standalone {
1214 track_namespace,
1215 track_name,
1216 start_group,
1217 start_object,
1218 end_group,
1219 end_object,
1220 }
1221 }
1222 FetchType::RelativeJoining | FetchType::AbsoluteJoining => {
1223 let joining_request_id = VarInt::decode(buf)?;
1224 let joining_start = VarInt::decode(buf)?;
1225 FetchPayload::Joining { joining_request_id, joining_start }
1226 }
1227 };
1228 let parameters = decode_parameters(buf)?;
1229 Ok(ControlMessage::Fetch(Fetch {
1230 request_id,
1231 fetch_type,
1232 fetch_payload,
1233 parameters,
1234 }))
1235 }
1236 MessageType::FetchOk => {
1237 let request_id = VarInt::decode(buf)?;
1238 let end_of_track = read_u8(buf)?;
1239 let end_group = VarInt::decode(buf)?;
1240 let end_object = VarInt::decode(buf)?;
1241 let parameters = decode_parameters(buf)?;
1242 Ok(ControlMessage::FetchOk(FetchOk {
1243 request_id,
1244 end_of_track,
1245 end_group,
1246 end_object,
1247 parameters,
1248 }))
1249 }
1250 MessageType::FetchCancel => {
1251 let request_id = VarInt::decode(buf)?;
1252 Ok(ControlMessage::FetchCancel(FetchCancel { request_id }))
1253 }
1254 }
1255 }
1256
1257 pub fn message_type(&self) -> MessageType {
1258 match self {
1259 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
1260 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
1261 ControlMessage::GoAway(_) => MessageType::GoAway,
1262 ControlMessage::MaxRequestId(_) => MessageType::MaxRequestId,
1263 ControlMessage::RequestsBlocked(_) => MessageType::RequestsBlocked,
1264 ControlMessage::RequestOk(_) => MessageType::RequestOk,
1265 ControlMessage::RequestError(_) => MessageType::RequestError,
1266 ControlMessage::Subscribe(_) => MessageType::Subscribe,
1267 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
1268 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
1269 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
1270 ControlMessage::Publish(_) => MessageType::Publish,
1271 ControlMessage::PublishOk(_) => MessageType::PublishOk,
1272 ControlMessage::PublishDone(_) => MessageType::PublishDone,
1273 ControlMessage::PublishNamespace(_) => MessageType::PublishNamespace,
1274 ControlMessage::PublishNamespaceDone(_) => MessageType::PublishNamespaceDone,
1275 ControlMessage::PublishNamespaceCancel(_) => MessageType::PublishNamespaceCancel,
1276 ControlMessage::SubscribeNamespace(_) => MessageType::SubscribeNamespace,
1277 ControlMessage::UnsubscribeNamespace(_) => MessageType::UnsubscribeNamespace,
1278 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
1279 ControlMessage::Fetch(_) => MessageType::Fetch,
1280 ControlMessage::FetchOk(_) => MessageType::FetchOk,
1281 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
1282 }
1283 }
1284}