Files
vdm/core/include/vdm/net/url.hpp
T
samiandClaude Sonnet 5 201ebc55d4 core: net/probe + Content-Disposition parser + URL splitter (stage 3)
net/content_disposition — total parser for the mojibake-prone header:
RFC 6266 filename (quoted/token), RFC 5987 filename* ext-values
(charset'lang'pct-encoded, incl. RFC 2231 continuations), legacy RFC 2047
encoded-words (=?UTF-8?B?..?= / ?Q?), and raw Latin-1 bytes; prefers
filename* over filename; strips path components AFTER decoding (a base64
payload can hold '/'). 22-case test table.

net/text_codec (internal) — percent-decode, UTF-8 validation, Latin-1->
UTF-8, base64, RFC 2047 — shared by the CD parser and the URL splitter.

net/url — a small total URL splitter (scheme/userinfo/host/port/path/
query/fragment, http(s) validity) and url_filename() for the last path
segment; used for the filename fallback.

net/probe — HEAD then a ranged GET bytes=0-0 that PROVES resumability
(206 + matching Content-Range + a validator), rather than trusting
Accept-Ranges which servers lie about; the ranged GET is also the HEAD-
refused (403/405/501) fallback. 401/407 -> success result with
requires_auth, not an error. Runs on its own pool (max_concurrent,
default 4) outside the segment budget per ADR 0011 §5. suggest_filename()
does the resolution order (explicit -> disposition -> URL -> download.bin)
with a light strip; rules/ (stage 9) owns the authoritative sanitize.

tools/fuzz — libFuzzer targets for the CD parser and the URL splitter,
compiling the parser sources directly so they're fully instrumented;
self-guards on VELOX_BUILD_FUZZ + Clang (the top-level CMake adds every
tools/* unconditionally). Seed corpora included.

Fixed on the way: a p -> Transfer -> State -> cbs -> p reference cycle in
Prober that leaked every probe (drop the stored Transfer; the worker
keeps State alive). Tests green under ASan/UBSan and TSan.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01HPPSGhiArbvQgwC2DNiURS
2026-09-09 23:53:55 +04:00

41 lines
1.4 KiB
C++

// vdm/net/url.hpp — a small, total URL splitter.
//
// Not a full RFC 3986 parser (libcurl does the real fetching); just enough to pull a
// filename out of a path and to sanity-check a scheme. Total on hostile input — it has a
// fuzz target (tools/fuzz) — never throws, never asserts.
//
// This header compiles standalone.
#ifndef VDM_NET_URL_HPP
#define VDM_NET_URL_HPP
#include <cstdint>
#include <optional>
#include <string>
#include <string_view>
namespace vdm::net {
struct SplitUrl {
std::string scheme; // lowercased, without "://"
std::string userinfo; // before '@', if any
std::string host; // lowercased; bracketed IPv6 keeps its brackets stripped
std::optional<std::uint16_t> port;
std::string path; // includes the leading '/', or empty
std::string query; // without the '?'
std::string fragment; // without the '#'
bool valid = false; // scheme + host present and scheme is http/https
[[nodiscard]] bool is_http() const noexcept { return scheme == "http" || scheme == "https"; }
};
[[nodiscard]] SplitUrl split_url(std::string_view url);
// The last non-empty path segment, percent-decoded, path components stripped. Empty when
// the path has no usable segment (ends in '/', is empty, or is only "/").
[[nodiscard]] std::string url_filename(std::string_view url);
} // namespace vdm::net
#endif // VDM_NET_URL_HPP