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 pub fn name(&self) -> &'static str {
102 match self {
103 MessageType::SubscribeUpdate => "subscribe_update",
104 MessageType::Subscribe => "subscribe",
105 MessageType::SubscribeOk => "subscribe_ok",
106 MessageType::SubscribeError => "subscribe_error",
107 MessageType::Announce => "announce",
108 MessageType::AnnounceOk => "announce_ok",
109 MessageType::AnnounceError => "announce_error",
110 MessageType::Unannounce => "unannounce",
111 MessageType::Unsubscribe => "unsubscribe",
112 MessageType::SubscribeDone => "subscribe_done",
113 MessageType::AnnounceCancel => "announce_cancel",
114 MessageType::TrackStatus => "track_status",
115 MessageType::TrackStatusOk => "track_status_ok",
116 MessageType::TrackStatusError => "track_status_error",
117 MessageType::GoAway => "goaway",
118 MessageType::SubscribeNamespace => "subscribe_namespace",
119 MessageType::SubscribeNamespaceOk => "subscribe_namespace_ok",
120 MessageType::SubscribeNamespaceError => "subscribe_namespace_error",
121 MessageType::UnsubscribeNamespace => "unsubscribe_namespace",
122 MessageType::MaxRequestId => "max_request_id",
123 MessageType::Fetch => "fetch",
124 MessageType::FetchCancel => "fetch_cancel",
125 MessageType::FetchOk => "fetch_ok",
126 MessageType::FetchError => "fetch_error",
127 MessageType::RequestsBlocked => "requests_blocked",
128 MessageType::Publish => "publish",
129 MessageType::PublishOk => "publish_ok",
130 MessageType::PublishError => "publish_error",
131 MessageType::ClientSetup => "client_setup",
132 MessageType::ServerSetup => "server_setup",
133 }
134 }
135}
136
137#[derive(Debug, Clone, PartialEq, Eq)]
142pub struct ClientSetup {
143 pub supported_versions: Vec<VarInt>,
144 pub parameters: Vec<KeyValuePair>,
145}
146
147#[derive(Debug, Clone, PartialEq, Eq)]
148pub struct ServerSetup {
149 pub selected_version: VarInt,
150 pub parameters: Vec<KeyValuePair>,
151}
152
153#[derive(Debug, Clone, PartialEq, Eq)]
154pub struct GoAway {
155 pub new_session_uri: Vec<u8>,
156}
157
158#[derive(Debug, Clone, PartialEq, Eq)]
159pub struct MaxRequestId {
160 pub request_id: VarInt,
161}
162
163#[derive(Debug, Clone, PartialEq, Eq)]
164pub struct RequestsBlocked {
165 pub maximum_request_id: VarInt,
166}
167
168#[derive(Debug, Clone, PartialEq, Eq)]
173pub struct Subscribe {
174 pub request_id: VarInt,
175 pub track_namespace: TrackNamespace,
176 pub track_name: Vec<u8>,
177 pub subscriber_priority: u8,
178 pub group_order: GroupOrder,
179 pub forward: Forward,
180 pub filter_type: FilterType,
181 pub start_group: Option<VarInt>,
182 pub start_object: Option<VarInt>,
183 pub end_group: Option<VarInt>,
184 pub parameters: Vec<KeyValuePair>,
185}
186
187#[derive(Debug, Clone, PartialEq, Eq)]
188pub struct SubscribeOk {
189 pub request_id: VarInt,
190 pub track_alias: VarInt,
191 pub expires: VarInt,
192 pub group_order: GroupOrder,
193 pub content_exists: ContentExists,
194 pub largest_location: Option<Location>,
195 pub parameters: Vec<KeyValuePair>,
196}
197
198#[derive(Debug, Clone, PartialEq, Eq)]
199pub struct SubscribeError {
200 pub request_id: VarInt,
201 pub error_code: VarInt,
202 pub reason_phrase: Vec<u8>,
203}
204
205#[derive(Debug, Clone, PartialEq, Eq)]
206pub struct SubscribeUpdate {
207 pub request_id: VarInt,
208 pub start_group: VarInt,
209 pub start_object: VarInt,
210 pub end_group: VarInt,
211 pub subscriber_priority: u8,
212 pub forward: Forward,
213 pub parameters: Vec<KeyValuePair>,
214}
215
216#[derive(Debug, Clone, PartialEq, Eq)]
217pub struct SubscribeDone {
218 pub request_id: VarInt,
219 pub status_code: VarInt,
220 pub stream_count: VarInt,
221 pub reason_phrase: Vec<u8>,
222}
223
224#[derive(Debug, Clone, PartialEq, Eq)]
225pub struct Unsubscribe {
226 pub request_id: VarInt,
227}
228
229#[derive(Debug, Clone, PartialEq, Eq)]
234pub struct Announce {
235 pub request_id: VarInt,
236 pub track_namespace: TrackNamespace,
237 pub parameters: Vec<KeyValuePair>,
238}
239
240#[derive(Debug, Clone, PartialEq, Eq)]
241pub struct AnnounceOk {
242 pub request_id: VarInt,
243}
244
245#[derive(Debug, Clone, PartialEq, Eq)]
246pub struct AnnounceError {
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 AnnounceCancel {
254 pub track_namespace: TrackNamespace,
255 pub error_code: VarInt,
256 pub reason_phrase: Vec<u8>,
257}
258
259#[derive(Debug, Clone, PartialEq, Eq)]
260pub struct Unannounce {
261 pub track_namespace: TrackNamespace,
262}
263
264#[derive(Debug, Clone, PartialEq, Eq)]
269pub struct SubscribeNamespace {
270 pub request_id: VarInt,
271 pub track_namespace_prefix: TrackNamespace,
272 pub parameters: Vec<KeyValuePair>,
273}
274
275#[derive(Debug, Clone, PartialEq, Eq)]
276pub struct SubscribeNamespaceOk {
277 pub request_id: VarInt,
278}
279
280#[derive(Debug, Clone, PartialEq, Eq)]
281pub struct SubscribeNamespaceError {
282 pub request_id: VarInt,
283 pub error_code: VarInt,
284 pub reason_phrase: Vec<u8>,
285}
286
287#[derive(Debug, Clone, PartialEq, Eq)]
288pub struct UnsubscribeNamespace {
289 pub track_namespace_prefix: TrackNamespace,
290}
291
292#[derive(Debug, Clone, PartialEq, Eq)]
304pub struct TrackStatus {
305 pub request_id: VarInt,
306 pub track_namespace: TrackNamespace,
307 pub track_name: Vec<u8>,
308 pub subscriber_priority: u8,
309 pub group_order: GroupOrder,
310 pub forward: Forward,
311 pub filter_type: FilterType,
312 pub start_group: Option<VarInt>,
314 pub start_object: Option<VarInt>,
316 pub end_group: Option<VarInt>,
318 pub parameters: Vec<KeyValuePair>,
319}
320
321#[derive(Debug, Clone, PartialEq, Eq)]
323pub struct TrackStatusOk {
324 pub request_id: VarInt,
325 pub track_alias: VarInt,
326 pub expires: VarInt,
327 pub group_order: GroupOrder,
328 pub content_exists: ContentExists,
329 pub largest_location: Option<Location>,
330 pub parameters: Vec<KeyValuePair>,
331}
332
333#[derive(Debug, Clone, PartialEq, Eq)]
335pub struct TrackStatusError {
336 pub request_id: VarInt,
337 pub error_code: VarInt,
338 pub reason_phrase: Vec<u8>,
339}
340
341#[derive(Debug, Clone, Copy, PartialEq, Eq)]
346#[repr(u64)]
347pub enum FetchType {
348 Standalone = 1,
349 RelativeJoining = 2,
350 AbsoluteJoining = 3,
351}
352
353impl FetchType {
354 pub fn from_u64(v: u64) -> Option<Self> {
355 match v {
356 1 => Some(FetchType::Standalone),
357 2 => Some(FetchType::RelativeJoining),
358 3 => Some(FetchType::AbsoluteJoining),
359 _ => None,
360 }
361 }
362}
363
364#[derive(Debug, Clone, PartialEq, Eq)]
365pub struct Fetch {
366 pub request_id: VarInt,
367 pub subscriber_priority: u8,
368 pub group_order: GroupOrder,
369 pub fetch_type: FetchType,
370 pub fetch_payload: FetchPayload,
371 pub parameters: Vec<KeyValuePair>,
372}
373
374#[derive(Debug, Clone, PartialEq, Eq)]
375pub enum FetchPayload {
376 Standalone {
377 track_namespace: TrackNamespace,
378 track_name: Vec<u8>,
379 start_group: VarInt,
380 start_object: VarInt,
381 end_group: VarInt,
382 end_object: VarInt,
383 },
384 Joining {
385 joining_request_id: VarInt,
394 joining_start: VarInt,
397 },
398}
399
400#[derive(Debug, Clone, PartialEq, Eq)]
401pub struct FetchOk {
402 pub request_id: VarInt,
403 pub group_order: GroupOrder,
404 pub end_of_track: u8,
411 pub end_location: Location,
412 pub parameters: Vec<KeyValuePair>,
413}
414
415#[derive(Debug, Clone, PartialEq, Eq)]
416pub struct FetchError {
417 pub request_id: VarInt,
418 pub error_code: VarInt,
419 pub reason_phrase: Vec<u8>,
420}
421
422#[derive(Debug, Clone, PartialEq, Eq)]
423pub struct FetchCancel {
424 pub request_id: VarInt,
425}
426
427#[derive(Debug, Clone, PartialEq, Eq)]
432pub struct Publish {
433 pub request_id: VarInt,
434 pub track_namespace: TrackNamespace,
435 pub track_name: Vec<u8>,
436 pub track_alias: VarInt,
437 pub group_order: GroupOrder,
438 pub content_exists: ContentExists,
439 pub largest_location: Option<Location>,
440 pub forward: Forward,
441 pub parameters: Vec<KeyValuePair>,
442}
443
444#[derive(Debug, Clone, PartialEq, Eq)]
445pub struct PublishOk {
446 pub request_id: VarInt,
447 pub forward: Forward,
448 pub subscriber_priority: u8,
449 pub group_order: GroupOrder,
450 pub filter_type: FilterType,
451 pub start_group: Option<VarInt>,
452 pub start_object: Option<VarInt>,
453 pub end_group: Option<VarInt>,
454 pub parameters: Vec<KeyValuePair>,
455}
456
457#[derive(Debug, Clone, PartialEq, Eq)]
458pub struct PublishError {
459 pub request_id: VarInt,
460 pub error_code: VarInt,
461 pub reason_phrase: Vec<u8>,
462}
463
464#[derive(Debug, Clone, PartialEq, Eq)]
469pub enum ControlMessage {
470 ClientSetup(ClientSetup),
471 ServerSetup(ServerSetup),
472 GoAway(GoAway),
473 MaxRequestId(MaxRequestId),
474 RequestsBlocked(RequestsBlocked),
475 Subscribe(Subscribe),
476 SubscribeOk(SubscribeOk),
477 SubscribeError(SubscribeError),
478 SubscribeUpdate(SubscribeUpdate),
479 SubscribeDone(SubscribeDone),
480 Unsubscribe(Unsubscribe),
481 Announce(Announce),
482 AnnounceOk(AnnounceOk),
483 AnnounceError(AnnounceError),
484 AnnounceCancel(AnnounceCancel),
485 Unannounce(Unannounce),
486 SubscribeNamespace(SubscribeNamespace),
487 SubscribeNamespaceOk(SubscribeNamespaceOk),
488 SubscribeNamespaceError(SubscribeNamespaceError),
489 UnsubscribeNamespace(UnsubscribeNamespace),
490 TrackStatus(TrackStatus),
491 TrackStatusOk(TrackStatusOk),
492 TrackStatusError(TrackStatusError),
493 Fetch(Fetch),
494 FetchOk(FetchOk),
495 FetchError(FetchError),
496 FetchCancel(FetchCancel),
497 Publish(Publish),
498 PublishOk(PublishOk),
499 PublishError(PublishError),
500}
501
502fn check_full_track_name(namespace: &TrackNamespace, track_name: &[u8]) -> Result<(), CodecError> {
503 let total = namespace.field_bytes_len().saturating_add(track_name.len());
504 if total > MAX_FULL_TRACK_NAME_LENGTH {
505 return Err(CodecError::TrackNameTooLong);
506 }
507 Ok(())
508}
509
510fn read_reason_phrase(buf: &mut impl Buf) -> Result<Vec<u8>, CodecError> {
518 let len = VarInt::decode(buf)?.into_inner() as usize;
519 if len > MAX_REASON_PHRASE_LENGTH {
520 return Err(CodecError::ReasonPhraseTooLong);
521 }
522 read_bytes(buf, len)
523}
524
525fn read_u8(buf: &mut impl Buf) -> Result<u8, CodecError> {
527 if !buf.has_remaining() {
528 return Err(CodecError::UnexpectedEnd);
529 }
530 Ok(buf.get_u8())
531}
532
533fn read_group_order(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
545 GroupOrder::from_u8(read_u8(buf)?).ok_or(CodecError::InvalidField)
546}
547
548fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
560 match read_group_order(buf)? {
561 GroupOrder::Publisher => Err(CodecError::InvalidField),
562 order => Ok(order),
563 }
564}
565
566fn read_forward(buf: &mut impl Buf) -> Result<Forward, CodecError> {
569 match read_u8(buf)? {
570 0 => Ok(Forward::DontForward),
571 1 => Ok(Forward::Forward),
572 other => Err(CodecError::InvalidForward(other)),
573 }
574}
575
576fn read_content_exists(buf: &mut impl Buf) -> Result<ContentExists, CodecError> {
579 match read_u8(buf)? {
580 0 => Ok(ContentExists::NoLargestLocation),
581 1 => Ok(ContentExists::HasLargestLocation),
582 other => Err(CodecError::InvalidContentExists(other)),
583 }
584}
585
586fn read_filter_type(buf: &mut impl Buf) -> Result<FilterType, CodecError> {
596 let value = VarInt::decode(buf)?.into_inner();
597 FilterType::from_u64(value).ok_or(CodecError::InvalidFilterType(value))
598}
599
600type StartLocation = (Option<VarInt>, Option<VarInt>);
604fn read_start_location(
605 filter_type: FilterType,
606 buf: &mut impl Buf,
607) -> Result<StartLocation, CodecError> {
608 match filter_type {
609 FilterType::AbsoluteStart | FilterType::AbsoluteRange => {
610 Ok((Some(VarInt::decode(buf)?), Some(VarInt::decode(buf)?)))
611 }
612 _ => Ok((None, None)),
613 }
614}
615
616fn read_end_group(
620 filter_type: FilterType,
621 buf: &mut impl Buf,
622) -> Result<Option<VarInt>, CodecError> {
623 match filter_type {
624 FilterType::AbsoluteRange => Ok(Some(VarInt::decode(buf)?)),
625 _ => Ok(None),
626 }
627}
628
629fn read_largest_location(
633 content_exists: ContentExists,
634 buf: &mut impl Buf,
635) -> Result<Option<Location>, CodecError> {
636 match content_exists {
637 ContentExists::HasLargestLocation => Ok(Some(Location::decode(buf)?)),
638 ContentExists::NoLargestLocation => Ok(None),
639 }
640}
641
642fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
647 let order = match message {
648 ControlMessage::SubscribeOk(m) => m.group_order,
649 ControlMessage::TrackStatusOk(m) => m.group_order,
650 ControlMessage::FetchOk(m) => m.group_order,
651 ControlMessage::Publish(m) => m.group_order,
652 ControlMessage::PublishOk(m) => m.group_order,
653 _ => return Ok(()),
654 };
655 if order == GroupOrder::Publisher {
656 return Err(CodecError::InvalidField);
657 }
658 Ok(())
659}
660
661fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
679 fn check_filter(
682 filter_type: FilterType,
683 start_group: &Option<VarInt>,
684 start_object: &Option<VarInt>,
685 end_group: &Option<VarInt>,
686 ) -> Result<(), CodecError> {
687 let wants_start =
688 matches!(filter_type, FilterType::AbsoluteStart | FilterType::AbsoluteRange);
689 if wants_start != start_group.is_some() || wants_start != start_object.is_some() {
690 return Err(CodecError::InvalidField);
691 }
692 if (filter_type == FilterType::AbsoluteRange) != end_group.is_some() {
693 return Err(CodecError::InvalidField);
694 }
695 Ok(())
696 }
697
698 fn check_content(
699 content_exists: ContentExists,
700 largest_location: &Option<Location>,
701 ) -> Result<(), CodecError> {
702 if (content_exists == ContentExists::HasLargestLocation) != largest_location.is_some() {
703 return Err(CodecError::InvalidField);
704 }
705 Ok(())
706 }
707
708 match message {
709 ControlMessage::Subscribe(m) => {
710 check_filter(m.filter_type, &m.start_group, &m.start_object, &m.end_group)
711 }
712 ControlMessage::TrackStatus(m) => {
713 check_filter(m.filter_type, &m.start_group, &m.start_object, &m.end_group)
714 }
715 ControlMessage::PublishOk(m) => {
716 check_filter(m.filter_type, &m.start_group, &m.start_object, &m.end_group)
717 }
718 ControlMessage::SubscribeOk(m) => check_content(m.content_exists, &m.largest_location),
719 ControlMessage::TrackStatusOk(m) => check_content(m.content_exists, &m.largest_location),
720 ControlMessage::Publish(m) => check_content(m.content_exists, &m.largest_location),
721 ControlMessage::Fetch(m) => {
722 let body_is_standalone = matches!(m.fetch_payload, FetchPayload::Standalone { .. });
723 if body_is_standalone != (m.fetch_type == FetchType::Standalone) {
724 return Err(CodecError::InvalidField);
725 }
726 Ok(())
727 }
728 _ => Ok(()),
729 }
730}
731
732fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
746 match message {
747 ControlMessage::Subscribe(m) => match (&m.start_group, &m.end_group) {
748 (Some(start_group), Some(end_group)) => {
749 check_group_range(start_group.into_inner(), end_group.into_inner())
750 }
751 _ => Ok(()),
752 },
753 ControlMessage::SubscribeUpdate(m) => {
754 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
755 }
756 ControlMessage::Fetch(m) => match &m.fetch_payload {
757 FetchPayload::Standalone {
758 start_group, start_object, end_group, end_object, ..
759 } => check_location_range(
760 start_group.into_inner(),
761 start_object.into_inner(),
762 end_group.into_inner(),
763 end_object.into_inner(),
764 ),
765 FetchPayload::Joining { .. } => Ok(()),
766 },
767 _ => Ok(()),
768 }
769}
770
771const AUTHORIZATION_TOKEN: u64 = 0x03;
778
779const DELIVERY_TIMEOUT: u64 = 0x02;
781
782const MAX_CACHE_DURATION: u64 = 0x04;
784
785const SETUP_PATH: u64 = 0x01;
787
788const SETUP_MAX_REQUEST_ID: u64 = 0x02;
790
791const SETUP_MAX_AUTH_TOKEN_CACHE_SIZE: u64 = 0x04;
793
794const SETUP_AUTHORIZATION_TOKEN: u64 = AUTHORIZATION_TOKEN;
802
803const KNOWN_PARAMETERS: &[u64] = &[AUTHORIZATION_TOKEN, DELIVERY_TIMEOUT, MAX_CACHE_DURATION];
809
810const REPEATABLE_PARAMETERS: &[u64] = &[AUTHORIZATION_TOKEN];
816
817const KNOWN_SETUP_PARAMETERS: &[u64] =
819 &[SETUP_PATH, SETUP_MAX_REQUEST_ID, SETUP_AUTHORIZATION_TOKEN, SETUP_MAX_AUTH_TOKEN_CACHE_SIZE];
820
821const REPEATABLE_SETUP_PARAMETERS: &[u64] = &[SETUP_AUTHORIZATION_TOKEN];
829
830fn check_sender_parameters(
844 parameters: &[KeyValuePair],
845 repeatable: &[u64],
846) -> Result<(), CodecError> {
847 for (i, parameter) in parameters.iter().enumerate() {
848 let key = parameter.key.into_inner();
849 if repeatable.contains(&key) {
850 continue;
851 }
852 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
853 return Err(CodecError::DuplicateParameter(key));
854 }
855 }
856 Ok(())
857}
858
859fn check_receiver_parameters(
873 parameters: &[KeyValuePair],
874 known: &[u64],
875 repeatable: &[u64],
876) -> Result<(), CodecError> {
877 for (i, parameter) in parameters.iter().enumerate() {
878 let key = parameter.key.into_inner();
879 if repeatable.contains(&key) || !known.contains(&key) {
880 continue;
881 }
882 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
883 return Err(CodecError::DuplicateParameter(key));
884 }
885 }
886 Ok(())
887}
888
889fn check_authorization_tokens(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
904 for parameter in parameters {
905 let key = parameter.key.into_inner();
906 if key != AUTH_TOKEN_PARAMETER {
907 continue;
908 }
909 match ¶meter.value {
910 KvpValue::Bytes(value) => {
911 AuthorizationToken::decode(key, value)?;
912 }
913 KvpValue::Varint(_) => {
918 return Err(CodecError::KeyValueFormatting {
919 key,
920 detail: "its value is a bare varint where the type defines a Token structure",
921 });
922 }
923 }
924 }
925 Ok(())
926}
927
928fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
930 let parameters = KeyValuePair::decode_list(buf)?;
931 check_receiver_parameters(¶meters, KNOWN_PARAMETERS, REPEATABLE_PARAMETERS)?;
932 check_authorization_tokens(¶meters)?;
933 Ok(parameters)
934}
935
936fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
938 check_sender_parameters(parameters, REPEATABLE_PARAMETERS)?;
939 check_authorization_tokens(parameters)?;
940 KeyValuePair::encode_list_checked(parameters, buf)?;
941 Ok(())
942}
943
944fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
946 let parameters = KeyValuePair::decode_list(buf)?;
947 check_receiver_parameters(¶meters, KNOWN_SETUP_PARAMETERS, REPEATABLE_SETUP_PARAMETERS)?;
948 check_authorization_tokens(¶meters)?;
949 Ok(parameters)
950}
951
952fn encode_setup_parameters(
958 parameters: &[KeyValuePair],
959 buf: &mut impl BufMut,
960) -> Result<(), CodecError> {
961 check_sender_parameters(parameters, REPEATABLE_SETUP_PARAMETERS)?;
962 check_authorization_tokens(parameters)?;
963 KeyValuePair::encode_list_checked(parameters, buf)?;
964 Ok(())
965}
966
967impl ControlMessage {
968 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
972 check_discriminators(self)?;
973 check_group_order(self)?;
974 check_ranges(self)?;
975 let mut payload = Vec::with_capacity(256);
976 self.encode_payload(&mut payload)?;
977
978 if payload.len() > MAX_MESSAGE_LENGTH {
979 return Err(CodecError::MessageTooLong(payload.len()));
980 }
981
982 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
983 buf.put_u16(payload.len() as u16);
985 buf.put_slice(&payload);
986 Ok(())
987 }
988
989 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
993 let type_id = VarInt::decode(buf)?.into_inner();
994 let msg_type =
995 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
996 if buf.remaining() < 2 {
998 return Err(CodecError::UnexpectedEnd);
999 }
1000 let payload_len = buf.get_u16() as usize;
1001 if buf.remaining() < payload_len {
1002 return Err(CodecError::UnexpectedEnd);
1003 }
1004 let payload_bytes = buf.copy_to_bytes(payload_len);
1005 let mut payload = &payload_bytes[..];
1006 let msg = match Self::decode_payload(msg_type, &mut payload) {
1007 Ok(msg) => msg,
1008 Err(
1014 CodecError::UnexpectedEnd
1015 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
1016 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
1017 crate::varint::VarIntError::UnexpectedEnd,
1018 ))
1019 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
1020 ) => {
1021 return Err(CodecError::ControlMessageLengthMismatch {
1022 declared: payload_len,
1023 detail: "its fields ran past the end",
1024 });
1025 }
1026 Err(e) => return Err(e),
1027 };
1028 check_ranges(&msg)?;
1029 if payload.has_remaining() {
1034 return Err(CodecError::ControlMessageLengthMismatch {
1035 declared: payload_len,
1036 detail: "its fields left bytes unread",
1037 });
1038 }
1039 Ok(msg)
1040 }
1041
1042 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
1043 match self {
1044 ControlMessage::ClientSetup(m) => {
1045 VarInt::from_usize(m.supported_versions.len()).encode(buf);
1046 for v in &m.supported_versions {
1047 v.encode(buf);
1048 }
1049 encode_setup_parameters(&m.parameters, buf)?;
1050 }
1051 ControlMessage::ServerSetup(m) => {
1052 m.selected_version.encode(buf);
1053 encode_setup_parameters(&m.parameters, buf)?;
1054 }
1055 ControlMessage::GoAway(m) => {
1056 if m.new_session_uri.len() > MAX_GOAWAY_URI_LENGTH {
1057 return Err(CodecError::GoAwayUriTooLong);
1058 }
1059 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
1060 buf.put_slice(&m.new_session_uri);
1061 }
1062 ControlMessage::MaxRequestId(m) => {
1063 m.request_id.encode(buf);
1064 }
1065 ControlMessage::RequestsBlocked(m) => {
1066 m.maximum_request_id.encode(buf);
1067 }
1068 ControlMessage::Subscribe(m) => {
1069 m.request_id.encode(buf);
1070 m.track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1071 m.track_namespace.encode(buf);
1072 check_full_track_name(&m.track_namespace, &m.track_name)?;
1073 VarInt::from_usize(m.track_name.len()).encode(buf);
1074 buf.put_slice(&m.track_name);
1075 buf.put_u8(m.subscriber_priority);
1076 buf.put_u8(m.group_order as u8);
1077 buf.put_u8(m.forward as u8);
1078 VarInt::from_usize(m.filter_type as usize).encode(buf);
1079 if let Some(sg) = &m.start_group {
1080 sg.encode(buf);
1081 }
1082 if let Some(so) = &m.start_object {
1083 so.encode(buf);
1084 }
1085 if let Some(eg) = &m.end_group {
1086 eg.encode(buf);
1087 }
1088 encode_parameters(&m.parameters, buf)?;
1089 }
1090 ControlMessage::SubscribeOk(m) => {
1091 m.request_id.encode(buf);
1092 m.track_alias.encode(buf);
1093 m.expires.encode(buf);
1094 buf.put_u8(m.group_order as u8);
1095 buf.put_u8(m.content_exists as u8);
1096 if let Some(loc) = &m.largest_location {
1097 loc.encode(buf);
1098 }
1099 encode_parameters(&m.parameters, buf)?;
1100 }
1101 ControlMessage::SubscribeError(m) => {
1102 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1103 return Err(CodecError::ReasonPhraseTooLong);
1104 }
1105 m.request_id.encode(buf);
1106 m.error_code.encode(buf);
1107 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1108 buf.put_slice(&m.reason_phrase);
1109 }
1110 ControlMessage::SubscribeUpdate(m) => {
1111 m.request_id.encode(buf);
1112 m.start_group.encode(buf);
1113 m.start_object.encode(buf);
1114 m.end_group.encode(buf);
1115 buf.put_u8(m.subscriber_priority);
1116 buf.put_u8(m.forward as u8);
1117 encode_parameters(&m.parameters, buf)?;
1118 }
1119 ControlMessage::SubscribeDone(m) => {
1120 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1121 return Err(CodecError::ReasonPhraseTooLong);
1122 }
1123 m.request_id.encode(buf);
1124 m.status_code.encode(buf);
1125 m.stream_count.encode(buf);
1126 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1127 buf.put_slice(&m.reason_phrase);
1128 }
1129 ControlMessage::Unsubscribe(m) => {
1130 m.request_id.encode(buf);
1131 }
1132 ControlMessage::Announce(m) => {
1133 m.request_id.encode(buf);
1134 m.track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1135 m.track_namespace.encode(buf);
1136 encode_parameters(&m.parameters, buf)?;
1137 }
1138 ControlMessage::AnnounceOk(m) => {
1139 m.request_id.encode(buf);
1140 }
1141 ControlMessage::AnnounceError(m) => {
1142 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1143 return Err(CodecError::ReasonPhraseTooLong);
1144 }
1145 m.request_id.encode(buf);
1146 m.error_code.encode(buf);
1147 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1148 buf.put_slice(&m.reason_phrase);
1149 }
1150 ControlMessage::AnnounceCancel(m) => {
1151 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1152 return Err(CodecError::ReasonPhraseTooLong);
1153 }
1154 m.track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1155 m.track_namespace.encode(buf);
1156 m.error_code.encode(buf);
1157 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1158 buf.put_slice(&m.reason_phrase);
1159 }
1160 ControlMessage::Unannounce(m) => {
1161 m.track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1162 m.track_namespace.encode(buf);
1163 }
1164 ControlMessage::SubscribeNamespace(m) => {
1165 m.request_id.encode(buf);
1166 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(13))?;
1167 m.track_namespace_prefix.encode(buf);
1168 encode_parameters(&m.parameters, buf)?;
1169 }
1170 ControlMessage::SubscribeNamespaceOk(m) => {
1171 m.request_id.encode(buf);
1172 }
1173 ControlMessage::SubscribeNamespaceError(m) => {
1174 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1175 return Err(CodecError::ReasonPhraseTooLong);
1176 }
1177 m.request_id.encode(buf);
1178 m.error_code.encode(buf);
1179 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1180 buf.put_slice(&m.reason_phrase);
1181 }
1182 ControlMessage::UnsubscribeNamespace(m) => {
1183 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(13))?;
1184 m.track_namespace_prefix.encode(buf);
1185 }
1186 ControlMessage::TrackStatus(m) => {
1187 m.request_id.encode(buf);
1188 m.track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1189 m.track_namespace.encode(buf);
1190 check_full_track_name(&m.track_namespace, &m.track_name)?;
1191 VarInt::from_usize(m.track_name.len()).encode(buf);
1192 buf.put_slice(&m.track_name);
1193 buf.put_u8(m.subscriber_priority);
1194 buf.put_u8(m.group_order as u8);
1195 buf.put_u8(m.forward as u8);
1196 VarInt::from_usize(m.filter_type as usize).encode(buf);
1197 if let Some(sg) = &m.start_group {
1198 sg.encode(buf);
1199 }
1200 if let Some(so) = &m.start_object {
1201 so.encode(buf);
1202 }
1203 if let Some(eg) = &m.end_group {
1204 eg.encode(buf);
1205 }
1206 encode_parameters(&m.parameters, buf)?;
1207 }
1208 ControlMessage::TrackStatusOk(m) => {
1209 m.request_id.encode(buf);
1210 m.track_alias.encode(buf);
1211 m.expires.encode(buf);
1212 buf.put_u8(m.group_order as u8);
1213 buf.put_u8(m.content_exists as u8);
1214 if let Some(loc) = &m.largest_location {
1215 loc.encode(buf);
1216 }
1217 encode_parameters(&m.parameters, buf)?;
1218 }
1219 ControlMessage::TrackStatusError(m) => {
1220 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1221 return Err(CodecError::ReasonPhraseTooLong);
1222 }
1223 m.request_id.encode(buf);
1224 m.error_code.encode(buf);
1225 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1226 buf.put_slice(&m.reason_phrase);
1227 }
1228 ControlMessage::Fetch(m) => {
1229 m.request_id.encode(buf);
1230 buf.put_u8(m.subscriber_priority);
1231 buf.put_u8(m.group_order as u8);
1232 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1233 match &m.fetch_payload {
1234 FetchPayload::Standalone {
1235 track_namespace,
1236 track_name,
1237 start_group,
1238 start_object,
1239 end_group,
1240 end_object,
1241 } => {
1242 track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1243 track_namespace.encode(buf);
1244 check_full_track_name(track_namespace, track_name)?;
1245 VarInt::from_usize(track_name.len()).encode(buf);
1246 buf.put_slice(track_name);
1247 start_group.encode(buf);
1248 start_object.encode(buf);
1249 end_group.encode(buf);
1250 end_object.encode(buf);
1251 }
1252 FetchPayload::Joining { joining_request_id, joining_start } => {
1253 joining_request_id.encode(buf);
1254 joining_start.encode(buf);
1255 }
1256 }
1257 encode_parameters(&m.parameters, buf)?;
1258 }
1259 ControlMessage::FetchOk(m) => {
1260 m.request_id.encode(buf);
1261 buf.put_u8(m.group_order as u8);
1262 buf.put_u8(m.end_of_track);
1263 m.end_location.encode(buf);
1264 encode_parameters(&m.parameters, buf)?;
1265 }
1266 ControlMessage::FetchError(m) => {
1267 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1268 return Err(CodecError::ReasonPhraseTooLong);
1269 }
1270 m.request_id.encode(buf);
1271 m.error_code.encode(buf);
1272 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1273 buf.put_slice(&m.reason_phrase);
1274 }
1275 ControlMessage::FetchCancel(m) => {
1276 m.request_id.encode(buf);
1277 }
1278 ControlMessage::Publish(m) => {
1279 m.request_id.encode(buf);
1280 m.track_namespace.validate(TrackNamespaceRules::for_draft(13))?;
1281 m.track_namespace.encode(buf);
1282 check_full_track_name(&m.track_namespace, &m.track_name)?;
1283 VarInt::from_usize(m.track_name.len()).encode(buf);
1284 buf.put_slice(&m.track_name);
1285 m.track_alias.encode(buf);
1286 buf.put_u8(m.group_order as u8);
1287 buf.put_u8(m.content_exists as u8);
1288 if let Some(loc) = &m.largest_location {
1289 loc.encode(buf);
1290 }
1291 buf.put_u8(m.forward as u8);
1292 encode_parameters(&m.parameters, buf)?;
1293 }
1294 ControlMessage::PublishOk(m) => {
1295 m.request_id.encode(buf);
1296 buf.put_u8(m.forward as u8);
1297 buf.put_u8(m.subscriber_priority);
1298 buf.put_u8(m.group_order as u8);
1299 VarInt::from_usize(m.filter_type as usize).encode(buf);
1300 if let Some(sg) = &m.start_group {
1301 sg.encode(buf);
1302 }
1303 if let Some(so) = &m.start_object {
1304 so.encode(buf);
1305 }
1306 if let Some(eg) = &m.end_group {
1307 eg.encode(buf);
1308 }
1309 encode_parameters(&m.parameters, buf)?;
1310 }
1311 ControlMessage::PublishError(m) => {
1312 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1313 return Err(CodecError::ReasonPhraseTooLong);
1314 }
1315 m.request_id.encode(buf);
1316 m.error_code.encode(buf);
1317 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1318 buf.put_slice(&m.reason_phrase);
1319 }
1320 }
1321 Ok(())
1322 }
1323
1324 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1325 match msg_type {
1326 MessageType::ClientSetup => {
1327 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1328 if num_versions == 0 {
1338 return Err(CodecError::InvalidField);
1339 }
1340 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1341 for _ in 0..num_versions {
1342 supported_versions.push(VarInt::decode(buf)?);
1343 }
1344 let parameters = decode_setup_parameters(buf)?;
1345 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1346 }
1347 MessageType::ServerSetup => {
1348 let selected_version = VarInt::decode(buf)?;
1349 let parameters = decode_setup_parameters(buf)?;
1350 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1351 }
1352 MessageType::GoAway => {
1353 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1354 if uri_len > MAX_GOAWAY_URI_LENGTH {
1355 return Err(CodecError::GoAwayUriTooLong);
1356 }
1357 let uri = read_bytes(buf, uri_len)?;
1358 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1359 }
1360 MessageType::MaxRequestId => {
1361 let request_id = VarInt::decode(buf)?;
1362 Ok(ControlMessage::MaxRequestId(MaxRequestId { request_id }))
1363 }
1364 MessageType::RequestsBlocked => {
1365 let maximum_request_id = VarInt::decode(buf)?;
1366 Ok(ControlMessage::RequestsBlocked(RequestsBlocked { maximum_request_id }))
1367 }
1368 MessageType::Subscribe => {
1369 let request_id = VarInt::decode(buf)?;
1370 let track_namespace = TrackNamespace::decode(buf)?;
1371 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1372 let track_name = read_bytes(buf, track_name_len)?;
1373 check_full_track_name(&track_namespace, &track_name)?;
1374 let subscriber_priority = read_u8(buf)?;
1375 let group_order = read_group_order(buf)?;
1376 let forward = read_forward(buf)?;
1377 let filter_type = read_filter_type(buf)?;
1378 let (start_group, start_object) = read_start_location(filter_type, buf)?;
1379 let end_group = read_end_group(filter_type, buf)?;
1380 let parameters = decode_parameters(buf)?;
1381 Ok(ControlMessage::Subscribe(Subscribe {
1382 request_id,
1383 track_namespace,
1384 track_name,
1385 subscriber_priority,
1386 group_order,
1387 forward,
1388 filter_type,
1389 start_group,
1390 start_object,
1391 end_group,
1392 parameters,
1393 }))
1394 }
1395 MessageType::SubscribeOk => {
1396 let request_id = VarInt::decode(buf)?;
1397 let track_alias = VarInt::decode(buf)?;
1398 let expires = VarInt::decode(buf)?;
1399 let group_order = read_group_order_response(buf)?;
1400 let content_exists = read_content_exists(buf)?;
1401 let largest_location = read_largest_location(content_exists, buf)?;
1402 let parameters = decode_parameters(buf)?;
1403 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1404 request_id,
1405 track_alias,
1406 expires,
1407 group_order,
1408 content_exists,
1409 largest_location,
1410 parameters,
1411 }))
1412 }
1413 MessageType::SubscribeError => {
1414 let request_id = VarInt::decode(buf)?;
1415 let error_code = VarInt::decode(buf)?;
1416 let reason_phrase = read_reason_phrase(buf)?;
1417 Ok(ControlMessage::SubscribeError(SubscribeError {
1418 request_id,
1419 error_code,
1420 reason_phrase,
1421 }))
1422 }
1423 MessageType::SubscribeUpdate => {
1424 let request_id = VarInt::decode(buf)?;
1425 let start_group = VarInt::decode(buf)?;
1426 let start_object = VarInt::decode(buf)?;
1427 let end_group = VarInt::decode(buf)?;
1428 let subscriber_priority = read_u8(buf)?;
1429 let forward = read_forward(buf)?;
1430 let parameters = decode_parameters(buf)?;
1431 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1432 request_id,
1433 start_group,
1434 start_object,
1435 end_group,
1436 subscriber_priority,
1437 forward,
1438 parameters,
1439 }))
1440 }
1441 MessageType::SubscribeDone => {
1442 let request_id = VarInt::decode(buf)?;
1443 let status_code = VarInt::decode(buf)?;
1444 let stream_count = VarInt::decode(buf)?;
1445 let reason_phrase = read_reason_phrase(buf)?;
1446 Ok(ControlMessage::SubscribeDone(SubscribeDone {
1447 request_id,
1448 status_code,
1449 stream_count,
1450 reason_phrase,
1451 }))
1452 }
1453 MessageType::Unsubscribe => {
1454 let request_id = VarInt::decode(buf)?;
1455 Ok(ControlMessage::Unsubscribe(Unsubscribe { request_id }))
1456 }
1457 MessageType::Announce => {
1458 let request_id = VarInt::decode(buf)?;
1459 let track_namespace = TrackNamespace::decode(buf)?;
1460 let parameters = decode_parameters(buf)?;
1461 Ok(ControlMessage::Announce(Announce { request_id, track_namespace, parameters }))
1462 }
1463 MessageType::AnnounceOk => {
1464 let request_id = VarInt::decode(buf)?;
1465 Ok(ControlMessage::AnnounceOk(AnnounceOk { request_id }))
1466 }
1467 MessageType::AnnounceError => {
1468 let request_id = VarInt::decode(buf)?;
1469 let error_code = VarInt::decode(buf)?;
1470 let reason_phrase = read_reason_phrase(buf)?;
1471 Ok(ControlMessage::AnnounceError(AnnounceError {
1472 request_id,
1473 error_code,
1474 reason_phrase,
1475 }))
1476 }
1477 MessageType::AnnounceCancel => {
1478 let track_namespace = TrackNamespace::decode(buf)?;
1479 let error_code = VarInt::decode(buf)?;
1480 let reason_phrase = read_reason_phrase(buf)?;
1481 Ok(ControlMessage::AnnounceCancel(AnnounceCancel {
1482 track_namespace,
1483 error_code,
1484 reason_phrase,
1485 }))
1486 }
1487 MessageType::Unannounce => {
1488 let track_namespace = TrackNamespace::decode(buf)?;
1489 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1490 }
1491 MessageType::SubscribeNamespace => {
1492 let request_id = VarInt::decode(buf)?;
1493 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1494 let parameters = decode_parameters(buf)?;
1495 Ok(ControlMessage::SubscribeNamespace(SubscribeNamespace {
1496 request_id,
1497 track_namespace_prefix,
1498 parameters,
1499 }))
1500 }
1501 MessageType::SubscribeNamespaceOk => {
1502 let request_id = VarInt::decode(buf)?;
1503 Ok(ControlMessage::SubscribeNamespaceOk(SubscribeNamespaceOk { request_id }))
1504 }
1505 MessageType::SubscribeNamespaceError => {
1506 let request_id = VarInt::decode(buf)?;
1507 let error_code = VarInt::decode(buf)?;
1508 let reason_phrase = read_reason_phrase(buf)?;
1509 Ok(ControlMessage::SubscribeNamespaceError(SubscribeNamespaceError {
1510 request_id,
1511 error_code,
1512 reason_phrase,
1513 }))
1514 }
1515 MessageType::UnsubscribeNamespace => {
1516 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1517 Ok(ControlMessage::UnsubscribeNamespace(UnsubscribeNamespace {
1518 track_namespace_prefix,
1519 }))
1520 }
1521 MessageType::TrackStatus => {
1522 let request_id = VarInt::decode(buf)?;
1523 let track_namespace = TrackNamespace::decode(buf)?;
1524 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1525 let track_name = read_bytes(buf, track_name_len)?;
1526 check_full_track_name(&track_namespace, &track_name)?;
1527 let subscriber_priority = read_u8(buf)?;
1528 let group_order = read_group_order(buf)?;
1529 let forward = read_forward(buf)?;
1530 let filter_type = read_filter_type(buf)?;
1531 let (start_group, start_object) = read_start_location(filter_type, buf)?;
1532 let end_group = read_end_group(filter_type, buf)?;
1533 let parameters = decode_parameters(buf)?;
1534 Ok(ControlMessage::TrackStatus(TrackStatus {
1535 request_id,
1536 track_namespace,
1537 track_name,
1538 subscriber_priority,
1539 group_order,
1540 forward,
1541 filter_type,
1542 start_group,
1543 start_object,
1544 end_group,
1545 parameters,
1546 }))
1547 }
1548 MessageType::TrackStatusOk => {
1549 let request_id = VarInt::decode(buf)?;
1550 let track_alias = VarInt::decode(buf)?;
1551 let expires = VarInt::decode(buf)?;
1552 let group_order = read_group_order_response(buf)?;
1553 let content_exists = read_content_exists(buf)?;
1554 let largest_location = read_largest_location(content_exists, buf)?;
1555 let parameters = decode_parameters(buf)?;
1556 Ok(ControlMessage::TrackStatusOk(TrackStatusOk {
1557 request_id,
1558 track_alias,
1559 expires,
1560 group_order,
1561 content_exists,
1562 largest_location,
1563 parameters,
1564 }))
1565 }
1566 MessageType::TrackStatusError => {
1567 let request_id = VarInt::decode(buf)?;
1568 let error_code = VarInt::decode(buf)?;
1569 let reason_phrase = read_reason_phrase(buf)?;
1570 Ok(ControlMessage::TrackStatusError(TrackStatusError {
1571 request_id,
1572 error_code,
1573 reason_phrase,
1574 }))
1575 }
1576 MessageType::Fetch => {
1577 let request_id = VarInt::decode(buf)?;
1578 let subscriber_priority = read_u8(buf)?;
1579 let group_order = read_group_order(buf)?;
1580 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1581 let fetch_type = FetchType::from_u64(fetch_type_val)
1582 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1583 let fetch_payload = match fetch_type {
1584 FetchType::Standalone => {
1585 let track_namespace = TrackNamespace::decode(buf)?;
1586 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1587 let track_name = read_bytes(buf, track_name_len)?;
1588 check_full_track_name(&track_namespace, &track_name)?;
1589 let start_group = VarInt::decode(buf)?;
1590 let start_object = VarInt::decode(buf)?;
1591 let end_group = VarInt::decode(buf)?;
1592 let end_object = VarInt::decode(buf)?;
1593 FetchPayload::Standalone {
1594 track_namespace,
1595 track_name,
1596 start_group,
1597 start_object,
1598 end_group,
1599 end_object,
1600 }
1601 }
1602 FetchType::RelativeJoining | FetchType::AbsoluteJoining => {
1603 let joining_request_id = VarInt::decode(buf)?;
1604 let joining_start = VarInt::decode(buf)?;
1605 FetchPayload::Joining { joining_request_id, joining_start }
1606 }
1607 };
1608 let parameters = decode_parameters(buf)?;
1609 Ok(ControlMessage::Fetch(Fetch {
1610 request_id,
1611 subscriber_priority,
1612 group_order,
1613 fetch_type,
1614 fetch_payload,
1615 parameters,
1616 }))
1617 }
1618 MessageType::FetchOk => {
1619 let request_id = VarInt::decode(buf)?;
1620 let group_order = read_group_order_response(buf)?;
1621 let end_of_track = read_u8(buf)?;
1622 let end_location = Location::decode(buf)?;
1623 let parameters = decode_parameters(buf)?;
1624 Ok(ControlMessage::FetchOk(FetchOk {
1625 request_id,
1626 group_order,
1627 end_of_track,
1628 end_location,
1629 parameters,
1630 }))
1631 }
1632 MessageType::FetchError => {
1633 let request_id = VarInt::decode(buf)?;
1634 let error_code = VarInt::decode(buf)?;
1635 let reason_phrase = read_reason_phrase(buf)?;
1636 Ok(ControlMessage::FetchError(FetchError { request_id, error_code, reason_phrase }))
1637 }
1638 MessageType::FetchCancel => {
1639 let request_id = VarInt::decode(buf)?;
1640 Ok(ControlMessage::FetchCancel(FetchCancel { request_id }))
1641 }
1642 MessageType::Publish => {
1643 let request_id = VarInt::decode(buf)?;
1644 let track_namespace = TrackNamespace::decode(buf)?;
1645 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1646 let track_name = read_bytes(buf, track_name_len)?;
1647 check_full_track_name(&track_namespace, &track_name)?;
1648 let track_alias = VarInt::decode(buf)?;
1649 let group_order = read_group_order_response(buf)?;
1650 let content_exists = read_content_exists(buf)?;
1651 let largest_location = read_largest_location(content_exists, buf)?;
1652 let forward = read_forward(buf)?;
1653 let parameters = decode_parameters(buf)?;
1654 Ok(ControlMessage::Publish(Publish {
1655 request_id,
1656 track_namespace,
1657 track_name,
1658 track_alias,
1659 group_order,
1660 content_exists,
1661 largest_location,
1662 forward,
1663 parameters,
1664 }))
1665 }
1666 MessageType::PublishOk => {
1667 let request_id = VarInt::decode(buf)?;
1668 let forward = read_forward(buf)?;
1669 let subscriber_priority = read_u8(buf)?;
1670 let group_order = read_group_order_response(buf)?;
1671 let filter_type = read_filter_type(buf)?;
1672 let (start_group, start_object) = read_start_location(filter_type, buf)?;
1673 let end_group = read_end_group(filter_type, buf)?;
1674 let parameters = decode_parameters(buf)?;
1675 Ok(ControlMessage::PublishOk(PublishOk {
1676 request_id,
1677 forward,
1678 subscriber_priority,
1679 group_order,
1680 filter_type,
1681 start_group,
1682 start_object,
1683 end_group,
1684 parameters,
1685 }))
1686 }
1687 MessageType::PublishError => {
1688 let request_id = VarInt::decode(buf)?;
1689 let error_code = VarInt::decode(buf)?;
1690 let reason_phrase = read_reason_phrase(buf)?;
1691 Ok(ControlMessage::PublishError(PublishError {
1692 request_id,
1693 error_code,
1694 reason_phrase,
1695 }))
1696 }
1697 }
1698 }
1699
1700 pub fn message_type(&self) -> MessageType {
1701 match self {
1702 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
1703 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
1704 ControlMessage::GoAway(_) => MessageType::GoAway,
1705 ControlMessage::MaxRequestId(_) => MessageType::MaxRequestId,
1706 ControlMessage::RequestsBlocked(_) => MessageType::RequestsBlocked,
1707 ControlMessage::Subscribe(_) => MessageType::Subscribe,
1708 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
1709 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
1710 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
1711 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
1712 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
1713 ControlMessage::Announce(_) => MessageType::Announce,
1714 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
1715 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
1716 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
1717 ControlMessage::Unannounce(_) => MessageType::Unannounce,
1718 ControlMessage::SubscribeNamespace(_) => MessageType::SubscribeNamespace,
1719 ControlMessage::SubscribeNamespaceOk(_) => MessageType::SubscribeNamespaceOk,
1720 ControlMessage::SubscribeNamespaceError(_) => MessageType::SubscribeNamespaceError,
1721 ControlMessage::UnsubscribeNamespace(_) => MessageType::UnsubscribeNamespace,
1722 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
1723 ControlMessage::TrackStatusOk(_) => MessageType::TrackStatusOk,
1724 ControlMessage::TrackStatusError(_) => MessageType::TrackStatusError,
1725 ControlMessage::Fetch(_) => MessageType::Fetch,
1726 ControlMessage::FetchOk(_) => MessageType::FetchOk,
1727 ControlMessage::FetchError(_) => MessageType::FetchError,
1728 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
1729 ControlMessage::Publish(_) => MessageType::Publish,
1730 ControlMessage::PublishOk(_) => MessageType::PublishOk,
1731 ControlMessage::PublishError(_) => MessageType::PublishError,
1732 }
1733 }
1734}