Line data Source code
1 : #ifndef THINGER_HTTP_UTIL_URL_HPP
2 : #define THINGER_HTTP_UTIL_URL_HPP
3 :
4 : #include <algorithm>
5 : #include <cctype>
6 : #include <cstddef>
7 : #include <initializer_list>
8 : #include <memory>
9 : #include <string>
10 : #include <map>
11 : #include <string_view>
12 : #include <vector>
13 :
14 : namespace thinger::http::util::url{
15 :
16 : std::string uri_path_encode(const std::string &value);
17 :
18 : std::string url_encode(const std::string &value);
19 :
20 : bool url_decode(const std::string &in, std::string &out);
21 :
22 : std::string url_decode(const std::string &in);
23 :
24 : namespace detail {
25 : // Percent-decodes the path of a URI into `out`; false on an invalid escape. Unlike
26 : // url_decode(), "+" stays literal: it means a space only in query and form data
27 : // (application/x-www-form-urlencoded), not in a path (RFC 3986; Node's URL.pathname
28 : // and Go's URL.Path keep it too)
29 : bool path_decode(std::string_view in, std::string &out);
30 : }
31 :
32 : void parse_url_encoded_data(const std::string &in, std::multimap<std::string, std::string>& store);
33 :
34 : void parse_url_encoded_data(std::string::const_iterator& start, std::string::const_iterator& end, std::multimap<std::string, std::string>& store);
35 :
36 : std::string get_url_encoded_data(const std::multimap<std::string, std::string>& store);
37 :
38 : // The names of the query parameters whose values are hidden from a log line. A name is
39 : // compared whole, without case, with the percent-decoded name of a parameter; there are no
40 : // wildcards, and empty names are ignored. A set replaces the defaults: start from defaults()
41 : // to add or remove a name, and from {} to redact no parameter at all. Copies share the names,
42 : // so copying one costs a reference count
43 : class redacted_parameters {
44 : public:
45 15 : redacted_parameters() = default;
46 : redacted_parameters(std::initializer_list<std::string_view> names);
47 :
48 : // access_token, api_key, apikey, authorization, client_secret, code, id_token, key,
49 : // password, refresh_token, secret, sig, signature, token, x-amz-security-token,
50 : // x-amz-signature, x-goog-signature
51 : static const redacted_parameters& defaults();
52 :
53 : redacted_parameters& add(std::string_view name);
54 : redacted_parameters& remove(std::string_view name);
55 :
56 : bool contains(std::string_view name) const;
57 30 : size_t size() const { return names_ ? names_->size() : 0; }
58 :
59 : private:
60 : std::shared_ptr<const std::vector<std::string>> names_;
61 : };
62 :
63 : // `uri` (a request target or a URL) for a log line: the values of the query parameters in
64 : // `names` and the password of the user info, always, are replaced by "[redacted]"; the rest
65 : // is kept as is
66 : std::string loggable_uri(std::string_view uri, const redacted_parameters& names);
67 :
68 : // loggable_uri() with redacted_parameters::defaults()
69 : std::string loggable_uri(std::string_view uri);
70 :
71 : }
72 :
73 : #endif
|