1use crate::auth_token::{AuthorizationToken, AUTH_TOKEN_PARAMETER};
13use crate::error::{
14 CodecError, MAX_FULL_TRACK_NAME_LENGTH, MAX_GOAWAY_URI_LENGTH, MAX_MESSAGE_LENGTH,
15 MAX_REASON_PHRASE_LENGTH,
16};
17use crate::kvp::{KeyValuePair, KvpValue};
18use crate::types::{self, *};
19pub use crate::types::{check_group_range, check_location_range, check_open_ended_group_range};
20use crate::varint::VarInt;
21use bytes::{Buf, BufMut};
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25#[repr(u64)]
26pub enum MessageType {
27 SubscribeUpdate = 0x02,
28 Subscribe = 0x03,
29 SubscribeOk = 0x04,
30 SubscribeError = 0x05,
31 Announce = 0x06,
32 AnnounceOk = 0x07,
33 AnnounceError = 0x08,
34 Unannounce = 0x09,
35 Unsubscribe = 0x0A,
36 SubscribeDone = 0x0B,
37 AnnounceCancel = 0x0C,
38 TrackStatusRequest = 0x0D,
39 TrackStatus = 0x0E,
40 GoAway = 0x10,
41 SubscribeAnnounces = 0x11,
42 SubscribeAnnouncesOk = 0x12,
43 SubscribeAnnouncesError = 0x13,
44 UnsubscribeAnnounces = 0x14,
45 MaxRequestId = 0x15,
46 Fetch = 0x16,
47 FetchCancel = 0x17,
48 FetchOk = 0x18,
49 FetchError = 0x19,
50 RequestsBlocked = 0x1A,
51 Publish = 0x1D,
52 PublishOk = 0x1E,
53 PublishError = 0x1F,
54 ClientSetup = 0x20,
55 ServerSetup = 0x21,
56}
57
58impl MessageType {
59 pub fn from_id(id: u64) -> Option<Self> {
60 match id {
61 0x02 => Some(MessageType::SubscribeUpdate),
62 0x03 => Some(MessageType::Subscribe),
63 0x04 => Some(MessageType::SubscribeOk),
64 0x05 => Some(MessageType::SubscribeError),
65 0x06 => Some(MessageType::Announce),
66 0x07 => Some(MessageType::AnnounceOk),
67 0x08 => Some(MessageType::AnnounceError),
68 0x09 => Some(MessageType::Unannounce),
69 0x0A => Some(MessageType::Unsubscribe),
70 0x0B => Some(MessageType::SubscribeDone),
71 0x0C => Some(MessageType::AnnounceCancel),
72 0x0D => Some(MessageType::TrackStatusRequest),
73 0x0E => Some(MessageType::TrackStatus),
74 0x10 => Some(MessageType::GoAway),
75 0x11 => Some(MessageType::SubscribeAnnounces),
76 0x12 => Some(MessageType::SubscribeAnnouncesOk),
77 0x13 => Some(MessageType::SubscribeAnnouncesError),
78 0x14 => Some(MessageType::UnsubscribeAnnounces),
79 0x15 => Some(MessageType::MaxRequestId),
80 0x16 => Some(MessageType::Fetch),
81 0x17 => Some(MessageType::FetchCancel),
82 0x18 => Some(MessageType::FetchOk),
83 0x19 => Some(MessageType::FetchError),
84 0x1A => Some(MessageType::RequestsBlocked),
85 0x1D => Some(MessageType::Publish),
86 0x1E => Some(MessageType::PublishOk),
87 0x1F => Some(MessageType::PublishError),
88 0x20 => Some(MessageType::ClientSetup),
89 0x21 => Some(MessageType::ServerSetup),
90 _ => None,
91 }
92 }
93
94 pub fn id(&self) -> u64 {
95 *self as u64
96 }
97}
98
99#[derive(Debug, Clone, PartialEq, Eq)]
104pub struct ClientSetup {
105 pub supported_versions: Vec<VarInt>,
106 pub parameters: Vec<KeyValuePair>,
107}
108
109#[derive(Debug, Clone, PartialEq, Eq)]
110pub struct ServerSetup {
111 pub selected_version: VarInt,
112 pub parameters: Vec<KeyValuePair>,
113}
114
115#[derive(Debug, Clone, PartialEq, Eq)]
116pub struct GoAway {
117 pub new_session_uri: Vec<u8>,
118}
119
120#[derive(Debug, Clone, PartialEq, Eq)]
121pub struct MaxRequestId {
122 pub request_id: VarInt,
123}
124
125#[derive(Debug, Clone, PartialEq, Eq)]
126pub struct RequestsBlocked {
127 pub maximum_request_id: VarInt,
128}
129
130#[derive(Debug, Clone, PartialEq, Eq)]
136pub struct Subscribe {
137 pub request_id: VarInt,
138 pub track_namespace: TrackNamespace,
139 pub track_name: Vec<u8>,
140 pub subscriber_priority: u8,
141 pub group_order: GroupOrder,
142 pub forward: Forward,
143 pub filter_type: VarInt,
144 pub start_group: Option<VarInt>,
145 pub start_object: Option<VarInt>,
146 pub end_group: Option<VarInt>,
147 pub parameters: Vec<KeyValuePair>,
148}
149
150#[derive(Debug, Clone, PartialEq, Eq)]
152pub struct SubscribeOk {
153 pub request_id: VarInt,
154 pub track_alias: VarInt,
155 pub expires: VarInt,
156 pub group_order: GroupOrder,
157 pub content_exists: ContentExists,
158 pub largest_location: Option<Location>,
159 pub parameters: Vec<KeyValuePair>,
160}
161
162#[derive(Debug, Clone, PartialEq, Eq)]
164pub struct SubscribeError {
165 pub request_id: VarInt,
166 pub error_code: VarInt,
167 pub reason_phrase: Vec<u8>,
168}
169
170#[derive(Debug, Clone, PartialEq, Eq)]
171pub struct SubscribeUpdate {
172 pub request_id: VarInt,
173 pub start_group: VarInt,
174 pub start_object: VarInt,
175 pub end_group: VarInt,
176 pub subscriber_priority: u8,
177 pub forward: Forward,
178 pub parameters: Vec<KeyValuePair>,
179}
180
181#[derive(Debug, Clone, PartialEq, Eq)]
182pub struct SubscribeDone {
183 pub request_id: VarInt,
184 pub status_code: VarInt,
185 pub stream_count: VarInt,
186 pub reason_phrase: Vec<u8>,
187}
188
189#[derive(Debug, Clone, PartialEq, Eq)]
190pub struct Unsubscribe {
191 pub request_id: VarInt,
192}
193
194#[derive(Debug, Clone, PartialEq, Eq)]
199pub struct Announce {
200 pub request_id: VarInt,
201 pub track_namespace: TrackNamespace,
202 pub parameters: Vec<KeyValuePair>,
203}
204
205#[derive(Debug, Clone, PartialEq, Eq)]
206pub struct AnnounceOk {
207 pub request_id: VarInt,
208}
209
210#[derive(Debug, Clone, PartialEq, Eq)]
211pub struct AnnounceError {
212 pub request_id: VarInt,
213 pub error_code: VarInt,
214 pub reason_phrase: Vec<u8>,
215}
216
217#[derive(Debug, Clone, PartialEq, Eq)]
218pub struct AnnounceCancel {
219 pub track_namespace: TrackNamespace,
220 pub error_code: VarInt,
221 pub reason_phrase: Vec<u8>,
222}
223
224#[derive(Debug, Clone, PartialEq, Eq)]
225pub struct Unannounce {
226 pub track_namespace: TrackNamespace,
227}
228
229#[derive(Debug, Clone, PartialEq, Eq)]
234pub struct SubscribeAnnounces {
235 pub request_id: VarInt,
236 pub track_namespace_prefix: TrackNamespace,
237 pub parameters: Vec<KeyValuePair>,
238}
239
240#[derive(Debug, Clone, PartialEq, Eq)]
241pub struct SubscribeAnnouncesOk {
242 pub request_id: VarInt,
243}
244
245#[derive(Debug, Clone, PartialEq, Eq)]
246pub struct SubscribeAnnouncesError {
247 pub request_id: VarInt,
248 pub error_code: VarInt,
249 pub reason_phrase: Vec<u8>,
250}
251
252#[derive(Debug, Clone, PartialEq, Eq)]
253pub struct UnsubscribeAnnounces {
254 pub track_namespace_prefix: TrackNamespace,
255}
256
257#[derive(Debug, Clone, PartialEq, Eq)]
262pub struct TrackStatusRequest {
263 pub request_id: VarInt,
264 pub track_namespace: TrackNamespace,
265 pub track_name: Vec<u8>,
266 pub parameters: Vec<KeyValuePair>,
267}
268
269#[derive(Debug, Clone, PartialEq, Eq)]
270pub struct TrackStatus {
271 pub request_id: VarInt,
272 pub status_code: VarInt,
273 pub largest_location: Location,
274 pub parameters: Vec<KeyValuePair>,
275}
276
277#[derive(Debug, Clone, Copy, PartialEq, Eq)]
282#[repr(u64)]
283pub enum FetchType {
284 Standalone = 1,
285 RelativeJoining = 2,
286 AbsoluteJoining = 3,
287}
288
289impl FetchType {
290 pub fn from_u64(v: u64) -> Option<Self> {
291 match v {
292 1 => Some(FetchType::Standalone),
293 2 => Some(FetchType::RelativeJoining),
294 3 => Some(FetchType::AbsoluteJoining),
295 _ => None,
296 }
297 }
298}
299
300#[derive(Debug, Clone, PartialEq, Eq)]
301pub struct Fetch {
302 pub request_id: VarInt,
303 pub subscriber_priority: u8,
304 pub group_order: GroupOrder,
305 pub fetch_type: FetchType,
306 pub fetch_payload: FetchPayload,
307 pub parameters: Vec<KeyValuePair>,
308}
309
310#[derive(Debug, Clone, PartialEq, Eq)]
311pub enum FetchPayload {
312 Standalone {
313 track_namespace: TrackNamespace,
314 track_name: Vec<u8>,
315 start_group: VarInt,
316 start_object: VarInt,
317 end_group: VarInt,
318 end_object: VarInt,
319 },
320 Joining {
321 joining_request_id: VarInt,
330 joining_start: VarInt,
333 },
334}
335
336#[derive(Debug, Clone, PartialEq, Eq)]
337pub struct FetchOk {
338 pub request_id: VarInt,
339 pub group_order: GroupOrder,
340 pub end_of_track: u8,
347 pub end_location: Location,
348 pub parameters: Vec<KeyValuePair>,
349}
350
351#[derive(Debug, Clone, PartialEq, Eq)]
352pub struct FetchError {
353 pub request_id: VarInt,
354 pub error_code: VarInt,
355 pub reason_phrase: Vec<u8>,
356}
357
358#[derive(Debug, Clone, PartialEq, Eq)]
359pub struct FetchCancel {
360 pub request_id: VarInt,
361}
362
363#[derive(Debug, Clone, PartialEq, Eq)]
369pub struct Publish {
370 pub request_id: VarInt,
371 pub track_namespace: TrackNamespace,
372 pub track_name: Vec<u8>,
373 pub track_alias: VarInt,
374 pub group_order: GroupOrder,
375 pub content_exists: ContentExists,
376 pub largest_location: Option<Location>,
377 pub forward: Forward,
378 pub parameters: Vec<KeyValuePair>,
379}
380
381#[derive(Debug, Clone, PartialEq, Eq)]
383pub struct PublishOk {
384 pub request_id: VarInt,
385 pub forward: Forward,
386 pub subscriber_priority: u8,
387 pub group_order: GroupOrder,
388 pub filter_type: VarInt,
389 pub start_group: Option<VarInt>,
390 pub start_object: Option<VarInt>,
391 pub end_group: Option<VarInt>,
392 pub parameters: Vec<KeyValuePair>,
393}
394
395#[derive(Debug, Clone, PartialEq, Eq)]
397pub struct PublishError {
398 pub request_id: VarInt,
399 pub error_code: VarInt,
400 pub reason_phrase: Vec<u8>,
401}
402
403fn read_u8(buf: &mut impl Buf) -> Result<u8, CodecError> {
405 if !buf.has_remaining() {
406 return Err(CodecError::UnexpectedEnd);
407 }
408 Ok(buf.get_u8())
409}
410
411fn read_group_order(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
423 GroupOrder::from_u8(read_u8(buf)?).ok_or(CodecError::InvalidField)
424}
425
426fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
437 match read_group_order(buf)? {
438 GroupOrder::Publisher => Err(CodecError::InvalidField),
439 order => Ok(order),
440 }
441}
442
443fn read_forward(buf: &mut impl Buf) -> Result<Forward, CodecError> {
446 match read_u8(buf)? {
447 0 => Ok(Forward::DontForward),
448 1 => Ok(Forward::Forward),
449 other => Err(CodecError::InvalidForward(other)),
450 }
451}
452
453fn read_content_exists(buf: &mut impl Buf) -> Result<ContentExists, CodecError> {
456 match read_u8(buf)? {
457 0 => Ok(ContentExists::NoLargestLocation),
458 1 => Ok(ContentExists::HasLargestLocation),
459 other => Err(CodecError::InvalidContentExists(other)),
460 }
461}
462
463fn check_filter(
467 filter_type: VarInt,
468 start_group: &Option<VarInt>,
469 start_object: &Option<VarInt>,
470 end_group: &Option<VarInt>,
471) -> Result<(), CodecError> {
472 let value = filter_type.into_inner();
473 if value == 0 || value > 4 {
474 return Err(CodecError::InvalidFilterType(value));
475 }
476 let wants_start = value == 3 || value == 4;
477 if wants_start != start_group.is_some() || wants_start != start_object.is_some() {
478 return Err(CodecError::InvalidField);
479 }
480 if (value == 4) != end_group.is_some() {
481 return Err(CodecError::InvalidField);
482 }
483 Ok(())
484}
485
486fn check_content(
487 content_exists: ContentExists,
488 largest_location: &Option<Location>,
489) -> Result<(), CodecError> {
490 if (content_exists == ContentExists::HasLargestLocation) != largest_location.is_some() {
491 return Err(CodecError::InvalidField);
492 }
493 Ok(())
494}
495
496fn check_track_status(status_code: VarInt, largest_location: Location) -> Result<(), CodecError> {
507 let code = crate::draft12::error_codes::TrackStatusCode::from_u64(status_code.into_inner())
508 .ok_or(CodecError::InvalidField)?;
509 if code.requires_zero_location()
510 && (largest_location.group.into_inner() != 0 || largest_location.object.into_inner() != 0)
511 {
512 return Err(CodecError::InvalidField);
513 }
514 Ok(())
515}
516
517fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
528 match message {
529 ControlMessage::Subscribe(m) => {
530 check_filter(m.filter_type, &m.start_group, &m.start_object, &m.end_group)
531 }
532 ControlMessage::PublishOk(m) => {
533 check_filter(m.filter_type, &m.start_group, &m.start_object, &m.end_group)
534 }
535 ControlMessage::SubscribeOk(m) => check_content(m.content_exists, &m.largest_location),
536 ControlMessage::Publish(m) => check_content(m.content_exists, &m.largest_location),
537 ControlMessage::Fetch(m) => {
538 let body_is_standalone = matches!(m.fetch_payload, FetchPayload::Standalone { .. });
539 if body_is_standalone != (m.fetch_type == FetchType::Standalone) {
540 return Err(CodecError::InvalidField);
541 }
542 Ok(())
543 }
544 _ => Ok(()),
545 }
546}
547
548fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
553 let order = match message {
554 ControlMessage::SubscribeOk(m) => m.group_order,
555 ControlMessage::FetchOk(m) => m.group_order,
556 ControlMessage::Publish(m) => m.group_order,
557 ControlMessage::PublishOk(m) => m.group_order,
558 _ => return Ok(()),
559 };
560 if order == GroupOrder::Publisher {
561 return Err(CodecError::InvalidField);
562 }
563 Ok(())
564}
565
566#[derive(Debug, Clone, PartialEq, Eq)]
571pub enum ControlMessage {
572 ClientSetup(ClientSetup),
573 ServerSetup(ServerSetup),
574 GoAway(GoAway),
575 MaxRequestId(MaxRequestId),
576 RequestsBlocked(RequestsBlocked),
577 Subscribe(Subscribe),
578 SubscribeOk(SubscribeOk),
579 SubscribeError(SubscribeError),
580 SubscribeUpdate(SubscribeUpdate),
581 SubscribeDone(SubscribeDone),
582 Unsubscribe(Unsubscribe),
583 Announce(Announce),
584 AnnounceOk(AnnounceOk),
585 AnnounceError(AnnounceError),
586 AnnounceCancel(AnnounceCancel),
587 Unannounce(Unannounce),
588 SubscribeAnnounces(SubscribeAnnounces),
589 SubscribeAnnouncesOk(SubscribeAnnouncesOk),
590 SubscribeAnnouncesError(SubscribeAnnouncesError),
591 UnsubscribeAnnounces(UnsubscribeAnnounces),
592 TrackStatusRequest(TrackStatusRequest),
593 TrackStatus(TrackStatus),
594 Fetch(Fetch),
595 FetchOk(FetchOk),
596 FetchError(FetchError),
597 FetchCancel(FetchCancel),
598 Publish(Publish),
599 PublishOk(PublishOk),
600 PublishError(PublishError),
601}
602
603fn check_full_track_name(namespace: &TrackNamespace, track_name: &[u8]) -> Result<(), CodecError> {
604 let total = namespace.field_bytes_len().saturating_add(track_name.len());
605 if total > MAX_FULL_TRACK_NAME_LENGTH {
606 return Err(CodecError::TrackNameTooLong);
607 }
608 Ok(())
609}
610
611fn read_reason_phrase(buf: &mut impl Buf) -> Result<Vec<u8>, CodecError> {
619 let len = VarInt::decode(buf)?.into_inner() as usize;
620 if len > MAX_REASON_PHRASE_LENGTH {
621 return Err(CodecError::ReasonPhraseTooLong);
622 }
623 types::read_bytes(buf, len)
624}
625
626fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
640 match message {
641 ControlMessage::Subscribe(m) => match (&m.start_group, &m.end_group) {
642 (Some(start_group), Some(end_group)) => {
643 check_group_range(start_group.into_inner(), end_group.into_inner())
644 }
645 _ => Ok(()),
646 },
647 ControlMessage::SubscribeUpdate(m) => {
648 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
649 }
650 ControlMessage::Fetch(m) => match &m.fetch_payload {
651 FetchPayload::Standalone {
652 start_group, start_object, end_group, end_object, ..
653 } => check_location_range(
654 start_group.into_inner(),
655 start_object.into_inner(),
656 end_group.into_inner(),
657 end_object.into_inner(),
658 ),
659 FetchPayload::Joining { .. } => Ok(()),
660 },
661 _ => Ok(()),
662 }
663}
664
665const AUTHORIZATION_TOKEN: u64 = 0x03;
672
673const DELIVERY_TIMEOUT: u64 = 0x02;
675
676const MAX_CACHE_DURATION: u64 = 0x04;
678
679const SETUP_PATH: u64 = 0x01;
681
682const SETUP_MAX_REQUEST_ID: u64 = 0x02;
684
685const SETUP_MAX_AUTH_TOKEN_CACHE_SIZE: u64 = 0x04;
687
688const SETUP_AUTHORIZATION_TOKEN: u64 = AUTHORIZATION_TOKEN;
696
697const KNOWN_PARAMETERS: &[u64] = &[AUTHORIZATION_TOKEN, DELIVERY_TIMEOUT, MAX_CACHE_DURATION];
703
704const REPEATABLE_PARAMETERS: &[u64] = &[AUTHORIZATION_TOKEN];
710
711const KNOWN_SETUP_PARAMETERS: &[u64] =
713 &[SETUP_PATH, SETUP_MAX_REQUEST_ID, SETUP_AUTHORIZATION_TOKEN, SETUP_MAX_AUTH_TOKEN_CACHE_SIZE];
714
715const REPEATABLE_SETUP_PARAMETERS: &[u64] = &[SETUP_AUTHORIZATION_TOKEN];
723
724fn check_sender_parameters(
738 parameters: &[KeyValuePair],
739 repeatable: &[u64],
740) -> Result<(), CodecError> {
741 for (i, parameter) in parameters.iter().enumerate() {
742 let key = parameter.key.into_inner();
743 if repeatable.contains(&key) {
744 continue;
745 }
746 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
747 return Err(CodecError::DuplicateParameter(key));
748 }
749 }
750 Ok(())
751}
752
753fn check_receiver_parameters(
767 parameters: &[KeyValuePair],
768 known: &[u64],
769 repeatable: &[u64],
770) -> Result<(), CodecError> {
771 for (i, parameter) in parameters.iter().enumerate() {
772 let key = parameter.key.into_inner();
773 if repeatable.contains(&key) || !known.contains(&key) {
774 continue;
775 }
776 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
777 return Err(CodecError::DuplicateParameter(key));
778 }
779 }
780 Ok(())
781}
782
783fn check_authorization_tokens(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
798 for parameter in parameters {
799 let key = parameter.key.into_inner();
800 if key != AUTH_TOKEN_PARAMETER {
801 continue;
802 }
803 match ¶meter.value {
804 KvpValue::Bytes(value) => {
805 AuthorizationToken::decode(key, value)?;
806 }
807 KvpValue::Varint(_) => {
812 return Err(CodecError::KeyValueFormatting {
813 key,
814 detail: "its value is a bare varint where the type defines a Token structure",
815 });
816 }
817 }
818 }
819 Ok(())
820}
821
822fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
824 let parameters = KeyValuePair::decode_list(buf)?;
825 check_receiver_parameters(¶meters, KNOWN_PARAMETERS, REPEATABLE_PARAMETERS)?;
826 check_authorization_tokens(¶meters)?;
827 Ok(parameters)
828}
829
830fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
832 check_sender_parameters(parameters, REPEATABLE_PARAMETERS)?;
833 check_authorization_tokens(parameters)?;
834 KeyValuePair::encode_list_checked(parameters, buf)?;
835 Ok(())
836}
837
838fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
840 let parameters = KeyValuePair::decode_list(buf)?;
841 check_receiver_parameters(¶meters, KNOWN_SETUP_PARAMETERS, REPEATABLE_SETUP_PARAMETERS)?;
842 check_authorization_tokens(¶meters)?;
843 Ok(parameters)
844}
845
846fn encode_setup_parameters(
852 parameters: &[KeyValuePair],
853 buf: &mut impl BufMut,
854) -> Result<(), CodecError> {
855 check_sender_parameters(parameters, REPEATABLE_SETUP_PARAMETERS)?;
856 check_authorization_tokens(parameters)?;
857 KeyValuePair::encode_list_checked(parameters, buf)?;
858 Ok(())
859}
860
861impl ControlMessage {
862 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
866 check_discriminators(self)?;
867 check_group_order(self)?;
868 check_ranges(self)?;
869 let mut payload = Vec::with_capacity(256);
870 self.encode_payload(&mut payload)?;
871
872 if payload.len() > MAX_MESSAGE_LENGTH {
873 return Err(CodecError::MessageTooLong(payload.len()));
874 }
875
876 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
877 buf.put_u16(payload.len() as u16);
879 buf.put_slice(&payload);
880 Ok(())
881 }
882
883 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
887 let type_id = VarInt::decode(buf)?.into_inner();
888 let msg_type =
889 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
890 if buf.remaining() < 2 {
892 return Err(CodecError::UnexpectedEnd);
893 }
894 let payload_len = buf.get_u16() as usize;
895 if buf.remaining() < payload_len {
896 return Err(CodecError::UnexpectedEnd);
897 }
898 let payload_bytes = buf.copy_to_bytes(payload_len);
899 let mut payload = &payload_bytes[..];
900 let msg = match Self::decode_payload(msg_type, &mut payload) {
901 Ok(msg) => msg,
902 Err(
908 CodecError::UnexpectedEnd
909 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
910 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
911 crate::varint::VarIntError::UnexpectedEnd,
912 ))
913 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
914 ) => {
915 return Err(CodecError::ControlMessageLengthMismatch {
916 declared: payload_len,
917 detail: "its fields ran past the end",
918 });
919 }
920 Err(e) => return Err(e),
921 };
922 check_ranges(&msg)?;
923 if payload.has_remaining() {
928 return Err(CodecError::ControlMessageLengthMismatch {
929 declared: payload_len,
930 detail: "its fields left bytes unread",
931 });
932 }
933 Ok(msg)
934 }
935
936 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
937 match self {
938 ControlMessage::ClientSetup(m) => {
939 VarInt::from_usize(m.supported_versions.len()).encode(buf);
940 for v in &m.supported_versions {
941 v.encode(buf);
942 }
943 encode_setup_parameters(&m.parameters, buf)?;
944 }
945 ControlMessage::ServerSetup(m) => {
946 m.selected_version.encode(buf);
947 encode_setup_parameters(&m.parameters, buf)?;
948 }
949 ControlMessage::GoAway(m) => {
950 if m.new_session_uri.len() > MAX_GOAWAY_URI_LENGTH {
951 return Err(CodecError::GoAwayUriTooLong);
952 }
953 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
954 buf.put_slice(&m.new_session_uri);
955 }
956 ControlMessage::MaxRequestId(m) => {
957 m.request_id.encode(buf);
958 }
959 ControlMessage::RequestsBlocked(m) => {
960 m.maximum_request_id.encode(buf);
961 }
962 ControlMessage::Subscribe(m) => {
963 m.request_id.encode(buf);
964 m.track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
965 m.track_namespace.encode(buf);
966 check_full_track_name(&m.track_namespace, &m.track_name)?;
967 VarInt::from_usize(m.track_name.len()).encode(buf);
968 buf.put_slice(&m.track_name);
969 buf.put_u8(m.subscriber_priority);
970 buf.put_u8(m.group_order as u8);
971 buf.put_u8(m.forward as u8);
972 m.filter_type.encode(buf);
973 if let Some(sg) = &m.start_group {
974 sg.encode(buf);
975 }
976 if let Some(so) = &m.start_object {
977 so.encode(buf);
978 }
979 if let Some(eg) = &m.end_group {
980 eg.encode(buf);
981 }
982 encode_parameters(&m.parameters, buf)?;
983 }
984 ControlMessage::SubscribeOk(m) => {
985 m.request_id.encode(buf);
986 m.track_alias.encode(buf);
987 m.expires.encode(buf);
988 buf.put_u8(m.group_order as u8);
989 buf.put_u8(m.content_exists as u8);
990 if let Some(loc) = &m.largest_location {
991 loc.encode(buf);
992 }
993 encode_parameters(&m.parameters, buf)?;
994 }
995 ControlMessage::SubscribeError(m) => {
996 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
997 return Err(CodecError::ReasonPhraseTooLong);
998 }
999 m.request_id.encode(buf);
1000 m.error_code.encode(buf);
1001 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1002 buf.put_slice(&m.reason_phrase);
1003 }
1004 ControlMessage::SubscribeUpdate(m) => {
1005 m.request_id.encode(buf);
1006 m.start_group.encode(buf);
1007 m.start_object.encode(buf);
1008 m.end_group.encode(buf);
1009 buf.put_u8(m.subscriber_priority);
1010 buf.put_u8(m.forward as u8);
1011 encode_parameters(&m.parameters, buf)?;
1012 }
1013 ControlMessage::SubscribeDone(m) => {
1014 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1015 return Err(CodecError::ReasonPhraseTooLong);
1016 }
1017 m.request_id.encode(buf);
1018 m.status_code.encode(buf);
1019 m.stream_count.encode(buf);
1020 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1021 buf.put_slice(&m.reason_phrase);
1022 }
1023 ControlMessage::Unsubscribe(m) => {
1024 m.request_id.encode(buf);
1025 }
1026 ControlMessage::Announce(m) => {
1027 m.request_id.encode(buf);
1028 m.track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1029 m.track_namespace.encode(buf);
1030 encode_parameters(&m.parameters, buf)?;
1031 }
1032 ControlMessage::AnnounceOk(m) => {
1033 m.request_id.encode(buf);
1034 }
1035 ControlMessage::AnnounceError(m) => {
1036 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1037 return Err(CodecError::ReasonPhraseTooLong);
1038 }
1039 m.request_id.encode(buf);
1040 m.error_code.encode(buf);
1041 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1042 buf.put_slice(&m.reason_phrase);
1043 }
1044 ControlMessage::AnnounceCancel(m) => {
1045 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1046 return Err(CodecError::ReasonPhraseTooLong);
1047 }
1048 m.track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1049 m.track_namespace.encode(buf);
1050 m.error_code.encode(buf);
1051 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1052 buf.put_slice(&m.reason_phrase);
1053 }
1054 ControlMessage::Unannounce(m) => {
1055 m.track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1056 m.track_namespace.encode(buf);
1057 }
1058 ControlMessage::SubscribeAnnounces(m) => {
1059 m.request_id.encode(buf);
1060 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(12))?;
1061 m.track_namespace_prefix.encode(buf);
1062 encode_parameters(&m.parameters, buf)?;
1063 }
1064 ControlMessage::SubscribeAnnouncesOk(m) => {
1065 m.request_id.encode(buf);
1066 }
1067 ControlMessage::SubscribeAnnouncesError(m) => {
1068 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1069 return Err(CodecError::ReasonPhraseTooLong);
1070 }
1071 m.request_id.encode(buf);
1072 m.error_code.encode(buf);
1073 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1074 buf.put_slice(&m.reason_phrase);
1075 }
1076 ControlMessage::UnsubscribeAnnounces(m) => {
1077 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(12))?;
1078 m.track_namespace_prefix.encode(buf);
1079 }
1080 ControlMessage::TrackStatusRequest(m) => {
1081 m.request_id.encode(buf);
1082 m.track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1083 m.track_namespace.encode(buf);
1084 check_full_track_name(&m.track_namespace, &m.track_name)?;
1085 VarInt::from_usize(m.track_name.len()).encode(buf);
1086 buf.put_slice(&m.track_name);
1087 encode_parameters(&m.parameters, buf)?;
1088 }
1089 ControlMessage::TrackStatus(m) => {
1090 m.request_id.encode(buf);
1091 check_track_status(m.status_code, m.largest_location)?;
1092 m.status_code.encode(buf);
1093 m.largest_location.encode(buf);
1094 encode_parameters(&m.parameters, buf)?;
1095 }
1096 ControlMessage::Fetch(m) => {
1097 m.request_id.encode(buf);
1098 buf.put_u8(m.subscriber_priority);
1099 buf.put_u8(m.group_order as u8);
1100 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1101 match &m.fetch_payload {
1102 FetchPayload::Standalone {
1103 track_namespace,
1104 track_name,
1105 start_group,
1106 start_object,
1107 end_group,
1108 end_object,
1109 } => {
1110 track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1111 track_namespace.encode(buf);
1112 check_full_track_name(track_namespace, track_name)?;
1113 VarInt::from_usize(track_name.len()).encode(buf);
1114 buf.put_slice(track_name);
1115 start_group.encode(buf);
1116 start_object.encode(buf);
1117 end_group.encode(buf);
1118 end_object.encode(buf);
1119 }
1120 FetchPayload::Joining { joining_request_id, joining_start } => {
1121 joining_request_id.encode(buf);
1122 joining_start.encode(buf);
1123 }
1124 }
1125 encode_parameters(&m.parameters, buf)?;
1126 }
1127 ControlMessage::FetchOk(m) => {
1128 m.request_id.encode(buf);
1129 buf.put_u8(m.group_order as u8);
1130 buf.put_u8(m.end_of_track);
1131 m.end_location.encode(buf);
1132 encode_parameters(&m.parameters, buf)?;
1133 }
1134 ControlMessage::FetchError(m) => {
1135 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1136 return Err(CodecError::ReasonPhraseTooLong);
1137 }
1138 m.request_id.encode(buf);
1139 m.error_code.encode(buf);
1140 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1141 buf.put_slice(&m.reason_phrase);
1142 }
1143 ControlMessage::FetchCancel(m) => {
1144 m.request_id.encode(buf);
1145 }
1146 ControlMessage::Publish(m) => {
1147 m.request_id.encode(buf);
1148 m.track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1149 m.track_namespace.encode(buf);
1150 check_full_track_name(&m.track_namespace, &m.track_name)?;
1151 VarInt::from_usize(m.track_name.len()).encode(buf);
1152 buf.put_slice(&m.track_name);
1153 m.track_alias.encode(buf);
1154 buf.put_u8(m.group_order as u8);
1155 buf.put_u8(m.content_exists as u8);
1156 if let Some(loc) = &m.largest_location {
1157 loc.encode(buf);
1158 }
1159 buf.put_u8(m.forward as u8);
1160 encode_parameters(&m.parameters, buf)?;
1161 }
1162 ControlMessage::PublishOk(m) => {
1163 m.request_id.encode(buf);
1164 buf.put_u8(m.forward as u8);
1165 buf.put_u8(m.subscriber_priority);
1166 buf.put_u8(m.group_order as u8);
1167 m.filter_type.encode(buf);
1168 if let Some(sg) = &m.start_group {
1169 sg.encode(buf);
1170 }
1171 if let Some(so) = &m.start_object {
1172 so.encode(buf);
1173 }
1174 if let Some(eg) = &m.end_group {
1175 eg.encode(buf);
1176 }
1177 encode_parameters(&m.parameters, buf)?;
1178 }
1179 ControlMessage::PublishError(m) => {
1180 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1181 return Err(CodecError::ReasonPhraseTooLong);
1182 }
1183 m.request_id.encode(buf);
1184 m.error_code.encode(buf);
1185 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1186 buf.put_slice(&m.reason_phrase);
1187 }
1188 }
1189 Ok(())
1190 }
1191
1192 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1193 match msg_type {
1194 MessageType::ClientSetup => {
1195 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1196 if num_versions == 0 {
1206 return Err(CodecError::InvalidField);
1207 }
1208 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1209 for _ in 0..num_versions {
1210 supported_versions.push(VarInt::decode(buf)?);
1211 }
1212 let parameters = decode_setup_parameters(buf)?;
1213 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1214 }
1215 MessageType::ServerSetup => {
1216 let selected_version = VarInt::decode(buf)?;
1217 let parameters = decode_setup_parameters(buf)?;
1218 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1219 }
1220 MessageType::GoAway => {
1221 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1222 if uri_len > MAX_GOAWAY_URI_LENGTH {
1223 return Err(CodecError::GoAwayUriTooLong);
1224 }
1225 let uri = types::read_bytes(buf, uri_len)?;
1226 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1227 }
1228 MessageType::MaxRequestId => {
1229 let request_id = VarInt::decode(buf)?;
1230 Ok(ControlMessage::MaxRequestId(MaxRequestId { request_id }))
1231 }
1232 MessageType::RequestsBlocked => {
1233 let maximum_request_id = VarInt::decode(buf)?;
1234 Ok(ControlMessage::RequestsBlocked(RequestsBlocked { maximum_request_id }))
1235 }
1236 MessageType::Subscribe => {
1237 let request_id = VarInt::decode(buf)?;
1238 let track_namespace = TrackNamespace::decode(buf)?;
1239 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1240 let track_name = types::read_bytes(buf, track_name_len)?;
1241 check_full_track_name(&track_namespace, &track_name)?;
1242 if buf.remaining() < 1 {
1243 return Err(CodecError::UnexpectedEnd);
1244 }
1245 let subscriber_priority = buf.get_u8();
1246 let group_order = read_group_order(buf)?;
1247 let forward = read_forward(buf)?;
1248 let filter_type = VarInt::decode(buf)?;
1249 let ft_val = filter_type.into_inner();
1250 if ft_val == 0 || ft_val > 4 {
1251 return Err(CodecError::InvalidFilterType(ft_val));
1252 }
1253 let (start_group, start_object) = if ft_val == 3 || ft_val == 4 {
1254 (Some(VarInt::decode(buf)?), Some(VarInt::decode(buf)?))
1255 } else {
1256 (None, None)
1257 };
1258 let end_group = if ft_val == 4 { Some(VarInt::decode(buf)?) } else { None };
1259 let parameters = decode_parameters(buf)?;
1260 Ok(ControlMessage::Subscribe(Subscribe {
1261 request_id,
1262 track_namespace,
1263 track_name,
1264 subscriber_priority,
1265 group_order,
1266 forward,
1267 filter_type,
1268 start_group,
1269 start_object,
1270 end_group,
1271 parameters,
1272 }))
1273 }
1274 MessageType::SubscribeOk => {
1275 let request_id = VarInt::decode(buf)?;
1276 let track_alias = VarInt::decode(buf)?;
1277 let expires = VarInt::decode(buf)?;
1278 let group_order = read_group_order_response(buf)?;
1279 let content_exists = read_content_exists(buf)?;
1280 let largest_location = if content_exists == ContentExists::HasLargestLocation {
1281 Some(Location::decode(buf)?)
1282 } else {
1283 None
1284 };
1285 let parameters = decode_parameters(buf)?;
1286 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1287 request_id,
1288 track_alias,
1289 expires,
1290 group_order,
1291 content_exists,
1292 largest_location,
1293 parameters,
1294 }))
1295 }
1296 MessageType::SubscribeError => {
1297 let request_id = VarInt::decode(buf)?;
1298 let error_code = VarInt::decode(buf)?;
1299 let reason_phrase = read_reason_phrase(buf)?;
1300 Ok(ControlMessage::SubscribeError(SubscribeError {
1301 request_id,
1302 error_code,
1303 reason_phrase,
1304 }))
1305 }
1306 MessageType::SubscribeUpdate => {
1307 let request_id = VarInt::decode(buf)?;
1308 let start_group = VarInt::decode(buf)?;
1309 let start_object = VarInt::decode(buf)?;
1310 let end_group = VarInt::decode(buf)?;
1311 if buf.remaining() < 1 {
1312 return Err(CodecError::UnexpectedEnd);
1313 }
1314 let subscriber_priority = buf.get_u8();
1315 let forward = read_forward(buf)?;
1316 let parameters = decode_parameters(buf)?;
1317 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1318 request_id,
1319 start_group,
1320 start_object,
1321 end_group,
1322 subscriber_priority,
1323 forward,
1324 parameters,
1325 }))
1326 }
1327 MessageType::SubscribeDone => {
1328 let request_id = VarInt::decode(buf)?;
1329 let status_code = VarInt::decode(buf)?;
1330 let stream_count = VarInt::decode(buf)?;
1331 let reason_phrase = read_reason_phrase(buf)?;
1332 Ok(ControlMessage::SubscribeDone(SubscribeDone {
1333 request_id,
1334 status_code,
1335 stream_count,
1336 reason_phrase,
1337 }))
1338 }
1339 MessageType::Unsubscribe => {
1340 let request_id = VarInt::decode(buf)?;
1341 Ok(ControlMessage::Unsubscribe(Unsubscribe { request_id }))
1342 }
1343 MessageType::Announce => {
1344 let request_id = VarInt::decode(buf)?;
1345 let track_namespace = TrackNamespace::decode(buf)?;
1346 let parameters = decode_parameters(buf)?;
1347 Ok(ControlMessage::Announce(Announce { request_id, track_namespace, parameters }))
1348 }
1349 MessageType::AnnounceOk => {
1350 let request_id = VarInt::decode(buf)?;
1351 Ok(ControlMessage::AnnounceOk(AnnounceOk { request_id }))
1352 }
1353 MessageType::AnnounceError => {
1354 let request_id = VarInt::decode(buf)?;
1355 let error_code = VarInt::decode(buf)?;
1356 let reason_phrase = read_reason_phrase(buf)?;
1357 Ok(ControlMessage::AnnounceError(AnnounceError {
1358 request_id,
1359 error_code,
1360 reason_phrase,
1361 }))
1362 }
1363 MessageType::AnnounceCancel => {
1364 let track_namespace = TrackNamespace::decode(buf)?;
1365 let error_code = VarInt::decode(buf)?;
1366 let reason_phrase = read_reason_phrase(buf)?;
1367 Ok(ControlMessage::AnnounceCancel(AnnounceCancel {
1368 track_namespace,
1369 error_code,
1370 reason_phrase,
1371 }))
1372 }
1373 MessageType::Unannounce => {
1374 let track_namespace = TrackNamespace::decode(buf)?;
1375 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1376 }
1377 MessageType::SubscribeAnnounces => {
1378 let request_id = VarInt::decode(buf)?;
1379 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1380 let parameters = decode_parameters(buf)?;
1381 Ok(ControlMessage::SubscribeAnnounces(SubscribeAnnounces {
1382 request_id,
1383 track_namespace_prefix,
1384 parameters,
1385 }))
1386 }
1387 MessageType::SubscribeAnnouncesOk => {
1388 let request_id = VarInt::decode(buf)?;
1389 Ok(ControlMessage::SubscribeAnnouncesOk(SubscribeAnnouncesOk { request_id }))
1390 }
1391 MessageType::SubscribeAnnouncesError => {
1392 let request_id = VarInt::decode(buf)?;
1393 let error_code = VarInt::decode(buf)?;
1394 let reason_phrase = read_reason_phrase(buf)?;
1395 Ok(ControlMessage::SubscribeAnnouncesError(SubscribeAnnouncesError {
1396 request_id,
1397 error_code,
1398 reason_phrase,
1399 }))
1400 }
1401 MessageType::UnsubscribeAnnounces => {
1402 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1403 Ok(ControlMessage::UnsubscribeAnnounces(UnsubscribeAnnounces {
1404 track_namespace_prefix,
1405 }))
1406 }
1407 MessageType::TrackStatusRequest => {
1408 let request_id = VarInt::decode(buf)?;
1409 let track_namespace = TrackNamespace::decode(buf)?;
1410 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1411 let track_name = types::read_bytes(buf, track_name_len)?;
1412 check_full_track_name(&track_namespace, &track_name)?;
1413 let parameters = decode_parameters(buf)?;
1414 Ok(ControlMessage::TrackStatusRequest(TrackStatusRequest {
1415 request_id,
1416 track_namespace,
1417 track_name,
1418 parameters,
1419 }))
1420 }
1421 MessageType::TrackStatus => {
1422 let request_id = VarInt::decode(buf)?;
1423 let status_code = VarInt::decode(buf)?;
1424 let largest_location = Location::decode(buf)?;
1425 check_track_status(status_code, largest_location)?;
1426 let parameters = decode_parameters(buf)?;
1427 Ok(ControlMessage::TrackStatus(TrackStatus {
1428 request_id,
1429 status_code,
1430 largest_location,
1431 parameters,
1432 }))
1433 }
1434 MessageType::Fetch => {
1435 let request_id = VarInt::decode(buf)?;
1436 if buf.remaining() < 1 {
1437 return Err(CodecError::UnexpectedEnd);
1438 }
1439 let subscriber_priority = buf.get_u8();
1440 let group_order = read_group_order(buf)?;
1441 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1442 let fetch_type = FetchType::from_u64(fetch_type_val)
1443 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1444 let fetch_payload = match fetch_type {
1445 FetchType::Standalone => {
1446 let track_namespace = TrackNamespace::decode(buf)?;
1447 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1448 let track_name = types::read_bytes(buf, track_name_len)?;
1449 check_full_track_name(&track_namespace, &track_name)?;
1450 let start_group = VarInt::decode(buf)?;
1451 let start_object = VarInt::decode(buf)?;
1452 let end_group = VarInt::decode(buf)?;
1453 let end_object = VarInt::decode(buf)?;
1454 FetchPayload::Standalone {
1455 track_namespace,
1456 track_name,
1457 start_group,
1458 start_object,
1459 end_group,
1460 end_object,
1461 }
1462 }
1463 FetchType::RelativeJoining | FetchType::AbsoluteJoining => {
1464 let joining_request_id = VarInt::decode(buf)?;
1465 let joining_start = VarInt::decode(buf)?;
1466 FetchPayload::Joining { joining_request_id, joining_start }
1467 }
1468 };
1469 let parameters = decode_parameters(buf)?;
1470 Ok(ControlMessage::Fetch(Fetch {
1471 request_id,
1472 subscriber_priority,
1473 group_order,
1474 fetch_type,
1475 fetch_payload,
1476 parameters,
1477 }))
1478 }
1479 MessageType::FetchOk => {
1480 let request_id = VarInt::decode(buf)?;
1481 let group_order = read_group_order_response(buf)?;
1482 let end_of_track = read_u8(buf)?;
1483 let end_location = Location::decode(buf)?;
1484 let parameters = decode_parameters(buf)?;
1485 Ok(ControlMessage::FetchOk(FetchOk {
1486 request_id,
1487 group_order,
1488 end_of_track,
1489 end_location,
1490 parameters,
1491 }))
1492 }
1493 MessageType::FetchError => {
1494 let request_id = VarInt::decode(buf)?;
1495 let error_code = VarInt::decode(buf)?;
1496 let reason_phrase = read_reason_phrase(buf)?;
1497 Ok(ControlMessage::FetchError(FetchError { request_id, error_code, reason_phrase }))
1498 }
1499 MessageType::FetchCancel => {
1500 let request_id = VarInt::decode(buf)?;
1501 Ok(ControlMessage::FetchCancel(FetchCancel { request_id }))
1502 }
1503 MessageType::Publish => {
1504 let request_id = VarInt::decode(buf)?;
1505 let track_namespace = TrackNamespace::decode(buf)?;
1506 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1507 let track_name = types::read_bytes(buf, track_name_len)?;
1508 check_full_track_name(&track_namespace, &track_name)?;
1509 let track_alias = VarInt::decode(buf)?;
1510 let group_order = read_group_order_response(buf)?;
1511 let content_exists = read_content_exists(buf)?;
1512 let largest_location = if content_exists == ContentExists::HasLargestLocation {
1513 Some(Location::decode(buf)?)
1514 } else {
1515 None
1516 };
1517 let forward = read_forward(buf)?;
1518 let parameters = decode_parameters(buf)?;
1519 Ok(ControlMessage::Publish(Publish {
1520 request_id,
1521 track_namespace,
1522 track_name,
1523 track_alias,
1524 group_order,
1525 content_exists,
1526 largest_location,
1527 forward,
1528 parameters,
1529 }))
1530 }
1531 MessageType::PublishOk => {
1532 let request_id = VarInt::decode(buf)?;
1533 let forward = read_forward(buf)?;
1534 if buf.remaining() < 1 {
1535 return Err(CodecError::UnexpectedEnd);
1536 }
1537 let subscriber_priority = buf.get_u8();
1538 let group_order = read_group_order_response(buf)?;
1539 let filter_type = VarInt::decode(buf)?;
1540 let ft_val = filter_type.into_inner();
1541 if ft_val == 0 || ft_val > 4 {
1542 return Err(CodecError::InvalidFilterType(ft_val));
1543 }
1544 let (start_group, start_object) = if ft_val == 3 || ft_val == 4 {
1545 (Some(VarInt::decode(buf)?), Some(VarInt::decode(buf)?))
1546 } else {
1547 (None, None)
1548 };
1549 let end_group = if ft_val == 4 { Some(VarInt::decode(buf)?) } else { None };
1550 let parameters = decode_parameters(buf)?;
1551 Ok(ControlMessage::PublishOk(PublishOk {
1552 request_id,
1553 forward,
1554 subscriber_priority,
1555 group_order,
1556 filter_type,
1557 start_group,
1558 start_object,
1559 end_group,
1560 parameters,
1561 }))
1562 }
1563 MessageType::PublishError => {
1564 let request_id = VarInt::decode(buf)?;
1565 let error_code = VarInt::decode(buf)?;
1566 let reason_phrase = read_reason_phrase(buf)?;
1567 Ok(ControlMessage::PublishError(PublishError {
1568 request_id,
1569 error_code,
1570 reason_phrase,
1571 }))
1572 }
1573 }
1574 }
1575
1576 pub fn message_type(&self) -> MessageType {
1577 match self {
1578 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
1579 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
1580 ControlMessage::GoAway(_) => MessageType::GoAway,
1581 ControlMessage::MaxRequestId(_) => MessageType::MaxRequestId,
1582 ControlMessage::RequestsBlocked(_) => MessageType::RequestsBlocked,
1583 ControlMessage::Subscribe(_) => MessageType::Subscribe,
1584 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
1585 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
1586 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
1587 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
1588 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
1589 ControlMessage::Announce(_) => MessageType::Announce,
1590 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
1591 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
1592 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
1593 ControlMessage::Unannounce(_) => MessageType::Unannounce,
1594 ControlMessage::SubscribeAnnounces(_) => MessageType::SubscribeAnnounces,
1595 ControlMessage::SubscribeAnnouncesOk(_) => MessageType::SubscribeAnnouncesOk,
1596 ControlMessage::SubscribeAnnouncesError(_) => MessageType::SubscribeAnnouncesError,
1597 ControlMessage::UnsubscribeAnnounces(_) => MessageType::UnsubscribeAnnounces,
1598 ControlMessage::TrackStatusRequest(_) => MessageType::TrackStatusRequest,
1599 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
1600 ControlMessage::Fetch(_) => MessageType::Fetch,
1601 ControlMessage::FetchOk(_) => MessageType::FetchOk,
1602 ControlMessage::FetchError(_) => MessageType::FetchError,
1603 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
1604 ControlMessage::Publish(_) => MessageType::Publish,
1605 ControlMessage::PublishOk(_) => MessageType::PublishOk,
1606 ControlMessage::PublishError(_) => MessageType::PublishError,
1607 }
1608 }
1609}