import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:dio/dio.dart'; import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/models/models.dart'; import 'package:fl_clash/state.dart'; import 'package:flutter/cupertino.dart'; class Request { late final Dio _dio; String? userAgent; Request() { _dio = Dio(); _dio.interceptors.add( InterceptorsWrapper( onRequest: (options, handler) { return handler.next(options); // 继续请求 }, ), ); } Future getFileResponseForUrl(String url) async { final response = await _dio .get( url, options: Options( headers: { "User-Agent": globalState.appController.clashConfig.globalUa }, responseType: ResponseType.bytes, ), ) .timeout( httpTimeoutDuration * 6, ); return response; } Future getImage(String url) async { if (url.isEmpty) return null; final response = await _dio.get( url, options: Options( responseType: ResponseType.bytes, ), ); final data = response.data; if (data == null) return null; return MemoryImage(data); } Future?> checkForUpdate() async { final response = await _dio.get( "https://api.github.com/repos/$repository/releases/latest", options: Options( responseType: ResponseType.json, ), ); if (response.statusCode != 200) return null; final data = response.data as Map; final remoteVersion = data['tag_name']; final version = globalState.packageInfo.version; final hasUpdate = other.compareVersions(remoteVersion.replaceAll('v', ''), version) > 0; if (!hasUpdate) return null; return data; } final Map)> _ipInfoSources = { "https://ipwho.is/": IpInfo.fromIpwhoIsJson, "https://api.ip.sb/geoip/": IpInfo.fromIpSbJson, "https://ipapi.co/json/": IpInfo.fromIpApiCoJson, "https://ipinfo.io/json/": IpInfo.fromIpInfoIoJson, }; Future checkIp({CancelToken? cancelToken}) async { for (final source in _ipInfoSources.entries) { try { final response = await _dio .get>(source.key, cancelToken: cancelToken) .timeout(httpTimeoutDuration); if (response.statusCode != 200 || response.data == null) { continue; } return source.value(response.data!); } catch (e) { if (e is DioException && e.type == DioExceptionType.cancel) { throw "cancelled"; } debugPrint("checkIp error ===> $e"); } } return null; } Future pingHelper() async { try { final response = await _dio .get( "http://$localhost:$helperPort/ping", options: Options( responseType: ResponseType.plain, ), ) .timeout( const Duration( milliseconds: 2000, ), ); if (response.statusCode != HttpStatus.ok) { return false; } return (response.data as String) == helperTag; } catch (_) { return false; } } Future startCoreByHelper(String arg) async { try { final response = await _dio .post( "http://$localhost:$helperPort/start", data: json.encode({ "path": appPath.corePath, "arg": arg, }), options: Options( responseType: ResponseType.plain, ), ) .timeout( const Duration( milliseconds: 2000, ), ); if (response.statusCode != HttpStatus.ok) { return false; } final data = response.data as String; return data.isEmpty; } catch (_) { return false; } } Future stopCoreByHelper() async { try { final response = await _dio .post( "http://$localhost:$helperPort/stop", options: Options( responseType: ResponseType.plain, ), ) .timeout( const Duration( milliseconds: 2000, ), ); if (response.statusCode != HttpStatus.ok) { return false; } final data = response.data as String; return data.isEmpty; } catch (_) { return false; } } } final request = Request();