Skip to content

Commit 3ab0963

Browse files
etrclaude
andcommitted
refactor: extract ip_representation from http_utils.hpp (505 → 478)
First step of the FILE_LOC_MAX ratchet. Splits ip_representation (struct + the five private parse helpers carved out during the CCN-10 sweep) into its own public sub-header httpserver/ip_representation.hpp. http_utils.hpp keeps a re-include of the new header so existing consumers of <httpserver/http_utils.hpp> still see the type without any code change; the umbrella picks up the new header explicitly too (every public sub-header is listed in <httpserver.hpp>). Detail headers and downstream tests are unaffected — webserver_impl.hpp still sees http::ip_representation through its existing http_utils.hpp include. FILE_LOC_MAX stays at 2700. The bar is pinned by the largest unfixed file (webserver.cpp at 2673), so the threshold can't drop until the top offender is decomposed. Each smaller-first step removes one file from the offender list without ticking the bar; the bar steps happen when the worst file shrinks. Offender list updated in scripts/check-file-size.sh: six files remain above the 500-line target. Verification: make check 51/51 PASS (includes header hygiene, install layout, doxygen, examples, readme, release-notes) ./scripts/check-file-size.sh PASS at FILE_LOC_MAX=2700 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0a1e42e commit 3ab0963

5 files changed

Lines changed: 103 additions & 38 deletions

File tree

scripts/check-file-size.sh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,19 @@
2929
# scripts/check-complexity.sh. New files must come in well below the
3030
# long-term target; lifting FILE_LOC_MAX is not allowed.
3131
#
32-
# Current offenders above the long-term 500-line target (2026-05-21):
32+
# Current offenders above the long-term 500-line target (2026-05-22):
3333
# src/webserver.cpp 2673
3434
# src/http_request.cpp 1175
3535
# src/httpserver/webserver.hpp 845
3636
# src/http_utils.cpp 730
3737
# src/httpserver/detail/webserver_impl.hpp 674
3838
# src/httpserver/http_request.hpp 656
39-
# src/httpserver/http_utils.hpp 505
39+
#
40+
# FILE_LOC_MAX is pinned by the largest unfixed file (webserver.cpp at
41+
# 2673), so it cannot drop until the top offender is decomposed. The
42+
# ratchet ticks once per shrink of the worst file, not once per fixed
43+
# offender — taking down a smaller file removes it from the list above
44+
# but leaves the threshold where it is.
4045
#
4146
# Exit codes:
4247
# 0 no violations

src/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ libhttpserver_la_SOURCES = string_utilities.cpp webserver.cpp http_utils.cpp fil
3030
# Detail headers (httpserver/detail/*.hpp) live here so they cannot leak to
3131
# downstream consumers — the public surface comes in through <httpserver.hpp>.
3232
noinst_HEADERS = httpserver/string_utilities.hpp httpserver/detail/modded_request.hpp httpserver/detail/http_endpoint.hpp httpserver/detail/body.hpp httpserver/detail/webserver_impl.hpp httpserver/detail/http_request_impl.hpp httpserver/detail/route_entry.hpp httpserver/detail/lambda_resource.hpp httpserver/detail/radix_tree.hpp httpserver/detail/route_cache.hpp gettext.h
33-
nobase_include_HEADERS = httpserver.hpp httpserver/body_kind.hpp httpserver/constants.hpp httpserver/create_webserver.hpp httpserver/create_test_request.hpp httpserver/webserver.hpp httpserver/websocket_handler.hpp httpserver/http_utils.hpp httpserver/file_info.hpp httpserver/http_request.hpp httpserver/http_response.hpp httpserver/http_resource.hpp httpserver/feature_unavailable.hpp httpserver/iovec_entry.hpp httpserver/http_arg_value.hpp httpserver/http_method.hpp httpserver/hook_phase.hpp httpserver/hook_action.hpp httpserver/hook_handle.hpp httpserver/hook_context.hpp
33+
nobase_include_HEADERS = httpserver.hpp httpserver/body_kind.hpp httpserver/constants.hpp httpserver/create_webserver.hpp httpserver/create_test_request.hpp httpserver/webserver.hpp httpserver/websocket_handler.hpp httpserver/http_utils.hpp httpserver/ip_representation.hpp httpserver/file_info.hpp httpserver/http_request.hpp httpserver/http_response.hpp httpserver/http_resource.hpp httpserver/feature_unavailable.hpp httpserver/iovec_entry.hpp httpserver/http_arg_value.hpp httpserver/http_method.hpp httpserver/hook_phase.hpp httpserver/hook_action.hpp httpserver/hook_handle.hpp httpserver/hook_context.hpp
3434

3535
AM_CXXFLAGS += -fPIC -Wall
3636

src/httpserver.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "httpserver/http_resource.hpp"
4141
#include "httpserver/http_response.hpp"
4242
#include "httpserver/http_utils.hpp"
43+
#include "httpserver/ip_representation.hpp"
4344
#include "httpserver/iovec_entry.hpp"
4445
#include "httpserver/file_info.hpp"
4546
#include "httpserver/webserver.hpp"

