Ada URL Parser

repository·main·Indexed 23 days ago

https://github.com/ada-url/ada

A high-performance, spec-compliant WHATWG URL parser written in C++20. Used in critical systems like Node.js, Cloudflare Workers, and Redpanda, Ada provides a self-contained library for parsing and manipulating URLs with support for C interfaces and various language bindings including Rust, Go, Python, and Kotlin. It features specialized types like ada::url and ada::url_aggregator, a CLI tool called adaparse, and support for architectures such as LoongArch64 and RISC-V Vector (RVV).

Tokens
4.9K
Snippets
21
Records
30
Agent score
77%

What's inside ada-url

  1. How `ada::url` and `ada::url_aggregator` differ

    main

    Ada provides two types of URL instances via the ada::parse template function:

    1. ada::url: The standard type. It stores URL components (path, host, etc.) as separate strings. This is useful when you need to manipulate or access individual parts of the URL.
    2. ada::url_aggregator: A lightweight type. It is backed by a single precomputed serialized URL string. Use this when you need a smaller memory footprint and primarily need the serialized string.

    You select the type by passing it as a template argument to ada::parse<T>().

  2. Implement custom regex for URLPattern

    main

    Ada does not include a built-in regex engine to avoid security risks (like ReDoS). Instead, it uses a provider pattern. To use ada::parse_url_pattern, you must provide a class that implements a specific interface for creating instances, searching, and matching.

    Required interface methods for the provider:

    • static std::optional<regex_type> create_instance(std::string_view pattern, bool ignore_case)
    • static std::optional<std::vector<std::optional<std::string>>> regex_search(std::string_view input, const regex_type& pattern)
    • static bool regex_match(std::string_view input, const regex_type& pattern)
    // Example using a hypothetical v8_regex_provider
    class v8_regex_provider {
     public:
      v8_regex_provider() = default;
      using regex_type = v8::Global<v8::RegExp>;
      static std::optional<regex_type> create_instance(std::string_view pattern, bool ignore_case);
      static std::optional<std::vector<std::optional<std::string>>> regex_search(std::string_view input, const regex_type& pattern);
      static bool regex_match(std::string_view input, const regex_type& pattern);
    };
    
    auto pattern = ada::parse_url_pattern<v8_regex_provider>("/books/:id(\d+)", "https://example.com");
    
    if (!pattern) { return EXIT_FAILURE; }
    
    auto match = pattern->match("https://example.com/books/123");
    auto matched = pattern->test("https://example.com/books/123");
  3. Use the adaparse CLI tool

    main

    The adaparse command-line tool is used to validate, normalize, and query URL strings (ASCII/UTF-8) efficiently. It can process single URLs provided via arguments or batches of URLs provided via piped input or files.

    adaparse "http://www.google.com"
  4. Generate the Ada single-header amalgamation

    main

    To use Ada as a single header and source file pair, you can use the amalgamation script. This is useful for simplifying integration into other projects. Run the following command from the ada main directory using Python 3 to generate ada.h and ada.cpp:

    python singleheader/amalgamate.py
  5. Build for LoongArch64

    main

    To build and run Ada for the LoongArch64 architecture, ensure you have the following requirements:

    • GCC >= 14.1
    • Binutils >= 2.41
    • QEMU >= 9.2

    Note: The compiler name might be loongarch64-linux-gnu-g++ (without the unknown part) depending on your system; adjust your environment accordingly.

    Follow these steps to set up QEMU, configure the toolchain, and build the project.

    $ sudo curl -L https://github.com/loongson/build-tools/releases/download/2025.06.06/qemu-loongarch64 --output /opt/qemu-loongarch64
    $ sudo chmod +x /opt/qemu-loongarch64
    $ export PATH=/opt:$PATH
    
    $ export QEMU_LD_PREFIX="/usr/loongarch64-linux-gnu" # ubuntu 24.04
    $ export QEMU_CPU="la464"
    $ mkdir build && cd build
    $ cmake -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains-dev/loongarch64.cmake -DADA_TESTING=ON ../
    $ make
  6. Install Ada for C++

    main

    Ada is a self-contained C++ library with no dependencies. To use it on Linux or macOS, you can manually download the header and source files and compile them with a C++20 compatible compiler (e.g., GCC 12+, LLVM 14+, or MSVC 2022).

    1. Download the library files using wget:
      wget https://github.com/ada-url/ada/releases/download/v3.0.0/ada.cpp
      wget https://github.com/ada-url/ada/releases/download/v3.0.0/ada.h
    2. Include ada.h and ada.cpp in your project.
    3. Compile with the -std=c++20 flag.
    wget https://github.com/ada-url/ada/releases/download/v3.0.0/ada.cpp
    wget https://github.com/ada-url/ada/releases/download/v3.0.0/ada.h
    
    c++ -std=c++20 -o demo demo.cpp
  7. Generate C bindings for servo-url using cbindgen

    main

    To generate the C header files (servo_url.h) for the servo-url FFI bindings, you must use cbindgen.

    1. Install cbindgen using Homebrew: brew install cbindgen.
    2. Run the generation command using the provided configuration file and crate name.
    cbindgen --config cbindgen.toml --crate servo-url --output servo_url.h
  8. Run LoongArch64 tests with QEMU

    main

    After building for LoongArch64, you can execute tests using make test, ctest, or by running the specific binary directly via qemu-loongarch64.

    $ make test
    # or
    $ ctest --output-on-failure --test-dir build
    # or
    $ qemu-loongarch64 build/singleheader/cdemo
  9. Build Ada locally with CMake

    main

    Ada uses CMake. You can build it without tests or with tests enabled.

    Build without tests:

    cmake -B build && cmake --build build

    Build with tests (requires git):

    cmake -B build -DADA_TESTING=ON && cmake --build build
    ctest --output-on-failure --test-dir build

    Build with local packages (CPM):

    cmake -B build -DADA_TESTING=ON -D CPM_USE_LOCAL_PACKAGES=ON && cmake --build build
    ctest --output-on-failure --test-dir build

    Build options:

    • ADA_USE_SIMDUTF: Enables SIMD-accelerated Unicode processing (default: OFF).
  10. Build with RISC-V Vector (RVV) Extension

    main

    Ada supports RISC-V Vector optimizations. This requires GCC-13, CLANG-16, or higher.

    Native builds will automatically use RVV code if the specified -march ISA string or default target ISA supports the V extension. For cross-compilation using riscv-gnu-toolchain, you may need to update the cross compiler target prefix in the toolchain file from riscv64-linux-gnu to riscv64-unknown-linux-gnu.

    On Debian/Ubuntu, follow these steps to set up the environment and build with RVV support:

    # For Debian/Ubuntu
    $ sudo apt install g++-riscv64-linux-gnu qemu-system-riscv qemu-user
    $ mkdir build; cd build
    $ export QEMU_LD_PREFIX="/usr/riscv64-linux-gnu"
    $ export QEMU_CPU="rv64,v=on"
    $ mkdir build && cd build
    $ cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains-dev/riscv64-rvv.cmake -DADA_TESTING=ON ..
    $ cmake --build -j $(nproc)