setting to exclude proxy from global routing

This commit is contained in:
Fabian Freund
2026-05-27 09:23:18 +02:00
parent 2812c24f35
commit 7275ac9400
27 changed files with 661 additions and 65 deletions
@@ -27,6 +27,8 @@ import 'package:weblibre/extensions/uri.dart';
import 'package:weblibre/features/geckoview/domain/entities/states/tab.dart';
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode.dart';
import 'package:weblibre/features/geckoview/features/tabs/data/providers.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/container.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart';
import 'package:weblibre/features/proxy/data/proxy_connection.dart';
import 'package:weblibre/features/tor/domain/services/tor_proxy.dart';
@@ -35,6 +37,20 @@ import 'package:weblibre/features/user/domain/repositories/proxy_routing_setting
part 'website_title.g.dart';
sealed class _PageInfoProxyAssignment {
const _PageInfoProxyAssignment();
}
final class _PageInfoDirectAssignment extends _PageInfoProxyAssignment {
const _PageInfoDirectAssignment();
}
final class _PageInfoExplicitProxyAssignment extends _PageInfoProxyAssignment {
final ProxyConnectionId proxyConnectionId;
const _PageInfoExplicitProxyAssignment(this.proxyConnectionId);
}
@Riverpod()
class CompletePageInfo extends _$CompletePageInfo {
@override
@@ -91,12 +107,34 @@ Future<WebPageInfo> pageInfo(
proxyRoutingSettingsWithDefaultsProvider,
);
if (containerData?.metadata.proxyConnectionId is TorProxyConnectionId ||
(tabState.tabMode is! PrivateTabMode &&
proxyRoutingSettings.regularTabsMode ==
ProxyRegularTabRoutingMode.all &&
proxyRoutingSettings.regularTabsProxyConnectionId
is TorProxyConnectionId) ||
final isolatedAssignment = tabState.isolationContextId != null
? await _pageInfoAssignmentForIsolationContext(
ref,
tabState.isolationContextId!,
)
: null;
final effectiveContainerProxyConnectionId = switch (isolatedAssignment) {
_PageInfoExplicitProxyAssignment(:final proxyConnectionId) =>
proxyConnectionId,
_PageInfoDirectAssignment() => null,
null => containerData?.metadata.proxyConnectionId,
};
final bypassesGlobalProxy =
isolatedAssignment is _PageInfoDirectAssignment ||
(isolatedAssignment == null &&
containerData?.metadata.bypassGlobalProxy == true);
final usesGlobalRegularTor =
tabState.tabMode is! PrivateTabMode &&
effectiveContainerProxyConnectionId == null &&
!bypassesGlobalProxy &&
proxyRoutingSettings.regularTabsMode ==
ProxyRegularTabRoutingMode.all &&
proxyRoutingSettings.regularTabsProxyConnectionId
is TorProxyConnectionId;
if (effectiveContainerProxyConnectionId is TorProxyConnectionId ||
usesGlobalRegularTor ||
(tabState.tabMode is PrivateTabMode &&
proxyRoutingSettings.privateTabsProxyConnectionId
is TorProxyConnectionId)) {
@@ -125,6 +163,51 @@ Future<WebPageInfo> pageInfo(
return result.value;
}
Future<_PageInfoProxyAssignment?> _pageInfoAssignmentForIsolationContext(
Ref ref,
String contextId,
) async {
final db = ref.read(tabDatabaseProvider);
final pairs = await db.tabDao.isolatedContextContainerPairs().get();
final containerIds = pairs
.where((pair) => pair.isolationContextId == contextId)
.map((pair) => pair.containerId)
.nonNulls
.toSet();
if (containerIds.isEmpty) return null;
final containers = await ref
.read(containerRepositoryProvider.notifier)
.getAllContainersWithCount();
final matchedContainers = containers.where(
(container) => containerIds.contains(container.id),
);
final proxyIds =
matchedContainers
.map((container) => container.metadata.proxyConnectionId?.encode())
.nonNulls
.toSet()
.toList()
..sort();
if (proxyIds.isNotEmpty) {
final proxyConnectionId = ProxyConnectionId.decode(proxyIds.first);
return proxyConnectionId != null
? _PageInfoExplicitProxyAssignment(proxyConnectionId)
: null;
}
final matchedContainerList = matchedContainers.toList();
if (matchedContainerList.isNotEmpty &&
matchedContainerList.every(
(container) => container.metadata.bypassGlobalProxy,
)) {
return const _PageInfoDirectAssignment();
}
return null;
}
@Riverpod()
AsyncValue<EquatableValue<Set<Uri>?>> websiteFeedProvider(
Ref ref,