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 197 : Transformation(): source_(""), source_i1_(0), source_i2_(0),
58 197 : target_(""),
59 985 : 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, Eraser, Math, Random, RandomSet, Timestamp, Strftime, Recvseq, SVar, SGVar, Value, ServerEvent, InState, STxtFile, SBinFile, Command, Sendseq, Seq, ClientEvent, ResponseHeader, ResponseStatusCode };
63 11 : const char* SourceTypeAsText(const SourceType & type) const
64 : {
65 : static const char* text [] = { "RequestUri", "RequestUriPath", "RequestUriParam", "RequestBody", "ResponseBody", "RequestHeader", "Eraser", "Math", "Random", "RandomSet", "Timestamp", "Strftime", "Recvseq", "SVar", "SGVar", "Value", "ServerEvent", "InState", "STxtFile", "SBinFile", "Command", "Sendseq", "Seq", "ClientEvent", "ResponseHeader", "ResponseStatusCode" };
66 11 : return text [type];
67 : }
68 :
69 : // Target type
70 : // Note: some labels use '_t' suffix (e.g. ResponseHeader_t, RequestUri_t) to avoid name collision
71 : // with identically-named values in SourceType, since both enums share the same class scope.
72 : 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, 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 };
73 11 : const char* TargetTypeAsText(const TargetType & type) const
74 : {
75 : 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", "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" };
76 11 : return text [type];
77 : }
78 :
79 : // Filter type
80 : enum FilterType { RegexCapture = 0, RegexReplace, Append, Prepend, Sum, Multiply, ConditionVar, EqualTo, DifferentFrom, JsonConstraint, SchemaId };
81 4 : const char* FilterTypeAsText(const FilterType & type) const
82 : {
83 : static const char* text [] = { "RegexCapture", "RegexReplace", "Append", "Prepend", "Sum", "Multiply", "ConditionVar", "EqualTo", "DifferentFrom", "JsonConstraint", "SchemaId" };
84 4 : return text [type];
85 : }
86 :
87 : // setters:
88 :
89 : /**
90 : * Load transformation information
91 : *
92 : * @param j Json transformation object
93 : *
94 : * @return Operation success
95 : */
96 : bool load(const nlohmann::json &j);
97 :
98 :
99 : /**
100 : * Class string representation
101 : *
102 : * @return string representation
103 : */
104 : std::string asString() const;
105 :
106 :
107 : private:
108 :
109 : SourceType source_type_{};
110 : std::string source_{}; // RequestUriParam, RequestBody(empty: whole, path: node), ResponseBody(empty: whole, path: node),
111 : // RequestHeader, Math, Timestamp, Strftime, SVar, SGVar, Value, STxtFile(path), SBinFile (path), Command(expression)
112 : std::vector<std::string> source_tokenized_{}; // RandomSet, ServerEvent
113 : int source_i1_{}, source_i2_{}; // Random
114 :
115 : TargetType target_type_{};
116 : std::string target_{}; // ResponseBodyJson_String/Integer/Unsigned/Float/Boolean/Object/JsonString(empty: whole, path: node),
117 : // ResponseHeader, TVar, TGVar, OutState (foreign method part), TTxtFile(path), TBinFile (path), UDPSocket (path[.delayMs])
118 : std::vector<std::string> target_tokenized_{}; // ServerEventToPurge
119 : std::string target2_{}; // OutState (foreign uri part)
120 :
121 : bool has_filter_{};
122 : FilterType filter_type_{};
123 : std::string filter_{}; // RegexReplace(fmt), RegexCapture(literal, although not actually needed, but useful to access & print on traces), Append, Prepend, ConditionVar, EqualTo, DifferentFrom, SchemaId
124 : nlohmann::json filter_object_{}; // JsonConstraint
125 : std::regex filter_rgx_{}; // RegexCapture, RegexReplace
126 : int filter_number_type_{}; // Sum, Multiply (0: integer, 1: unsigned, 2: float)
127 : std::int64_t filter_i_{}; // Sum, Multiply
128 : std::uint64_t filter_u_{}; // Sum, Multiply
129 : double filter_f_{}; // Sum, Multiply
130 :
131 : /**
132 : * Builds a map of patterns (pattern, varname) where pattern is @{varname}
133 : *
134 : * @param str string to analyze
135 : * @param patterns map generated by reference
136 : */
137 : void collectVariablePatterns(const std::string &str, std::map<std::string, std::string> &patterns);
138 :
139 : std::map<std::string, std::string> source_patterns_;
140 : std::map<std::string, std::string> filter_patterns_;
141 : std::map<std::string, std::string> target_patterns_;
142 : std::map<std::string, std::string> target2_patterns_;
143 :
144 : public:
145 :
146 : // getters:
147 :
148 : /** Gets source type */
149 315 : SourceType getSourceType() const {
150 315 : return source_type_;
151 : }
152 : /** Gets source */
153 142 : const std::string &getSource() const {
154 142 : return source_;
155 : }
156 : /** Gets source tokenized */
157 29 : const std::vector<std::string> &getSourceTokenized() const {
158 29 : return source_tokenized_;
159 : }
160 : /** Gets source for random min */
161 6 : int getSourceI1() const {
162 6 : return source_i1_;
163 : }
164 : /** Gets source for random max */
165 3 : int getSourceI2() const {
166 3 : return source_i2_;
167 : }
168 :
169 : /** Gets target type */
170 1104 : TargetType getTargetType() const {
171 1104 : return target_type_;
172 : }
173 : /** Gets target */
174 156 : const std::string &getTarget() const {
175 156 : return target_;
176 : }
177 : /** Gets target tokenized */
178 6 : const std::vector<std::string> &getTargetTokenized() const {
179 6 : return target_tokenized_;
180 : }
181 : /** Gets target2 */
182 117 : const std::string &getTarget2() const {
183 117 : return target2_;
184 : }
185 :
186 : /** Gets filter existence */
187 157 : bool hasFilter() const {
188 157 : return has_filter_;
189 : }
190 : /** Gets filter type */
191 96 : FilterType getFilterType() const {
192 96 : return filter_type_;
193 : }
194 : /** Gets filter */
195 20 : const std::string &getFilter() const {
196 20 : return filter_;
197 : }
198 : /** Gets filter regex */
199 4 : const std::regex &getFilterRegex() const {
200 4 : return filter_rgx_;
201 : }
202 : /** Gets filter type for sum/multiply */
203 7 : int getFilterNumberType() const {
204 7 : return filter_number_type_;
205 : }
206 : /** Integer container for sum/multiply */
207 2 : std::int64_t getFilterI() const {
208 2 : return filter_i_;
209 : }
210 : /** Unsigned integer container for sum/multiply */
211 3 : std::uint64_t getFilterU() const {
212 3 : return filter_u_;
213 : }
214 : /** Float container for sum/multiply */
215 2 : double getFilterF() const {
216 2 : return filter_f_;
217 : }
218 : /** Obecjt container for json constraint */
219 3 : const nlohmann::json &getFilterObject() const {
220 3 : return filter_object_;
221 : }
222 :
223 : /** Source patterns */
224 156 : const std::map<std::string, std::string> &getSourcePatterns() const {
225 156 : return source_patterns_;
226 : }
227 : /** Filter patterns */
228 9 : const std::map<std::string, std::string> &getFilterPatterns() const {
229 9 : return filter_patterns_;
230 : }
231 : /** Target patterns */
232 164 : const std::map<std::string, std::string> &getTargetPatterns() const {
233 164 : return target_patterns_;
234 : }
235 : /** Target2 patterns */
236 1 : const std::map<std::string, std::string> &getTarget2Patterns() const {
237 1 : return target2_patterns_;
238 : }
239 : };
240 :
241 : }
242 : }
|