dsf_core/net/
request.rs

1use core::convert::TryFrom;
2use core::ops::Deref;
3
4#[cfg(feature = "alloc")]
5use alloc::prelude::v1::*;
6
7use crate::base::{Base, BaseOptions, Body, Header};
8use crate::error::Error;
9use crate::options::Options;
10use crate::page::Page;
11use crate::types::*;
12
13use super::Common;
14use super::BUFF_SIZE;
15
16#[derive(Clone, Debug)]
17pub struct Request {
18    pub common: Common,
19    pub data: RequestKind,
20}
21
22impl Deref for Request {
23    type Target = Common;
24
25    fn deref(&self) -> &Common {
26        &self.common
27    }
28}
29
30#[derive(Clone, PartialEq, Debug)]
31#[cfg_attr(feature = "strum", derive(strum_macros::Display))]
32pub enum RequestKind {
33    Hello,
34    Ping,
35    FindNode(Id),
36    FindValue(Id),
37    Store(Id, Vec<Page>),
38
39    Subscribe(Id),
40    Unsubscribe(Id),
41    Query(Id),
42    PushData(Id, Vec<Page>),
43
44    Register(Id, Vec<Page>),
45    Unregister(Id),
46}
47
48impl Request {
49    pub fn new(from: Id, request_id: u16, data: RequestKind, flags: Flags) -> Request {
50        let common = Common {
51            from,
52            id: request_id,
53            flags,
54            public_key: None,
55            remote_address: None,
56        };
57        Request { common, data }
58    }
59
60    pub fn flags(&mut self) -> &mut Flags {
61        &mut self.common.flags
62    }
63
64    pub fn set_public_key(&mut self, pk: PublicKey) {
65        self.common.public_key = Some(pk);
66    }
67
68    pub fn with_public_key(mut self, pk: PublicKey) -> Self {
69        self.common.public_key = Some(pk);
70        self
71    }
72}
73
74impl PartialEq for Request {
75    fn eq(&self, b: &Self) -> bool {
76        self.from == b.from && self.flags == b.flags && self.data == b.data
77    }
78}
79
80impl Request {
81    pub fn convert<V>(base: Base, key_source: V) -> Result<Request, Error>
82    where
83        V: Fn(&Id) -> Option<PublicKey>,
84    {
85        let header = base.header();
86
87        let empty_body = vec![];
88        let body = match base.body() {
89            Body::Cleartext(d) => d,
90            Body::None => &empty_body,
91            Body::Encrypted(_e) => {
92                panic!("Attempting to convert encrypted object to response message")
93            }
94        };
95
96        let remote_address = None;
97        let _public_options = base.public_options().to_vec();
98        //let _private_options = base.private_options().to_vec();
99
100        let kind = match MessageKind::try_from(header.kind()) {
101            Ok(k) => k,
102            Err(_) => return Err(Error::InvalidMessageKind),
103        };
104
105        let data = match kind {
106            MessageKind::Hello => RequestKind::Hello,
107            MessageKind::Ping => RequestKind::Ping,
108            MessageKind::FindNodes => {
109                let mut id = Id::default();
110                id.copy_from_slice(&body[0..ID_LEN]);
111                RequestKind::FindNode(id)
112            }
113            MessageKind::FindValues => {
114                let mut id = Id::default();
115                id.copy_from_slice(&body[0..ID_LEN]);
116                RequestKind::FindValue(id)
117            }
118            MessageKind::Subscribe => {
119                let mut id = Id::default();
120                id.copy_from_slice(&body[0..ID_LEN]);
121                RequestKind::Subscribe(id)
122            }
123            MessageKind::Query => {
124                let mut id = Id::default();
125                id.copy_from_slice(&body[0..ID_LEN]);
126                RequestKind::Query(id)
127            }
128            MessageKind::Store => {
129                let mut id = Id::default();
130                id.copy_from_slice(&body[0..ID_LEN]);
131
132                // Perhaps i should not fetch pages until later..?
133                // And also sign them earlier..?
134                let pages = Page::decode_pages(&body[ID_LEN..], key_source).unwrap();
135
136                RequestKind::Store(id, pages)
137            }
138            MessageKind::PushData => {
139                let mut id = Id::default();
140                id.copy_from_slice(&body[0..ID_LEN]);
141
142                let pages = Page::decode_pages(&body[ID_LEN..], key_source).unwrap();
143
144                RequestKind::PushData(id, pages)
145            }
146            MessageKind::Register => {
147                let mut id = Id::default();
148                id.copy_from_slice(&body[0..ID_LEN]);
149
150                let pages = Page::decode_pages(&body[ID_LEN..], key_source).unwrap();
151
152                RequestKind::Register(id, pages)
153            }
154            MessageKind::Unregister => {
155                let mut id = Id::default();
156                id.copy_from_slice(&body[0..ID_LEN]);
157
158                RequestKind::Unregister(id)
159            }
160            _ => {
161                error!(
162                    "Error converting base object of kind {:?} to request message",
163                    header.kind()
164                );
165                return Err(Error::InvalidMessageKind);
166            }
167        };
168
169        // Fetch other key options
170        let public_key = base.public_key.clone();
171        //let remote_address = Base::filter_address_option(&mut public_options);
172
173        let common = Common {
174            from: base.id().clone(),
175            id: header.index(),
176            flags: header.flags(),
177            public_key,
178            remote_address,
179        };
180        Ok(Request { common, data })
181    }
182}
183
184// TODO: this is duplicated in the service module
185// where should it be?
186impl Into<Base> for Request {
187    fn into(self) -> Base {
188        let kind: MessageKind;
189        let body;
190
191        let mut options = BaseOptions::default();
192
193        match &self.data {
194            RequestKind::Hello => {
195                kind = MessageKind::Hello;
196                body = vec![];
197            }
198            RequestKind::Ping => {
199                kind = MessageKind::Ping;
200                body = vec![];
201            }
202            RequestKind::FindNode(id) => {
203                kind = MessageKind::FindNodes;
204                body = id.to_vec();
205            }
206            RequestKind::FindValue(id) => {
207                kind = MessageKind::FindValues;
208                body = id.to_vec();
209            }
210            RequestKind::Store(id, pages) => {
211                kind = MessageKind::Store;
212
213                let mut buff = vec![0u8; BUFF_SIZE];
214                (&mut buff[..ID_LEN]).copy_from_slice(id);
215
216                let i = Page::encode_pages(pages, &mut buff[ID_LEN..]).unwrap();
217
218                body = buff[..ID_LEN + i].to_vec();
219            }
220            RequestKind::Subscribe(id) => {
221                kind = MessageKind::Subscribe;
222                body = id.to_vec();
223            }
224            RequestKind::Unsubscribe(id) => {
225                kind = MessageKind::Unsubscribe;
226                body = id.to_vec();
227            }
228            RequestKind::Query(id) => {
229                kind = MessageKind::Query;
230                body = id.to_vec();
231            }
232            RequestKind::PushData(id, pages) => {
233                kind = MessageKind::PushData;
234
235                let mut buff = vec![0u8; BUFF_SIZE];
236                (&mut buff[..ID_LEN]).copy_from_slice(id);
237
238                let i = Page::encode_pages(pages, &mut buff[ID_LEN..]).unwrap();
239
240                body = buff[..ID_LEN + i].to_vec();
241            }
242            RequestKind::Register(id, pages) => {
243                kind = MessageKind::Register;
244
245                let mut buff = vec![0u8; BUFF_SIZE];
246                (&mut buff[..ID_LEN]).copy_from_slice(id);
247
248                let i = Page::encode_pages(pages, &mut buff[ID_LEN..]).unwrap();
249
250                body = buff[..ID_LEN + i].to_vec();
251            }
252            RequestKind::Unregister(id) => {
253                kind = MessageKind::Unregister;
254                body = id.to_vec();
255            }
256        }
257
258        // Create object header
259        let header = Header {
260            kind: kind.into(),
261            flags: self.flags,
262            index: self.id,
263            ..Default::default()
264        };
265
266        // Attach public key and address options if supplied
267        options.public_key = self.public_key.clone();
268        if let Some(a) = self.remote_address {
269            options.append_public_option(Options::address(a));
270        }
271
272        // Build base object
273        Base::new(self.from.clone(), header, Body::from(body), options)
274    }
275}
276
277#[cfg(nope)]
278impl fmt::Debug for RequestKind {
279    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
280        match self {
281            RequestKind::Hello => write!(f, "status"),
282            RequestKind::Ping => write!(f, "Ping"),
283            RequestKind::FindNode(id) => write!(f, "FindNode ({:?})", id),
284            RequestKind::FindValue(id) => write!(f, "FindValue ({:?})", id),
285            RequestKind::Store(id, values) => {
286                write!(f, "Store({:?}): [", id)?;
287                for v in values {
288                    write!(f, "\n    - {:?}", v)?;
289                }
290                writeln!(f, "]")
291            }
292        }
293    }
294}