net_file/jsons/
json_parser.rs1use std::str::from_utf8;
2
3use chrono::{DateTime, Utc, NaiveDateTime};
4use jsonpath_rust::JsonPathFinder;
5use serde_json::Value;
6use unescape::unescape;
7
8pub struct JsonParser;
9
10impl JsonParser {
11 pub fn find(json_binary: &[u8], path: &str) -> Value {
12 let json = from_utf8(json_binary).unwrap();
13 let finder = JsonPathFinder::from_str(json, path).expect("path not found");
14
15 finder.find()
16 }
17 pub fn first(value: &Value) -> Option<&Value> {
18 let value_json = value.as_array().unwrap();
19 if value_json.len() > 1 {
20 panic!("currently supported only one packet in the file: CU-861mdc6t7")
21 }
22
23 value_json.first()
24 }
25
26 pub fn print(json_path_value: &Value) -> String {
27 format!("{}", json_path_value)
28 }
29
30 pub fn pretty(json_path_value: &Value) -> String {
31 format!("{:#}", json_path_value)
32 }
33
34 pub fn get_vec(json_path_value: Value) -> Vec<u8> {
35 serde_json::to_vec(&json_path_value).unwrap()
36 }
37
38 pub fn get_string(mut json_path_value: Value) -> String {
39 let value = json_path_value.get_mut(0).take()
40 .expect("value not found");
41
42 unescape(value.as_str().unwrap()).unwrap()
43 }
44
45 pub fn get_utc_frame_time(json_path_value: Value) -> DateTime<Utc> {
46 const FORMAT_STR: &str = "%b %d, %Y %H:%M:%S.%f %Z";
47 let datetime_str = Self::get_string(json_path_value);
48 NaiveDateTime::parse_from_str(&datetime_str, FORMAT_STR).unwrap().and_utc()
49 }
50
51 pub fn get_utc_timestamp_millis(json_path_value: Value) -> i64 {
52 let path_value = JsonParser::get_string(json_path_value);
53 let timestamp: Vec<&str> = path_value
54 .split('.')
55 .collect();
56 let fraction = ×tamp.get(1).unwrap()[0..3];
57 format!("{}{}", ×tamp.first().unwrap(), fraction).parse::<i64>().unwrap()
58 }
59
60 pub fn get_utc_timestamp_nanos(json_path_value: Value) -> i64 {
61 let value_str: String = JsonParser::get_string(json_path_value).split('.').collect();
62
63 value_str.parse::<i64>().unwrap()
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use chrono::NaiveDateTime;
70
71 use crate::file::files::Files;
72 use crate::jsons::json_pcap_parser::PATH_FRAME_TIME_EPOCH;
73 use crate::test_resources;
74
75 use super::*;
76
77 #[test]
78 fn expected_extract_layer() {
79 let pcap_buffer = Files::read_vector(test_resources!("captures/arp.json"));
80 let json_buffer = Files::read_vector(test_resources!("captures/arp_layer_extracted.json"));
81
82 let result = JsonParser::find(&pcap_buffer, "$.._source.layers");
83 let json = JsonParser::print(&result);
84
85 assert_eq!(json, from_utf8(&json_buffer).unwrap());
86 }
87
88 #[test]
89 #[should_panic]
90 fn support_only_one_packet_in_file() {
91 let pcap_buffer = Files::read_vector(test_resources!("captures/dhcp.pcap"));
92
93 let value = JsonParser::find(&pcap_buffer, "$.._source.layers");
94 JsonParser::first(&value);
95 }
96
97 #[test]
98 fn expected_extract_layer_pretty() {
99 let pcap_buffer = Files::read_vector(test_resources!("captures/arp.json"));
100 let json_buffer = Files::read_vector(test_resources!("captures/arp_layer_extracted_pretty.json"));
101
102 let result = JsonParser::find(&pcap_buffer, "$.._source.layers");
103 let json = JsonParser::pretty(&result);
104
105 assert_eq!(json, from_utf8(&json_buffer).unwrap());
106 }
107
108 #[test]
109 fn expected_extract_frame_time() {
110 let pcap_buffer = Files::read_vector(test_resources!("captures/arp_layer_extracted_pretty.json"));
111
112 let result = JsonParser::find(&pcap_buffer, "$..frame['frame.time']");
113 let time = JsonParser::get_string(result);
114
115 assert_eq!(time, "Sep 18, 2013 04:49:07.000000000 UTC");
116 }
117
118 #[test]
119 fn expected_get_utc_timestamp_millis() {
120 const EXPECTED_TIME: i64 = 1379479747000;
121
122 let pcap_buffer = Files::read_vector(test_resources!("captures/arp_layer_extracted_pretty.json"));
123 let value = JsonParser::find(&pcap_buffer, PATH_FRAME_TIME_EPOCH);
124 let result = JsonParser::get_utc_timestamp_millis(value);
125
126 assert_eq!(result, EXPECTED_TIME)
127 }
128
129 #[test]
130 fn expected_get_utc_timestamp_nanos() {
131 const EXPECTED_TIME: i64 = 1379479747000000000;
132
133 let pcap_buffer = Files::read_vector(test_resources!("captures/arp_layer_extracted_pretty.json"));
134 let value = JsonParser::find(&pcap_buffer, PATH_FRAME_TIME_EPOCH);
135 let result = JsonParser::get_utc_timestamp_nanos(value);
136
137 assert_eq!(result, EXPECTED_TIME)
138 }
139
140 #[test]
141 fn expected_get_utc_timestamp_nanos_2() {
142 const EXPECTED_TIME: i64 = 1688714981480935000;
143
144 let pcap_buffer = Files::read_vector(test_resources!("captures/epoch_frame_time.json"));
145 let value = JsonParser::find(&pcap_buffer, PATH_FRAME_TIME_EPOCH);
146 let result = JsonParser::get_utc_timestamp_nanos(value);
147
148 assert_eq!(result, EXPECTED_TIME)
149 }
150
151 #[test]
152 #[should_panic]
153 fn panic_if_unknown_path() {
154 let pcap_buffer = Files::read_vector(test_resources!("captures/arp_layer_extracted_pretty.json"));
155
156 let unknown_path = "";
157 JsonParser::find(&pcap_buffer, unknown_path);
158 }
159
160 #[test]
161 #[should_panic]
162 fn panic_if_value_not_found() {
163 let pcap_buffer = Files::read_vector(test_resources!("captures/arp_layer_extracted_pretty.json"));
164
165 let unknown_path = "$..frame1";
166 let result = JsonParser::find(&pcap_buffer, unknown_path);
167 JsonParser::get_string(result);
168 }
169
170 #[test]
171 fn expected_extract_layer_and_return_vec() {
172 let pcap_buffer = Files::read_vector(test_resources!("captures/arp.json"));
173 let json_buffer = Files::read_vector(test_resources!("captures/arp_layer_extracted.json"));
174
175 let result = JsonParser::find(&pcap_buffer, "$.._source.layers");
176 let json = JsonParser::get_vec(result);
177
178 assert_eq!(json, json_buffer);
179 }
180
181 #[test]
182 fn expected_convert_frame_time_to_date_time() {
183 let time = NaiveDateTime::parse_from_str("Sat, 11 Feb 2023 23:40:00.000000000 UTC", "%a, %d %b %Y %H:%M:%S.%f %Z").unwrap().and_utc();
184 println!("{:?}", time);
185
186 let time = NaiveDateTime::parse_from_str("Sep 18, 2013 07:49:07.000000000 EEST", "%b %d, %Y %H:%M:%S.%f %Z").unwrap().and_utc();
187 println!("{:?}", time);
188
189 let time = NaiveDateTime::parse_from_str("Dec 5, 2004 21:16:24.317453000 EET", "%b %d, %Y %H:%M:%S.%f %Z").unwrap().and_utc();
190 println!("{:?}", time);
191
192 let pcap_buffer = Files::read_vector(test_resources!("captures/arp.json"));
193 let result = JsonParser::find(&pcap_buffer, "$..frame['frame.time']");
194 let time = JsonParser::get_utc_frame_time(result);
195 println!("{:?}", time);
196 assert_eq!(time.to_string(), "2013-09-18 04:49:07 UTC".to_string());
197 }
198}