瀏覽代碼

Low-level protocol tests.

Mathias Gottschlag 5 年之前
父節點
當前提交
1582be81c0
共有 5 個文件被更改,包括 151 次插入8 次删除
  1. 37
    0
      Cargo.lock
  2. 1
    0
      Cargo.toml
  3. 82
    0
      src/bin/protocol-tests.rs
  4. 1
    0
      src/lib.rs
  5. 30
    8
      src/protocol.rs

+ 37
- 0
Cargo.lock 查看文件

@@ -53,6 +53,11 @@ name = "autocfg"
53 53
 version = "0.1.7"
54 54
 source = "registry+https://github.com/rust-lang/crates.io-index"
55 55
 
56
+[[package]]
57
+name = "autocfg"
58
+version = "1.0.0"
59
+source = "registry+https://github.com/rust-lang/crates.io-index"
60
+
56 61
 [[package]]
57 62
 name = "base64"
58 63
 version = "0.11.0"
@@ -520,6 +525,14 @@ dependencies = [
520 525
  "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
521 526
 ]
522 527
 
528
+[[package]]
529
+name = "num-traits"
530
+version = "0.2.11"
531
+source = "registry+https://github.com/rust-lang/crates.io-index"
532
+dependencies = [
533
+ "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
534
+]
535
+
523 536
 [[package]]
524 537
 name = "num_cpus"
525 538
 version = "1.12.0"
@@ -700,6 +713,25 @@ name = "regex-syntax"
700 713
 version = "0.6.14"
701 714
 source = "registry+https://github.com/rust-lang/crates.io-index"
702 715
 
716
+[[package]]
717
+name = "rmp"
718
+version = "0.8.9"
719
+source = "registry+https://github.com/rust-lang/crates.io-index"
720
+dependencies = [
721
+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
722
+ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
723
+]
724
+
725
+[[package]]
726
+name = "rmp-serde"
727
+version = "0.14.3"
728
+source = "registry+https://github.com/rust-lang/crates.io-index"
729
+dependencies = [
730
+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
731
+ "rmp 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
732
+ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
733
+]
734
+
703 735
 [[package]]
704 736
 name = "rust-argon2"
705 737
 version = "0.7.0"
