Skip to content

Commit 0424bb5

Browse files
committed
feat(filters): introduce new html filters
1 parent 4e7c1d9 commit 0424bb5

13 files changed

Lines changed: 1187 additions & 142 deletions

File tree

src/action/mod.rs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub use crate::action::unit_trace::UnitTrace;
2525
#[cfg(feature = "router")]
2626
use crate::api::Rule;
2727
#[cfg(feature = "router")]
28-
use crate::api::{HTMLBodyFilter, TextBodyFilter};
28+
use crate::api::TextBodyFilter;
2929
#[cfg(feature = "router")]
3030
use crate::http::Request;
3131
#[cfg(feature = "router")]
@@ -219,22 +219,7 @@ impl Action {
219219
for filter in rule_body_filters {
220220
body_filters.push(BodyFilterAction {
221221
filter: match filter {
222-
BodyFilter::HTML(html_body_filter) => BodyFilter::HTML(HTMLBodyFilter {
223-
action: html_body_filter.action.clone(),
224-
css_selector: html_body_filter.css_selector.clone(),
225-
element_tree: html_body_filter.element_tree.clone(),
226-
value: StaticOrDynamic::replace(html_body_filter.value.clone(), &variables, false),
227-
inner_value: Some(StaticOrDynamic::replace(
228-
html_body_filter
229-
.inner_value
230-
.clone()
231-
.unwrap_or_else(|| html_body_filter.value.clone()),
232-
&variables,
233-
false,
234-
)),
235-
id: html_body_filter.id.clone(),
236-
target_hash: html_body_filter.target_hash.clone(),
237-
}),
222+
BodyFilter::HTML(html_body_filter) => BodyFilter::HTML(html_body_filter.clone_with_variables_replaced(&variables)),
238223
BodyFilter::Text(text_body_filter) => BodyFilter::Text(TextBodyFilter {
239224
action: text_body_filter.action.clone(),
240225
content: StaticOrDynamic::replace(text_body_filter.content.clone(), &variables, true),

src/api/body_filter.rs

Lines changed: 118 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use serde::{Deserialize, Serialize};
22

3+
use crate::{api::VariableValue, marker::StaticOrDynamic};
4+
35
#[derive(Serialize, Deserialize, Debug, Clone)]
4-
pub struct HTMLBodyFilter {
5-
pub action: String,
6+
pub struct HTMLBodyFilterInnerLegacy {
67
pub value: String,
78
pub inner_value: Option<String>,
89
pub element_tree: Vec<String>,
@@ -11,6 +12,121 @@ pub struct HTMLBodyFilter {
1112
pub target_hash: Option<String>,
1213
}
1314

15+
impl HTMLBodyFilterInnerLegacy {
16+
pub fn clone_with_variables_replaced(&self, variables: &[(String, VariableValue)]) -> HTMLBodyFilterInnerLegacy {
17+
HTMLBodyFilterInnerLegacy {
18+
css_selector: self.css_selector.clone(),
19+
element_tree: self.element_tree.clone(),
20+
value: StaticOrDynamic::replace(self.value.clone(), variables, false),
21+
inner_value: Some(StaticOrDynamic::replace(
22+
self.inner_value.clone().unwrap_or_else(|| self.value.clone()),
23+
variables,
24+
false,
25+
)),
26+
id: self.id.clone(),
27+
target_hash: self.target_hash.clone(),
28+
}
29+
}
30+
}
31+
32+
#[derive(Serialize, Deserialize, Debug, Clone)]
33+
pub struct HTMLBodyFilterInner {
34+
pub value: String,
35+
pub inner_value: Option<String>,
36+
pub css_selector: String,
37+
pub id: Option<String>,
38+
pub target_hash: Option<String>,
39+
}
40+
41+
impl HTMLBodyFilterInner {
42+
pub fn clone_with_variables_replaced(&self, variables: &[(String, VariableValue)]) -> HTMLBodyFilterInner {
43+
HTMLBodyFilterInner {
44+
css_selector: self.css_selector.clone(),
45+
value: StaticOrDynamic::replace(self.value.clone(), variables, false),
46+
inner_value: Some(StaticOrDynamic::replace(
47+
self.inner_value.clone().unwrap_or_else(|| self.value.clone()),
48+
variables,
49+
false,
50+
)),
51+
id: self.id.clone(),
52+
target_hash: self.target_hash.clone(),
53+
}
54+
}
55+
}
56+
57+
#[derive(Serialize, Deserialize, Debug, Clone)]
58+
pub struct HTMLBodyFilterAppend {
59+
pub value: String,
60+
pub inner_value: Option<String>,
61+
pub css_selector: String,
62+
pub ignore_css_selector: Option<String>,
63+
pub id: Option<String>,
64+
pub target_hash: Option<String>,
65+
}
66+
67+
impl HTMLBodyFilterAppend {
68+
pub fn clone_with_variables_replaced(&self, variables: &[(String, VariableValue)]) -> HTMLBodyFilterAppend {
69+
HTMLBodyFilterAppend {
70+
value: StaticOrDynamic::replace(self.value.clone(), variables, false),
71+
inner_value: Some(StaticOrDynamic::replace(
72+
self.inner_value.clone().unwrap_or_else(|| self.value.clone()),
73+
variables,
74+
false,
75+
)),
76+
css_selector: self.css_selector.clone(),
77+
ignore_css_selector: self.ignore_css_selector.clone(),
78+
id: self.id.clone(),
79+
target_hash: self.target_hash.clone(),
80+
}
81+
}
82+
}
83+
84+
#[derive(Serialize, Deserialize, Debug, Clone)]
85+
pub struct HTMLBodyFilterRemove {
86+
pub css_selector: String,
87+
pub id: Option<String>,
88+
pub target_hash: Option<String>,
89+
}
90+
91+
#[derive(Serialize, Deserialize, Debug, Clone)]
92+
#[serde(tag = "action")]
93+
pub enum HTMLBodyFilter {
94+
#[serde(rename = "append_html")]
95+
Append(HTMLBodyFilterAppend),
96+
#[serde(rename = "prepend_html")]
97+
Prepend(HTMLBodyFilterInner),
98+
#[serde(rename = "replace_html")]
99+
Replace(HTMLBodyFilterInner),
100+
#[serde(rename = "remove_html")]
101+
Remove(HTMLBodyFilterRemove),
102+
#[serde(rename = "after_html")]
103+
After(HTMLBodyFilterInner),
104+
#[serde(rename = "before_html")]
105+
Before(HTMLBodyFilterInner),
106+
#[serde(rename = "append_child")]
107+
AppendLegacy(HTMLBodyFilterInnerLegacy),
108+
#[serde(rename = "prepend_child")]
109+
PrependLegacy(HTMLBodyFilterInnerLegacy),
110+
#[serde(rename = "replace")]
111+
ReplaceLegacy(HTMLBodyFilterInnerLegacy),
112+
}
113+
114+
impl HTMLBodyFilter {
115+
pub fn clone_with_variables_replaced(&self, variables: &[(String, VariableValue)]) -> HTMLBodyFilter {
116+
match self {
117+
HTMLBodyFilter::AppendLegacy(inner) => HTMLBodyFilter::AppendLegacy(inner.clone_with_variables_replaced(variables)),
118+
HTMLBodyFilter::PrependLegacy(inner) => HTMLBodyFilter::PrependLegacy(inner.clone_with_variables_replaced(variables)),
119+
HTMLBodyFilter::ReplaceLegacy(inner) => HTMLBodyFilter::ReplaceLegacy(inner.clone_with_variables_replaced(variables)),
120+
HTMLBodyFilter::Append(inner) => HTMLBodyFilter::Append(inner.clone_with_variables_replaced(variables)),
121+
HTMLBodyFilter::Prepend(inner) => HTMLBodyFilter::Prepend(inner.clone_with_variables_replaced(variables)),
122+
HTMLBodyFilter::Replace(inner) => HTMLBodyFilter::Replace(inner.clone_with_variables_replaced(variables)),
123+
HTMLBodyFilter::Remove(inner) => HTMLBodyFilter::Remove(inner.clone()),
124+
HTMLBodyFilter::After(inner) => HTMLBodyFilter::After(inner.clone_with_variables_replaced(variables)),
125+
HTMLBodyFilter::Before(inner) => HTMLBodyFilter::Before(inner.clone_with_variables_replaced(variables)),
126+
}
127+
}
128+
}
129+
14130
#[derive(Serialize, Deserialize, Debug, Clone)]
15131
pub struct TextBodyFilter {
16132
pub action: TextAction,
@@ -27,8 +143,6 @@ pub enum TextAction {
27143
Prepend,
28144
#[serde(rename = "replace_text")]
29145
Replace,
30-
#[serde(untagged)]
31-
Other(serde_json::Value),
32146
}
33147

34148
#[derive(Serialize, Deserialize, Debug, Clone)]

src/api/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ mod transformer;
2727
mod unit_ids;
2828
mod variable;
2929

30-
pub use body_filter::{BodyFilter, HTMLBodyFilter, TextAction, TextBodyFilter};
30+
pub use body_filter::{BodyFilter, HTMLBodyFilter, HTMLBodyFilterInnerLegacy, TextAction, TextBodyFilter};
3131
pub use date_time::DateTimeConstraint;
3232
pub use examples::Example;
3333
#[cfg(feature = "router")]

src/build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ struct BodyFilter {
178178
element_tree: Option<Vec<String>>,
179179
#[serde(skip_serializing_if = "Option::is_none")]
180180
css_selector: Option<String>,
181+
#[serde(skip_serializing_if = "Option::is_none")]
182+
ignore_css_selector: Option<String>,
181183
}
182184

183185
#[derive(Serialize, Deserialize, Debug, Clone)]

src/filter/filter_body.rs

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,6 @@ impl FilterBodyActionItem {
215215
TextAction::Append => TextFilterAction::Append,
216216
TextAction::Prepend => TextFilterAction::Prepend,
217217
TextAction::Replace => TextFilterAction::Replace,
218-
_ => {
219-
log::warn!(
220-
"unsupported text body filter action: {:?}, you may need to update your agent or module",
221-
text_body_filter.action
222-
);
223-
return None;
224-
}
225218
},
226219
text_body_filter.content,
227220
))),
@@ -267,7 +260,7 @@ mod tests {
267260
};
268261

269262
use super::*;
270-
use crate::api::HTMLBodyFilter;
263+
use crate::api::{HTMLBodyFilter, HTMLBodyFilterInnerLegacy};
271264

272265
#[test]
273266
pub fn test_filter_gzip() {
@@ -288,15 +281,14 @@ mod tests {
288281
];
289282

290283
let mut filter = FilterBodyAction::new(
291-
vec![BodyFilter::HTML(HTMLBodyFilter {
292-
action: "prepend_child".to_string(),
284+
vec![BodyFilter::HTML(HTMLBodyFilter::PrependLegacy(HTMLBodyFilterInnerLegacy {
293285
element_tree: vec!["html".to_string(), "body".to_string()],
294286
css_selector: Some("".to_string()),
295287
value: "<p>This is as test</p>".to_string(),
296288
id: Some("test".to_string()),
297289
target_hash: Some("target_hash".to_string()),
298290
inner_value: None,
299-
})],
291+
}))],
300292
&headers,
301293
None,
302294
Vec::new(),
@@ -343,15 +335,14 @@ mod tests {
343335
];
344336

345337
let mut filter = FilterBodyAction::new(
346-
vec![BodyFilter::HTML(HTMLBodyFilter {
347-
action: "prepend_child".to_string(),
338+
vec![BodyFilter::HTML(HTMLBodyFilter::PrependLegacy(HTMLBodyFilterInnerLegacy {
348339
element_tree: vec!["html".to_string(), "body".to_string()],
349340
css_selector: Some("".to_string()),
350341
value: "<p>This is as test</p>".to_string(),
351342
id: Some("test".to_string()),
352343
target_hash: Some("target_hash".to_string()),
353344
inner_value: None,
354-
})],
345+
}))],
355346
&headers,
356347
None,
357348
Vec::new(),
@@ -398,15 +389,14 @@ mod tests {
398389
];
399390

400391
let mut filter = FilterBodyAction::new(
401-
vec![BodyFilter::HTML(HTMLBodyFilter {
402-
action: "prepend_child".to_string(),
392+
vec![BodyFilter::HTML(HTMLBodyFilter::PrependLegacy(HTMLBodyFilterInnerLegacy {
403393
element_tree: vec!["html".to_string(), "body".to_string()],
404394
css_selector: Some("".to_string()),
405395
value: "<p>This is as test</p>".to_string(),
406396
id: Some("test".to_string()),
407397
target_hash: Some("target_hash".to_string()),
408398
inner_value: None,
409-
})],
399+
}))],
410400
&headers,
411401
None,
412402
Vec::new(),
@@ -460,24 +450,22 @@ mod tests {
460450
pub fn test_replace() {
461451
let mut filter = FilterBodyAction::new(
462452
vec![
463-
BodyFilter::HTML(HTMLBodyFilter {
464-
action: "append_child".to_string(),
453+
BodyFilter::HTML(HTMLBodyFilter::AppendLegacy(HTMLBodyFilterInnerLegacy {
465454
element_tree: vec!["html".to_string(), "head".to_string()],
466455
css_selector: Some(r#"meta[name="description"]"#.to_string()),
467456
value: "<meta name=\"description\" content=\"New Description\" />".to_string(),
468457
id: Some("test".to_string()),
469458
target_hash: Some("target_hash".to_string()),
470459
inner_value: None,
471-
}),
472-
BodyFilter::HTML(HTMLBodyFilter {
473-
action: "replace".to_string(),
460+
})),
461+
BodyFilter::HTML(HTMLBodyFilter::ReplaceLegacy(HTMLBodyFilterInnerLegacy {
474462
element_tree: vec!["html".to_string(), "head".to_string(), "meta".to_string()],
475463
css_selector: Some(r#"meta[name="description"]"#.to_string()),
476464
value: "<meta name=\"description\" content=\"New Description\" />".to_string(),
477465
id: Some("test".to_string()),
478466
target_hash: Some("target_hash".to_string()),
479467
inner_value: None,
480-
}),
468+
})),
481469
],
482470
&[],
483471
None,
@@ -500,24 +488,22 @@ mod tests {
500488
pub fn test_append() {
501489
let mut filter = FilterBodyAction::new(
502490
vec![
503-
BodyFilter::HTML(HTMLBodyFilter {
504-
action: "append_child".to_string(),
491+
BodyFilter::HTML(HTMLBodyFilter::AppendLegacy(HTMLBodyFilterInnerLegacy {
505492
element_tree: vec!["html".to_string(), "head".to_string()],
506493
css_selector: Some(r#"meta[name="description"]"#.to_string()),
507494
value: "<meta name=\"description\" content=\"New Description\" />".to_string(),
508495
id: Some("test".to_string()),
509496
target_hash: Some("target_hash".to_string()),
510497
inner_value: None,
511-
}),
512-
BodyFilter::HTML(HTMLBodyFilter {
513-
action: "replace".to_string(),
498+
})),
499+
BodyFilter::HTML(HTMLBodyFilter::ReplaceLegacy(HTMLBodyFilterInnerLegacy {
514500
element_tree: vec!["html".to_string(), "head".to_string(), "meta".to_string()],
515501
css_selector: Some(r#"meta[name="description"]"#.to_string()),
516502
value: "<meta name=\"description\" content=\"New Description\" />".to_string(),
517503
id: Some("test".to_string()),
518504
target_hash: Some("target_hash".to_string()),
519505
inner_value: None,
520-
}),
506+
})),
521507
],
522508
&[],
523509
None,
@@ -536,15 +522,14 @@ mod tests {
536522
#[test]
537523
pub fn test_prepend() {
538524
let mut filter = FilterBodyAction::new(
539-
vec![BodyFilter::HTML(HTMLBodyFilter {
540-
action: "prepend_child".to_string(),
525+
vec![BodyFilter::HTML(HTMLBodyFilter::PrependLegacy(HTMLBodyFilterInnerLegacy {
541526
element_tree: vec!["html".to_string(), "body".to_string()],
542527
css_selector: Some("".to_string()),
543528
value: "<p>This is as test</p>".to_string(),
544529
id: Some("test".to_string()),
545530
target_hash: Some("target_hash".to_string()),
546531
inner_value: None,
547-
})],
532+
}))],
548533
&[],
549534
None,
550535
Vec::new(),
@@ -567,15 +552,14 @@ mod tests {
567552
#[test]
568553
pub fn test_description_2() {
569554
let mut filter = FilterBodyAction::new(
570-
vec![BodyFilter::HTML(HTMLBodyFilter {
571-
action: "replace".to_string(),
555+
vec![BodyFilter::HTML(HTMLBodyFilter::ReplaceLegacy(HTMLBodyFilterInnerLegacy {
572556
element_tree: vec!["html".to_string(), "head".to_string(), "meta".to_string()],
573557
css_selector: Some(r#"meta[property="og:description"]"#.to_string()),
574558
value: r#"<meta property="og:description" content="New Description" />"#.to_string(),
575559
id: Some("test".to_string()),
576560
target_hash: Some("target_hash".to_string()),
577561
inner_value: None,
578-
})],
562+
}))],
579563
&[],
580564
None,
581565
Vec::new(),
@@ -593,15 +577,14 @@ mod tests {
593577
#[test]
594578
pub fn test_capture_buffered() {
595579
let mut filter = FilterBodyAction::new(
596-
vec![BodyFilter::HTML(HTMLBodyFilter {
597-
action: "replace".to_string(),
580+
vec![BodyFilter::HTML(HTMLBodyFilter::ReplaceLegacy(HTMLBodyFilterInnerLegacy {
598581
element_tree: vec!["html".to_string(), "body".to_string(), "h2".to_string()],
599582
css_selector: None,
600583
value: r#"<h2>@var1</h2>"#.to_string(),
601584
id: Some("test".to_string()),
602585
target_hash: Some("target_hash".to_string()),
603586
inner_value: None,
604-
})],
587+
}))],
605588
&[],
606589
None,
607590
vec![(

0 commit comments

Comments
 (0)