Skip to content

Commit c20b661

Browse files
committed
Trim doc comments to match the rest of httplib.h
The new code carried inline doc comments (15-line set_no_proxy block, 18-line set_proxy_from_env block, plus narrating comments inside parser bodies, plus section dividers in the test file) that were heavy compared to the rest of the codebase — neighboring setters like set_proxy / set_proxy_basic_auth carry no doc at all, the test file does not use sub-section dividers, and the README / cookbook already document the behavior in detail. Removed: - Public-API doc blocks on set_no_proxy and set_proxy_from_env. - Narrating comments inside parse_no_proxy_entry, normalize_target, apply_proxy_url, host_matches_no_proxy that were just describing the obvious code structure. - Multi-line BORDER-rationale meta comments. - In-test sub-section dividers ("// ---- Hostname suffix matching", etc.) and per-class doc comments on the test fixtures. - Test-side comments that paraphrased their own test name. - Redundant ordering comments inside setup_redirect_client. Kept: - Security WHY comments (CRLF rejection, dot-boundary suffix matching, httpoxy / CVE-2016-5385, GHSA-6hrp-7fq9-3qv2 analog, CVE-2026-21428). - Regression-target WHY comments (UB shift on prefix=0). - Non-obvious external knowledge (detail::split already trims). 635 unit tests still pass under both the regular and split builds.
1 parent 97b357f commit c20b661

2 files changed

Lines changed: 0 additions & 61 deletions

File tree

