Boost.URL

repository·develop·Indexed 41 days ago

https://github.com/boostorg/url

A portable C++ library for parsing, validating, examining, modifying, and normalizing URLs according to the RFC 3986 specification. It provides `url_view` for non-owning inspection and `url` for owning, mutable containers, focusing on high performance and low memory overhead. The library uses `char` for direct interoperability with `std::string` and `std::string_view`, and employs a dual error-handling approach using error codes via `result<>` and exceptions.

Tokens
19K
Snippets
61
Records
93
Agent score
52%

What's inside Boost.URL

  1. Overview of Boost.URL

    develop

    Boost.URL is a portable C++ library providing containers and algorithms to model Uniform Resource Identifiers (URIs) as defined in RFC 3986. It allows developers to validate, parse, examine, modify, normalize, and resolve URLs.

    Key characteristics include:

    • Strict Compliance: Follows RFC 3986 grammar.
    • Safety: All modifications ensure the URL remains in a valid state.
    • Efficiency: Designed for network programs, offering control over storage and allocation to minimize dynamic memory usage.
    • Robustness: Supports environments without exceptions (-fno-exceptions) and is suitable for embedded devices.
    • Compatibility: Requires C++11 or higher.
  2. What is a Character Set in Boost.URL grammar?

    develop

    A character set is a subset of low-ASCII characters used as a building block for constructing grammar rules. In the library, character sets are modeled as callable predicates (functors) that satisfy the CharSet concept. They must be invocable with the following signature:

    bool( char ch ) const noexcept;

    To ensure zero-cost abstraction, user-defined character sets should be constexpr constructible. You can verify if a type meets the requirements using the grammar::is_charset<T> type trait.

    struct ws_chars_t
    {
        constexpr bool operator()( char c ) const noexcept
        {
            return c == '\t' || c == ' ' || c == '\r' || c == '\n';
        }
    };
    
    // Verify the type meets CharSet requirements
    static_assert( grammar::is_charset< ws_chars_t >::value, "CharSet requirements not met" );
    
    // Use as a constexpr instance for zero-cost abstraction
    constexpr ws_chars_t ws_chars{};
  3. Error handling and exception safety

    develop

    Boost.URL uses a dual approach to error handling depending on the operation:

    1. Error Codes: For parsing and grammar validation, the library uses error codes reported through result<> instead of throwing exceptions. This allows the library to be used in environments where exceptions are disabled (-fno-exceptions).
    2. Exceptions: Certain modifying functions (e.g., setting a scheme or port to an invalid string) will throw exceptions.

    Safety Guarantees:

    • URL Validity Invariant: A url object is guaranteed to always hold syntactically legal text. Modifying functions perform validation to maintain this invariant.
    • Strong Exception Safety: All non-const operations offer the strong exception safety guarantee.
  4. Choose the right URL container

    develop

    Boost.URL provides three main container types for interacting with URLs, depending on your ownership and performance requirements:

    • url[]: A valid, modifiable URL that performs dynamic memory allocation to store the character buffer. Use this when you need to own and modify the URL.
    • url_view[]: A read-only reference to a character buffer containing a valid URL. It does not retain ownership; the caller must manage the underlying buffer. Use this for efficient, non-owning inspection.
    • static_url[]: A valid, modifiable URL that stores the character buffer inside the class itself. This is a class template where the maximum buffer size is a non-type template parameter. Use this for fixed-size, stack-allocated URLs.

    Note on Inheritance:

    • All containers support observers (via url_view_base).
    • Only url[] and static_url[] support modifiers (via url_base).
  5. Use Syntax-Based Normalization for URL comparison

    develop

    Comparison operators (==, !=, etc.) in Boost.URL implement Syntax-Based Normalization according to RFC 3986. This ensures that URLs that are syntactically equivalent are treated as equal, even if their underlying string representations differ (e.g., due to percent-encoding or path segments).

    To minimize false negatives, Syntax-Based Normalization performs:

    • Case Normalization: Normalizes percent-encoding triplets to use uppercase letters.
    • Percent-Encoding Normalization: Decodes octets that do not require percent-encoding.
    • Path Segment Normalization: Resolves . and .. path segments.
    // snippet_normalizing_2
  6. Automatic percent-escaping during URL formatting

    develop

    When using format(), the library identifies which URL component each replacement field belongs to before applying the replacement. Any characters in the arguments that are invalid for that specific component are automatically percent-escaped to ensure the resulting URL remains valid.

    // Replacement fields are escaped based on their component context
    // e.g., spaces or special characters in a path component will be percent-encoded
    auto url = boost::urls::format("https://{}/{}?query={}", "example.com", "path with space", "val#ue");
  7. Convert url_view to owning URL containers

    develop

    Since url_view is non-owning, you may need to convert it to an owning container to manage the lifetime of the URL string:

    • url: An allocating container that owns its character buffer. Constructing it from a url_view performs a dynamic memory allocation to copy the string.
    • static_url: A container that owns its character buffer but does not perform dynamic memory allocations, provided the maximum size of the URL is known at compile time.
    // From view to owning url
    boost::urls::url my_url(view);
    
    // From view to static_url (no dynamic allocation)
    boost::urls::static_url<64> my_static_url(view);
  8. Understand parameter value semantics

    develop

    In Boost.URL, query parameters are composed of a key and an optional value. The presence or absence of the = character determines how the value is interpreted:

    Query StringResulting Parameter Structure
    ?name=John{ "name", "John" }
    ?=John{ "", "John" }
    ?name={ "name", "" } (Empty string)
    ?name{ "name", no_value } (No value)
    ?{ "", no_value }
    "" (Empty){} (Empty container)

    Note: An empty query string (?) is distinct from a completely empty query string (no ? at all). The former produces a sequence with one empty parameter.

  9. Validate percent-encoded strings with pct_string_view

    develop

    The pct_string_view class represents a reference to a percent-encoded string. Unlike a standard string_view, it ensures the underlying buffer is valid percent-encoding.

    • Exception-based validation: Constructing a pct_string_view directly from an invalid string will throw an exception.
    • Non-throwing validation: Use make_pct_string_view to return a result object. This allows you to validate a string and handle errors without exceptions.

    Many modifying functions in classes like url expect pct_string_view instances, meaning they skip re-validation because the type itself guarantees the data is valid.

    // snippet_encoding_6
    // snippet_encoding_7
    // snippet_encoding_8
    // snippet_encoding_9
    // snippet_encoding_10
  10. Apply Scheme and Protocol-Based Normalization

    develop

    Scheme-Based and Protocol-Based Normalization build upon Syntax-Based Normalization to apply rules specific to certain URI schemes. Common rules include:

    • Ignoring the default port for a specific scheme.
    • Treating empty absolute paths as the default path.

    Note that comparison methods are designed to minimize false negatives while strictly avoiding false positives. If two URLs compare equal, they definitely represent the same resource; if they are different, they might still refer to the same resource depending on the application context.

    // snippet_normalizing_5
  11. What are IRIs and does Boost.URL support them?

    develop

    Boost.URL does not support Internationalized Resource Identifiers (IRIs).

    IRIs are governed by a separate specification (RFC 3987) and use Unicode strings rather than the low-ASCII strings used by URLs. If your application requires IRI support, you will need to handle the Unicode transformations separately.