Skip to content

Commit fa63d33

Browse files
committed
ci: drop <config.h> include + collapse radix descent duplicate
* test/unit/http_request_operator_stream_test.cpp: remove the `#include <config.h>` I added in 203780f. HAVE_BAUTH is forwarded into test compiles via -DHAVE_BAUTH on the libtool command line (the same mechanism every other HAVE_BAUTH-gated test uses); pulling in config.h directly re-defines DEBUG and conflicts with the -DDEBUG flag autotools sets on the debug + coverage / sanitiser lanes (DEBUG macro redefined -Werror). The `#ifdef HAVE_BAUTH` gate itself stays; only the redundant include goes. * src/httpserver/detail/radix_tree.hpp: hoist the has_terminus_at / remove descent loop into a single templated walk_registered_pattern_ helper. The two functions both walked the registered-pattern tree by exact-child-then-wildcard step and shared a 14-line / 101-token block (PMD CPD finding). The helper is templated on Node so the mutable / const variants share one descent body; CCN stays inside the gate and the duplicate is gone.
1 parent 203780f commit fa63d33

2 files changed

Lines changed: 44 additions & 40 deletions

File tree

src/httpserver/detail/radix_tree.hpp

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -271,20 +271,9 @@ class radix_tree {
271271
// prefix terminus is already registered at /admin (and vice versa)
272272
// — silent shadowing would corrupt the (method, path) cache key.
273273
bool has_terminus_at(const std::string& path, bool is_prefix) const {
274-
const radix_node<T>* node = root_.get();
275-
const auto segments = tokenize(path);
276-
for (const std::string& seg : segments) {
277-
auto it = node->children_.find(seg);
278-
if (it != node->children_.end()) {
279-
node = it->second.get();
280-
continue;
281-
}
282-
if (node->wildcard_child_ && is_wildcard_segment(seg)) {
283-
node = node->wildcard_child_.get();
284-
continue;
285-
}
286-
return false;
287-
}
274+
const radix_node<T>* node = walk_registered_pattern_(root_.get(),
275+
tokenize(path));
276+
if (node == nullptr) return false;
288277
return is_prefix ? node->prefix_terminus_.has_value()
289278
: node->exact_terminus_.has_value();
290279
}
@@ -295,23 +284,9 @@ class radix_tree {
295284
// segment value (e.g. "42"), remove() receives the registered pattern
296285
// (e.g. "{id}") and matches wildcard nodes by the placeholder shape.
297286
bool remove(const std::string& path, bool is_prefix) {
298-
radix_node<T>* node = root_.get();
299-
const auto segments = tokenize(path);
300-
for (const std::string& seg : segments) {
301-
auto it = node->children_.find(seg);
302-
if (it != node->children_.end()) {
303-
node = it->second.get();
304-
continue;
305-
}
306-
// Walk wildcard child if seg matches the {name} placeholder
307-
// shape. We compare the exact registered key, so removal of
308-
// /users/{id} requires the same {id} string.
309-
if (node->wildcard_child_ && is_wildcard_segment(seg)) {
310-
node = node->wildcard_child_.get();
311-
continue;
312-
}
313-
return false;
314-
}
287+
radix_node<T>* node = walk_registered_pattern_(root_.get(),
288+
tokenize(path));
289+
if (node == nullptr) return false;
315290
if (is_prefix) {
316291
if (!node->prefix_terminus_.has_value()) return false;
317292
node->prefix_terminus_.reset();
@@ -337,6 +312,34 @@ class radix_tree {
337312
return ::httpserver::http::http_utils::tokenize_url(path);
338313
}
339314

315+
// Descend from `start` along `segments`, matching exact children
316+
// first and falling back to a wildcard child when the segment has
317+
// the {name} placeholder shape. Returns the terminal node or
318+
// nullptr if any segment failed to match.
319+
//
320+
// Templated on Node (radix_node<T> or const radix_node<T>) so the
321+
// const-correct mutable / const variants share one descent body --
322+
// collapses the previous in-place duplicate descent loops in
323+
// has_terminus_at and remove (PMD CPD finding).
324+
template <class Node>
325+
static Node* walk_registered_pattern_(Node* start,
326+
const std::vector<std::string>& segments) {
327+
Node* node = start;
328+
for (const std::string& seg : segments) {
329+
auto it = node->children_.find(seg);
330+
if (it != node->children_.end()) {
331+
node = it->second.get();
332+
continue;
333+
}
334+
if (node->wildcard_child_ && is_wildcard_segment(seg)) {
335+
node = node->wildcard_child_.get();
336+
continue;
337+
}
338+
return nullptr;
339+
}
340+
return node;
341+
}
342+
340343
static bool is_wildcard_segment(const std::string& seg) noexcept {
341344
return seg.size() >= 2 && seg.front() == '{' && seg.back() == '}';
342345
}

test/unit/http_request_operator_stream_test.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@
2626
// through create_test_request::expose_credentials_in_logs() for unit
2727
// scope) restores the v1 verbose form for development.
2828

29-
// HAVE_BAUTH (config.h via HAVE_CONFIG_H) gates the username / password
30-
// surfaces that operator<< streams. On HAVE_BAUTH-off builds (Windows
31-
// MSYS2 lane, flag-invariance-off lane) get_user() / get_pass() return
32-
// empty string_views by contract, so the user:"admin" / pass:"hunter2"
33-
// expectations below do not hold; the BAUTH-off build path is covered
34-
// by webserver_dauth_unavailable / webserver_features tests instead.
35-
#if defined(HAVE_CONFIG_H)
36-
#include <config.h>
37-
#endif
29+
// HAVE_BAUTH gates the username / password surfaces that operator<<
30+
// streams. On HAVE_BAUTH-off builds (Windows MSYS2 lane, flag-invariance-
31+
// off lane) get_user() / get_pass() return empty string_views by
32+
// contract, so the user:"admin" / pass:"hunter2" expectations below do
33+
// not hold; the BAUTH-off build path is covered by
34+
// webserver_dauth_unavailable / webserver_features tests instead.
35+
// HAVE_BAUTH is forwarded into the test compile via -DHAVE_BAUTH on the
36+
// libtool command line; no explicit <config.h> include is needed (and
37+
// would clash with the -DDEBUG flag autotools sets on debug lanes,
38+
// since config.h re-defines DEBUG).
3839

3940
#include <sstream>
4041
#include <string>

0 commit comments

Comments
 (0)