Line data Source code
1 : /*
2 : ___________________________________________
3 : | _ ___ _ |
4 : | | | |__ \ | | |
5 : | | |__ ) |__ _ __ _ ___ _ __ | |_ |
6 : | | '_ \ / // _` |/ _` |/ _ \ '_ \| __| | HTTP/2 AGENT FOR MOCK TESTING
7 : | | | | |/ /| (_| | (_| | __/ | | | |_ | Version 0.0.z
8 : | |_| |_|____\__,_|\__, |\___|_| |_|\__| | https://github.com/testillano/h2agent
9 : | __/ | |
10 : | |___/ |
11 : |___________________________________________|
12 :
13 : Licensed under the MIT License <http://opensource.org/licenses/MIT>.
14 : SPDX-License-Identifier: MIT
15 : Copyright (c) 2021 Eduardo Ramos
16 :
17 : Permission is hereby granted, free of charge, to any person obtaining a copy
18 : of this software and associated documentation files (the "Software"), to deal
19 : in the Software without restriction, including without limitation the rights
20 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21 : copies of the Software, and to permit persons to whom the Software is
22 : furnished to do so, subject to the following conditions:
23 :
24 : The above copyright notice and this permission notice shall be included in all
25 : copies or substantial portions of the Software.
26 :
27 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 : SOFTWARE.
34 : */
35 :
36 : #pragma once
37 :
38 :
39 : #include <string>
40 : #include <vector>
41 : #include <regex>
42 : #include <cstdint>
43 :
44 :
45 : #include <nlohmann/json.hpp>
46 :
47 :
48 : namespace h2agent
49 : {
50 : namespace model
51 : {
52 :
53 : class Transformation
54 : {
55 : public:
56 :
57 277 : Transformation(): source_(""), source_i1_(0), source_i2_(0),
58 277 : target_(""),
59 1385 : has_filter_(false), filter_(""), filter_number_type_(0), filter_i_(0), filter_u_(0), filter_f_(0) {;}
60 :
61 : // Source type
62 : enum SourceType { RequestUri = 0, RequestUriPath, RequestUriParam, RequestBody, ResponseBody, RequestHeader, RequestHeaders, Eraser, Math, Random, RandomSet, Timestamp, Strftime, Recvseq, SVar, SGVar, Value, ServerEvent, InState, STxtFile, SBinFile, Command, Sendseq, ClientEvent, ResponseHeader, ResponseHeaders, ResponseStatusCode };
63 12 : const char* SourceTypeAsText(const SourceType & type) const
64 : {
65 : static const char* text [] = { "RequestUri", "RequestUriPath", "RequestUriParam", "RequestBody", "ResponseBody", "RequestHeader", "RequestHeaders", "Eraser", "Math", "Random", "RandomSet", "Timestamp", "Strftime", "Recvseq", "SVar", "SGVar", "Value", "ServerEvent", "InState", "STxtFile", "SBinFile", "Command", "Sendseq", "ClientEvent", "ResponseHeader", "ResponseHeaders", "ResponseStatusCode" };
66 12 : return text [type];
67 : }
68 :
69 : // Target type
70 : // Note: some labels use '_t' suffix (e.g. ResponseHeader_t, RequestUri_t) or descriptive
71 : // suffixes (ServerEventToPurge, ClientEventToPurge) to avoid name collision with identically-named
72 : // values in SourceType, since both are unscoped enums sharing the same class scope.
73 : // The user-facing target name is just "serverEvent"/"clientEvent" (same as the source);
74 : // the "ToPurge" suffix only reflects that as a target (with eraser source) it deletes events.
75 : enum TargetType { ResponseBodyString = 0, ResponseBodyHexString, ResponseBodyJson_String, ResponseBodyJson_Integer, ResponseBodyJson_Unsigned, ResponseBodyJson_Float, ResponseBodyJson_Boolean, ResponseBodyJson_Object, ResponseBodyJson_JsonString, ResponseHeader_t, ResponseStatusCode_t, ResponseDelayMs, TVar, TGVar, TGVarJson_Object, TGVarJson_JsonString, OutState, TTxtFile, TBinFile, UDPSocket, ServerEventToPurge, Break, RequestBodyString, RequestBodyHexString, RequestBodyJson_String, RequestBodyJson_Integer, RequestBodyJson_Unsigned, RequestBodyJson_Float, RequestBodyJson_Boolean, RequestBodyJson_Object, RequestBodyJson_JsonString, RequestHeader_t, RequestDelayMs, RequestTimeoutMs, ClientEventToPurge, RequestUri_t, RequestMethod_t, ClientProvision_t };
76 12 : const char* TargetTypeAsText(const TargetType & type) const
77 : {
78 : static const char* text [] = { "ResponseBodyString", "ResponseBodyHexString", "ResponseBodyJson_String", "ResponseBodyJson_Integer", "ResponseBodyJson_Unsigned", "ResponseBodyJson_Float", "ResponseBodyJson_Boolean", "ResponseBodyJson_Object", "ResponseBodyJson_JsonString", "ResponseHeader", "ResponseStatusCode", "ResponseDelayMs", "TVar", "TGVar", "TGVarJson_Object", "TGVarJson_JsonString", "OutState", "TTxtFile", "TBinFile", "UDPSocket", "ServerEventToPurge", "Break", "RequestBodyString", "RequestBodyHexString", "RequestBodyJson_String", "RequestBodyJson_Integer", "RequestBodyJson_Unsigned", "RequestBodyJson_Float", "RequestBodyJson_Boolean", "RequestBodyJson_Object", "RequestBodyJson_JsonString", "RequestHeader", "RequestDelayMs", "RequestTimeoutMs", "ClientEventToPurge", "RequestUri", "RequestMethod", "ClientProvision" };
79 12 : return text [type];
80 : }
81 :
82 : // Filter type
83 : enum FilterType { RegexCapture = 0, RegexReplace, Append, Prepend, Sum, Multiply, ConditionVar, EqualTo, DifferentFrom, JsonConstraint, SchemaId, Split, BaseConvert, FStrptime, FStrftime, RegexKey, Size };
84 5 : const char* FilterTypeAsText(const FilterType & type) const
85 : {
86 : static const char* text [] = { "RegexCapture", "RegexReplace", "Append", "Prepend", "Sum", "Multiply", "ConditionVar", "EqualTo", "DifferentFrom", "JsonConstraint", "SchemaId", "Split", "BaseConvert", "Strptime", "Strftime", "RegexKey", "Size" };
87 5 : return text [type];
88 : }
89 :
90 : // setters:
91 :
92 : /**
93 : * Load transformation information
94 : *
95 : * @param j Json transformation object
96 : *
97 : * @return Operation success
98 : */
99 : bool load(const nlohmann::json &j);
100 :
101 :
102 : /**
103 : * Class string representation
104 : *
105 : * @return string representation
106 : */
107 : std::string asString() const;
108 :
109 :
110 : private:
111 :
112 : SourceType source_type_{};
113 : std::string source_{}; // RequestUriParam, RequestBody(empty: whole, path: node), ResponseBody(empty: whole, path: node),
114 : // RequestHeader, Math, Timestamp, Strftime, SVar, SGVar(key), Value, STxtFile(path), SBinFile (path), Command(expression)
115 : std::string source2_{}; // SGVar (optional json path)
116 : std::vector<std::string> source_tokenized_{}; // RandomSet, ServerEvent
117 : int source_i1_{}, source_i2_{}; // Random
118 :
119 : TargetType target_type_{};
120 : std::string target_{}; // ResponseBodyJson_String/Integer/Unsigned/Float/Boolean/Object/JsonString(empty: whole, path: node),
121 : // ResponseHeader, TVar, TGVar, OutState (foreign method part), TTxtFile(path), TBinFile (path), UDPSocket (path[.delayMs])
122 : std::vector<std::string> target_tokenized_{}; // ServerEventToPurge
123 : std::string target2_{}; // OutState (foreign uri part), TGVar (optional json path)
124 :
125 : bool has_filter_{};
126 : FilterType filter_type_{};
127 : std::string filter_{}; // RegexReplace(fmt), RegexCapture(literal, although not actually needed, but useful to access & print on traces), Append, Prepend, ConditionVar, EqualTo, DifferentFrom, SchemaId, Strptime(fmt), Strftime(fmt)
128 : nlohmann::json filter_object_{}; // JsonConstraint
129 : std::regex filter_rgx_{}; // RegexCapture, RegexReplace
130 : int filter_number_type_{}; // Sum, Multiply (0: integer, 1: unsigned, 2: float); Strptime, Strftime (0: s, 1: ms, 2: us, 3: ns)
131 : std::int64_t filter_i_{}; // Sum, Multiply
132 : std::uint64_t filter_u_{}; // Sum, Multiply
133 : double filter_f_{}; // Sum, Multiply
134 : std::string filter_filler_{}; // Split
135 :
136 : /**
137 : * Builds a map of patterns (pattern, varname) where pattern is @{varname}
138 : *
139 : * @param str string to analyze
140 : * @param patterns map generated by reference
141 : */
142 : void collectVariablePatterns(const std::string &str, std::map<std::string, std::string> &patterns);
143 :
144 : std::map<std::string, std::string> source_patterns_;
145 : std::map<std::string, std::string> filter_patterns_;
146 : std::map<std::string, std::string> target_patterns_;
147 : std::map<std::string, std::string> target2_patterns_;
148 :
149 : std::vector<std::shared_ptr<Transformation>> on_filter_fail_;
150 :
151 : public:
152 :
153 : // getters:
154 :
155 : /** Gets source type */
156 460 : SourceType getSourceType() const {
157 460 : return source_type_;
158 : }
159 : /** Gets source */
160 218 : const std::string &getSource() const {
161 218 : return source_;
162 : }
163 : /** Gets source2 (SGVar json path) */
164 29 : const std::string &getSource2() const {
165 29 : return source2_;
166 : }
167 : /** Gets source tokenized */
168 35 : const std::vector<std::string> &getSourceTokenized() const {
169 35 : return source_tokenized_;
170 : }
171 : /** Gets source for random min */
172 6 : int getSourceI1() const {
173 6 : return source_i1_;
174 : }
175 : /** Gets source for random max */
176 3 : int getSourceI2() const {
177 3 : return source_i2_;
178 : }
179 :
180 : /** Gets target type */
181 1700 : TargetType getTargetType() const {
182 1700 : return target_type_;
183 : }
184 : /** Gets target */
185 221 : const std::string &getTarget() const {
186 221 : return target_;
187 : }
188 : /** Gets target tokenized */
189 8 : const std::vector<std::string> &getTargetTokenized() const {
190 8 : return target_tokenized_;
191 : }
192 : /** Gets target2 */
193 207 : const std::string &getTarget2() const {
194 207 : return target2_;
195 : }
196 :
197 : /** Gets filter existence */
198 233 : bool hasFilter() const {
199 233 : return has_filter_;
200 : }
201 : /** Gets filter type */
202 373 : FilterType getFilterType() const {
203 373 : return filter_type_;
204 : }
205 : /** Gets filter */
206 40 : const std::string &getFilter() const {
207 40 : return filter_;
208 : }
209 : /** Gets filter regex */
210 15 : const std::regex &getFilterRegex() const {
211 15 : return filter_rgx_;
212 : }
213 : /** Gets filter type for sum/multiply */
214 25 : int getFilterNumberType() const {
215 25 : return filter_number_type_;
216 : }
217 : /** Integer container for sum/multiply */
218 13 : std::int64_t getFilterI() const {
219 13 : return filter_i_;
220 : }
221 : /** Unsigned integer container for sum/multiply */
222 15 : std::uint64_t getFilterU() const {
223 15 : return filter_u_;
224 : }
225 : /** Float container for sum/multiply */
226 2 : double getFilterF() const {
227 2 : return filter_f_;
228 : }
229 : /** Obecjt container for json constraint */
230 3 : const nlohmann::json &getFilterObject() const {
231 3 : return filter_object_;
232 : }
233 : /** Filler string for Split */
234 5 : const std::string &getFilterFiller() const {
235 5 : return filter_filler_;
236 : }
237 : /** Gets onFilterFail transforms */
238 12 : const std::vector<std::shared_ptr<Transformation>> &getOnFilterFail() const {
239 12 : return on_filter_fail_;
240 : }
241 :
242 : /** Source patterns */
243 249 : const std::map<std::string, std::string> &getSourcePatterns() const {
244 249 : return source_patterns_;
245 : }
246 : /** Filter patterns */
247 12 : const std::map<std::string, std::string> &getFilterPatterns() const {
248 12 : return filter_patterns_;
249 : }
250 : /** Target patterns */
251 231 : const std::map<std::string, std::string> &getTargetPatterns() const {
252 231 : return target_patterns_;
253 : }
254 : /** Target2 patterns */
255 14 : const std::map<std::string, std::string> &getTarget2Patterns() const {
256 14 : return target2_patterns_;
257 : }
258 : };
259 :
260 : }
261 : }
|