Skip to content

Use Network.framework on macOS for TLS instead of OpenSSL #398

@frostney

Description

@frostney

Context

HTTPClient.pas currently routes HTTPS through FPC's openssl unit on every platform, which dlopens libssl/libcrypto at runtime. That's fine on Linux (where OpenSSL is universally available), but on macOS it pulls in a Homebrew dependency that isn't shipped by Apple, and runs into ABI mismatches: FPC 3.2.2's openssl unit probes for the legacy SSLeay_version symbol that OpenSSL 3 removed (renamed to OpenSSL_version), so on a system with only openssl@3 installed, IsSSLloaded returns false even after dlopen succeeds.

Apple deprecated their bundled OpenSSL years ago and the modern guidance is to use the system TLS stack — Network.framework is the supported successor to the deprecated SecureTransport API.

Proposal

Introduce a small TLS-backend interface in HTTPClient.pas so platforms use their native stack:

{$IF DEFINED(DARWIN)}    use Network.framework
{$ELSEIF DEFINED(MSWINDOWS)} use SChannel
{$ELSE}                  use OpenSSL
{$IFEND}

This keeps Linux on OpenSSL (right answer there — including the Vercel Linux container we deploy the website API binary into) and gets macOS off the Homebrew dependency entirely.

Acceptance criteria

  • HTTPClient.pas exposes a TLS-backend abstraction (connect / read / write / close / verify-host).
  • macOS build uses Network.framework (preferred) or SecureTransport (acceptable interim) — no Homebrew OpenSSL on the macOS code path.
  • Linux build still uses the openssl unit; the existing LocateOpenSSL library probing stays intact.
  • fetch("https://...") works on a clean macOS install with no Homebrew packages installed.
  • Existing tests pass on both backends; add a small fetch-over-TLS integration test.

Notes

  • Path-of-least-resistance interim: bind SecureTransport (deprecated since macOS 10.15 but still ships in current OS releases). Long-term: Network.framework via nw_connection_t.
  • Once this lands, the openssl@3 + FPC 3.2.2 symbol-mismatch issue stops affecting macOS users entirely.

Discovered while

Building the website /api/run endpoint that shells out to GocciaScriptLoader. The LocateOpenSSL probe added to source/shared/HTTPClient.pas is a partial mitigation — it sets DLLSSLName/DLLUtilName to absolute Homebrew paths so the right dylib is loaded — but the FPC-3.2.2-vs-OpenSSL-3 symbol issue still bites on systems with only OpenSSL 3 installed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    new featureNew feature or requestos specificThis issue is only for a specific platform/OS

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions