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