Skip to content

Commit 37e1f13

Browse files
committed
Update content-length in regeression_tests format subcommand
when UPDATE_CONTENT_LENGTH env var is set
1 parent 488370c commit 37e1f13

5 files changed

Lines changed: 61 additions & 1 deletion

File tree

test/common/modsecurity_test.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ void ModSecurityTest<T>::cmd_options(int argc, char **argv) {
151151
i++;
152152
m_format = true;
153153
}
154+
if (std::getenv("UPDATE_CONTENT_LENGTH")) {
155+
m_update_content_length = true;
156+
}
154157
if (std::getenv("AUTOMAKE_TESTS")) {
155158
m_automake_output = true;
156159
}

test/common/modsecurity_test.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ template <class T> class ModSecurityTest :
3636
m_automake_output(false),
3737
m_count_all(false),
3838
m_test_multithreaded(false),
39-
m_format{false} { }
39+
m_format{false},
40+
m_update_content_length{false} { }
4041

4142
std::string header();
4243
void cmd_options(int, char **);
@@ -52,6 +53,7 @@ template <class T> class ModSecurityTest :
5253
bool m_count_all;
5354
bool m_test_multithreaded;
5455
bool m_format;
56+
bool m_update_content_length;
5557
};
5658

5759
} // namespace modsecurity_test

test/regression/regression.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,9 @@ int main(int argc, char **argv)
450450
std::cerr << "cannot open " << name << " for writing." << std::endl;
451451
return 1;
452452
}
453+
if (test.m_update_content_length) {
454+
tests[0]->update_content_lengths();
455+
}
453456
ofs << tests[0]->toJSON();
454457
ofs.close();
455458
std::cout << "written formatted JSON to " << name << std::endl;

test/regression/regression_test.cc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <sstream>
2121
#include <unordered_map>
2222
#include <string>
23+
#include <algorithm>
2324

2425
#ifdef WITH_YAJL
2526
#include <yajl/yajl_gen.h>
@@ -225,6 +226,49 @@ RegressionTest *RegressionTest::from_yajl_node(const yajl_val &node) {
225226
return u;
226227
}
227228

229+
constexpr char ascii_tolower(char c) {
230+
return 'A' <= c && c <= 'Z' ? (c + ('a' - 'A')) : c;
231+
}
232+
233+
bool iequals_ascii(std::string_view a, std::string_view b) {
234+
return a.size() == b.size() &&
235+
std::equal(a.begin(), a.end(), b.begin(), b.end(),
236+
[](char x, char y) {
237+
return ascii_tolower(x) == ascii_tolower(y);
238+
});
239+
}
240+
241+
static bool has_chunked_header(const std::vector<std::pair<std::string, std::string>> &headers) {
242+
for (const auto &header : headers) {
243+
if (iequals_ascii(header.first, "Transfer-Encoding") && iequals_ascii(header.second, "chunked")) {
244+
return true;
245+
}
246+
}
247+
return false;
248+
}
249+
250+
static void update_content_length(std::vector<std::pair<std::string, std::string>> &headers, size_t length) {
251+
if (has_chunked_header(headers)) {
252+
return;
253+
}
254+
255+
bool has_content_length = false;
256+
for (auto &header : headers) {
257+
if (iequals_ascii(header.first, "Content-Length")) {
258+
header.second = std::to_string(length);
259+
has_content_length = true;
260+
}
261+
}
262+
if (!has_content_length) {
263+
headers.push_back(std::pair{"Content-Length", std::to_string(length)});
264+
}
265+
}
266+
267+
void RegressionTest::update_content_lengths() {
268+
update_content_length(request_headers, request_body.size());
269+
update_content_length(response_headers, response_body.size());
270+
}
271+
228272
RegressionTests *RegressionTests::from_yajl_node(const yajl_val &node) {
229273
RegressionTests *u = new RegressionTests();
230274
size_t num_tests = node->u.array.len;
@@ -235,6 +279,12 @@ RegressionTests *RegressionTests::from_yajl_node(const yajl_val &node) {
235279
return u;
236280
}
237281

282+
void RegressionTests::update_content_lengths() {
283+
for (auto & test : tests) {
284+
test.update_content_lengths();
285+
}
286+
}
287+
238288
#ifdef WITH_YAJL
239289

240290
static yajl_gen_status gen_string_view(yajl_gen g, std::string_view s) {

test/regression/regression_test.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,13 @@ class RegressionTest {
8383
std::vector<std::string> request_body_lines;
8484
std::vector<std::string> response_body_lines;
8585
std::vector<std::string> rules_lines;
86+
void update_content_lengths();
8687
};
8788

8889
class RegressionTests {
8990
public:
9091
static RegressionTests *from_yajl_node(const yajl_val &);
92+
void update_content_lengths();
9193
std::string toJSON();
9294

9395
std::string filename;

0 commit comments

Comments
 (0)