Repository navigation
database: replace uWebSockets and libuv with libcurl WebSockets - #1959
AustinBenoit wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request replaces the legacy uWebSockets and libuv WebSocket transport in the desktop Realtime Database SDK with a native libcurl-based implementation. It removes the libuv and uWebSockets dependencies entirely, centralizes the TLS policy across REST and WebSocket connections, and introduces a robust set of unit and integration tests. The reviewer identified a potential memory leak in web_socket_client_impl.cc where request_headers_.release() is passed directly to curl_slist_append; if the append fails, the original list is leaked. A safer helper lambda was suggested to handle appending safely.
ebbb972 to
beef0b1
Compare
2a9856c to
2323985
Compare
2323985 to
94d75ff
Compare
- Drop unmaintained external dependencies uWebSockets (v0.14) and libuv
(v1.40) from CMake, external rules, patches, and release NOTICES.
- Migrate Realtime Database WebSocket client (WebSocketClientImpl) to
libcurl's native WebSocket support (curl_ws_send, curl_ws_recv,
CURLOPT_CONNECT_ONLY = 2L).
- Give each WebSocket connection its own lightweight event thread and private
CURLM* handle using curl_multi_poll() and curl_multi_wakeup().
- Add stalled handshake deadline watchdog (5000 ms default).
- Centralize SDK transport security in app/rest/curl/tls_policy.{h,cc}
(TLS 1.2+ minimum, peer/hostname verification, and native OS certificate
trust store via Schannel on Windows, Keychain on macOS, and runtime CA bundle
detection on Linux).
- Add thread-safe reference-counted AcquireCurlGlobal() / ReleaseCurlGlobal()
and RAII handle deleters in app/rest/curl/curl_handles.{h,cc}.
- Initialize DatabaseInternal::persistence_enabled_ to false to prevent
reading uninitialized member variables on desktop platforms.
- Guard Logger::LogMessageImplV when parent_logger_ is null.
- Fix package.sh symbol hiding script generation for libfirebase_database.a.
- Add local loopback RFC 6455 WebSocket unit tests (8/8 passing).
94d75ff to
32dac60
Compare
❌ Integration test FAILEDRequested by @AustinBenoit on commit 1c8d0ae
Add flaky tests to go/fpl-cpp-flake-tracker |
|
Triggered Firebase Unity SDK build & integration tests against
|
Summary
Replaces Realtime Database's desktop WebSocket transport (
uWebSocketsv0.14 andlibuvv1.40) withlibcurl's native WebSocket implementation (CURLOPT_CONNECT_ONLY = 2L,curl_ws_recv(),curl_ws_send()), eliminating two legacy, unmaintained external dependencies from the Firebase C++ SDK.Architecture & Key Changes
1. External Dependency Deletion (
-2Third-Party Libraries)uWebSockets(2017 v0.14 snapshot + patch) andlibuv(2020 v1.40 snapshot) fromCMakeLists.txt,cmake/external/CMakeLists.txt,cmake/external_rules.cmake,README.md,scripts/gha/print_matrix_configuration.py, andrelease_build_files/NOTICES.psapianduserenvsystem library link requirements forfirebase_database(documented inrelease_build_files/readme.md).libcurl >= 8.14.0withws/wssprotocol support (CURLWS_NOAUTOPONG) at compile time (static_assertinapp/rest/curl/curl_handles.h).2.
WebSocketClientImpl(database/src/desktop/connection/)WebSocketClientImplowns one background event loop thread (EventLoopRoutine/RunEventLoop) and a privateCURLM*handle (curl_multi_poll()+curl_multi_wakeup()), marshalling allWebSocketClientEventHandlercallbacks (OnOpen,OnMessage,OnClose,OnError) back onto the Databasescheduler_thread viasafe_this_.101 Switching Protocolsupgrade non-blockingly onmulti_with an explicithandshake_deadline_watchdog enforced on the I/O thread so stalled connects or destructor teardown abort immediately.curl_ws_recv()andcurl_ws_send()in non-blocking mode (CURLWS_TEXT,CURLWS_BINARY,CURLWS_CONT,CURLWS_PING,CURLWS_PONG,CURLWS_CLOSE).frame_in_progress_,current_send_offset_) and waits for socket writability (CURL_WAIT_POLLOUT) onCURLE_AGAINwithout busy-spinning.kMaxMessagePayloadBytes).Connection::OnError): Removes the redundant secondscheduler_->Schedule(...)hop insideConnection::OnError()so mid-session WebSocket errors reportkDisconnectReasonWebsocketErrorbeforeOnClose()transitions the connection tokStateDisconnected.3. Shared
libcurlPrimitives (app/rest/curl/)tls_policy.{h,cc}: Centralizes desktop TLS configuration shared by REST (transport_curl.cc) and WebSockets (web_socket_client_impl.cc):CURL_SSLVERSION_TLSv1_2),CURLOPT_SSL_VERIFYPEER = 1L, andCURLOPT_SSL_VERIFYHOST = 2L.CURL_CA_BUNDLE,SSL_CERT_FILE, and standard Debian/Ubuntu, RHEL/Fedora, openSUSE, and Alpine paths) and CA directory (SSL_CERT_DIR,/etc/ssl/certs) on Linux.curl_handles.{h,cc}: Provides RAIIstd::unique_ptrdeleters (UniqueEasy,UniqueMulti,UniqueSList), MSVC#pragma comment(lib, ...)directives for Windows SDK system libraries, and a process-wide, mutex-protected reference count (AcquireCurlGlobal()/ReleaseCurlGlobal()) aroundcurl_global_init()/curl_global_cleanup()used acrosstransport_curl.cc,util.cc, andweb_socket_client_impl.cc.4. Supporting Fixes
DatabaseInternal::persistence_enabled_ = falseon desktop (database_desktop.cc).Logger::LogMessageImplVagainst a nullparent_logger_(app/src/logger.cc+ unit test inapp/tests/logger_test.cc).build_scripts/desktop/package.shtemporary linker version script path generation (hide_symbols_*.lds).File Breakdown
CMakeLists.txt,cmake/external/CMakeLists.txt,cmake/external_rules.cmake,cmake/external/libuv.cmake(deleted),cmake/external/uWebSockets.cmake(deleted),scripts/git/patches/uWebSockets/...(deleted),release_build_files/NOTICES,release_build_files/readme.md,README.md,scripts/gha/print_matrix_configuration.pyuWebSockets&libuvbuild rules, patches, notices, and Windowspsapi/userenvlink flagslibcurlCoreapp/rest/CMakeLists.txt,app/rest/curl/curl_handles.{h,cc},app/rest/curl/tls_policy.{h,cc},app/rest/transport_curl.cc,app/rest/util.{h,cc}curl_globalrefcount, RAII handle wrappers, and unified TLS 1.2+ / OS trust store policydatabase/CMakeLists.txt,database/src/desktop/connection/web_socket_client_impl.{h,cc},database/src/desktop/connection/connection.cc,database/src/desktop/connection/util_connection.cc,database/src/desktop/database_desktop.{h,cc}libcurlWebSocket client with privateCURLM*poll/wakeup loopdatabase/tests/CMakeLists.txt,database/tests/desktop/connection/web_socket_client_impl_test.cc,database/integration_test/CMakeLists.txt,app/src/logger.cc,app/tests/logger_test.cc,build_scripts/desktop/package.sh,cmake/CTestCustom.cmakeVerification
firebase_rtdb_desktop_connection_web_socket_client_impl_test: 8 / 8 passed (happy-path connect/echo/close, immediate teardown before connect and mid-handshake, multi-fragmentCURLWS_CONTreassembly with interleavedPING/PONGand 100 KB multi-chunk payload +User-Agent/X-Firebase-AppCheckheaders, server-initiatedCLOSE, connection refusedOnError, stalled handshake watchdog timeout, andws/wssURI scheme enforcement).firebase_rtdb_desktop_connection_connection_test: 9 / 9 passed against livewss://Realtime Database backend.