@@ -906,6 +938,7 @@ dependencies = [
906 938
  "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
907 939
  "futures-tokio-compat 0.1.0 (git+https://github.com/mgottschlag/futures-tokio-compat.git)",
908 940
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
941
+ "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
909 942
  "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
910 943
  "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
911 944
  "structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1027,6 +1060,7 @@ dependencies = [
1027 1060
 "checksum async-tungstenite 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37250bc739b253cf2d861047a7bcaad1d46d1d027070b44dbeab9168b40cf407"
1028 1061
 "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
1029 1062
 "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
1063
+"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
1030 1064
 "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
1031 1065
 "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
1032 1066
 "checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
@@ -1083,6 +1117,7 @@ dependencies = [
1083 1117
 "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
1084 1118
 "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
1085 1119
 "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
1120
+"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
1086 1121
 "checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
1087 1122
 "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
1088 1123
 "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
@@ -1106,6 +1141,8 @@ dependencies = [
1106 1141
 "checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
1107 1142
 "checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8"
1108 1143
 "checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06"
1144
+"checksum rmp 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "0f10b46df14cf1ee1ac7baa4d2fbc2c52c0622a4b82fa8740e37bc452ac0184f"
1145
+"checksum rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4c1ee98f14fe8b8e9c5ea13d25da7b2a1796169202c57a09d7288de90d56222b"
1109 1146
 "checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
1110 1147
 "checksum rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6"
1111 1148
 "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"

+ 1
- 0
Cargo.toml 查看文件

@@ -16,4 +16,5 @@ futures-tokio-compat = { git = "https://github.com/mgottschlag/futures-tokio-com
16 16
 async-tungstenite = { version = "0.3", features = ["tokio-runtime"] }
17 17
 env_logger = "0.7"
18 18
 log = "0.4"
19
+rmp-serde = "0.14"
19 20
 fswatcher = { git = "https://github.com/mgottschlag/fswatcher-rs.git" }

+ 82
- 0
src/bin/protocol-tests.rs 查看文件

@@ -0,0 +1,82 @@
1
+extern crate rmp_serde as rmps;
2
+extern crate serde;
3
+
4
+use rmps::Serializer;
5
+use serde::Serialize;
6
+use twfss::protocol;
7
+
8
+fn print_serialized_deserialized(packet: protocol::Packet) {
9
+    let mut buf = Vec::new();
10
+    packet
11
+        .serialize(
12
+            &mut Serializer::new(&mut buf)
13
+                .with_struct_map()
14
+                .with_string_variants(),
15
+        )
16
+        .unwrap();
17
+    println!("Serialized: {:?}", buf);
18
+    let packet: protocol::Packet = rmps::decode::from_slice(&buf).unwrap();
19
+    println!("Deserialized: {:?}\n", packet);
20
+}
21
+
22
+fn main() {
23
+    // Open questions:
24
+    // - Do we actually need the "response" field? Actually, separating the ID range so that
25
+    //   server->client events get IDs from the range between 2^31 and above would be enough.
26
+
27
+    // The low-level protocol needs to implement two basic pieces of functionality: It needs to be
28
+    // able to implement remote procedure calls from the client to the server, and it needs to
29
+    // provide a method for the server to send asynchronous events. A protocol for both cases is
30
+    // outlined below, where each packet is sent as one WebSocket message.
31
+    //
32
+    // Remote procedure call:
33
+    // - The client allocates an ID from the range between 0..2^31-1 that is not currently in use
34
+    //   for another RPC in progress.
35
+    // - The client prepares a packet with this ID, "response = false", and the appropriate
36
+    //   payload and sends the packet to the server.
37
+    // - The server receives the packet, processes the request and sends a packet back with the
38
+    //   identical ID and "response = true".
39
+    // - In case of an error, the payload has the type "Error" which in turn contains the error
40
+    //   type.
41
+    // - Unpon reception of the response, the client is free to reuse the ID for further RPCs.
42
+    // Note that this protocol does not allow the client to cancel an RPC that is currently in
43
+    // progress - implementing such functionality is difficult, error-prone, and most likely not
44
+    // worth the effort.
45
+    //
46
+    // Server-side event:
47
+    // - The server creates a packet with the ID 2^31 and the event content and sends it to the
48
+    //   client.
49
+    // Note that the client does not have any method to acknowledge event reception. As events are
50
+    // asynchronous compared to RPCs on the same connection, the event type needs to be designed in
51
+    // a way that no such temporal information is necessary to process the events.
52
+    // TODO: Example to demonstrate the problem.
53
+
54
+    println!("Without request content:");
55
+    let packet = protocol::Packet {
56
+        id: 42,
57
+        response: false,
58
+        payload: protocol::PacketPayload::ServerInfo,
59
+    };
60
+    print_serialized_deserialized(packet);
61
+    // Should be: [131, 162, 105, 100, 42, 168, 114, 101, 115, 112, 111, 110, 115, 101, 194, 167, 112, 97, 121, 108, 111, 97, 100, 129, 170, 83, 101, 114, 118, 101, 114, 73, 110, 102, 111, 192]
62
+
63
+    println!("\nWith request content:");
64
+    let packet = protocol::Packet {
65
+        id: 42,
66
+        response: true,
67
+        payload: protocol::PacketPayload::ServerInfoResponse(protocol::ServerInfoResponse {
68
+            version: "0.1".to_owned(),
69
+        }),
70
+    };
71
+    print_serialized_deserialized(packet);
72
+    // Should be: [131, 162, 105, 100, 42, 168, 114, 101, 115, 112, 111, 110, 115, 101, 194, 167, 112, 97, 121, 108, 111, 97, 100, 129, 178, 83, 101, 114, 118, 101, 114, 73, 110, 102, 111, 82, 101, 115, 112, 111, 110, 115, 101, 129, 167, 118, 101, 114, 115, 105, 111, 110, 163, 48, 46, 49]
73
+
74
+    println!("Error:");
75
+    let packet = protocol::Packet {
76
+        id: 42,
77
+        response: true,
78
+        payload: protocol::PacketPayload::Error(protocol::Error::InvalidParameter),
79
+    };
80
+    print_serialized_deserialized(packet);
81
+    // Should be: [131, 162, 105, 100, 42, 168, 114, 101, 115, 112, 111, 110, 115, 101, 195, 167, 112, 97, 121, 108, 111, 97, 100, 129, 165, 69, 114, 114, 111, 114, 129, 176, 73, 110, 118, 97, 108, 105, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 192]
82
+}

+ 1
- 0
src/lib.rs 查看文件

@@ -4,6 +4,7 @@ mod database;
4 4
 mod file_system_watcher;
5 5
 mod file_tree;
6 6
 pub mod network;
7
+pub mod protocol;
7 8
 
8 9
 pub use database::Database;
9 10
 pub use file_system_watcher::FileSystemWatcher;

+ 30
- 8
src/protocol.rs 查看文件

@@ -1,3 +1,5 @@
1
+use serde::{Deserialize, Serialize};
2
+
1 3
 /*pub trait Protocol {
2 4
     fn login_password(&mut self, user: &str, password: &str) -> Result<String, Error>;
3 5
     fn login_app_key(&mut self, user: &str, key: &str) -> Result<(), Error>;
@@ -11,7 +13,7 @@
11 13
     // TODO
12 14
 }*/
13 15
 
14
-pub struct DirectoryListing {
16
+/*pub struct DirectoryListing {
15 17
     own_version: u64,
16 18
     entries: Vec<FileMetadata>,
17 19
     // TODO
@@ -28,18 +30,20 @@ pub enum DirectoryEntryType {
28 30
     Directory,
29 31
     File,
30 32
     SymbolicLink,
31
-}
33
+}*/
32 34
 
35
+#[derive(Debug, Deserialize, Serialize)]
33 36
 pub struct Packet {
34
-    pub serial_number: u32,
35
-    pub type_: PacketContent,
37
+    pub id: u32,
38
+    pub response: bool,
39
+    pub payload: PacketPayload,
36 40
 }
37 41
 
38
-pub enum PacketContent {
39
-    Keepalive,
42
+#[derive(Debug, Deserialize, Serialize)]
43
+pub enum PacketPayload {
40 44
     Error(Error),
41 45
     ServerInfo,
42
-    ServerInfoResponse(ServerInfoResponse,
46
+    ServerInfoResponse(ServerInfoResponse),
43 47
     PasswordLogin(PasswordLogin),
44 48
     PasswordLoginResponse(PasswordLoginResponse),
45 49
     AppKeyLogin(AppKeyLogin),
@@ -59,65 +63,83 @@ pub enum PacketContent {
59 63
     FinishFileUpdate,
60 64
 }
61 65
 
66
+#[derive(Debug, Deserialize, Serialize)]
62 67
 pub enum Error {
63
-    // TODO
68
+    InvalidParameter,
64 69
 }
65 70
 
71
+#[derive(Debug, Deserialize, Serialize)]
66 72
 pub struct ServerInfoResponse {
67 73
     // TODO: Version of the protocol, type of the server (encrypted/unencrypted).
74
+    pub version: String,
68 75
 }
69 76
 
77
+#[derive(Debug, Deserialize, Serialize)]
70 78
 pub struct PasswordLogin {
71 79
     // TODO
72 80
 }
73 81
 
82
+#[derive(Debug, Deserialize, Serialize)]
74 83
 pub struct PasswordLoginResponse {
75 84
     // TODO
76 85
 }
77 86
 
87
+#[derive(Debug, Deserialize, Serialize)]
78 88
 pub struct AppKeyLogin {
79 89
     // TODO
80 90
 }
91
+
92
+#[derive(Debug, Deserialize, Serialize)]
81 93
 pub struct AppKeyLoginResponse {
82 94
     // TODO
83 95
 }
84 96
 
97
+#[derive(Debug, Deserialize, Serialize)]
85 98
 pub struct RegisterInterest {
86 99
     // TODO
87 100
 }
88 101
 
102
+#[derive(Debug, Deserialize, Serialize)]
89 103
 pub struct RegisterInterestResponse {
90 104
     // TODO
91 105
 }
92 106
 
107
+#[derive(Debug, Deserialize, Serialize)]
93 108
 pub struct UnregisterInterest {
94 109
     // TODO
95 110
 }
96 111
 
112
+#[derive(Debug, Deserialize, Serialize)]
97 113
 pub struct UnregisterInterestResponse {
98 114
     // TODO
99 115
 }
100 116
 
117
+#[derive(Debug, Deserialize, Serialize)]
101 118
 pub struct ListDirectory {
102 119
     // TODO
103 120
 }
104 121
 
122
+#[derive(Debug, Deserialize, Serialize)]
105 123
 pub struct ListDirectoryResponse {
106 124
     // TODO
107 125
 }
108 126
 
127
+#[derive(Debug, Deserialize, Serialize)]
109 128
 pub struct GetFileMetadata {
110 129
     // TODO
111 130
 }
112 131
 
132
+#[derive(Debug, Deserialize, Serialize)]
113 133
 pub struct GetFileMetadataResponse {
114 134
     // TODO
115 135
 }
116 136
 
137
+#[derive(Debug, Deserialize, Serialize)]
117 138
 pub struct GetFileContent {
118 139
     // TODO
119 140
 }
120 141
 
142
+#[derive(Debug, Deserialize, Serialize)]
121 143
 pub struct GetFileContentResponse {
122 144
     // TODO
123 145
 }

Loading…
取消
儲存