vector/sources/util/http/
query.rs

1use std::collections::HashMap;
2
3use vector_lib::{
4    config::{LegacyKey, LogNamespace},
5    event::Event,
6    lookup::path,
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 vector_lib::config::LogNamespace;
68    use vrl::{path, value};
69
70    use crate::{
71        event::LogEvent,
72        sources::{http_server::HttpConfigParamKind, util::add_query_parameters},
73    };
74
75    #[test]
76    fn multiple_query_params() {
77        let query_params_names = [
78            HttpConfigParamKind::Exact("param1".into()),
79            HttpConfigParamKind::Exact("param2".into()),
80        ];
81        let query_params = [
82            ("param1".into(), "value1".into()),
83            ("param2".into(), "value2".into()),
84            ("param3".into(), "value3".into()),
85        ]
86        .into();
87
88        let mut base_log = [LogEvent::from(value!({})).into()];
89        add_query_parameters(
90            &mut base_log,
91            &query_params_names,
92            &query_params,
93            LogNamespace::Legacy,
94            "test",
95        );
96        let mut namespaced_log = [LogEvent::from(value!({})).into()];
97        add_query_parameters(
98            &mut namespaced_log,
99            &query_params_names,
100            &query_params,
101            LogNamespace::Vector,
102            "test",
103        );
104
105        assert_eq!(
106            base_log[0].as_log().value(),
107            namespaced_log[0]
108                .metadata()
109                .value()
110                .get(path!("test", "query_parameters"))
111                .unwrap()
112        );
113    }
114    #[test]
115    fn multiple_query_params_wildcard() {
116        let query_params_names = [HttpConfigParamKind::Glob(glob::Pattern::new("*").unwrap())];
117        let query_params = [
118            ("param1".into(), "value1".into()),
119            ("param2".into(), "value2".into()),
120            ("param3".into(), "value3".into()),
121        ]
122        .into();
123
124        let mut base_log = [LogEvent::from(value!({})).into()];
125        add_query_parameters(
126            &mut base_log,
127            &query_params_names,
128            &query_params,
129            LogNamespace::Legacy,
130            "test",
131        );
132        let mut namespaced_log = [LogEvent::from(value!({})).into()];
133        add_query_parameters(
134            &mut namespaced_log,
135            &query_params_names,
136            &query_params,
137            LogNamespace::Vector,
138            "test",
139        );
140
141        let log = base_log[0].as_log();
142        assert_eq!(
143            log.value(),
144            namespaced_log[0]
145                .metadata()
146                .value()
147                .get(path!("test", "query_parameters"))
148                .unwrap(),
149            "Checking legacy and namespaced log contain query parameters string"
150        );
151        assert_eq!(
152            log["param1"],
153            "value1".into(),
154            "Checking log contains first query parameter"
155        );
156        assert_eq!(
157            log["param2"],
158            "value2".into(),
159            "Checking log contains second query parameter"
160        );
161        assert_eq!(
162            log["param3"],
163            "value3".into(),
164            "Checking log contains third query parameter"
165        );
166    }
167}