OpenVPN 3 Core Library
Loading...
Searching...
No Matches
urlencode.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12#ifndef OPENVPN_HTTP_URLENCODE_H
13#define OPENVPN_HTTP_URLENCODE_H
14
15#include <string>
16#include <vector>
17
24
25namespace openvpn::URL {
27
28inline std::string encode(const std::string &str)
29{
30 std::string ret;
31 ret.reserve(str.length() * 2); // just a guess
32 for (auto &c : str)
33 {
35 {
36 ret += '%';
37 ret += render_hex_number((unsigned char)c, true);
38 }
39 else
40 ret += c;
41 }
42 return ret;
43}
44
45inline std::string decode(const std::string &encoded)
46{
47 enum State
48 {
49 TEXT,
50 PERCENT,
51 DIGIT
52 };
53
54 int value = 0;
55 State state = TEXT;
56 std::string ret;
57 ret.reserve(encoded.size()); // just a guess
58
59 for (auto &c : encoded)
60 {
61 switch (state)
62 {
63 case TEXT:
64 {
65 if (c == '%')
66 state = PERCENT;
67 else
68 ret += c;
69 break;
70 }
71 case PERCENT:
72 {
73 const int v = parse_hex_char(c);
74 if (v < 0)
75 throw url_error(std::string("decode error after %: ") + encoded);
76 value = v;
77 state = DIGIT;
78 break;
79 }
80 case DIGIT:
81 {
82 const int v = parse_hex_char(c);
83 if (v < 0)
84 throw url_error(std::string("decode error after %: ") + encoded);
85 ret += static_cast<unsigned char>((value * 16) + v);
86 state = TEXT;
87 }
88 }
89 }
90 if (state != TEXT)
91 throw url_error(std::string("decode error: %-encoding item not closed out: ") + encoded);
93 throw url_error(std::string("not UTF-8: ") + encoded);
94 return ret;
95}
96
97inline std::vector<std::string> decode_path(std::string path)
98{
99 std::vector<std::string> list;
100 if (!path.empty() && path[0] == '/')
101 path = path.substr(1);
102 Split::by_char_void<decltype(list), NullLex, Split::NullLimit>(list, path, '/');
103 for (auto &i : list)
104 i = decode(i);
105 return list;
106}
107} // namespace openvpn::URL
108
109#endif
#define OPENVPN_EXCEPTION(C)
bool is_escaped(const unsigned char c)
Definition parseutil.hpp:74
std::string decode(const std::string &encoded)
Definition urlencode.hpp:45
std::string encode(const std::string &str)
Definition urlencode.hpp:28
std::vector< std::string > decode_path(std::string path)
Definition urlencode.hpp:97
bool is_valid_utf8(const STRING &str, const size_t max_len_flags=0)
Definition unicode.hpp:75
int parse_hex_char(const int c)
Definition hexstr.hpp:65
std::string render_hex_number(T value, const bool caps=false)
Definition hexstr.hpp:461
os<< "Session Name: "<< tbc-> session_name<< '\n';os<< "Layer: "<< tbc-> layer str()<< '\n'
std::string ret