libsignal_service/
proto.rs1#![allow(clippy::all)]
2
3use rand::{CryptoRng, Rng};
4use reqwest::StatusCode;
5include!(concat!(env!("OUT_DIR"), "/signalservice.rs"));
6include!(concat!(env!("OUT_DIR"), "/signal.rs"));
7
8impl WebSocketRequestMessage {
9 pub fn is_signal_service_envelope(&self) -> bool {
12 self.verb.as_deref() == Some("PUT")
13 && self.path.as_deref() == Some("/api/v1/message")
14 }
15
16 pub fn is_queue_empty(&self) -> bool {
17 self.verb.as_deref() == Some("PUT")
18 && self.path.as_deref() == Some("/api/v1/queue/empty")
19 }
20
21 pub fn is_signal_key_encrypted(&self) -> bool {
24 if self.headers.is_empty() {
25 return true;
26 }
27
28 for header in &self.headers {
29 let parts: Vec<_> = header.split(':').collect();
30 if parts.len() != 2 {
31 tracing::warn!(
32 "Got a weird header: {:?}, split in {:?}",
33 header,
34 parts
35 );
36 continue;
37 }
38
39 if parts[0].trim().eq_ignore_ascii_case("X-Signal-Key")
40 && parts[1].trim().eq_ignore_ascii_case("false")
41 {
42 return false;
43 }
44 }
45
46 true
47 }
48}
49
50impl WebSocketResponseMessage {
51 pub fn from_request(msg: &WebSocketRequestMessage) -> Self {
54 if msg.is_signal_service_envelope() || msg.is_queue_empty() {
55 WebSocketResponseMessage {
56 id: msg.id,
57 status: Some(200),
58 message: Some("OK".to_string()),
59 ..Default::default()
60 }
61 } else {
62 WebSocketResponseMessage {
63 id: msg.id,
64 status: Some(400),
65 message: Some("Unknown".to_string()),
66 ..Default::default()
67 }
68 }
69 }
70
71 pub fn status_code(&self) -> Option<reqwest::StatusCode> {
72 StatusCode::from_u16(self.status().try_into().ok()?).ok()
73 }
74}
75
76impl SyncMessage {
77 pub fn with_padding<R: Rng + CryptoRng>(csprng: &mut R) -> Self {
78 let random_size = csprng.random_range(1..=512);
79 let mut padding: Vec<u8> = vec![0; random_size];
80 csprng.fill_bytes(&mut padding);
81
82 Self {
83 padding: Some(padding),
84 ..Default::default()
85 }
86 }
87}