1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use std::ffi::CString;
use std::os::raw::c_char;
use std::os::raw::c_int;
use std::sync::atomic::{AtomicI32, Ordering};
use std::sync::Arc;
use tide::{Middleware, Next, Request, Result};
#[derive(Debug, Clone)]
pub struct USDTMiddleware {
reqid: Arc<AtomicI32>,
}
impl USDTMiddleware {
pub fn new() -> Self {
Self {
reqid: Arc::new(<AtomicI32>::new(1)),
}
}
}
#[tide::utils::async_trait]
impl<State: Clone + Send + Sync + 'static> Middleware<State> for USDTMiddleware {
async fn handle(&self, req: Request<State>, next: Next<'_, State>) -> Result {
let count = self.reqid.fetch_add(1, Ordering::SeqCst);
let path = CString::new(req.url().path().to_owned()).expect("CString::new path failed");
let method =
CString::new(req.method().to_string()).expect("CString::new method failed");
let req_headers_coll = req
.iter()
.map(|h| format!("{:?};", h))
.collect::<Vec<String>>()
.join("; ");
let req_headers = CString::new(req_headers_coll).expect("CString::new header failed");
unsafe {
startroute(method.as_ptr(), path.as_ptr(), count, req_headers.as_ptr());
}
let res = next.run(req).await;
let status = res.status() as i32;
let res_headers_coll = res
.iter()
.map(|h| format!("{:?};", h))
.collect::<Vec<String>>()
.join("; ");
let res_headers = CString::new(res_headers_coll).expect("CString::new header failed");
unsafe {
endroute(
method.as_ptr(),
path.as_ptr(),
count,
status,
res_headers.as_ptr(),
);
}
self.reqid.load(Ordering::SeqCst);
Ok(res)
}
}
extern "C" {
fn startroute(method: *const c_char, path: *const c_char, reqid: c_int, headers: *const c_char);
fn endroute(
method: *const c_char,
path: *const c_char,
reqid: c_int,
status: c_int,
headers: *const c_char,
);
fn fire(tag: *const c_char, data: *const c_char);
}
pub fn probe(tag: String, data: String) {
let c_data = CString::new(data).expect("CString::new data failed");
let c_tag = CString::new(tag).expect("CString::new tag failed");
unsafe {
fire(c_tag.as_ptr(), c_data.as_ptr());
}
}