vector/sources/util/http/
query.rs

1use std::collections::HashMap;
2
3use vector_lib::lookup::path;
4use vector_lib::{
5    config::{LegacyKey, LogNamespace},
6    event::Event,
7};
8
9use crate::sources::http_server::HttpConfigParamKind;
10
11pub fn add_query_parameters(
12    events: &mut [Event],
13    query_parameters_config: &[HttpConfigParamKind],
14    query_parameters: &HashMap<String, String>,
15    log_namespace: LogNamespace,
16    source_name: &'static str,
17) {
18    for qp in query_parameters_config {
19        match qp {
20            // Add each non-wildcard containing query_parameter that was specified
21            // in the `query_parameters` config option to the event if an exact match
22            // is found.
23            HttpConfigParamKind::Exact(query_parameter_name) => {
24                let value = query_parameters.get(query_parameter_name);
25
26                for event in events.iter_mut() {
27                    if let Event::Log(log) = event {
28                        log_namespace.insert_source_metadata(
29                            source_name,
30                            log,
31                            Some(LegacyKey::Overwrite(path!(query_parameter_name))),
32                            path!("query_parameters", query_parameter_name),
33                            crate::event::Value::from(value.map(String::to_owned)),
34                        );
35                    }
36                }
37            }
38            // Add all query_parameters that match against wildcard pattens specified
39            // in the `query_parameters` config option to the event.
40            HttpConfigParamKind::Glob(query_parameter_pattern) => {
41                for query_parameter_name in query_parameters.keys() {
42                    if query_parameter_pattern
43                        .matches_with(query_parameter_name.as_str(), glob::MatchOptions::default())
44                    {
45                        let value = query_parameters.get(query_parameter_name);
46
47                        for event in events.iter_mut() {
48                            if let Event::Log(log) = event {
49                                log_namespace.insert_source_metadata(
50                                    source_name,
51                                    log,
52                                    Some(LegacyKey::Overwrite(path!(query_parameter_name))),
53                                    path!("query_parameters", query_parameter_name),
54                                    crate::event::Value::from(value.map(String::to_owned)),
55                                );
56                            }
57                        }
58                    }
59                }
60            }
61        };
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use crate::event::LogEvent;
68    use crate::sources::{http_server::HttpConfigParamKind, util::add_query_parameters};
69
70    use vector_lib::config::LogNamespace;
71    use vrl::{path, value};
72
73    #[test]
74    fn multiple_query_params() {
75        let query_params_names = [
76            HttpConfigParamKind::Exact("param1".into()),
77            HttpConfigParamKind::Exact("param2".into()),
78        ];
79        let query_params = [
80            ("param1".into(), "value1".into()),
81            ("param2".into(), "value2".into()),
82            ("param3".into(), "value3".into()),
83        ]
84        .into();
85
86        let mut base_log = [LogEvent::from(value!({})).into()];
87        add_query_parameters(
88            &mut base_log,
89            &query_params_names,
90            &query_params,
91            LogNamespace::Legacy,
92            "test",
93        );
94        let mut namespaced_log = [LogEvent::from(value!({})).into()];
95        add_query_parameters(
96            &mut namespaced_log,
97            &query_params_names,
98            &query_params,
99            LogNamespace::Vector,
100            "test",
101        );
102
103        assert_eq!(
104            base_log[0].as_log().value(),
105            namespaced_log[0]
106                .metadata()
107                .value()
108                .get(path!("test", "query_parameters"))
109                .unwrap()
110        );
111    }
112    #[test]
113    fn multiple_query_params_wildcard() {
114        let query_params_names = [HttpConfigParamKind::Glob(glob::Pattern::new("*").unwrap())];
115        let query_params = [
116            ("param1".into(), "value1".into()),
117            ("param2".into(), "value2".into()),
118            ("param3".into(), "value3".into()),
119        ]
120        .into();
121
122        let mut base_log = [LogEvent::from(value!({})).into()];
123        add_query_parameters(
124            &mut base_log,
125            &query_params_names,
126            &query_params,
127            LogNamespace::Legacy,
128            "test",
129        );
130        let mut namespaced_log = [LogEvent::from(value!({})).into()];
131        add_query_parameters(
132            &mut namespaced_log,
133            &query_params_names,
134            &query_params,
135            LogNamespace::Vector,
136            "test",
137        );
138
139        let log = base_log[0].as_log();
140        assert_eq!(
141            log.value(),
142            namespaced_log[0]
143                .metadata()
144                .value()
145                .get(path!("test", "query_parameters"))
146                .unwrap(),
147            "Checking legacy and namespaced log contain query parameters string"
148        );
149        assert_eq!(
150            log["param1"],
151            "value1".into(),
152            "Checking log contains first query parameter"
153        );
154        assert_eq!(
155            log["param2"],
156            "value2".into(),
157            "Checking log contains second query parameter"
158        );
159        assert_eq!(
160            log["param3"],
161            "value3".into(),
162            "Checking log contains third query parameter"
163        );
164    }
165}