Add proxy routing and sing-box support
This commit is contained in:
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024-2026 Fabian Freund.
|
||||
*
|
||||
* This file is part of WebLibre
|
||||
* (see https://weblibre.eu).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:synchronized/synchronized.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/data/models/site_assignment.dart';
|
||||
|
||||
part 'tor_proxy.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class TorProxyRepository extends _$TorProxyRepository {
|
||||
final _service = GeckoContainerProxyService();
|
||||
final _serviceLock = Lock();
|
||||
|
||||
Future<void> setProxyPort(int port) {
|
||||
return _serviceLock.synchronized(() async {
|
||||
await _waitHealthcheck().timeout(const Duration(seconds: 30));
|
||||
|
||||
return _service.setProxyPort(port);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> addContainerProxy(String contextId) {
|
||||
return _serviceLock.synchronized(() async {
|
||||
await _waitHealthcheck().timeout(const Duration(seconds: 10));
|
||||
|
||||
return _service.addContainerProxy(contextId);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> removeContainerProxy(String contextId) {
|
||||
return _serviceLock.synchronized(() async {
|
||||
await _waitHealthcheck().timeout(const Duration(seconds: 10));
|
||||
|
||||
return _service.removeContainerProxy(contextId);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> setSiteAssignments(List<SiteAssignment> assignements) {
|
||||
return _serviceLock.synchronized(() async {
|
||||
await _waitHealthcheck().timeout(const Duration(seconds: 10));
|
||||
|
||||
return _service.setSiteAssignments(
|
||||
Map.fromEntries(
|
||||
assignements.map(
|
||||
(e) => MapEntry(
|
||||
e.assignedSite.origin,
|
||||
e.contextualIdentity ?? 'general',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _waitHealthcheck({
|
||||
Duration timeout = const Duration(seconds: 15),
|
||||
}) async {
|
||||
final startTime = DateTime.now();
|
||||
|
||||
var healthy = await _service.healthcheck();
|
||||
while (!healthy) {
|
||||
if (DateTime.now().difference(startTime) > timeout) {
|
||||
throw TimeoutException('Timed out waiting for proxy service');
|
||||
}
|
||||
|
||||
await Future.delayed(const Duration(milliseconds: 25));
|
||||
healthy = await _service.healthcheck();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void build() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'tor_proxy.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(TorProxyRepository)
|
||||
final torProxyRepositoryProvider = TorProxyRepositoryProvider._();
|
||||
|
||||
final class TorProxyRepositoryProvider
|
||||
extends $NotifierProvider<TorProxyRepository, void> {
|
||||
TorProxyRepositoryProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'torProxyRepositoryProvider',
|
||||
isAutoDispose: false,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$torProxyRepositoryHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
TorProxyRepository create() => TorProxyRepository();
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(void value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<void>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$torProxyRepositoryHash() =>
|
||||
r'83c2976750f3f7907274b1ae4f926cd1de89be83';
|
||||
|
||||
abstract class _$TorProxyRepository extends $Notifier<void> {
|
||||
void build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final ref = this.ref as $Ref<void, void>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<void, void>,
|
||||
void,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user