src/httpserver/http_utils.hpp

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -413,42 +413,15 @@ using arg_map = std::map<std::string, http_arg_value, http::arg_comparator>;
413413
using arg_view_map = std::map<std::string_view, http_arg_value, http::arg_comparator>;
414414

415415

416-
struct ip_representation {
417-
http_utils::IP_version_T ip_version;
418-
uint16_t pieces[16];
419-
uint16_t mask;
420-
421-
explicit ip_representation(http_utils::IP_version_T ip_version) :
422-
ip_version(ip_version) {
423-
mask = constants::DEFAULT_MASK_VALUE;
424-
std::fill(pieces, pieces + 16, 0);
425-
}
426-
427-
explicit ip_representation(const std::string& ip);
428-
explicit ip_representation(const struct sockaddr* ip);
429-
430-
bool operator<(const ip_representation& b) const;
431-
432-
int weight() const {
433-
// variable-precision SWAR algorithm
434-
uint16_t x = mask;
435-
x = x - ((x >> 1) & 0x55555555);
436-
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
437-
return (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
438-
}
416+
} // namespace http
417+
} // namespace httpserver
439418

440-
private:
441-
// Helpers carved out of the string-ctor to keep each function under
442-
// the project cyclomatic-complexity bar. parse_ipv6 / parse_ipv4
443-
// do the top-level dispatch; the rest serve parse_ipv6.
444-
void parse_ipv4(const std::string& ip);
445-
void parse_ipv6(const std::string& ip);
446-
static unsigned int compute_ipv6_omitted_segments(std::vector<std::string>& parts);
447-
void apply_ipv6_part(std::vector<std::string>& parts, unsigned int i,
448-
int& y, unsigned int omitted);
449-
void parse_nested_ipv4(const std::vector<std::string>& parts,
450-
unsigned int i, int y);
451-
};
419+
// ip_representation lives in its own header; included here so existing
420+
// consumers of <httpserver/http_utils.hpp> still see the type.
421+
#include "httpserver/ip_representation.hpp"
422+
423+
namespace httpserver {
424+
namespace http {
452425

453426
/**
454427
* Method used to get an ip in form of string from a sockaddr structure.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
This file is part of libhttpserver
3+
Copyright (C) 2011-2019 Sebastiano Merlino
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18+
USA
19+
*/
20+
21+
#if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION)
22+
#error "Only <httpserver.hpp> or <httpserverpp> can be included directly."
23+
#endif
24+
25+
#ifndef SRC_HTTPSERVER_IP_REPRESENTATION_HPP_
26+
#define SRC_HTTPSERVER_IP_REPRESENTATION_HPP_
27+
28+
#include <stdint.h>
29+
30+
#include <algorithm>
31+
#include <string>
32+
#include <vector>
33+
34+
#include "httpserver/constants.hpp"
35+
#include "httpserver/http_utils.hpp"
36+
37+
// Forward-declared at file scope; the parsing path in src/http_utils.cpp
38+
// pulls in <sys/socket.h> directly so the sockaddr ctor can read the
39+
// address family. Same rationale as http_utils.hpp: backend headers must
40+
// not leak through the umbrella to downstream consumers.
41+
struct sockaddr;
42+
43+
namespace httpserver {
44+
namespace http {
45+
46+
struct ip_representation {
47+
http_utils::IP_version_T ip_version;
48+
uint16_t pieces[16];
49+
uint16_t mask;
50+
51+
explicit ip_representation(http_utils::IP_version_T ip_version) :
52+
ip_version(ip_version) {
53+
mask = constants::DEFAULT_MASK_VALUE;
54+
std::fill(pieces, pieces + 16, 0);
55+
}
56+
57+
explicit ip_representation(const std::string& ip);
58+
explicit ip_representation(const struct sockaddr* ip);
59+
60+
bool operator<(const ip_representation& b) const;
61+
62+
int weight() const {
63+
// variable-precision SWAR algorithm
64+
uint16_t x = mask;
65+
x = x - ((x >> 1) & 0x55555555);
66+
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
67+
return (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
68+
}
69+
70+
private:
71+
// Helpers carved out of the string-ctor to keep each function under
72+
// the project cyclomatic-complexity bar. parse_ipv6 / parse_ipv4
73+
// do the top-level dispatch; the rest serve parse_ipv6.
74+
void parse_ipv4(const std::string& ip);
75+
void parse_ipv6(const std::string& ip);
76+
static unsigned int compute_ipv6_omitted_segments(std::vector<std::string>& parts);
77+
void apply_ipv6_part(std::vector<std::string>& parts, unsigned int i,
78+
int& y, unsigned int omitted);
79+
void parse_nested_ipv4(const std::vector<std::string>& parts,
80+
unsigned int i, int y);
81+
};
82+
83+
} // namespace http
84+
} // namespace httpserver
85+
86+
#endif // SRC_HTTPSERVER_IP_REPRESENTATION_HPP_

0 commit comments

Comments
 (0)