httplib.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2014,8 +2014,6 @@ inline ssize_t read_body_content(Stream *stream, BodyReader &br, char *buf,
20142014

20152015
class decompressor;
20162016

2017-
// NoProxyEntry / NormalizedTarget are referenced as ClientImpl member
2018-
// types, so they must be defined above the split.py BORDER.
20192017
enum class NoProxyKind {
20202018
Wildcard, // "*"
20212019
HostnameSuffix, // "example.com" or ".example.com"
@@ -2283,11 +2281,6 @@ class ClientImpl {
22832281
Response &res, bool &success, Error &error);
22842282

22852283
bool is_proxy_enabled_for_host(const std::string &host) const;
2286-
2287-
// Parses "http(s)://[user[:pass]@]host[:port][/...]" and, on success,
2288-
// applies the result to proxy_host_ / proxy_port_ / proxy_basic_auth_*.
2289-
// Rejects control characters, non-http(s) schemes, and ports outside
2290-
// [1, 65535]. Defaults port to 80 / 443 from the scheme.
22912284
bool apply_proxy_url(const std::string &url);
22922285

22932286
// All of:
@@ -2379,7 +2372,6 @@ class ClientImpl {
23792372

23802373
std::vector<detail::NoProxyEntry> no_proxy_entries_;
23812374

2382-
// Memoized normalize_target(host_); host_ is const, so this is invariant.
23832375
mutable detail::NormalizedTarget host_normalized_;
23842376
mutable bool host_normalized_valid_ = false;
23852377

@@ -10542,7 +10534,6 @@ make_host_and_port_string_always_port(const std::string &host, int port) {
1054210534
return prepare_host_string(host) + ":" + std::to_string(port);
1054310535
}
1054410536

10545-
// Implementation-only NO_PROXY helpers.
1054610537
bool parse_no_proxy_entry(const std::string &token, NoProxyEntry &out);
1054710538
std::vector<NoProxyEntry> parse_no_proxy_list(const std::string &value);
1054810539
NormalizedTarget normalize_target(const std::string &host);
@@ -10664,7 +10655,6 @@ inline NormalizedTarget normalize_target(const std::string &host) {
1066410655
NormalizedTarget t;
1066510656
std::string h = host;
1066610657

10667-
// Strip "[ipv6]" brackets if the host arrived in URL form.
1066810658
if (h.size() >= 2 && h.front() == '[' && h.back() == ']') {
1066910659
h = h.substr(1, h.size() - 2);
1067010660
}
@@ -13388,7 +13378,6 @@ inline void ClientImpl::setup_redirect_client(ClientType &client,
1338813378
// host would still go through the proxy (and carry Proxy-Authorization).
1338913379
client.no_proxy_entries_ = no_proxy_entries_;
1339013380

13391-
// Proxy host/port must be set BEFORE proxy auth.
1339213381
if (is_proxy_enabled_for_host(next_host)) {
1339313382
// First set proxy host and port
1339413383
client.set_proxy(proxy_host_, proxy_port_);
@@ -14985,7 +14974,6 @@ inline bool ClientImpl::apply_proxy_url(const std::string &url) {
1498514974
}
1498614975
if (host_port.empty()) { return false; }
1498714976

14988-
// host_port forms: "[ipv6]:port", "[ipv6]", "host:port", "host".
1498914977
std::string host;
1499014978
std::string port_str;
1499114979
if (host_port.front() == '[') {

test/test.cc

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18158,14 +18158,9 @@ TEST(RequestSmugglingTest, ContentLengthAndTransferEncodingRejected) {
1815818158
}
1815918159
}
1816018160

18161-
// =============================================================================
18162-
// NO_PROXY / set_proxy_from_env (#2446)
18163-
// =============================================================================
18164-
1816518161
namespace no_proxy_test {
1816618162

1816718163
#ifndef _WIN32
18168-
// RAII helper that saves, sets, and restores an environment variable.
1816918164
class ScopedEnv {
1817018165
public:
1817118166
ScopedEnv(const char *name, const char *value) : name_(name) {
@@ -18193,9 +18188,6 @@ class ScopedEnv {
1819318188
};
1819418189
#endif // !_WIN32
1819518190

18196-
// In-process proxy mock + direct target. Each request that arrives bumps
18197-
// the corresponding counter, so a test can assert "this request went via
18198-
// the proxy" or "this request bypassed the proxy".
1819918191
class ProxyAndTargetServers {
1820018192
public:
1820118193
ProxyAndTargetServers() {
@@ -18251,8 +18243,6 @@ class ProxyAndTargetServers {
1825118243
std::atomic<bool> last_had_proxy_authz_{false};
1825218244
};
1825318245

18254-
// Helper: build a client targeted at `host` with a hostname mapping to
18255-
// 127.0.0.1, the proxy pointed at the mock.
1825618246
inline std::unique_ptr<Client> make_client(const std::string &host,
1825718247
ProxyAndTargetServers &s) {
1825818248
auto cli = detail::make_unique<Client>(host, s.target_port());
@@ -18266,9 +18256,6 @@ inline std::unique_ptr<Client> make_client(const std::string &host,
1826618256
using no_proxy_test::make_client;
1826718257
using no_proxy_test::ProxyAndTargetServers;
1826818258

18269-
// ---- Hostname suffix matching: dot-boundary rule
18270-
// -----------------------------
18271-
1827218259
TEST(NoProxyTest, ExactHostnameBypasses) {
1827318260
ProxyAndTargetServers s;
1827418261
auto cli = make_client("example.com", s);
@@ -18350,9 +18337,6 @@ TEST(NoProxyTest, TrailingDotIsNormalized) {
1835018337
EXPECT_EQ(1, s.target_hits());
1835118338
}
1835218339

18353-
// ---- Wildcard
18354-
// ----------------------------------------------------------------
18355-
1835618340
TEST(NoProxyTest, WildcardBypassesEverything) {
1835718341
ProxyAndTargetServers s;
1835818342
auto cli = make_client("anything.invalid.test", s);
@@ -18364,9 +18348,6 @@ TEST(NoProxyTest, WildcardBypassesEverything) {
1836418348
EXPECT_EQ(1, s.target_hits());
1836518349
}
1836618350

18367-
// ---- IP normalization
18368-
// --------------------------------------------------------
18369-
1837018351
TEST(NoProxyTest, IPv4LiteralExactMatch) {
1837118352
ProxyAndTargetServers s;
1837218353
Client cli("127.0.0.1", s.target_port());
@@ -18380,9 +18361,6 @@ TEST(NoProxyTest, IPv4LiteralExactMatch) {
1838018361
}
1838118362

1838218363
TEST(NoProxyTest, IPv6LiteralExactMatchAcrossEquivalentForms) {
18383-
// Different string forms of the same IPv6 address ("::1" and the
18384-
// expanded "0:0:0:0:0:0:0:1") must match because both go through
18385-
// inet_pton during normalization.
1838618364
ProxyAndTargetServers s;
1838718365
Client cli("0:0:0:0:0:0:0:1", s.target_port());
1838818366
cli.set_hostname_addr_map({{"0:0:0:0:0:0:0:1", "127.0.0.1"}});
@@ -18411,9 +18389,6 @@ TEST(NoProxyTest, IPv4MappedIPv6IsNotCrossMatchedAgainstIPv4Entry) {
1841118389
EXPECT_EQ(0, s.target_hits());
1841218390
}
1841318391

18414-
// ---- CIDR matching
18415-
// -----------------------------------------------------------
18416-
1841718392
TEST(NoProxyTest, IPv4CidrMatch) {
1841818393
ProxyAndTargetServers s;
1841918394
Client cli("127.0.0.1", s.target_port());
@@ -18453,7 +18428,6 @@ TEST(NoProxyTest, IPv4CidrPrefixZeroMatchesAll) {
1845318428
}
1845418429

1845518430
TEST(NoProxyTest, IPv4CidrSingleHostNoSlash) {
18456-
// Bare IP without a /prefix is treated as /32 (single host).
1845718431
ProxyAndTargetServers s;
1845818432
Client cli("127.0.0.1", s.target_port());
1845918433
cli.set_proxy("127.0.0.1", s.proxy_port());
@@ -18466,8 +18440,6 @@ TEST(NoProxyTest, IPv4CidrSingleHostNoSlash) {
1846618440
}
1846718441

1846818442
TEST(NoProxyTest, MalformedCidrPrefixIsDropped) {
18469-
// /33 on IPv4 is invalid and must be silently dropped during parsing,
18470-
// leaving no NO_PROXY effect.
1847118443
ProxyAndTargetServers s;
1847218444
Client cli("127.0.0.1", s.target_port());
1847318445
cli.set_proxy("127.0.0.1", s.proxy_port());
@@ -18479,9 +18451,6 @@ TEST(NoProxyTest, MalformedCidrPrefixIsDropped) {
1847918451
EXPECT_EQ(0, s.target_hits());
1848018452
}
1848118453

18482-
// ---- Proxy-Authorization handling
18483-
// --------------------------------------------
18484-
1848518454
TEST(NoProxyTest, ProxyAuthorizationSuppressedWhenBypassed) {
1848618455
ProxyAndTargetServers s;
1848718456
auto cli = make_client("internal.corp", s);
@@ -18508,9 +18477,6 @@ TEST(NoProxyTest, ProxyAuthorizationSentWhenNotBypassed) {
1850818477
EXPECT_TRUE(s.last_had_proxy_authz());
1850918478
}
1851018479

18511-
// ---- Backward compatibility
18512-
// --------------------------------------------------
18513-
1851418480
TEST(NoProxyTest, EmptyNoProxyKeepsProxyOn) {
1851518481
ProxyAndTargetServers s;
1851618482
auto cli = make_client("anything.test", s);
@@ -18521,9 +18487,6 @@ TEST(NoProxyTest, EmptyNoProxyKeepsProxyOn) {
1852118487
EXPECT_EQ(0, s.target_hits());
1852218488
}
1852318489

18524-
// ---- Parsing edge cases
18525-
// ------------------------------------------------------
18526-
1852718490
TEST(NoProxyTest, PortSpecificEntryRejected) {
1852818491
ProxyAndTargetServers s;
1852918492
auto cli = make_client("example.com", s);
@@ -18546,9 +18509,6 @@ TEST(NoProxyTest, EmptyAndWhitespaceEntriesDropped) {
1854618509
EXPECT_EQ(0, s.target_hits());
1854718510
}
1854818511

18549-
// ---- Cross-origin redirect honors NO_PROXY
18550-
// -----------------------------------
18551-
1855218512
TEST(NoProxyTest, RedirectToBypassedHostStripsProxyAndProxyAuth) {
1855318513
// Analog of GHSA-6hrp-7fq9-3qv2: when a redirect targets a host in
1855418514
// NO_PROXY, the follow-up request must go direct and must NOT carry
@@ -18563,8 +18523,6 @@ TEST(NoProxyTest, RedirectToBypassedHostStripsProxyAndProxyAuth) {
1856318523
Server proxy_mock;
1856418524
Server target;
1856518525

18566-
// Proxy mock: redirect /redir to the target's loopback URL; everything
18567-
// else returns 200.
1856818526
int target_port = target.bind_to_any_port("127.0.0.1");
1856918527
int proxy_port = proxy_mock.bind_to_any_port("127.0.0.1");
1857018528

@@ -18597,9 +18555,6 @@ TEST(NoProxyTest, RedirectToBypassedHostStripsProxyAndProxyAuth) {
1859718555
proxy_mock.wait_until_ready();
1859818556
target.wait_until_ready();
1859918557

18600-
// Initial request goes to a host that is NOT in NO_PROXY → uses the
18601-
// proxy. The proxy issues a 302 to 127.0.0.1, which IS in NO_PROXY →
18602-
// the redirect leg must go direct.
1860318558
Client cli("public.example", target_port);
1860418559
cli.set_hostname_addr_map({{"public.example", "127.0.0.1"}});
1860518560
cli.set_proxy("127.0.0.1", proxy_port);
@@ -18618,10 +18573,6 @@ TEST(NoProxyTest, RedirectToBypassedHostStripsProxyAndProxyAuth) {
1861818573
// Proxy-Authorization; we only assert the bypassed leg does not.
1861918574
}
1862018575

18621-
// ---- set_proxy_from_env: httpoxy mitigation
18622-
// ---------------------------------- Skipped on Windows because setenv/unsetenv
18623-
// are POSIX-only.
18624-
1862518576
#ifndef _WIN32
1862618577

1862718578
TEST(NoProxyTest, SetProxyFromEnv_LowercaseHttpProxy_Applied) {

0 commit comments

Comments
 (0)