118 lines
3.8 KiB
Dart
118 lines
3.8 KiB
Dart
|
|
|
|
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'proxy_settings.dart';
|
|
|
|
class ProxyService {
|
|
ProxyService._privateConstructor();
|
|
static final ProxyService instance = ProxyService._privateConstructor();
|
|
|
|
static const _proxySettingsKey = 'proxy_settings';
|
|
|
|
Future<void> saveProxySettings(ProxySettings settings) async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final jsonString = jsonEncode(settings.toJson());
|
|
await prefs.setString(_proxySettingsKey, jsonString);
|
|
}
|
|
|
|
Future<ProxySettings> loadProxySettings() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final jsonString = prefs.getString(_proxySettingsKey);
|
|
if (jsonString != null) {
|
|
try {
|
|
return ProxySettings.fromJson(jsonDecode(jsonString));
|
|
} catch (e) {
|
|
return ProxySettings();
|
|
}
|
|
}
|
|
return ProxySettings();
|
|
}
|
|
|
|
|
|
Future<void> checkProxy(ProxySettings settings) async {
|
|
print("Проверка прокси: ${settings.host}:${settings.port}");
|
|
HttpClient client = _createClientWithOptions(settings);
|
|
|
|
client.connectionTimeout = const Duration(seconds: 10);
|
|
|
|
try {
|
|
final request = await client.headUrl(
|
|
Uri.parse('https://www.google.com/generate_204'),
|
|
);
|
|
final response = await request.close();
|
|
|
|
print("Ответ от прокси получен, статус: ${response.statusCode}");
|
|
|
|
if (response.statusCode >= 400) {
|
|
|
|
throw Exception('Прокси вернул ошибку: ${response.statusCode}');
|
|
}
|
|
} on HandshakeException catch (e) {
|
|
print("Поймана ошибка сертификата при проверке прокси: $e");
|
|
print(
|
|
"Предполагаем, что badCertificateCallback обработает это в реальном соединении. Считаем проверку успешной.",
|
|
);
|
|
|
|
return;
|
|
} on SocketException catch (e) {
|
|
print("Ошибка сокета при проверке прокси: $e");
|
|
throw Exception('Неверный хост или порт');
|
|
} on TimeoutException catch (_) {
|
|
print("Таймаут при проверке прокси");
|
|
throw Exception('Сервер не отвечает (таймаут)');
|
|
} catch (e) {
|
|
print("Неизвестная ошибка при проверке прокси: $e");
|
|
throw Exception('Неизвестная ошибка: ${e.toString()}');
|
|
} finally {
|
|
client.close();
|
|
}
|
|
}
|
|
|
|
|
|
Future<HttpClient> getHttpClientWithProxy() async {
|
|
final settings = await loadProxySettings();
|
|
return _createClientWithOptions(settings);
|
|
}
|
|
|
|
|
|
HttpClient _createClientWithOptions(ProxySettings settings) {
|
|
final client = HttpClient();
|
|
|
|
if (settings.isEnabled && settings.host.isNotEmpty) {
|
|
print("Используется прокси: ${settings.toFindProxyString()}");
|
|
|
|
client.findProxy = (uri) {
|
|
return settings.toFindProxyString();
|
|
};
|
|
|
|
if (settings.username != null && settings.username!.isNotEmpty) {
|
|
print(
|
|
"Настраивается аутентификация на прокси для пользователя: ${settings.username}",
|
|
);
|
|
client.authenticateProxy = (host, port, scheme, realm) async {
|
|
client.addProxyCredentials(
|
|
host,
|
|
port,
|
|
realm ?? '',
|
|
HttpClientBasicCredentials(
|
|
settings.username!,
|
|
settings.password ?? '',
|
|
),
|
|
);
|
|
return true;
|
|
};
|
|
}
|
|
|
|
client.badCertificateCallback =
|
|
(X509Certificate cert, String host, int port) => true;
|
|
} else {
|
|
client.findProxy = HttpClient.findProxyFromEnvironment;
|
|
}
|
|
|
|
return client;
|
|
}
|
|
}
|