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::*;
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)]
24#[repr(u64)]
25pub enum MessageType {
26 SubscribeUpdate = 0x02,
27 Subscribe = 0x03,
28 SubscribeOk = 0x04,
29 SubscribeError = 0x05,
30 Announce = 0x06,
31 AnnounceOk = 0x07,
32 AnnounceError = 0x08,
33 Unannounce = 0x09,
34 Unsubscribe = 0x0A,
35 SubscribeDone = 0x0B,
36 AnnounceCancel = 0x0C,
37 TrackStatus = 0x0D,
38 TrackStatusOk = 0x0E,
39 TrackStatusError = 0x0F,
40 GoAway = 0x10,
41 SubscribeNamespace = 0x11,
42 SubscribeNamespaceOk = 0x12,
43 SubscribeNamespaceError = 0x13,
44 UnsubscribeNamespace = 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::TrackStatus),
73 0x0E => Some(MessageType::TrackStatusOk),
74 0x0F => Some(MessageType::TrackStatusError),
75 0x10 => Some(MessageType::GoAway),
76 0x11 => Some(MessageType::SubscribeNamespace),
77 0x12 => Some(MessageType::SubscribeNamespaceOk),
78 0x13 => Some(MessageType::SubscribeNamespaceError),
79 0x14 => Some(MessageType::UnsubscribeNamespace),
80 0x15 => Some(MessageType::MaxRequestId),
81 0x16 => Some(MessageType::Fetch),
82 0x17 => Some(MessageType::FetchCancel),
83 0x18 => Some(MessageType::FetchOk),
84 0x19 => Some(MessageType::FetchError),
85 0x1A => Some(MessageType::RequestsBlocked),
86 0x1D => Some(MessageType::Publish),
87 0x1E => Some(MessageType::PublishOk),
88 0x1F => Some(MessageType::PublishError),
89 0x20 => Some(MessageType::ClientSetup),
90 0x21 => Some(MessageType::ServerSetup),
91 _ => None,
92 }
93 }
94
95 pub fn id(&self) -> u64 {
96 *self as u64
97 }
98}
99
100#[derive(Debug, Clone, PartialEq, Eq)]
105pub struct ClientSetup {
106 pub supported_versions: Vec<VarInt>,
107 pub parameters: Vec<KeyValuePair>,
108}
109
110#[derive(Debug, Clone, PartialEq, Eq)]
111pub struct ServerSetup {
112 pub selected_version: VarInt,
113 pub parameters: Vec<KeyValuePair>,
114}
115
116#[derive(Debug, Clone, PartialEq, Eq)]
117pub struct GoAway {
118 pub new_session_uri: Vec<u8>,
119}
120
121#[derive(Debug, Clone, PartialEq, Eq)]
122pub struct MaxRequestId {
123 pub request_id: VarInt,
124}
125
126#[derive(Debug, Clone, PartialEq, Eq)]
127pub struct RequestsBlocked {
128 pub maximum_request_id: VarInt,
129}
130
131#[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: FilterType,
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)]
151pub struct SubscribeOk {
152 pub request_id: VarInt,
153 pub track_alias: VarInt,
154 pub expires: VarInt,
155 pub group_order: GroupOrder,
156 pub content_exists: ContentExists,
157 pub largest_location: Option<Location>,
158 pub parameters: Vec<KeyValuePair>,
159}
160
161#[derive(Debug, Clone, PartialEq, Eq)]
162pub struct SubscribeError {
163 pub request_id: VarInt,
164 pub error_code: VarInt,
165 pub reason_phrase: Vec<u8>,
166}
167
168#[derive(Debug, Clone, PartialEq, Eq)]
169pub struct SubscribeUpdate {
170 pub request_id: VarInt,
171 pub start_group: VarInt,
172 pub start_object: VarInt,
173 pub end_group: VarInt,
174 pub subscriber_priority: u8,
175 pub forward: Forward,
176 pub parameters: Vec<KeyValuePair>,
177}
178
179#[derive(Debug, Clone, PartialEq, Eq)]
180pub struct SubscribeDone {
181 pub request_id: VarInt,
182 pub status_code: VarInt,
183 pub stream_count: VarInt,
184 pub reason_phrase: Vec<u8>,
185}
186
187#[derive(Debug, Clone, PartialEq, Eq)]
188pub struct Unsubscribe {
189 pub request_id: VarInt,
190}
191
192#[derive(Debug, Clone, PartialEq, Eq)]
197pub struct Announce {
198 pub request_id: VarInt,
199 pub track_namespace: TrackNamespace,
200 pub parameters: Vec<KeyValuePair>,
201}
202
203#[derive(Debug, Clone, PartialEq, Eq)]
204pub struct AnnounceOk {
205 pub request_id: VarInt,
206}
207
208#[derive(Debug, Clone, PartialEq, Eq)]
209pub struct AnnounceError {
210 pub request_id: VarInt,
211 pub error_code: VarInt,
212 pub reason_phrase: Vec<u8>,
213}
214
215#[derive(Debug, Clone, PartialEq, Eq)]
216pub struct AnnounceCancel {
217 pub track_namespace: TrackNamespace,
218 pub error_code: VarInt,
219 pub reason_phrase: Vec<u8>,
220}
221
222#[derive(Debug, Clone, PartialEq, Eq)]
223pub struct Unannounce {
224 pub track_namespace: TrackNamespace,
225}
226
227#[derive(Debug, Clone, PartialEq, Eq)]
232pub struct SubscribeNamespace {
233 pub request_id: VarInt,
234 pub track_namespace_prefix: TrackNamespace,
235 pub parameters: Vec<KeyValuePair>,
236}
237
238#[derive(Debug, Clone, PartialEq, Eq)]
239pub struct SubscribeNamespaceOk {
240 pub request_id: VarInt,
241}
242
243#[derive(Debug, Clone, PartialEq, Eq)]
244pub struct SubscribeNamespaceError {
245 pub request_id: VarInt,
246 pub error_code: VarInt,
247 pub reason_phrase: Vec<u8>,
248}
249
250#[derive(Debug, Clone, PartialEq, Eq)]
251pub struct UnsubscribeNamespace {
252 pub track_namespace_prefix: TrackNamespace,
253}
254
255#[derive(Debug, Clone, PartialEq, Eq)]
267pub struct TrackStatus {
268 pub request_id: VarInt,
269 pub track_namespace: TrackNamespace,
270 pub track_name: Vec<u8>,
271 pub subscriber_priority: u8,
272 pub group_order: GroupOrder,
273 pub forward: Forward,
274 pub filter_type: FilterType,
275 pub start_group: Option<VarInt>,
277 pub start_object: Option<VarInt>,
279 pub end_group: Option<VarInt>,
281 pub parameters: Vec<KeyValuePair>,
282}
283
284#[derive(Debug, Clone, PartialEq, Eq)]
286pub struct TrackStatusOk {
287 pub request_id: VarInt,
288 pub track_alias: VarInt,
289 pub expires: VarInt,
290 pub group_order: GroupOrder,
291 pub content_exists: ContentExists,
292 pub largest_location: Option<Location>,
293 pub parameters: Vec<KeyValuePair>,
294}
295
296#[derive(Debug, Clone, PartialEq, Eq)]
298pub struct TrackStatusError {
299 pub request_id: VarInt,
300 pub error_code: VarInt,
301 pub reason_phrase: Vec<u8>,
302}
303
304#[derive(Debug, Clone, Copy, PartialEq, Eq)]
309#[repr(u64)]
310pub enum FetchType {
311 Standalone = 1,
312 RelativeJoining = 2,
313 AbsoluteJoining = 3,
314}
315
316impl FetchType {
317 pub fn from_u64(v: u64) -> Option<Self> {
318 match v {
319 1 => Some(FetchType::Standalone),
320 2 => Some(FetchType::RelativeJoining),
321 3 => Some(FetchType::AbsoluteJoining),
322 _ => None,
323 }
324 }
325}
326
327#[derive(Debug, Clone, PartialEq, Eq)]
328pub struct Fetch {
329 pub request_id: VarInt,
330 pub subscriber_priority: u8,
331 pub group_order: GroupOrder,
332 pub fetch_type: FetchType,
333 pub fetch_payload: FetchPayload,
334 pub parameters: Vec<KeyValuePair>,
335}
336
337#[derive(Debug, Clone, PartialEq, Eq)]
338pub enum FetchPayload {
339 Standalone {
340 track_namespace: TrackNamespace,
341 track_name: Vec<u8>,
342 start_group: VarInt,
343 start_object: VarInt,
344 end_group: VarInt,
345 end_object: VarInt,
346 },
347 Joining {
348 joining_request_id: VarInt,
357 joining_start: VarInt,
360 },
361}
362
363#[derive(Debug, Clone, PartialEq, Eq)]
364pub struct FetchOk {
365 pub request_id: VarInt,
366 pub group_order: GroupOrder,
367 pub end_of_track: u8,
374 pub end_location: Location,
375 pub parameters: Vec<KeyValuePair>,
376}
377
378#[derive(Debug, Clone, PartialEq, Eq)]
379pub struct FetchError {
380 pub request_id: VarInt,
381 pub error_code: VarInt,
382 pub reason_phrase: Vec<u8>,
383}
384
385#[derive(Debug, Clone, PartialEq, Eq)]
386pub struct FetchCancel {
387 pub request_id: VarInt,
388}
389
390#[derive(Debug, Clone, PartialEq, Eq)]
395pub struct Publish {
396 pub request_id: VarInt,
397 pub track_namespace: TrackNamespace,
398 pub track_name: Vec<u8>,
399 pub track_alias: VarInt,
400 pub group_order: GroupOrder,
401 pub content_exists: ContentExists,
402 pub largest_location: Option<Location>,
403 pub forward: Forward,
404 pub parameters: Vec<KeyValuePair>,
405}
406
407#[derive(Debug, Clone, PartialEq, Eq)]
408pub struct PublishOk {
409 pub request_id: VarInt,
410 pub forward: Forward,
411 pub subscriber_priority: u8,
412 pub group_order: GroupOrder,
413 pub filter_type: FilterType,
414 pub start_group: Option<VarInt>,
415 pub start_object: Option<VarInt>,
416 pub end_group: Option<VarInt>,
417 pub parameters: Vec<KeyValuePair>,
418}
419
420#[derive(Debug, Clone, PartialEq, Eq)]
421pub struct PublishError {
422 pub request_id: VarInt,
423 pub error_code: VarInt,
424 pub reason_phrase: Vec<u8>,
425}
426
427#[derive(Debug, Clone, PartialEq, Eq)]
432pub enum ControlMessage {
433 ClientSetup(ClientSetup),
434 ServerSetup(ServerSetup),
435 GoAway(GoAway),
436 MaxRequestId(MaxRequestId),
437 RequestsBlocked(RequestsBlocked),
438 Subscribe(Subscribe),
439 SubscribeOk(SubscribeOk),
440 SubscribeError(SubscribeError),
441 SubscribeUpdate(SubscribeUpdate),
442 SubscribeDone(SubscribeDone),
443 Unsubscribe(Unsubscribe),
444 Announce(Announce),
445 AnnounceOk(AnnounceOk),
446 AnnounceError(AnnounceError),
447 AnnounceCancel(AnnounceCancel),
448 Unannounce(Unannounce),
449 SubscribeNamespace(SubscribeNamespace),
450 SubscribeNamespaceOk(SubscribeNamespaceOk),
451 SubscribeNamespaceError(SubscribeNamespaceError),
452 UnsubscribeNamespace(UnsubscribeNamespace),
453 TrackStatus(TrackStatus),
454 TrackStatusOk(TrackStatusOk),
455 TrackStatusError(TrackStatusError),
456 Fetch(Fetch),
457 FetchOk(FetchOk),
458 FetchError(FetchError),
459 FetchCancel(FetchCancel),
460 Publish(Publish),
461 PublishOk(PublishOk),
462 PublishError(PublishError),
463}
464
465fn check_full_track_name(namespace: &TrackNamespace, track_name: &[u8]) -> Result<(), CodecError> {
466 let total = namespace.field_bytes_len().saturating_add(track_name.len());
467 if total > MAX_FULL_TRACK_NAME_LENGTH {
468 return Err(CodecError::TrackNameTooLong);
469 }
470 Ok(())
471}
472
473fn read_reason_phrase(buf: &mut impl Buf) -> Result<Vec<u8>, CodecError> {
481 let len = VarInt::decode(buf)?.into_inner() as usize;
482 if len > MAX_REASON_PHRASE_LENGTH {
483 return Err(CodecError::ReasonPhraseTooLong);
484 }
485 read_bytes(buf, len)
486}
487
488fn read_u8(buf: &mut impl Buf) -> Result<u8, CodecError> {
490 if !buf.has_remaining() {
491 return Err(CodecError::UnexpectedEnd);
492 }
493 Ok(buf.get_u8())
494}
495
496fn read_group_order(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
508 GroupOrder::from_u8(read_u8(buf)?).ok_or(CodecError::InvalidField)
509}
510
511fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
523 match read_group_order(buf)? {
524 GroupOrder::Publisher => Err(CodecError::InvalidField),
525 order => Ok(order),
526 }
527}
528
529fn read_forward(buf: &mut impl Buf) -> Result<Forward, CodecError> {
532 match read_u8(buf)? {
533 0 => Ok(Forward::DontForward),
534 1 => Ok(Forward::Forward),
535 other => Err(CodecError::InvalidForward(other)),
536 }
537}
538
539fn read_content_exists(buf: &mut impl Buf) -> Result<ContentExists, CodecError> {
542 match read_u8(buf)? {
543 0 => Ok(ContentExists::NoLargestLocation),
544 1 => Ok(ContentExists::HasLargestLocation),
545 other => Err(CodecError::InvalidContentExists(other)),
546 }
547}
548
549fn read_filter_type(buf: &mut impl Buf) -> Result<FilterType, CodecError> {
559 let value = VarInt::decode(buf)?.into_inner();
560 FilterType::from_u64(value).ok_or(CodecError::InvalidFilterType(value))
561}
562
563type StartLocation = (Option<VarInt>, Option<VarInt>);
567fn read_start_location(
568 filter_type: FilterType,
569 buf: &mut impl Buf,
570) -> Result<StartLocation, CodecError> {
571 match filter_type {
572 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
573 Ok((Some(VarInt::decode(buf)?), Some(VarInt::decode(buf)?)))
574 }
575 _ => Ok((None, None)),
576 }
577}
578
579fn read_end_group(
583 filter_type: FilterType,
584 buf: &mut impl Buf,
585) -> Result<Option<VarInt>, CodecError> {
586 match filter_type {
587 FilterType::AbsoluteRange => Ok(Some(VarInt::decode(buf)?)),
588 _ => Ok(None),
589 }
590}
591
592fn read_largest_location(
596 content_exists: ContentExists,
597 buf: &mut impl Buf,
598) -> Result<Option<Location>, CodecError> {
599 match content_exists {
600 ContentExists::HasLargestLocation => Ok(Some(Location::decode(buf)?)),
601 ContentExists::NoLargestLocation => Ok(None),
602 }
603}
604
605fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
610 let order = match message {
611 ControlMessage::SubscribeOk(m) => m.group_order,
612 ControlMessage::TrackStatusOk(m) => m.group_order,
613 ControlMessage::FetchOk(m) => m.group_order,
614 ControlMessage::Publish(m) => m.group_order,
615 ControlMessage::PublishOk(m) => m.group_order,
616 _ => return Ok(()),
617 };
618 if order == GroupOrder::Publisher {
619 return Err(CodecError::InvalidField);
620 }
621 Ok(())
622}
623
624fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
642 fn check_filter(
645 filter_type: FilterType,
646 start_group: &Option<VarInt>,
647 start_object: &Option<VarInt>,
648 end_group: &Option<VarInt>,
649 ) -> Result<(), CodecError> {
650 let wants_start =
651 matches!(filter_type, FilterType::AbsoluteStart | FilterType::AbsoluteRange);
652 if wants_start != start_group.is_some() || wants_start != start_object.is_some() {
653 return Err(CodecError::InvalidField);
654 }
655 if (filter_type == FilterType::AbsoluteRange) != end_group.is_some() {
656 return Err(CodecError::InvalidField);
657 }
658 Ok(())
659 }
660
661 fn check_content(
662 content_exists: ContentExists,
663 largest_location: &Option<Location>,
664 ) -> Result<(), CodecError> {
665 if (content_exists == ContentExists::HasLargestLocation) != largest_location.is_some() {
666 return Err(CodecError::InvalidField);
667 }
668 Ok(())
669 }
670
671 match message {
672 ControlMessage::Subscribe(m) => {
673 check_filter(m.filter_type, &m.start_group, &m.start_object, &m.end_group)
674 }
675 ControlMessage::TrackStatus(m) => {
676 check_filter(m.filter_type, &m.start_group, &m.start_object, &m.end_group)
677 }
678 ControlMessage::PublishOk(m) => {
679 check_filter(m.filter_type, &m.start_group, &m.start_object, &m.end_group)
680 }
681 ControlMessage::SubscribeOk(m) => check_content(m.content_exists, &m.largest_location),
682 ControlMessage::TrackStatusOk(m) => check_content(m.content_exists, &m.largest_location),
683 ControlMessage::Publish(m) => check_content(m.content_exists, &m.largest_location),
684 ControlMessage::Fetch(m) => {
685 let body_is_standalone = matches!(m.fetch_payload, FetchPayload::Standalone { .. });
686 if body_is_standalone != (m.fetch_type == FetchType::Standalone) {
687 return Err(CodecError::InvalidField);
688 }
689 Ok(())
690 }
691 _ => Ok(()),
692 }
693}
694
695fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
709 match message {
710 ControlMessage::Subscribe(m) => match (&m.start_group, &m.end_group) {
711 (Some(start_group), Some(end_group)) => {
712 check_group_range(start_group.into_inner(), end_group.into_inner())
713 }
714 _ => Ok(()),
715 },
716 ControlMessage::SubscribeUpdate(m) => {
717 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
718 }
719 ControlMessage::Fetch(m) => match &m.fetch_payload {
720 FetchPayload::Standalone {
721 start_group, start_object, end_group, end_object, ..
722 } => check_location_range(
723 start_group.into_inner(),
724 start_object.into_inner(),
725 end_group.into_inner(),
726 end_object.into_inner(),
727 ),
728 FetchPayload::Joining { .. } => Ok(()),
729 },
730 _ => Ok(()),
731 }
732}
733
734const AUTHORIZATION_TOKEN: u64 = 0x03;
741
742const DELIVERY_TIMEOUT: u64 = 0x02;
744
745const MAX_CACHE_DURATION: u64 = 0x04;
747
748const SETUP_PATH: u64 = 0x01;
750
751const SETUP_MAX_REQUEST_ID: u64 = 0x02;
753
754const SETUP_MAX_AUTH_TOKEN_CACHE_SIZE: u64 = 0x04;
756
757const SETUP_AUTHORIZATION_TOKEN: u64 = AUTHORIZATION_TOKEN;
765
766const KNOWN_PARAMETERS: &[u64] = &[AUTHORIZATION_TOKEN, DELIVERY_TIMEOUT, MAX_CACHE_DURATION];
772
773const REPEATABLE_PARAMETERS: &[u64] = &[AUTHORIZATION_TOKEN];
779
780const KNOWN_SETUP_PARAMETERS: &[u64] =
782 &[SETUP_PATH, SETUP_MAX_REQUEST_ID, SETUP_AUTHORIZATION_TOKEN, SETUP_MAX_AUTH_TOKEN_CACHE_SIZE];
783
784const REPEATABLE_SETUP_PARAMETERS: &[u64] = &[SETUP_AUTHORIZATION_TOKEN];
792
793fn check_sender_parameters(
807 parameters: &[KeyValuePair],
808 repeatable: &[u64],
809) -> Result<(), CodecError> {
810 for (i, parameter) in parameters.iter().enumerate() {
811 let key = parameter.key.into_inner();
812 if repeatable.contains(&key) {
813 continue;
814 }
815 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
816 return Err(CodecError::DuplicateParameter(key));
817 }
818 }
819 Ok(())
820}
821
822fn check_receiver_parameters(
836 parameters: &[KeyValuePair],
837 known: &[u64],
838 repeatable: &[u64],
839) -> Result<(), CodecError> {
840 for (i, parameter) in parameters.iter().enumerate() {
841 let key = parameter.key.into_inner();
842 if repeatable.contains(&key) || !known.contains(&key) {
843 continue;
844 }
845 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
846 return Err(CodecError::DuplicateParameter(key));
847 }
848 }
849 Ok(())
850}
851
852fn check_authorization_tokens(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
867 for parameter in parameters {
868 let key = parameter.key.into_inner();
869 if key != AUTH_TOKEN_PARAMETER {
870 continue;
871 }
872 match ¶meter.value {
873 KvpValue::Bytes(value) => {
874 AuthorizationToken::decode(key, value)?;
875 }
876 KvpValue::Varint(_) => {
881 return Err(CodecError::KeyValueFormatting {
882 key,
883 detail: "its value is a bare varint where the type defines a Token structure",
884 });
885 }
886 }
887 }
888 Ok(())
889}
890
891fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
893 let parameters = KeyValuePair::decode_list(buf)?;
894 check_receiver_parameters(¶meters, KNOWN_PARAMETERS, REPEATABLE_PARAMETERS)?;
895 check_authorization_tokens(¶meters)?;
896 Ok(parameters)
897}
898
899fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
901 check_sender_parameters(parameters, REPEATABLE_PARAMETERS)?;
902 check_authorization_tokens(parameters)?;
903 KeyValuePair::encode_list_checked(parameters, buf)?;
904 Ok(())
905}
906
907fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
909 let parameters = KeyValuePair::decode_list(buf)?;
910 check_receiver_parameters(¶meters, KNOWN_SETUP_PARAMETERS, REPEATABLE_SETUP_PARAMETERS)?;
911 check_authorization_tokens(¶meters)?;
912 Ok(parameters)
913}
914
915fn encode_setup_parameters(
921 parameters: &[KeyValuePair],
922 buf: &mut impl BufMut,
923) -> Result<(), CodecError> {
924 check_sender_parameters(parameters, REPEATABLE_SETUP_PARAMETERS)?;
925 check_authorization_tokens(parameters)?;
926 KeyValuePair::encode_list_checked(parameters, buf)?;
927 Ok(())
928}
929
930impl ControlMessage {
931 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
935 check_discriminators(self)?;
936 check_group_order(self)?;
937 check_ranges(self)?;
938 let mut payload = Vec::with_capacity(256);
939 self.encode_payload(&mut payload)?;
940
941 if payload.len() > MAX_MESSAGE_LENGTH {
942 return Err(CodecError::MessageTooLong(payload.len()));
943 }
944
945 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
946 buf.put_u16(payload.len() as u16);
948 buf.put_slice(&payload);
949 Ok(())
950 }
951
952 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
956 let type_id = VarInt::decode(buf)?.into_inner();
957 let msg_type =
958 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
959 if buf.remaining() < 2 {
961 return Err(CodecError::UnexpectedEnd);
962 }
963 let payload_len = buf.get_u16() as usize;
964 if buf.remaining() < payload_len {
965 return Err(CodecError::UnexpectedEnd);
966 }
967 let payload_bytes = buf.copy_to_bytes(payload_len);
968 let mut payload = &payload_bytes[..];
969 let msg = match Self::decode_payload(msg_type, &mut payload) {
970 Ok(msg) => msg,
971 Err(
977 CodecError::UnexpectedEnd
978 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
979 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
980 crate::varint::VarIntError::UnexpectedEnd,
981 ))
982 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
983 ) => {
984 return Err(CodecError::ControlMessageLengthMismatch {
985 declared: payload_len,
986 detail: "its fields ran past the end",
987 });
988 }
989 Err(e) => return Err(e),
990 };
991 check_ranges(&msg)?;
992 if payload.has_remaining() {
997 return Err(CodecError::ControlMessageLengthMismatch {
998 declared: payload_len,
999 detail: "its fields left bytes unread",
1000 });
1001 }
1002 Ok(msg)
1003 }
1004
1005 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
1006 match self {
1007 ControlMessage::ClientSetup(m) => {
1008 VarInt::from_usize(m.supported_versions.len()).encode(buf);
1009 for v in &m.supported_versions {
1010 v.encode(buf);
1011 }
1012 encode_setup_parameters(&m.parameters, buf)?;
1013 }
1014 ControlMessage::ServerSetup(m) => {
1015 m.selected_version.encode(buf);
1016 encode_setup_parameters(&m.parameters, buf)?;
1017 }
1018 ControlMessage::GoAway(m) => {
1019 if m.new_session_uri.len() > MAX_GOAWAY_URI_LENGTH {
1020 return Err(CodecError::GoAwayUriTooLong);
1021 }
1022 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
1023 buf.put_slice(&m.new_session_uri);
1024 }
1025 ControlMessage::MaxRequestId(m) => {
1026 m.request_id.encode(buf);
1027 }
1028 ControlMessage::RequestsBlocked(m) => {
1029 m.maximum_request_id.encode(buf);
1030 }
1031 ControlMessage::Subscribe(m) => {
1032 m.request_id.encode(buf);
1033 m.track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1034 m.track_namespace.encode(buf);
1035 check_full_track_name(&m.track_namespace, &m.track_name)?;
1036 VarInt::from_usize(m.track_name.len()).encode(buf);
1037 buf.put_slice(&m.track_name);
1038 buf.put_u8(m.subscriber_priority);
1039 buf.put_u8(m.group_order as u8);
1040 buf.put_u8(m.forward as u8);
1041 VarInt::from_usize(m.filter_type as usize).encode(buf);
1042 if let Some(sg) = &m.start_group {
1043 sg.encode(buf);
1044 }
1045 if let Some(so) = &m.start_object {
1046 so.encode(buf);
1047 }
1048 if let Some(eg) = &m.end_group {
1049 eg.encode(buf);
1050 }
1051 encode_parameters(&m.parameters, buf)?;
1052 }
1053 ControlMessage::SubscribeOk(m) => {
1054 m.request_id.encode(buf);
1055 m.track_alias.encode(buf);
1056 m.expires.encode(buf);
1057 buf.put_u8(m.group_order as u8);
1058 buf.put_u8(m.content_exists as u8);
1059 if let Some(loc) = &m.largest_location {
1060 loc.encode(buf);
1061 }
1062 encode_parameters(&m.parameters, buf)?;
1063 }
1064 ControlMessage::SubscribeError(m) => {
1065 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1066 return Err(CodecError::ReasonPhraseTooLong);
1067 }
1068 m.request_id.encode(buf);
1069 m.error_code.encode(buf);
1070 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1071 buf.put_slice(&m.reason_phrase);
1072 }
1073 ControlMessage::SubscribeUpdate(m) => {
1074 m.request_id.encode(buf);
1075 m.start_group.encode(buf);
1076 m.start_object.encode(buf);
1077 m.end_group.encode(buf);
1078 buf.put_u8(m.subscriber_priority);
1079 buf.put_u8(m.forward as u8);
1080 encode_parameters(&m.parameters, buf)?;
1081 }
1082 ControlMessage::SubscribeDone(m) => {
1083 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1084 return Err(CodecError::ReasonPhraseTooLong);
1085 }
1086 m.request_id.encode(buf);
1087 m.status_code.encode(buf);
1088 m.stream_count.encode(buf);
1089 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1090 buf.put_slice(&m.reason_phrase);
1091 }
1092 ControlMessage::Unsubscribe(m) => {
1093 m.request_id.encode(buf);
1094 }
1095 ControlMessage::Announce(m) => {
1096 m.request_id.encode(buf);
1097 m.track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1098 m.track_namespace.encode(buf);
1099 encode_parameters(&m.parameters, buf)?;
1100 }
1101 ControlMessage::AnnounceOk(m) => {
1102 m.request_id.encode(buf);
1103 }
1104 ControlMessage::AnnounceError(m) => {
1105 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1106 return Err(CodecError::ReasonPhraseTooLong);
1107 }
1108 m.request_id.encode(buf);
1109 m.error_code.encode(buf);
1110 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1111 buf.put_slice(&m.reason_phrase);
1112 }
1113 ControlMessage::AnnounceCancel(m) => {
1114 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1115 return Err(CodecError::ReasonPhraseTooLong);
1116 }
1117 m.track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1118 m.track_namespace.encode(buf);
1119 m.error_code.encode(buf);
1120 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1121 buf.put_slice(&m.reason_phrase);
1122 }
1123 ControlMessage::Unannounce(m) => {
1124 m.track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1125 m.track_namespace.encode(buf);
1126 }
1127 ControlMessage::SubscribeNamespace(m) => {
1128 m.request_id.encode(buf);
1129 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(13))?;
1130 m.track_namespace_prefix.encode(buf);
1131 encode_parameters(&m.parameters, buf)?;
1132 }
1133 ControlMessage::SubscribeNamespaceOk(m) => {
1134 m.request_id.encode(buf);
1135 }
1136 ControlMessage::SubscribeNamespaceError(m) => {
1137 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1138 return Err(CodecError::ReasonPhraseTooLong);
1139 }
1140 m.request_id.encode(buf);
1141 m.error_code.encode(buf);
1142 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1143 buf.put_slice(&m.reason_phrase);
1144 }
1145 ControlMessage::UnsubscribeNamespace(m) => {
1146 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(13))?;
1147 m.track_namespace_prefix.encode(buf);
1148 }
1149 ControlMessage::TrackStatus(m) => {
1150 m.request_id.encode(buf);
1151 m.track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1152 m.track_namespace.encode(buf);
1153 check_full_track_name(&m.track_namespace, &m.track_name)?;
1154 VarInt::from_usize(m.track_name.len()).encode(buf);
1155 buf.put_slice(&m.track_name);
1156 buf.put_u8(m.subscriber_priority);
1157 buf.put_u8(m.group_order as u8);
1158 buf.put_u8(m.forward as u8);
1159 VarInt::from_usize(m.filter_type as usize).encode(buf);
1160 if let Some(sg) = &m.start_group {
1161 sg.encode(buf);
1162 }
1163 if let Some(so) = &m.start_object {
1164 so.encode(buf);
1165 }
1166 if let Some(eg) = &m.end_group {
1167 eg.encode(buf);
1168 }
1169 encode_parameters(&m.parameters, buf)?;
1170 }
1171 ControlMessage::TrackStatusOk(m) => {
1172 m.request_id.encode(buf);
1173 m.track_alias.encode(buf);
1174 m.expires.encode(buf);
1175 buf.put_u8(m.group_order as u8);
1176 buf.put_u8(m.content_exists as u8);
1177 if let Some(loc) = &m.largest_location {
1178 loc.encode(buf);
1179 }
1180 encode_parameters(&m.parameters, buf)?;
1181 }
1182 ControlMessage::TrackStatusError(m) => {
1183 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1184 return Err(CodecError::ReasonPhraseTooLong);
1185 }
1186 m.request_id.encode(buf);
1187 m.error_code.encode(buf);
1188 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1189 buf.put_slice(&m.reason_phrase);
1190 }
1191 ControlMessage::Fetch(m) => {
1192 m.request_id.encode(buf);
1193 buf.put_u8(m.subscriber_priority);
1194 buf.put_u8(m.group_order as u8);
1195 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1196 match &m.fetch_payload {
1197 FetchPayload::Standalone {
1198 track_namespace,
1199 track_name,
1200 start_group,
1201 start_object,
1202 end_group,
1203 end_object,
1204 } => {
1205 track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1206 track_namespace.encode(buf);
1207 check_full_track_name(track_namespace, track_name)?;
1208 VarInt::from_usize(track_name.len()).encode(buf);
1209 buf.put_slice(track_name);
1210 start_group.encode(buf);
1211 start_object.encode(buf);
1212 end_group.encode(buf);
1213 end_object.encode(buf);
1214 }
1215 FetchPayload::Joining { joining_request_id, joining_start } => {
1216 joining_request_id.encode(buf);
1217 joining_start.encode(buf);
1218 }
1219 }
1220 encode_parameters(&m.parameters, buf)?;
1221 }
1222 ControlMessage::FetchOk(m) => {
1223 m.request_id.encode(buf);
1224 buf.put_u8(m.group_order as u8);
1225 buf.put_u8(m.end_of_track);
1226 m.end_location.encode(buf);
1227 encode_parameters(&m.parameters, buf)?;
1228 }
1229 ControlMessage::FetchError(m) => {
1230 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1231 return Err(CodecError::ReasonPhraseTooLong);
1232 }
1233 m.request_id.encode(buf);
1234 m.error_code.encode(buf);
1235 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1236 buf.put_slice(&m.reason_phrase);
1237 }
1238 ControlMessage::FetchCancel(m) => {
1239 m.request_id.encode(buf);
1240 }
1241 ControlMessage::Publish(m) => {
1242 m.request_id.encode(buf);
1243 m.track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1244 m.track_namespace.encode(buf);
1245 check_full_track_name(&m.track_namespace, &m.track_name)?;
1246 VarInt::from_usize(m.track_name.len()).encode(buf);
1247 buf.put_slice(&m.track_name);
1248 m.track_alias.encode(buf);
1249 buf.put_u8(m.group_order as u8);
1250 buf.put_u8(m.content_exists as u8);
1251 if let Some(loc) = &m.largest_location {
1252 loc.encode(buf);
1253 }
1254 buf.put_u8(m.forward as u8);
1255 encode_parameters(&m.parameters, buf)?;
1256 }
1257 ControlMessage::PublishOk(m) => {
1258 m.request_id.encode(buf);
1259 buf.put_u8(m.forward as u8);
1260 buf.put_u8(m.subscriber_priority);
1261 buf.put_u8(m.group_order as u8);
1262 VarInt::from_usize(m.filter_type as usize).encode(buf);
1263 if let Some(sg) = &m.start_group {
1264 sg.encode(buf);
1265 }
1266 if let Some(so) = &m.start_object {
1267 so.encode(buf);
1268 }
1269 if let Some(eg) = &m.end_group {
1270 eg.encode(buf);
1271 }
1272 encode_parameters(&m.parameters, buf)?;
1273 }
1274 ControlMessage::PublishError(m) => {
1275 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1276 return Err(CodecError::ReasonPhraseTooLong);
1277 }
1278 m.request_id.encode(buf);
1279 m.error_code.encode(buf);
1280 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1281 buf.put_slice(&m.reason_phrase);
1282 }
1283 }
1284 Ok(())
1285 }
1286
1287 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1288 match msg_type {
1289 MessageType::ClientSetup => {
1290 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1291 if num_versions == 0 {
1301 return Err(CodecError::InvalidField);
1302 }
1303 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1304 for _ in 0..num_versions {
1305 supported_versions.push(VarInt::decode(buf)?);
1306 }
1307 let parameters = decode_setup_parameters(buf)?;
1308 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1309 }
1310 MessageType::ServerSetup => {
1311 let selected_version = VarInt::decode(buf)?;
1312 let parameters = decode_setup_parameters(buf)?;
1313 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1314 }
1315 MessageType::GoAway => {
1316 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1317 if uri_len > MAX_GOAWAY_URI_LENGTH {
1318 return Err(CodecError::GoAwayUriTooLong);
1319 }
1320 let uri = read_bytes(buf, uri_len)?;
1321 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1322 }
1323 MessageType::MaxRequestId => {
1324 let request_id = VarInt::decode(buf)?;
1325 Ok(ControlMessage::MaxRequestId(MaxRequestId { request_id }))
1326 }
1327 MessageType::RequestsBlocked => {
1328 let maximum_request_id = VarInt::decode(buf)?;
1329 Ok(ControlMessage::RequestsBlocked(RequestsBlocked { maximum_request_id }))
1330 }
1331 MessageType::Subscribe => {
1332 let request_id = VarInt::decode(buf)?;
1333 let track_namespace = TrackNamespace::decode(buf)?;
1334 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1335 let track_name = read_bytes(buf, track_name_len)?;
1336 check_full_track_name(&track_namespace, &track_name)?;
1337 let subscriber_priority = read_u8(buf)?;
1338 let group_order = read_group_order(buf)?;
1339 let forward = read_forward(buf)?;
1340 let filter_type = read_filter_type(buf)?;
1341 let (start_group, start_object) = read_start_location(filter_type, buf)?;
1342 let end_group = read_end_group(filter_type, buf)?;
1343 let parameters = decode_parameters(buf)?;
1344 Ok(ControlMessage::Subscribe(Subscribe {
1345 request_id,
1346 track_namespace,
1347 track_name,
1348 subscriber_priority,
1349 group_order,
1350 forward,
1351 filter_type,
1352 start_group,
1353 start_object,
1354 end_group,
1355 parameters,
1356 }))
1357 }
1358 MessageType::SubscribeOk => {
1359 let request_id = VarInt::decode(buf)?;
1360 let track_alias = VarInt::decode(buf)?;
1361 let expires = VarInt::decode(buf)?;
1362 let group_order = read_group_order_response(buf)?;
1363 let content_exists = read_content_exists(buf)?;
1364 let largest_location = read_largest_location(content_exists, buf)?;
1365 let parameters = decode_parameters(buf)?;
1366 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1367 request_id,
1368 track_alias,
1369 expires,
1370 group_order,
1371 content_exists,
1372 largest_location,
1373 parameters,
1374 }))
1375 }
1376 MessageType::SubscribeError => {
1377 let request_id = VarInt::decode(buf)?;
1378 let error_code = VarInt::decode(buf)?;
1379 let reason_phrase = read_reason_phrase(buf)?;
1380 Ok(ControlMessage::SubscribeError(SubscribeError {
1381 request_id,
1382 error_code,
1383 reason_phrase,
1384 }))
1385 }
1386 MessageType::SubscribeUpdate => {
1387 let request_id = VarInt::decode(buf)?;
1388 let start_group = VarInt::decode(buf)?;
1389 let start_object = VarInt::decode(buf)?;
1390 let end_group = VarInt::decode(buf)?;
1391 let subscriber_priority = read_u8(buf)?;
1392 let forward = read_forward(buf)?;
1393 let parameters = decode_parameters(buf)?;
1394 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1395 request_id,
1396 start_group,
1397 start_object,
1398 end_group,
1399 subscriber_priority,
1400 forward,
1401 parameters,
1402 }))
1403 }
1404 MessageType::SubscribeDone => {
1405 let request_id = VarInt::decode(buf)?;
1406 let status_code = VarInt::decode(buf)?;
1407 let stream_count = VarInt::decode(buf)?;
1408 let reason_phrase = read_reason_phrase(buf)?;
1409 Ok(ControlMessage::SubscribeDone(SubscribeDone {
1410 request_id,
1411 status_code,
1412 stream_count,
1413 reason_phrase,
1414 }))
1415 }
1416 MessageType::Unsubscribe => {
1417 let request_id = VarInt::decode(buf)?;
1418 Ok(ControlMessage::Unsubscribe(Unsubscribe { request_id }))
1419 }
1420 MessageType::Announce => {
1421 let request_id = VarInt::decode(buf)?;
1422 let track_namespace = TrackNamespace::decode(buf)?;
1423 let parameters = decode_parameters(buf)?;
1424 Ok(ControlMessage::Announce(Announce { request_id, track_namespace, parameters }))
1425 }
1426 MessageType::AnnounceOk => {
1427 let request_id = VarInt::decode(buf)?;
1428 Ok(ControlMessage::AnnounceOk(AnnounceOk { request_id }))
1429 }
1430 MessageType::AnnounceError => {
1431 let request_id = VarInt::decode(buf)?;
1432 let error_code = VarInt::decode(buf)?;
1433 let reason_phrase = read_reason_phrase(buf)?;
1434 Ok(ControlMessage::AnnounceError(AnnounceError {
1435 request_id,
1436 error_code,
1437 reason_phrase,
1438 }))
1439 }
1440 MessageType::AnnounceCancel => {
1441 let track_namespace = TrackNamespace::decode(buf)?;
1442 let error_code = VarInt::decode(buf)?;
1443 let reason_phrase = read_reason_phrase(buf)?;
1444 Ok(ControlMessage::AnnounceCancel(AnnounceCancel {
1445 track_namespace,
1446 error_code,
1447 reason_phrase,
1448 }))
1449 }
1450 MessageType::Unannounce => {
1451 let track_namespace = TrackNamespace::decode(buf)?;
1452 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1453 }
1454 MessageType::SubscribeNamespace => {
1455 let request_id = VarInt::decode(buf)?;
1456 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1457 let parameters = decode_parameters(buf)?;
1458 Ok(ControlMessage::SubscribeNamespace(SubscribeNamespace {
1459 request_id,
1460 track_namespace_prefix,
1461 parameters,
1462 }))
1463 }
1464 MessageType::SubscribeNamespaceOk => {
1465 let request_id = VarInt::decode(buf)?;
1466 Ok(ControlMessage::SubscribeNamespaceOk(SubscribeNamespaceOk { request_id }))
1467 }
1468 MessageType::SubscribeNamespaceError => {
1469 let request_id = VarInt::decode(buf)?;
1470 let error_code = VarInt::decode(buf)?;
1471 let reason_phrase = read_reason_phrase(buf)?;
1472 Ok(ControlMessage::SubscribeNamespaceError(SubscribeNamespaceError {
1473 request_id,
1474 error_code,
1475 reason_phrase,
1476 }))
1477 }
1478 MessageType::UnsubscribeNamespace => {
1479 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1480 Ok(ControlMessage::UnsubscribeNamespace(UnsubscribeNamespace {
1481 track_namespace_prefix,
1482 }))
1483 }
1484 MessageType::TrackStatus => {
1485 let request_id = VarInt::decode(buf)?;
1486 let track_namespace = TrackNamespace::decode(buf)?;
1487 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1488 let track_name = read_bytes(buf, track_name_len)?;
1489 check_full_track_name(&track_namespace, &track_name)?;
1490 let subscriber_priority = read_u8(buf)?;
1491 let group_order = read_group_order(buf)?;
1492 let forward = read_forward(buf)?;
1493 let filter_type = read_filter_type(buf)?;
1494 let (start_group, start_object) = read_start_location(filter_type, buf)?;
1495 let end_group = read_end_group(filter_type, buf)?;
1496 let parameters = decode_parameters(buf)?;
1497 Ok(ControlMessage::TrackStatus(TrackStatus {
1498 request_id,
1499 track_namespace,
1500 track_name,
1501 subscriber_priority,
1502 group_order,
1503 forward,
1504 filter_type,
1505 start_group,
1506 start_object,
1507 end_group,
1508 parameters,
1509 }))
1510 }
1511 MessageType::TrackStatusOk => {
1512 let request_id = VarInt::decode(buf)?;
1513 let track_alias = VarInt::decode(buf)?;
1514 let expires = VarInt::decode(buf)?;
1515 let group_order = read_group_order_response(buf)?;
1516 let content_exists = read_content_exists(buf)?;
1517 let largest_location = read_largest_location(content_exists, buf)?;
1518 let parameters = decode_parameters(buf)?;
1519 Ok(ControlMessage::TrackStatusOk(TrackStatusOk {
1520 request_id,
1521 track_alias,
1522 expires,
1523 group_order,
1524 content_exists,
1525 largest_location,
1526 parameters,
1527 }))
1528 }
1529 MessageType::TrackStatusError => {
1530 let request_id = VarInt::decode(buf)?;
1531 let error_code = VarInt::decode(buf)?;
1532 let reason_phrase = read_reason_phrase(buf)?;
1533 Ok(ControlMessage::TrackStatusError(TrackStatusError {
1534 request_id,
1535 error_code,
1536 reason_phrase,
1537 }))
1538 }
1539 MessageType::Fetch => {
1540 let request_id = VarInt::decode(buf)?;
1541 let subscriber_priority = read_u8(buf)?;
1542 let group_order = read_group_order(buf)?;
1543 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1544 let fetch_type = FetchType::from_u64(fetch_type_val)
1545 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1546 let fetch_payload = match fetch_type {
1547 FetchType::Standalone => {
1548 let track_namespace = TrackNamespace::decode(buf)?;
1549 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1550 let track_name = read_bytes(buf, track_name_len)?;
1551 check_full_track_name(&track_namespace, &track_name)?;
1552 let start_group = VarInt::decode(buf)?;
1553 let start_object = VarInt::decode(buf)?;
1554 let end_group = VarInt::decode(buf)?;
1555 let end_object = VarInt::decode(buf)?;
1556 FetchPayload::Standalone {
1557 track_namespace,
1558 track_name,
1559 start_group,
1560 start_object,
1561 end_group,
1562 end_object,
1563 }
1564 }
1565 FetchType::RelativeJoining | FetchType::AbsoluteJoining => {
1566 let joining_request_id = VarInt::decode(buf)?;
1567 let joining_start = VarInt::decode(buf)?;
1568 FetchPayload::Joining { joining_request_id, joining_start }
1569 }
1570 };
1571 let parameters = decode_parameters(buf)?;
1572 Ok(ControlMessage::Fetch(Fetch {
1573 request_id,
1574 subscriber_priority,
1575 group_order,
1576 fetch_type,
1577 fetch_payload,
1578 parameters,
1579 }))
1580 }
1581 MessageType::FetchOk => {
1582 let request_id = VarInt::decode(buf)?;
1583 let group_order = read_group_order_response(buf)?;
1584 let end_of_track = read_u8(buf)?;
1585 let end_location = Location::decode(buf)?;
1586 let parameters = decode_parameters(buf)?;
1587 Ok(ControlMessage::FetchOk(FetchOk {
1588 request_id,
1589 group_order,
1590 end_of_track,
1591 end_location,
1592 parameters,
1593 }))
1594 }
1595 MessageType::FetchError => {
1596 let request_id = VarInt::decode(buf)?;
1597 let error_code = VarInt::decode(buf)?;
1598 let reason_phrase = read_reason_phrase(buf)?;
1599 Ok(ControlMessage::FetchError(FetchError { request_id, error_code, reason_phrase }))
1600 }
1601 MessageType::FetchCancel => {
1602 let request_id = VarInt::decode(buf)?;
1603 Ok(ControlMessage::FetchCancel(FetchCancel { request_id }))
1604 }
1605 MessageType::Publish => {
1606 let request_id = VarInt::decode(buf)?;
1607 let track_namespace = TrackNamespace::decode(buf)?;
1608 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1609 let track_name = read_bytes(buf, track_name_len)?;
1610 check_full_track_name(&track_namespace, &track_name)?;
1611 let track_alias = VarInt::decode(buf)?;
1612 let group_order = read_group_order_response(buf)?;
1613 let content_exists = read_content_exists(buf)?;
1614 let largest_location = read_largest_location(content_exists, buf)?;
1615 let forward = read_forward(buf)?;
1616 let parameters = decode_parameters(buf)?;
1617 Ok(ControlMessage::Publish(Publish {
1618 request_id,
1619 track_namespace,
1620 track_name,
1621 track_alias,
1622 group_order,
1623 content_exists,
1624 largest_location,
1625 forward,
1626 parameters,
1627 }))
1628 }
1629 MessageType::PublishOk => {
1630 let request_id = VarInt::decode(buf)?;
1631 let forward = read_forward(buf)?;
1632 let subscriber_priority = read_u8(buf)?;
1633 let group_order = read_group_order_response(buf)?;
1634 let filter_type = read_filter_type(buf)?;
1635 let (start_group, start_object) = read_start_location(filter_type, buf)?;
1636 let end_group = read_end_group(filter_type, buf)?;
1637 let parameters = decode_parameters(buf)?;
1638 Ok(ControlMessage::PublishOk(PublishOk {
1639 request_id,
1640 forward,
1641 subscriber_priority,
1642 group_order,
1643 filter_type,
1644 start_group,
1645 start_object,
1646 end_group,
1647 parameters,
1648 }))
1649 }
1650 MessageType::PublishError => {
1651 let request_id = VarInt::decode(buf)?;
1652 let error_code = VarInt::decode(buf)?;
1653 let reason_phrase = read_reason_phrase(buf)?;
1654 Ok(ControlMessage::PublishError(PublishError {
1655 request_id,
1656 error_code,
1657 reason_phrase,
1658 }))
1659 }
1660 }
1661 }
1662
1663 pub fn message_type(&self) -> MessageType {
1664 match self {
1665 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
1666 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
1667 ControlMessage::GoAway(_) => MessageType::GoAway,
1668 ControlMessage::MaxRequestId(_) => MessageType::MaxRequestId,
1669 ControlMessage::RequestsBlocked(_) => MessageType::RequestsBlocked,
1670 ControlMessage::Subscribe(_) => MessageType::Subscribe,
1671 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
1672 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
1673 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
1674 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
1675 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
1676 ControlMessage::Announce(_) => MessageType::Announce,
1677 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
1678 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
1679 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
1680 ControlMessage::Unannounce(_) => MessageType::Unannounce,
1681 ControlMessage::SubscribeNamespace(_) => MessageType::SubscribeNamespace,
1682 ControlMessage::SubscribeNamespaceOk(_) => MessageType::SubscribeNamespaceOk,
1683 ControlMessage::SubscribeNamespaceError(_) => MessageType::SubscribeNamespaceError,
1684 ControlMessage::UnsubscribeNamespace(_) => MessageType::UnsubscribeNamespace,
1685 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
1686 ControlMessage::TrackStatusOk(_) => MessageType::TrackStatusOk,
1687 ControlMessage::TrackStatusError(_) => MessageType::TrackStatusError,
1688 ControlMessage::Fetch(_) => MessageType::Fetch,
1689 ControlMessage::FetchOk(_) => MessageType::FetchOk,
1690 ControlMessage::FetchError(_) => MessageType::FetchError,
1691 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
1692 ControlMessage::Publish(_) => MessageType::Publish,
1693 ControlMessage::PublishOk(_) => MessageType::PublishOk,
1694 ControlMessage::PublishError(_) => MessageType::PublishError,
1695 }
1696 }
1697}