1use crate::auth_token::{AuthorizationToken, AUTH_TOKEN_PARAMETER};
13use crate::error::{
14 CodecError, MAX_FULL_TRACK_NAME_LENGTH, MAX_GOAWAY_URI_LENGTH, MAX_MESSAGE_LENGTH,
15 MAX_REASON_PHRASE_LENGTH,
16};
17use crate::kvp::{KeyValuePair, KvpValue};
18use crate::types::{self, *};
19pub use crate::types::{check_group_range, check_location_range, check_open_ended_group_range};
20use crate::varint::VarInt;
21use bytes::{Buf, BufMut};
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25#[repr(u64)]
26pub enum MessageType {
27 SubscribeUpdate = 0x02,
28 Subscribe = 0x03,
29 SubscribeOk = 0x04,
30 SubscribeError = 0x05,
31 Announce = 0x06,
32 AnnounceOk = 0x07,
33 AnnounceError = 0x08,
34 Unannounce = 0x09,
35 Unsubscribe = 0x0A,
36 SubscribeDone = 0x0B,
37 AnnounceCancel = 0x0C,
38 TrackStatusRequest = 0x0D,
39 TrackStatus = 0x0E,
40 GoAway = 0x10,
41 SubscribeAnnounces = 0x11,
42 SubscribeAnnouncesOk = 0x12,
43 SubscribeAnnouncesError = 0x13,
44 UnsubscribeAnnounces = 0x14,
45 MaxRequestId = 0x15,
46 Fetch = 0x16,
47 FetchCancel = 0x17,
48 FetchOk = 0x18,
49 FetchError = 0x19,
50 RequestsBlocked = 0x1A,
51 Publish = 0x1D,
52 PublishOk = 0x1E,
53 PublishError = 0x1F,
54 ClientSetup = 0x20,
55 ServerSetup = 0x21,
56}
57
58impl MessageType {
59 pub fn from_id(id: u64) -> Option<Self> {
60 match id {
61 0x02 => Some(MessageType::SubscribeUpdate),
62 0x03 => Some(MessageType::Subscribe),
63 0x04 => Some(MessageType::SubscribeOk),
64 0x05 => Some(MessageType::SubscribeError),
65 0x06 => Some(MessageType::Announce),
66 0x07 => Some(MessageType::AnnounceOk),
67 0x08 => Some(MessageType::AnnounceError),
68 0x09 => Some(MessageType::Unannounce),
69 0x0A => Some(MessageType::Unsubscribe),
70 0x0B => Some(MessageType::SubscribeDone),
71 0x0C => Some(MessageType::AnnounceCancel),
72 0x0D => Some(MessageType::TrackStatusRequest),
73 0x0E => Some(MessageType::TrackStatus),
74 0x10 => Some(MessageType::GoAway),
75 0x11 => Some(MessageType::SubscribeAnnounces),
76 0x12 => Some(MessageType::SubscribeAnnouncesOk),
77 0x13 => Some(MessageType::SubscribeAnnouncesError),
78 0x14 => Some(MessageType::UnsubscribeAnnounces),
79 0x15 => Some(MessageType::MaxRequestId),
80 0x16 => Some(MessageType::Fetch),
81 0x17 => Some(MessageType::FetchCancel),
82 0x18 => Some(MessageType::FetchOk),
83 0x19 => Some(MessageType::FetchError),
84 0x1A => Some(MessageType::RequestsBlocked),
85 0x1D => Some(MessageType::Publish),
86 0x1E => Some(MessageType::PublishOk),
87 0x1F => Some(MessageType::PublishError),
88 0x20 => Some(MessageType::ClientSetup),
89 0x21 => Some(MessageType::ServerSetup),
90 _ => None,
91 }
92 }
93
94 pub fn id(&self) -> u64 {
95 *self as u64
96 }
97
98 pub fn name(&self) -> &'static str {
101 match self {
102 MessageType::SubscribeUpdate => "subscribe_update",
103 MessageType::Subscribe => "subscribe",
104 MessageType::SubscribeOk => "subscribe_ok",
105 MessageType::SubscribeError => "subscribe_error",
106 MessageType::Announce => "announce",
107 MessageType::AnnounceOk => "announce_ok",
108 MessageType::AnnounceError => "announce_error",
109 MessageType::Unannounce => "unannounce",
110 MessageType::Unsubscribe => "unsubscribe",
111 MessageType::SubscribeDone => "subscribe_done",
112 MessageType::AnnounceCancel => "announce_cancel",
113 MessageType::TrackStatusRequest => "track_status_request",
114 MessageType::TrackStatus => "track_status",
115 MessageType::GoAway => "goaway",
116 MessageType::SubscribeAnnounces => "subscribe_announces",
117 MessageType::SubscribeAnnouncesOk => "subscribe_announces_ok",
118 MessageType::SubscribeAnnouncesError => "subscribe_announces_error",
119 MessageType::UnsubscribeAnnounces => "unsubscribe_announces",
120 MessageType::MaxRequestId => "max_request_id",
121 MessageType::Fetch => "fetch",
122 MessageType::FetchCancel => "fetch_cancel",
123 MessageType::FetchOk => "fetch_ok",
124 MessageType::FetchError => "fetch_error",
125 MessageType::RequestsBlocked => "requests_blocked",
126 MessageType::Publish => "publish",
127 MessageType::PublishOk => "publish_ok",
128 MessageType::PublishError => "publish_error",
129 MessageType::ClientSetup => "client_setup",
130 MessageType::ServerSetup => "server_setup",
131 }
132 }
133}
134
135#[derive(Debug, Clone, PartialEq, Eq)]
140pub struct ClientSetup {
141 pub supported_versions: Vec<VarInt>,
142 pub parameters: Vec<KeyValuePair>,
143}
144
145#[derive(Debug, Clone, PartialEq, Eq)]
146pub struct ServerSetup {
147 pub selected_version: VarInt,
148 pub parameters: Vec<KeyValuePair>,
149}
150
151#[derive(Debug, Clone, PartialEq, Eq)]
152pub struct GoAway {
153 pub new_session_uri: Vec<u8>,
154}
155
156#[derive(Debug, Clone, PartialEq, Eq)]
157pub struct MaxRequestId {
158 pub request_id: VarInt,
159}
160
161#[derive(Debug, Clone, PartialEq, Eq)]
162pub struct RequestsBlocked {
163 pub maximum_request_id: VarInt,
164}
165
166#[derive(Debug, Clone, PartialEq, Eq)]
172pub struct Subscribe {
173 pub request_id: VarInt,
174 pub track_namespace: TrackNamespace,
175 pub track_name: Vec<u8>,
176 pub subscriber_priority: u8,
177 pub group_order: GroupOrder,
178 pub forward: Forward,
179 pub filter_type: VarInt,
180 pub start_group: Option<VarInt>,
181 pub start_object: Option<VarInt>,
182 pub end_group: Option<VarInt>,
183 pub parameters: Vec<KeyValuePair>,
184}
185
186#[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)]
200pub struct SubscribeError {
201 pub request_id: VarInt,
202 pub error_code: VarInt,
203 pub reason_phrase: Vec<u8>,
204}
205
206#[derive(Debug, Clone, PartialEq, Eq)]
207pub struct SubscribeUpdate {
208 pub request_id: VarInt,
209 pub start_group: VarInt,
210 pub start_object: VarInt,
211 pub end_group: VarInt,
212 pub subscriber_priority: u8,
213 pub forward: Forward,
214 pub parameters: Vec<KeyValuePair>,
215}
216
217#[derive(Debug, Clone, PartialEq, Eq)]
218pub struct SubscribeDone {
219 pub request_id: VarInt,
220 pub status_code: VarInt,
221 pub stream_count: VarInt,
222 pub reason_phrase: Vec<u8>,
223}
224
225#[derive(Debug, Clone, PartialEq, Eq)]
226pub struct Unsubscribe {
227 pub request_id: VarInt,
228}
229
230#[derive(Debug, Clone, PartialEq, Eq)]
235pub struct Announce {
236 pub request_id: VarInt,
237 pub track_namespace: TrackNamespace,
238 pub parameters: Vec<KeyValuePair>,
239}
240
241#[derive(Debug, Clone, PartialEq, Eq)]
242pub struct AnnounceOk {
243 pub request_id: VarInt,
244}
245
246#[derive(Debug, Clone, PartialEq, Eq)]
247pub struct AnnounceError {
248 pub request_id: VarInt,
249 pub error_code: VarInt,
250 pub reason_phrase: Vec<u8>,
251}
252
253#[derive(Debug, Clone, PartialEq, Eq)]
254pub struct AnnounceCancel {
255 pub track_namespace: TrackNamespace,
256 pub error_code: VarInt,
257 pub reason_phrase: Vec<u8>,
258}
259
260#[derive(Debug, Clone, PartialEq, Eq)]
261pub struct Unannounce {
262 pub track_namespace: TrackNamespace,
263}
264
265#[derive(Debug, Clone, PartialEq, Eq)]
270pub struct SubscribeAnnounces {
271 pub request_id: VarInt,
272 pub track_namespace_prefix: TrackNamespace,
273 pub parameters: Vec<KeyValuePair>,
274}
275
276#[derive(Debug, Clone, PartialEq, Eq)]
277pub struct SubscribeAnnouncesOk {
278 pub request_id: VarInt,
279}
280
281#[derive(Debug, Clone, PartialEq, Eq)]
282pub struct SubscribeAnnouncesError {
283 pub request_id: VarInt,
284 pub error_code: VarInt,
285 pub reason_phrase: Vec<u8>,
286}
287
288#[derive(Debug, Clone, PartialEq, Eq)]
289pub struct UnsubscribeAnnounces {
290 pub track_namespace_prefix: TrackNamespace,
291}
292
293#[derive(Debug, Clone, PartialEq, Eq)]
298pub struct TrackStatusRequest {
299 pub request_id: VarInt,
300 pub track_namespace: TrackNamespace,
301 pub track_name: Vec<u8>,
302 pub parameters: Vec<KeyValuePair>,
303}
304
305#[derive(Debug, Clone, PartialEq, Eq)]
306pub struct TrackStatus {
307 pub request_id: VarInt,
308 pub status_code: VarInt,
309 pub largest_location: Location,
310 pub parameters: Vec<KeyValuePair>,
311}
312
313#[derive(Debug, Clone, Copy, PartialEq, Eq)]
318#[repr(u64)]
319pub enum FetchType {
320 Standalone = 1,
321 RelativeJoining = 2,
322 AbsoluteJoining = 3,
323}
324
325impl FetchType {
326 pub fn from_u64(v: u64) -> Option<Self> {
327 match v {
328 1 => Some(FetchType::Standalone),
329 2 => Some(FetchType::RelativeJoining),
330 3 => Some(FetchType::AbsoluteJoining),
331 _ => None,
332 }
333 }
334}
335
336#[derive(Debug, Clone, PartialEq, Eq)]
337pub struct Fetch {
338 pub request_id: VarInt,
339 pub subscriber_priority: u8,
340 pub group_order: GroupOrder,
341 pub fetch_type: FetchType,
342 pub fetch_payload: FetchPayload,
343 pub parameters: Vec<KeyValuePair>,
344}
345
346#[derive(Debug, Clone, PartialEq, Eq)]
347pub enum FetchPayload {
348 Standalone {
349 track_namespace: TrackNamespace,
350 track_name: Vec<u8>,
351 start_group: VarInt,
352 start_object: VarInt,
353 end_group: VarInt,
354 end_object: VarInt,
355 },
356 Joining {
357 joining_request_id: VarInt,
366 joining_start: VarInt,
369 },
370}
371
372#[derive(Debug, Clone, PartialEq, Eq)]
373pub struct FetchOk {
374 pub request_id: VarInt,
375 pub group_order: GroupOrder,
376 pub end_of_track: u8,
383 pub end_location: Location,
384 pub parameters: Vec<KeyValuePair>,
385}
386
387#[derive(Debug, Clone, PartialEq, Eq)]
388pub struct FetchError {
389 pub request_id: VarInt,
390 pub error_code: VarInt,
391 pub reason_phrase: Vec<u8>,
392}
393
394#[derive(Debug, Clone, PartialEq, Eq)]
395pub struct FetchCancel {
396 pub request_id: VarInt,
397}
398
399#[derive(Debug, Clone, PartialEq, Eq)]
405pub struct Publish {
406 pub request_id: VarInt,
407 pub track_namespace: TrackNamespace,
408 pub track_name: Vec<u8>,
409 pub track_alias: VarInt,
410 pub group_order: GroupOrder,
411 pub content_exists: ContentExists,
412 pub largest_location: Option<Location>,
413 pub forward: Forward,
414 pub parameters: Vec<KeyValuePair>,
415}
416
417#[derive(Debug, Clone, PartialEq, Eq)]
419pub struct PublishOk {
420 pub request_id: VarInt,
421 pub forward: Forward,
422 pub subscriber_priority: u8,
423 pub group_order: GroupOrder,
424 pub filter_type: VarInt,
425 pub start_group: Option<VarInt>,
426 pub start_object: Option<VarInt>,
427 pub end_group: Option<VarInt>,
428 pub parameters: Vec<KeyValuePair>,
429}
430
431#[derive(Debug, Clone, PartialEq, Eq)]
433pub struct PublishError {
434 pub request_id: VarInt,
435 pub error_code: VarInt,
436 pub reason_phrase: Vec<u8>,
437}
438
439fn read_u8(buf: &mut impl Buf) -> Result<u8, CodecError> {
441 if !buf.has_remaining() {
442 return Err(CodecError::UnexpectedEnd);
443 }
444 Ok(buf.get_u8())
445}
446
447fn read_group_order(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
459 GroupOrder::from_u8(read_u8(buf)?).ok_or(CodecError::InvalidField)
460}
461
462fn read_group_order_response(buf: &mut impl Buf) -> Result<GroupOrder, CodecError> {
473 match read_group_order(buf)? {
474 GroupOrder::Publisher => Err(CodecError::InvalidField),
475 order => Ok(order),
476 }
477}
478
479fn read_forward(buf: &mut impl Buf) -> Result<Forward, CodecError> {
482 match read_u8(buf)? {
483 0 => Ok(Forward::DontForward),
484 1 => Ok(Forward::Forward),
485 other => Err(CodecError::InvalidForward(other)),
486 }
487}
488
489fn read_content_exists(buf: &mut impl Buf) -> Result<ContentExists, CodecError> {
492 match read_u8(buf)? {
493 0 => Ok(ContentExists::NoLargestLocation),
494 1 => Ok(ContentExists::HasLargestLocation),
495 other => Err(CodecError::InvalidContentExists(other)),
496 }
497}
498
499fn check_filter(
503 filter_type: VarInt,
504 start_group: &Option<VarInt>,
505 start_object: &Option<VarInt>,
506 end_group: &Option<VarInt>,
507) -> Result<(), CodecError> {
508 let value = filter_type.into_inner();
509 if value == 0 || value > 4 {
510 return Err(CodecError::InvalidFilterType(value));
511 }
512 let wants_start = value == 3 || value == 4;
513 if wants_start != start_group.is_some() || wants_start != start_object.is_some() {
514 return Err(CodecError::InvalidField);
515 }
516 if (value == 4) != end_group.is_some() {
517 return Err(CodecError::InvalidField);
518 }
519 Ok(())
520}
521
522fn check_content(
523 content_exists: ContentExists,
524 largest_location: &Option<Location>,
525) -> Result<(), CodecError> {
526 if (content_exists == ContentExists::HasLargestLocation) != largest_location.is_some() {
527 return Err(CodecError::InvalidField);
528 }
529 Ok(())
530}
531
532fn check_track_status(status_code: VarInt, largest_location: Location) -> Result<(), CodecError> {
543 let code = crate::draft12::error_codes::TrackStatusCode::from_u64(status_code.into_inner())
544 .ok_or(CodecError::InvalidField)?;
545 if code.requires_zero_location()
546 && (largest_location.group.into_inner() != 0 || largest_location.object.into_inner() != 0)
547 {
548 return Err(CodecError::InvalidField);
549 }
550 Ok(())
551}
552
553fn check_discriminators(message: &ControlMessage) -> Result<(), CodecError> {
564 match message {
565 ControlMessage::Subscribe(m) => {
566 check_filter(m.filter_type, &m.start_group, &m.start_object, &m.end_group)
567 }
568 ControlMessage::PublishOk(m) => {
569 check_filter(m.filter_type, &m.start_group, &m.start_object, &m.end_group)
570 }
571 ControlMessage::SubscribeOk(m) => check_content(m.content_exists, &m.largest_location),
572 ControlMessage::Publish(m) => check_content(m.content_exists, &m.largest_location),
573 ControlMessage::Fetch(m) => {
574 let body_is_standalone = matches!(m.fetch_payload, FetchPayload::Standalone { .. });
575 if body_is_standalone != (m.fetch_type == FetchType::Standalone) {
576 return Err(CodecError::InvalidField);
577 }
578 Ok(())
579 }
580 _ => Ok(()),
581 }
582}
583
584fn check_group_order(message: &ControlMessage) -> Result<(), CodecError> {
589 let order = match message {
590 ControlMessage::SubscribeOk(m) => m.group_order,
591 ControlMessage::FetchOk(m) => m.group_order,
592 ControlMessage::Publish(m) => m.group_order,
593 ControlMessage::PublishOk(m) => m.group_order,
594 _ => return Ok(()),
595 };
596 if order == GroupOrder::Publisher {
597 return Err(CodecError::InvalidField);
598 }
599 Ok(())
600}
601
602#[derive(Debug, Clone, PartialEq, Eq)]
607pub enum ControlMessage {
608 ClientSetup(ClientSetup),
609 ServerSetup(ServerSetup),
610 GoAway(GoAway),
611 MaxRequestId(MaxRequestId),
612 RequestsBlocked(RequestsBlocked),
613 Subscribe(Subscribe),
614 SubscribeOk(SubscribeOk),
615 SubscribeError(SubscribeError),
616 SubscribeUpdate(SubscribeUpdate),
617 SubscribeDone(SubscribeDone),
618 Unsubscribe(Unsubscribe),
619 Announce(Announce),
620 AnnounceOk(AnnounceOk),
621 AnnounceError(AnnounceError),
622 AnnounceCancel(AnnounceCancel),
623 Unannounce(Unannounce),
624 SubscribeAnnounces(SubscribeAnnounces),
625 SubscribeAnnouncesOk(SubscribeAnnouncesOk),
626 SubscribeAnnouncesError(SubscribeAnnouncesError),
627 UnsubscribeAnnounces(UnsubscribeAnnounces),
628 TrackStatusRequest(TrackStatusRequest),
629 TrackStatus(TrackStatus),
630 Fetch(Fetch),
631 FetchOk(FetchOk),
632 FetchError(FetchError),
633 FetchCancel(FetchCancel),
634 Publish(Publish),
635 PublishOk(PublishOk),
636 PublishError(PublishError),
637}
638
639fn check_full_track_name(namespace: &TrackNamespace, track_name: &[u8]) -> Result<(), CodecError> {
640 let total = namespace.field_bytes_len().saturating_add(track_name.len());
641 if total > MAX_FULL_TRACK_NAME_LENGTH {
642 return Err(CodecError::TrackNameTooLong);
643 }
644 Ok(())
645}
646
647fn read_reason_phrase(buf: &mut impl Buf) -> Result<Vec<u8>, CodecError> {
655 let len = VarInt::decode(buf)?.into_inner() as usize;
656 if len > MAX_REASON_PHRASE_LENGTH {
657 return Err(CodecError::ReasonPhraseTooLong);
658 }
659 types::read_bytes(buf, len)
660}
661
662fn check_ranges(message: &ControlMessage) -> Result<(), CodecError> {
676 match message {
677 ControlMessage::Subscribe(m) => match (&m.start_group, &m.end_group) {
678 (Some(start_group), Some(end_group)) => {
679 check_group_range(start_group.into_inner(), end_group.into_inner())
680 }
681 _ => Ok(()),
682 },
683 ControlMessage::SubscribeUpdate(m) => {
684 check_open_ended_group_range(m.start_group.into_inner(), m.end_group.into_inner())
685 }
686 ControlMessage::Fetch(m) => match &m.fetch_payload {
687 FetchPayload::Standalone {
688 start_group, start_object, end_group, end_object, ..
689 } => check_location_range(
690 start_group.into_inner(),
691 start_object.into_inner(),
692 end_group.into_inner(),
693 end_object.into_inner(),
694 ),
695 FetchPayload::Joining { .. } => Ok(()),
696 },
697 _ => Ok(()),
698 }
699}
700
701const AUTHORIZATION_TOKEN: u64 = 0x03;
708
709const DELIVERY_TIMEOUT: u64 = 0x02;
711
712const MAX_CACHE_DURATION: u64 = 0x04;
714
715const SETUP_PATH: u64 = 0x01;
717
718const SETUP_MAX_REQUEST_ID: u64 = 0x02;
720
721const SETUP_MAX_AUTH_TOKEN_CACHE_SIZE: u64 = 0x04;
723
724const SETUP_AUTHORIZATION_TOKEN: u64 = AUTHORIZATION_TOKEN;
732
733const KNOWN_PARAMETERS: &[u64] = &[AUTHORIZATION_TOKEN, DELIVERY_TIMEOUT, MAX_CACHE_DURATION];
739
740const REPEATABLE_PARAMETERS: &[u64] = &[AUTHORIZATION_TOKEN];
746
747const KNOWN_SETUP_PARAMETERS: &[u64] =
749 &[SETUP_PATH, SETUP_MAX_REQUEST_ID, SETUP_AUTHORIZATION_TOKEN, SETUP_MAX_AUTH_TOKEN_CACHE_SIZE];
750
751const REPEATABLE_SETUP_PARAMETERS: &[u64] = &[SETUP_AUTHORIZATION_TOKEN];
759
760fn check_sender_parameters(
774 parameters: &[KeyValuePair],
775 repeatable: &[u64],
776) -> Result<(), CodecError> {
777 for (i, parameter) in parameters.iter().enumerate() {
778 let key = parameter.key.into_inner();
779 if repeatable.contains(&key) {
780 continue;
781 }
782 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
783 return Err(CodecError::DuplicateParameter(key));
784 }
785 }
786 Ok(())
787}
788
789fn check_receiver_parameters(
803 parameters: &[KeyValuePair],
804 known: &[u64],
805 repeatable: &[u64],
806) -> Result<(), CodecError> {
807 for (i, parameter) in parameters.iter().enumerate() {
808 let key = parameter.key.into_inner();
809 if repeatable.contains(&key) || !known.contains(&key) {
810 continue;
811 }
812 if parameters[..i].iter().any(|earlier| earlier.key == parameter.key) {
813 return Err(CodecError::DuplicateParameter(key));
814 }
815 }
816 Ok(())
817}
818
819fn check_authorization_tokens(parameters: &[KeyValuePair]) -> Result<(), CodecError> {
834 for parameter in parameters {
835 let key = parameter.key.into_inner();
836 if key != AUTH_TOKEN_PARAMETER {
837 continue;
838 }
839 match ¶meter.value {
840 KvpValue::Bytes(value) => {
841 AuthorizationToken::decode(key, value)?;
842 }
843 KvpValue::Varint(_) => {
848 return Err(CodecError::KeyValueFormatting {
849 key,
850 detail: "its value is a bare varint where the type defines a Token structure",
851 });
852 }
853 }
854 }
855 Ok(())
856}
857
858fn decode_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
860 let parameters = KeyValuePair::decode_list(buf)?;
861 check_receiver_parameters(¶meters, KNOWN_PARAMETERS, REPEATABLE_PARAMETERS)?;
862 check_authorization_tokens(¶meters)?;
863 Ok(parameters)
864}
865
866fn encode_parameters(parameters: &[KeyValuePair], buf: &mut impl BufMut) -> Result<(), CodecError> {
868 check_sender_parameters(parameters, REPEATABLE_PARAMETERS)?;
869 check_authorization_tokens(parameters)?;
870 KeyValuePair::encode_list_checked(parameters, buf)?;
871 Ok(())
872}
873
874fn decode_setup_parameters(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, CodecError> {
876 let parameters = KeyValuePair::decode_list(buf)?;
877 check_receiver_parameters(¶meters, KNOWN_SETUP_PARAMETERS, REPEATABLE_SETUP_PARAMETERS)?;
878 check_authorization_tokens(¶meters)?;
879 Ok(parameters)
880}
881
882fn encode_setup_parameters(
888 parameters: &[KeyValuePair],
889 buf: &mut impl BufMut,
890) -> Result<(), CodecError> {
891 check_sender_parameters(parameters, REPEATABLE_SETUP_PARAMETERS)?;
892 check_authorization_tokens(parameters)?;
893 KeyValuePair::encode_list_checked(parameters, buf)?;
894 Ok(())
895}
896
897impl ControlMessage {
898 pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
902 check_discriminators(self)?;
903 check_group_order(self)?;
904 check_ranges(self)?;
905 let mut payload = Vec::with_capacity(256);
906 self.encode_payload(&mut payload)?;
907
908 if payload.len() > MAX_MESSAGE_LENGTH {
909 return Err(CodecError::MessageTooLong(payload.len()));
910 }
911
912 VarInt::from_usize(self.message_type().id() as usize).encode(buf);
913 buf.put_u16(payload.len() as u16);
915 buf.put_slice(&payload);
916 Ok(())
917 }
918
919 pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError> {
923 let type_id = VarInt::decode(buf)?.into_inner();
924 let msg_type =
925 MessageType::from_id(type_id).ok_or(CodecError::UnknownMessageType(type_id))?;
926 if buf.remaining() < 2 {
928 return Err(CodecError::UnexpectedEnd);
929 }
930 let payload_len = buf.get_u16() as usize;
931 if buf.remaining() < payload_len {
932 return Err(CodecError::UnexpectedEnd);
933 }
934 let payload_bytes = buf.copy_to_bytes(payload_len);
935 let mut payload = &payload_bytes[..];
936 let msg = match Self::decode_payload(msg_type, &mut payload) {
937 Ok(msg) => msg,
938 Err(
944 CodecError::UnexpectedEnd
945 | CodecError::Kvp(crate::kvp::KvpError::UnexpectedEnd)
946 | CodecError::Kvp(crate::kvp::KvpError::VarInt(
947 crate::varint::VarIntError::UnexpectedEnd,
948 ))
949 | CodecError::VarInt(crate::varint::VarIntError::UnexpectedEnd),
950 ) => {
951 return Err(CodecError::ControlMessageLengthMismatch {
952 declared: payload_len,
953 detail: "its fields ran past the end",
954 });
955 }
956 Err(e) => return Err(e),
957 };
958 check_ranges(&msg)?;
959 if payload.has_remaining() {
964 return Err(CodecError::ControlMessageLengthMismatch {
965 declared: payload_len,
966 detail: "its fields left bytes unread",
967 });
968 }
969 Ok(msg)
970 }
971
972 fn encode_payload(&self, buf: &mut impl BufMut) -> Result<(), CodecError> {
973 match self {
974 ControlMessage::ClientSetup(m) => {
975 VarInt::from_usize(m.supported_versions.len()).encode(buf);
976 for v in &m.supported_versions {
977 v.encode(buf);
978 }
979 encode_setup_parameters(&m.parameters, buf)?;
980 }
981 ControlMessage::ServerSetup(m) => {
982 m.selected_version.encode(buf);
983 encode_setup_parameters(&m.parameters, buf)?;
984 }
985 ControlMessage::GoAway(m) => {
986 if m.new_session_uri.len() > MAX_GOAWAY_URI_LENGTH {
987 return Err(CodecError::GoAwayUriTooLong);
988 }
989 VarInt::from_usize(m.new_session_uri.len()).encode(buf);
990 buf.put_slice(&m.new_session_uri);
991 }
992 ControlMessage::MaxRequestId(m) => {
993 m.request_id.encode(buf);
994 }
995 ControlMessage::RequestsBlocked(m) => {
996 m.maximum_request_id.encode(buf);
997 }
998 ControlMessage::Subscribe(m) => {
999 m.request_id.encode(buf);
1000 m.track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1001 m.track_namespace.encode(buf);
1002 check_full_track_name(&m.track_namespace, &m.track_name)?;
1003 VarInt::from_usize(m.track_name.len()).encode(buf);
1004 buf.put_slice(&m.track_name);
1005 buf.put_u8(m.subscriber_priority);
1006 buf.put_u8(m.group_order as u8);
1007 buf.put_u8(m.forward as u8);
1008 m.filter_type.encode(buf);
1009 if let Some(sg) = &m.start_group {
1010 sg.encode(buf);
1011 }
1012 if let Some(so) = &m.start_object {
1013 so.encode(buf);
1014 }
1015 if let Some(eg) = &m.end_group {
1016 eg.encode(buf);
1017 }
1018 encode_parameters(&m.parameters, buf)?;
1019 }
1020 ControlMessage::SubscribeOk(m) => {
1021 m.request_id.encode(buf);
1022 m.track_alias.encode(buf);
1023 m.expires.encode(buf);
1024 buf.put_u8(m.group_order as u8);
1025 buf.put_u8(m.content_exists as u8);
1026 if let Some(loc) = &m.largest_location {
1027 loc.encode(buf);
1028 }
1029 encode_parameters(&m.parameters, buf)?;
1030 }
1031 ControlMessage::SubscribeError(m) => {
1032 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1033 return Err(CodecError::ReasonPhraseTooLong);
1034 }
1035 m.request_id.encode(buf);
1036 m.error_code.encode(buf);
1037 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1038 buf.put_slice(&m.reason_phrase);
1039 }
1040 ControlMessage::SubscribeUpdate(m) => {
1041 m.request_id.encode(buf);
1042 m.start_group.encode(buf);
1043 m.start_object.encode(buf);
1044 m.end_group.encode(buf);
1045 buf.put_u8(m.subscriber_priority);
1046 buf.put_u8(m.forward as u8);
1047 encode_parameters(&m.parameters, buf)?;
1048 }
1049 ControlMessage::SubscribeDone(m) => {
1050 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1051 return Err(CodecError::ReasonPhraseTooLong);
1052 }
1053 m.request_id.encode(buf);
1054 m.status_code.encode(buf);
1055 m.stream_count.encode(buf);
1056 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1057 buf.put_slice(&m.reason_phrase);
1058 }
1059 ControlMessage::Unsubscribe(m) => {
1060 m.request_id.encode(buf);
1061 }
1062 ControlMessage::Announce(m) => {
1063 m.request_id.encode(buf);
1064 m.track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1065 m.track_namespace.encode(buf);
1066 encode_parameters(&m.parameters, buf)?;
1067 }
1068 ControlMessage::AnnounceOk(m) => {
1069 m.request_id.encode(buf);
1070 }
1071 ControlMessage::AnnounceError(m) => {
1072 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1073 return Err(CodecError::ReasonPhraseTooLong);
1074 }
1075 m.request_id.encode(buf);
1076 m.error_code.encode(buf);
1077 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1078 buf.put_slice(&m.reason_phrase);
1079 }
1080 ControlMessage::AnnounceCancel(m) => {
1081 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1082 return Err(CodecError::ReasonPhraseTooLong);
1083 }
1084 m.track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1085 m.track_namespace.encode(buf);
1086 m.error_code.encode(buf);
1087 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1088 buf.put_slice(&m.reason_phrase);
1089 }
1090 ControlMessage::Unannounce(m) => {
1091 m.track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1092 m.track_namespace.encode(buf);
1093 }
1094 ControlMessage::SubscribeAnnounces(m) => {
1095 m.request_id.encode(buf);
1096 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(12))?;
1097 m.track_namespace_prefix.encode(buf);
1098 encode_parameters(&m.parameters, buf)?;
1099 }
1100 ControlMessage::SubscribeAnnouncesOk(m) => {
1101 m.request_id.encode(buf);
1102 }
1103 ControlMessage::SubscribeAnnouncesError(m) => {
1104 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1105 return Err(CodecError::ReasonPhraseTooLong);
1106 }
1107 m.request_id.encode(buf);
1108 m.error_code.encode(buf);
1109 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1110 buf.put_slice(&m.reason_phrase);
1111 }
1112 ControlMessage::UnsubscribeAnnounces(m) => {
1113 m.track_namespace_prefix.validate(TrackNamespaceRules::for_draft(12))?;
1114 m.track_namespace_prefix.encode(buf);
1115 }
1116 ControlMessage::TrackStatusRequest(m) => {
1117 m.request_id.encode(buf);
1118 m.track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1119 m.track_namespace.encode(buf);
1120 check_full_track_name(&m.track_namespace, &m.track_name)?;
1121 VarInt::from_usize(m.track_name.len()).encode(buf);
1122 buf.put_slice(&m.track_name);
1123 encode_parameters(&m.parameters, buf)?;
1124 }
1125 ControlMessage::TrackStatus(m) => {
1126 m.request_id.encode(buf);
1127 check_track_status(m.status_code, m.largest_location)?;
1128 m.status_code.encode(buf);
1129 m.largest_location.encode(buf);
1130 encode_parameters(&m.parameters, buf)?;
1131 }
1132 ControlMessage::Fetch(m) => {
1133 m.request_id.encode(buf);
1134 buf.put_u8(m.subscriber_priority);
1135 buf.put_u8(m.group_order as u8);
1136 VarInt::from_usize(m.fetch_type as usize).encode(buf);
1137 match &m.fetch_payload {
1138 FetchPayload::Standalone {
1139 track_namespace,
1140 track_name,
1141 start_group,
1142 start_object,
1143 end_group,
1144 end_object,
1145 } => {
1146 track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1147 track_namespace.encode(buf);
1148 check_full_track_name(track_namespace, track_name)?;
1149 VarInt::from_usize(track_name.len()).encode(buf);
1150 buf.put_slice(track_name);
1151 start_group.encode(buf);
1152 start_object.encode(buf);
1153 end_group.encode(buf);
1154 end_object.encode(buf);
1155 }
1156 FetchPayload::Joining { joining_request_id, joining_start } => {
1157 joining_request_id.encode(buf);
1158 joining_start.encode(buf);
1159 }
1160 }
1161 encode_parameters(&m.parameters, buf)?;
1162 }
1163 ControlMessage::FetchOk(m) => {
1164 m.request_id.encode(buf);
1165 buf.put_u8(m.group_order as u8);
1166 buf.put_u8(m.end_of_track);
1167 m.end_location.encode(buf);
1168 encode_parameters(&m.parameters, buf)?;
1169 }
1170 ControlMessage::FetchError(m) => {
1171 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1172 return Err(CodecError::ReasonPhraseTooLong);
1173 }
1174 m.request_id.encode(buf);
1175 m.error_code.encode(buf);
1176 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1177 buf.put_slice(&m.reason_phrase);
1178 }
1179 ControlMessage::FetchCancel(m) => {
1180 m.request_id.encode(buf);
1181 }
1182 ControlMessage::Publish(m) => {
1183 m.request_id.encode(buf);
1184 m.track_namespace.validate(TrackNamespaceRules::for_draft(12))?;
1185 m.track_namespace.encode(buf);
1186 check_full_track_name(&m.track_namespace, &m.track_name)?;
1187 VarInt::from_usize(m.track_name.len()).encode(buf);
1188 buf.put_slice(&m.track_name);
1189 m.track_alias.encode(buf);
1190 buf.put_u8(m.group_order as u8);
1191 buf.put_u8(m.content_exists as u8);
1192 if let Some(loc) = &m.largest_location {
1193 loc.encode(buf);
1194 }
1195 buf.put_u8(m.forward as u8);
1196 encode_parameters(&m.parameters, buf)?;
1197 }
1198 ControlMessage::PublishOk(m) => {
1199 m.request_id.encode(buf);
1200 buf.put_u8(m.forward as u8);
1201 buf.put_u8(m.subscriber_priority);
1202 buf.put_u8(m.group_order as u8);
1203 m.filter_type.encode(buf);
1204 if let Some(sg) = &m.start_group {
1205 sg.encode(buf);
1206 }
1207 if let Some(so) = &m.start_object {
1208 so.encode(buf);
1209 }
1210 if let Some(eg) = &m.end_group {
1211 eg.encode(buf);
1212 }
1213 encode_parameters(&m.parameters, buf)?;
1214 }
1215 ControlMessage::PublishError(m) => {
1216 if m.reason_phrase.len() > MAX_REASON_PHRASE_LENGTH {
1217 return Err(CodecError::ReasonPhraseTooLong);
1218 }
1219 m.request_id.encode(buf);
1220 m.error_code.encode(buf);
1221 VarInt::from_usize(m.reason_phrase.len()).encode(buf);
1222 buf.put_slice(&m.reason_phrase);
1223 }
1224 }
1225 Ok(())
1226 }
1227
1228 fn decode_payload(msg_type: MessageType, buf: &mut impl Buf) -> Result<Self, CodecError> {
1229 match msg_type {
1230 MessageType::ClientSetup => {
1231 let num_versions = VarInt::decode(buf)?.into_inner() as usize;
1232 if num_versions == 0 {
1242 return Err(CodecError::InvalidField);
1243 }
1244 let mut supported_versions = crate::types::reserve_bounded(num_versions, buf);
1245 for _ in 0..num_versions {
1246 supported_versions.push(VarInt::decode(buf)?);
1247 }
1248 let parameters = decode_setup_parameters(buf)?;
1249 Ok(ControlMessage::ClientSetup(ClientSetup { supported_versions, parameters }))
1250 }
1251 MessageType::ServerSetup => {
1252 let selected_version = VarInt::decode(buf)?;
1253 let parameters = decode_setup_parameters(buf)?;
1254 Ok(ControlMessage::ServerSetup(ServerSetup { selected_version, parameters }))
1255 }
1256 MessageType::GoAway => {
1257 let uri_len = VarInt::decode(buf)?.into_inner() as usize;
1258 if uri_len > MAX_GOAWAY_URI_LENGTH {
1259 return Err(CodecError::GoAwayUriTooLong);
1260 }
1261 let uri = types::read_bytes(buf, uri_len)?;
1262 Ok(ControlMessage::GoAway(GoAway { new_session_uri: uri }))
1263 }
1264 MessageType::MaxRequestId => {
1265 let request_id = VarInt::decode(buf)?;
1266 Ok(ControlMessage::MaxRequestId(MaxRequestId { request_id }))
1267 }
1268 MessageType::RequestsBlocked => {
1269 let maximum_request_id = VarInt::decode(buf)?;
1270 Ok(ControlMessage::RequestsBlocked(RequestsBlocked { maximum_request_id }))
1271 }
1272 MessageType::Subscribe => {
1273 let request_id = VarInt::decode(buf)?;
1274 let track_namespace = TrackNamespace::decode(buf)?;
1275 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1276 let track_name = types::read_bytes(buf, track_name_len)?;
1277 check_full_track_name(&track_namespace, &track_name)?;
1278 if buf.remaining() < 1 {
1279 return Err(CodecError::UnexpectedEnd);
1280 }
1281 let subscriber_priority = buf.get_u8();
1282 let group_order = read_group_order(buf)?;
1283 let forward = read_forward(buf)?;
1284 let filter_type = VarInt::decode(buf)?;
1285 let ft_val = filter_type.into_inner();
1286 if ft_val == 0 || ft_val > 4 {
1287 return Err(CodecError::InvalidFilterType(ft_val));
1288 }
1289 let (start_group, start_object) = if ft_val == 3 || ft_val == 4 {
1290 (Some(VarInt::decode(buf)?), Some(VarInt::decode(buf)?))
1291 } else {
1292 (None, None)
1293 };
1294 let end_group = if ft_val == 4 { Some(VarInt::decode(buf)?) } else { None };
1295 let parameters = decode_parameters(buf)?;
1296 Ok(ControlMessage::Subscribe(Subscribe {
1297 request_id,
1298 track_namespace,
1299 track_name,
1300 subscriber_priority,
1301 group_order,
1302 forward,
1303 filter_type,
1304 start_group,
1305 start_object,
1306 end_group,
1307 parameters,
1308 }))
1309 }
1310 MessageType::SubscribeOk => {
1311 let request_id = VarInt::decode(buf)?;
1312 let track_alias = VarInt::decode(buf)?;
1313 let expires = VarInt::decode(buf)?;
1314 let group_order = read_group_order_response(buf)?;
1315 let content_exists = read_content_exists(buf)?;
1316 let largest_location = if content_exists == ContentExists::HasLargestLocation {
1317 Some(Location::decode(buf)?)
1318 } else {
1319 None
1320 };
1321 let parameters = decode_parameters(buf)?;
1322 Ok(ControlMessage::SubscribeOk(SubscribeOk {
1323 request_id,
1324 track_alias,
1325 expires,
1326 group_order,
1327 content_exists,
1328 largest_location,
1329 parameters,
1330 }))
1331 }
1332 MessageType::SubscribeError => {
1333 let request_id = VarInt::decode(buf)?;
1334 let error_code = VarInt::decode(buf)?;
1335 let reason_phrase = read_reason_phrase(buf)?;
1336 Ok(ControlMessage::SubscribeError(SubscribeError {
1337 request_id,
1338 error_code,
1339 reason_phrase,
1340 }))
1341 }
1342 MessageType::SubscribeUpdate => {
1343 let request_id = VarInt::decode(buf)?;
1344 let start_group = VarInt::decode(buf)?;
1345 let start_object = VarInt::decode(buf)?;
1346 let end_group = VarInt::decode(buf)?;
1347 if buf.remaining() < 1 {
1348 return Err(CodecError::UnexpectedEnd);
1349 }
1350 let subscriber_priority = buf.get_u8();
1351 let forward = read_forward(buf)?;
1352 let parameters = decode_parameters(buf)?;
1353 Ok(ControlMessage::SubscribeUpdate(SubscribeUpdate {
1354 request_id,
1355 start_group,
1356 start_object,
1357 end_group,
1358 subscriber_priority,
1359 forward,
1360 parameters,
1361 }))
1362 }
1363 MessageType::SubscribeDone => {
1364 let request_id = VarInt::decode(buf)?;
1365 let status_code = VarInt::decode(buf)?;
1366 let stream_count = VarInt::decode(buf)?;
1367 let reason_phrase = read_reason_phrase(buf)?;
1368 Ok(ControlMessage::SubscribeDone(SubscribeDone {
1369 request_id,
1370 status_code,
1371 stream_count,
1372 reason_phrase,
1373 }))
1374 }
1375 MessageType::Unsubscribe => {
1376 let request_id = VarInt::decode(buf)?;
1377 Ok(ControlMessage::Unsubscribe(Unsubscribe { request_id }))
1378 }
1379 MessageType::Announce => {
1380 let request_id = VarInt::decode(buf)?;
1381 let track_namespace = TrackNamespace::decode(buf)?;
1382 let parameters = decode_parameters(buf)?;
1383 Ok(ControlMessage::Announce(Announce { request_id, track_namespace, parameters }))
1384 }
1385 MessageType::AnnounceOk => {
1386 let request_id = VarInt::decode(buf)?;
1387 Ok(ControlMessage::AnnounceOk(AnnounceOk { request_id }))
1388 }
1389 MessageType::AnnounceError => {
1390 let request_id = VarInt::decode(buf)?;
1391 let error_code = VarInt::decode(buf)?;
1392 let reason_phrase = read_reason_phrase(buf)?;
1393 Ok(ControlMessage::AnnounceError(AnnounceError {
1394 request_id,
1395 error_code,
1396 reason_phrase,
1397 }))
1398 }
1399 MessageType::AnnounceCancel => {
1400 let track_namespace = TrackNamespace::decode(buf)?;
1401 let error_code = VarInt::decode(buf)?;
1402 let reason_phrase = read_reason_phrase(buf)?;
1403 Ok(ControlMessage::AnnounceCancel(AnnounceCancel {
1404 track_namespace,
1405 error_code,
1406 reason_phrase,
1407 }))
1408 }
1409 MessageType::Unannounce => {
1410 let track_namespace = TrackNamespace::decode(buf)?;
1411 Ok(ControlMessage::Unannounce(Unannounce { track_namespace }))
1412 }
1413 MessageType::SubscribeAnnounces => {
1414 let request_id = VarInt::decode(buf)?;
1415 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1416 let parameters = decode_parameters(buf)?;
1417 Ok(ControlMessage::SubscribeAnnounces(SubscribeAnnounces {
1418 request_id,
1419 track_namespace_prefix,
1420 parameters,
1421 }))
1422 }
1423 MessageType::SubscribeAnnouncesOk => {
1424 let request_id = VarInt::decode(buf)?;
1425 Ok(ControlMessage::SubscribeAnnouncesOk(SubscribeAnnouncesOk { request_id }))
1426 }
1427 MessageType::SubscribeAnnouncesError => {
1428 let request_id = VarInt::decode(buf)?;
1429 let error_code = VarInt::decode(buf)?;
1430 let reason_phrase = read_reason_phrase(buf)?;
1431 Ok(ControlMessage::SubscribeAnnouncesError(SubscribeAnnouncesError {
1432 request_id,
1433 error_code,
1434 reason_phrase,
1435 }))
1436 }
1437 MessageType::UnsubscribeAnnounces => {
1438 let track_namespace_prefix = TrackNamespace::decode(buf)?;
1439 Ok(ControlMessage::UnsubscribeAnnounces(UnsubscribeAnnounces {
1440 track_namespace_prefix,
1441 }))
1442 }
1443 MessageType::TrackStatusRequest => {
1444 let request_id = VarInt::decode(buf)?;
1445 let track_namespace = TrackNamespace::decode(buf)?;
1446 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1447 let track_name = types::read_bytes(buf, track_name_len)?;
1448 check_full_track_name(&track_namespace, &track_name)?;
1449 let parameters = decode_parameters(buf)?;
1450 Ok(ControlMessage::TrackStatusRequest(TrackStatusRequest {
1451 request_id,
1452 track_namespace,
1453 track_name,
1454 parameters,
1455 }))
1456 }
1457 MessageType::TrackStatus => {
1458 let request_id = VarInt::decode(buf)?;
1459 let status_code = VarInt::decode(buf)?;
1460 let largest_location = Location::decode(buf)?;
1461 check_track_status(status_code, largest_location)?;
1462 let parameters = decode_parameters(buf)?;
1463 Ok(ControlMessage::TrackStatus(TrackStatus {
1464 request_id,
1465 status_code,
1466 largest_location,
1467 parameters,
1468 }))
1469 }
1470 MessageType::Fetch => {
1471 let request_id = VarInt::decode(buf)?;
1472 if buf.remaining() < 1 {
1473 return Err(CodecError::UnexpectedEnd);
1474 }
1475 let subscriber_priority = buf.get_u8();
1476 let group_order = read_group_order(buf)?;
1477 let fetch_type_val = VarInt::decode(buf)?.into_inner();
1478 let fetch_type = FetchType::from_u64(fetch_type_val)
1479 .ok_or(CodecError::InvalidFetchType(fetch_type_val))?;
1480 let fetch_payload = match fetch_type {
1481 FetchType::Standalone => {
1482 let track_namespace = TrackNamespace::decode(buf)?;
1483 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1484 let track_name = types::read_bytes(buf, track_name_len)?;
1485 check_full_track_name(&track_namespace, &track_name)?;
1486 let start_group = VarInt::decode(buf)?;
1487 let start_object = VarInt::decode(buf)?;
1488 let end_group = VarInt::decode(buf)?;
1489 let end_object = VarInt::decode(buf)?;
1490 FetchPayload::Standalone {
1491 track_namespace,
1492 track_name,
1493 start_group,
1494 start_object,
1495 end_group,
1496 end_object,
1497 }
1498 }
1499 FetchType::RelativeJoining | FetchType::AbsoluteJoining => {
1500 let joining_request_id = VarInt::decode(buf)?;
1501 let joining_start = VarInt::decode(buf)?;
1502 FetchPayload::Joining { joining_request_id, joining_start }
1503 }
1504 };
1505 let parameters = decode_parameters(buf)?;
1506 Ok(ControlMessage::Fetch(Fetch {
1507 request_id,
1508 subscriber_priority,
1509 group_order,
1510 fetch_type,
1511 fetch_payload,
1512 parameters,
1513 }))
1514 }
1515 MessageType::FetchOk => {
1516 let request_id = VarInt::decode(buf)?;
1517 let group_order = read_group_order_response(buf)?;
1518 let end_of_track = read_u8(buf)?;
1519 let end_location = Location::decode(buf)?;
1520 let parameters = decode_parameters(buf)?;
1521 Ok(ControlMessage::FetchOk(FetchOk {
1522 request_id,
1523 group_order,
1524 end_of_track,
1525 end_location,
1526 parameters,
1527 }))
1528 }
1529 MessageType::FetchError => {
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::FetchError(FetchError { request_id, error_code, reason_phrase }))
1534 }
1535 MessageType::FetchCancel => {
1536 let request_id = VarInt::decode(buf)?;
1537 Ok(ControlMessage::FetchCancel(FetchCancel { request_id }))
1538 }
1539 MessageType::Publish => {
1540 let request_id = VarInt::decode(buf)?;
1541 let track_namespace = TrackNamespace::decode(buf)?;
1542 let track_name_len = VarInt::decode(buf)?.into_inner() as usize;
1543 let track_name = types::read_bytes(buf, track_name_len)?;
1544 check_full_track_name(&track_namespace, &track_name)?;
1545 let track_alias = VarInt::decode(buf)?;
1546 let group_order = read_group_order_response(buf)?;
1547 let content_exists = read_content_exists(buf)?;
1548 let largest_location = if content_exists == ContentExists::HasLargestLocation {
1549 Some(Location::decode(buf)?)
1550 } else {
1551 None
1552 };
1553 let forward = read_forward(buf)?;
1554 let parameters = decode_parameters(buf)?;
1555 Ok(ControlMessage::Publish(Publish {
1556 request_id,
1557 track_namespace,
1558 track_name,
1559 track_alias,
1560 group_order,
1561 content_exists,
1562 largest_location,
1563 forward,
1564 parameters,
1565 }))
1566 }
1567 MessageType::PublishOk => {
1568 let request_id = VarInt::decode(buf)?;
1569 let forward = read_forward(buf)?;
1570 if buf.remaining() < 1 {
1571 return Err(CodecError::UnexpectedEnd);
1572 }
1573 let subscriber_priority = buf.get_u8();
1574 let group_order = read_group_order_response(buf)?;
1575 let filter_type = VarInt::decode(buf)?;
1576 let ft_val = filter_type.into_inner();
1577 if ft_val == 0 || ft_val > 4 {
1578 return Err(CodecError::InvalidFilterType(ft_val));
1579 }
1580 let (start_group, start_object) = if ft_val == 3 || ft_val == 4 {
1581 (Some(VarInt::decode(buf)?), Some(VarInt::decode(buf)?))
1582 } else {
1583 (None, None)
1584 };
1585 let end_group = if ft_val == 4 { Some(VarInt::decode(buf)?) } else { None };
1586 let parameters = decode_parameters(buf)?;
1587 Ok(ControlMessage::PublishOk(PublishOk {
1588 request_id,
1589 forward,
1590 subscriber_priority,
1591 group_order,
1592 filter_type,
1593 start_group,
1594 start_object,
1595 end_group,
1596 parameters,
1597 }))
1598 }
1599 MessageType::PublishError => {
1600 let request_id = VarInt::decode(buf)?;
1601 let error_code = VarInt::decode(buf)?;
1602 let reason_phrase = read_reason_phrase(buf)?;
1603 Ok(ControlMessage::PublishError(PublishError {
1604 request_id,
1605 error_code,
1606 reason_phrase,
1607 }))
1608 }
1609 }
1610 }
1611
1612 pub fn message_type(&self) -> MessageType {
1613 match self {
1614 ControlMessage::ClientSetup(_) => MessageType::ClientSetup,
1615 ControlMessage::ServerSetup(_) => MessageType::ServerSetup,
1616 ControlMessage::GoAway(_) => MessageType::GoAway,
1617 ControlMessage::MaxRequestId(_) => MessageType::MaxRequestId,
1618 ControlMessage::RequestsBlocked(_) => MessageType::RequestsBlocked,
1619 ControlMessage::Subscribe(_) => MessageType::Subscribe,
1620 ControlMessage::SubscribeOk(_) => MessageType::SubscribeOk,
1621 ControlMessage::SubscribeError(_) => MessageType::SubscribeError,
1622 ControlMessage::SubscribeUpdate(_) => MessageType::SubscribeUpdate,
1623 ControlMessage::SubscribeDone(_) => MessageType::SubscribeDone,
1624 ControlMessage::Unsubscribe(_) => MessageType::Unsubscribe,
1625 ControlMessage::Announce(_) => MessageType::Announce,
1626 ControlMessage::AnnounceOk(_) => MessageType::AnnounceOk,
1627 ControlMessage::AnnounceError(_) => MessageType::AnnounceError,
1628 ControlMessage::AnnounceCancel(_) => MessageType::AnnounceCancel,
1629 ControlMessage::Unannounce(_) => MessageType::Unannounce,
1630 ControlMessage::SubscribeAnnounces(_) => MessageType::SubscribeAnnounces,
1631 ControlMessage::SubscribeAnnouncesOk(_) => MessageType::SubscribeAnnouncesOk,
1632 ControlMessage::SubscribeAnnouncesError(_) => MessageType::SubscribeAnnouncesError,
1633 ControlMessage::UnsubscribeAnnounces(_) => MessageType::UnsubscribeAnnounces,
1634 ControlMessage::TrackStatusRequest(_) => MessageType::TrackStatusRequest,
1635 ControlMessage::TrackStatus(_) => MessageType::TrackStatus,
1636 ControlMessage::Fetch(_) => MessageType::Fetch,
1637 ControlMessage::FetchOk(_) => MessageType::FetchOk,
1638 ControlMessage::FetchError(_) => MessageType::FetchError,
1639 ControlMessage::FetchCancel(_) => MessageType::FetchCancel,
1640 ControlMessage::Publish(_) => MessageType::Publish,
1641 ControlMessage::PublishOk(_) => MessageType::PublishOk,
1642 ControlMessage::PublishError(_) => MessageType::PublishError,
1643 }
1644 }
1645}