From 7d4aca194450591132352227483987d961ce64fe Mon Sep 17 00:00:00 2001 From: cogwheel0 <172976095+cogwheel0@users.noreply.github.com> Date: Sat, 11 Oct 2025 16:17:35 +0530 Subject: [PATCH] fix: add tls override for websockets incase of self signed certs --- lib/core/models/model.dart | 3 +- .../background_streaming_handler.dart | 3 +- .../persistent_streaming_service.dart | 3 +- lib/core/services/socket_service.dart | 7 ++- lib/core/services/socket_tls_override.dart | 12 +++++ .../services/socket_tls_override_impl_io.dart | 54 +++++++++++++++++++ .../socket_tls_override_impl_stub.dart | 12 +++++ 7 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 lib/core/services/socket_tls_override.dart create mode 100644 lib/core/services/socket_tls_override_impl_io.dart create mode 100644 lib/core/services/socket_tls_override_impl_stub.dart diff --git a/lib/core/models/model.dart b/lib/core/models/model.dart index 712f59f..99ee7d0 100644 --- a/lib/core/models/model.dart +++ b/lib/core/models/model.dart @@ -114,7 +114,8 @@ sealed class Model with _$Model { // Extract toolIds from info.meta.toolIds (OpenWebUI format) List? toolIds; - final infoMeta = (infoSection?['meta'] as Map?) ?? + final infoMeta = + (infoSection?['meta'] as Map?) ?? (metaSection) ?? (mergedMetadata['meta'] as Map?); if (infoMeta != null) { diff --git a/lib/core/services/background_streaming_handler.dart b/lib/core/services/background_streaming_handler.dart index 3376314..57ea40f 100644 --- a/lib/core/services/background_streaming_handler.dart +++ b/lib/core/services/background_streaming_handler.dart @@ -26,7 +26,8 @@ class BackgroundStreamingHandler { // Callbacks for platform-specific events void Function(List streamIds)? onStreamsSuspending; void Function()? onBackgroundTaskExpiring; - void Function(List streamIds, int estimatedSeconds)? onBackgroundTaskExtended; + void Function(List streamIds, int estimatedSeconds)? + onBackgroundTaskExtended; void Function()? onBackgroundKeepAlive; bool Function()? shouldContinueInBackground; diff --git a/lib/core/services/persistent_streaming_service.dart b/lib/core/services/persistent_streaming_service.dart index b37da24..b7ec066 100644 --- a/lib/core/services/persistent_streaming_service.dart +++ b/lib/core/services/persistent_streaming_service.dart @@ -62,7 +62,8 @@ class PersistentStreamingService with WidgetsBindingObserver { _saveStreamStatesForRecovery(); }; - _backgroundHandler.onBackgroundTaskExtended = (streamIds, estimatedSeconds) { + _backgroundHandler + .onBackgroundTaskExtended = (streamIds, estimatedSeconds) { DebugLogger.stream( 'PersistentStreaming: Background task extended for $estimatedSeconds seconds', ); diff --git a/lib/core/services/socket_service.dart b/lib/core/services/socket_service.dart index 1a8eced..22ff8e2 100644 --- a/lib/core/services/socket_service.dart +++ b/lib/core/services/socket_service.dart @@ -3,6 +3,7 @@ import 'package:socket_io_client/socket_io_client.dart' as io; import '../models/server_config.dart'; import '../utils/debug_logger.dart'; +import 'socket_tls_override.dart'; typedef SocketChatEventHandler = void Function( @@ -120,7 +121,11 @@ class SocketService with WidgetsBindingObserver { builder.setExtraHeaders(extraHeaders); } - _socket = io.io(base, builder.build()); + _socket = createSocketWithOptionalBadCertOverride( + base, + builder, + serverConfig, + ); _bindCoreSocketHandlers(); } diff --git a/lib/core/services/socket_tls_override.dart b/lib/core/services/socket_tls_override.dart new file mode 100644 index 0000000..b05b5d8 --- /dev/null +++ b/lib/core/services/socket_tls_override.dart @@ -0,0 +1,12 @@ +import 'package:socket_io_client/socket_io_client.dart' as io; + +import '../models/server_config.dart'; +import 'socket_tls_override_impl_stub.dart' + if (dart.library.io) 'socket_tls_override_impl_io.dart' + as impl; + +io.Socket createSocketWithOptionalBadCertOverride( + String base, + io.OptionBuilder builder, + ServerConfig serverConfig, +) => impl.createSocketWithOptionalBadCertOverride(base, builder, serverConfig); diff --git a/lib/core/services/socket_tls_override_impl_io.dart b/lib/core/services/socket_tls_override_impl_io.dart new file mode 100644 index 0000000..c9c74a6 --- /dev/null +++ b/lib/core/services/socket_tls_override_impl_io.dart @@ -0,0 +1,54 @@ +import 'dart:io' + show HttpOverrides, SecurityContext, HttpClient, X509Certificate; +import 'package:socket_io_client/socket_io_client.dart' as io; + +import '../models/server_config.dart'; + +io.Socket createSocketWithOptionalBadCertOverride( + String base, + io.OptionBuilder builder, + ServerConfig serverConfig, +) { + if (!serverConfig.allowSelfSignedCertificates) { + return io.io(base, builder.build()); + } + + final target = _tryParseUri(base); + if (target == null || !(target.scheme == 'https' || target.scheme == 'wss')) { + return io.io(base, builder.build()); + } + + final host = target.host.toLowerCase(); + final port = target.hasPort ? target.port : null; + return HttpOverrides.runWithHttpOverrides( + () => io.io(base, builder.build()), + _ScopedBadCertOverrides(host: host, port: port), + ); +} + +Uri? _tryParseUri(String url) { + try { + final parsed = Uri.parse(url); + if (parsed.hasScheme) return parsed; + } catch (_) {} + return null; +} + +class _ScopedBadCertOverrides extends HttpOverrides { + _ScopedBadCertOverrides({required this.host, this.port}); + + final String host; + final int? port; + + @override + HttpClient createHttpClient(SecurityContext? context) { + final client = super.createHttpClient(context); + client.badCertificateCallback = + (X509Certificate cert, String requestHost, int requestPort) { + if (requestHost.toLowerCase() != host) return false; + if (port == null) return true; + return requestPort == port; + }; + return client; + } +} diff --git a/lib/core/services/socket_tls_override_impl_stub.dart b/lib/core/services/socket_tls_override_impl_stub.dart new file mode 100644 index 0000000..c11d011 --- /dev/null +++ b/lib/core/services/socket_tls_override_impl_stub.dart @@ -0,0 +1,12 @@ +import 'package:socket_io_client/socket_io_client.dart' as io; + +import '../models/server_config.dart'; + +io.Socket createSocketWithOptionalBadCertOverride( + String base, + io.OptionBuilder builder, + ServerConfig serverConfig, +) { + // Web and other non-IO platforms: no TLS override possible/needed + return io.io(base, builder.build()); +}