mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 15:57:25 +00:00
Fixed issue where http client settings were not synchronised with appdata. Close #337
This commit is contained in:
@@ -25,6 +25,7 @@ import 'package:venera/components/js_ui.dart';
|
|||||||
import 'package:venera/foundation/app.dart';
|
import 'package:venera/foundation/app.dart';
|
||||||
import 'package:venera/network/app_dio.dart';
|
import 'package:venera/network/app_dio.dart';
|
||||||
import 'package:venera/network/cookie_jar.dart';
|
import 'package:venera/network/cookie_jar.dart';
|
||||||
|
import 'package:venera/network/proxy.dart';
|
||||||
import 'package:venera/utils/init.dart';
|
import 'package:venera/utils/init.dart';
|
||||||
|
|
||||||
import 'comic_source/comic_source.dart';
|
import 'comic_source/comic_source.dart';
|
||||||
@@ -194,7 +195,7 @@ class JsEngine with _JSEngineApi, JsUiApi, Init {
|
|||||||
responseType: ResponseType.plain,
|
responseType: ResponseType.plain,
|
||||||
validateStatus: (status) => true,
|
validateStatus: (status) => true,
|
||||||
));
|
));
|
||||||
var proxy = await AppDio.getProxy();
|
var proxy = await getProxy();
|
||||||
dio.httpClientAdapter = IOHttpClientAdapter(
|
dio.httpClientAdapter = IOHttpClientAdapter(
|
||||||
createHttpClient: () {
|
createHttpClient: () {
|
||||||
return HttpClient()
|
return HttpClient()
|
||||||
|
@@ -7,7 +7,7 @@ import 'package:rhttp/rhttp.dart' as rhttp;
|
|||||||
import 'package:venera/foundation/appdata.dart';
|
import 'package:venera/foundation/appdata.dart';
|
||||||
import 'package:venera/foundation/log.dart';
|
import 'package:venera/foundation/log.dart';
|
||||||
import 'package:venera/network/cache.dart';
|
import 'package:venera/network/cache.dart';
|
||||||
import 'package:venera/utils/ext.dart';
|
import 'package:venera/network/proxy.dart';
|
||||||
|
|
||||||
import '../foundation/app.dart';
|
import '../foundation/app.dart';
|
||||||
import 'cloudflare.dart';
|
import 'cloudflare.dart';
|
||||||
@@ -96,7 +96,9 @@ class MyLogInterceptor implements Interceptor {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||||
Log.info("Network", "${options.method} ${options.uri}\n"
|
Log.info(
|
||||||
|
"Network",
|
||||||
|
"${options.method} ${options.uri}\n"
|
||||||
"headers:\n${options.headers}\n"
|
"headers:\n${options.headers}\n"
|
||||||
"data:\n${options.data}");
|
"data:\n${options.data}");
|
||||||
options.connectTimeout = const Duration(seconds: 15);
|
options.connectTimeout = const Duration(seconds: 15);
|
||||||
@@ -107,64 +109,15 @@ class MyLogInterceptor implements Interceptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AppDio with DioMixin {
|
class AppDio with DioMixin {
|
||||||
String? _proxy = proxy;
|
|
||||||
|
|
||||||
AppDio([BaseOptions? options]) {
|
AppDio([BaseOptions? options]) {
|
||||||
this.options = options ?? BaseOptions();
|
this.options = options ?? BaseOptions();
|
||||||
httpClientAdapter = RHttpAdapter(rhttp.ClientSettings(
|
httpClientAdapter = RHttpAdapter();
|
||||||
proxySettings: proxy == null
|
|
||||||
? const rhttp.ProxySettings.noProxy()
|
|
||||||
: rhttp.ProxySettings.proxy(proxy!),
|
|
||||||
));
|
|
||||||
interceptors.add(CookieManagerSql(SingleInstanceCookieJar.instance!));
|
interceptors.add(CookieManagerSql(SingleInstanceCookieJar.instance!));
|
||||||
interceptors.add(NetworkCacheManager());
|
interceptors.add(NetworkCacheManager());
|
||||||
interceptors.add(CloudflareInterceptor());
|
interceptors.add(CloudflareInterceptor());
|
||||||
interceptors.add(MyLogInterceptor());
|
interceptors.add(MyLogInterceptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
static String? proxy;
|
|
||||||
|
|
||||||
static Future<String?> getProxy() async {
|
|
||||||
if ((appdata.settings['proxy'] as String).removeAllBlank == "direct") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (appdata.settings['proxy'] != "system") return appdata.settings['proxy'];
|
|
||||||
|
|
||||||
String res;
|
|
||||||
if (!App.isLinux) {
|
|
||||||
const channel = MethodChannel("venera/method_channel");
|
|
||||||
try {
|
|
||||||
res = await channel.invokeMethod("getProxy");
|
|
||||||
} catch (e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res = "No Proxy";
|
|
||||||
}
|
|
||||||
if (res == "No Proxy") return null;
|
|
||||||
|
|
||||||
if (res.contains(";")) {
|
|
||||||
var proxies = res.split(";");
|
|
||||||
for (String proxy in proxies) {
|
|
||||||
proxy = proxy.removeAllBlank;
|
|
||||||
if (proxy.startsWith('https=')) {
|
|
||||||
return proxy.substring(6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final RegExp regex = RegExp(
|
|
||||||
r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$',
|
|
||||||
caseSensitive: false,
|
|
||||||
multiLine: false,
|
|
||||||
);
|
|
||||||
if (!regex.hasMatch(res)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static final Map<String, bool> _requests = {};
|
static final Map<String, bool> _requests = {};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -184,16 +137,6 @@ class AppDio with DioMixin {
|
|||||||
_requests[path] = true;
|
_requests[path] = true;
|
||||||
options!.headers!.remove('prevent-parallel');
|
options!.headers!.remove('prevent-parallel');
|
||||||
}
|
}
|
||||||
proxy = await getProxy();
|
|
||||||
if (_proxy != proxy) {
|
|
||||||
Log.info("Network", "Proxy changed to $proxy");
|
|
||||||
_proxy = proxy;
|
|
||||||
httpClientAdapter = RHttpAdapter(rhttp.ClientSettings(
|
|
||||||
proxySettings: proxy == null
|
|
||||||
? const rhttp.ProxySettings.noProxy()
|
|
||||||
: rhttp.ProxySettings.proxy(proxy!),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
return super.request<T>(
|
return super.request<T>(
|
||||||
path,
|
path,
|
||||||
@@ -213,7 +156,26 @@ class AppDio with DioMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RHttpAdapter implements HttpClientAdapter {
|
class RHttpAdapter implements HttpClientAdapter {
|
||||||
rhttp.ClientSettings settings;
|
Future<rhttp.ClientSettings> get settings async {
|
||||||
|
var proxy = await getProxy();
|
||||||
|
|
||||||
|
return rhttp.ClientSettings(
|
||||||
|
proxySettings: proxy == null
|
||||||
|
? const rhttp.ProxySettings.noProxy()
|
||||||
|
: rhttp.ProxySettings.proxy(proxy),
|
||||||
|
redirectSettings: const rhttp.RedirectSettings.limited(5),
|
||||||
|
timeoutSettings: const rhttp.TimeoutSettings(
|
||||||
|
connectTimeout: Duration(seconds: 15),
|
||||||
|
keepAliveTimeout: Duration(seconds: 60),
|
||||||
|
keepAlivePing: Duration(seconds: 30),
|
||||||
|
),
|
||||||
|
throwOnStatusCode: false,
|
||||||
|
dnsSettings: rhttp.DnsSettings.static(overrides: _getOverrides()),
|
||||||
|
tlsSettings: rhttp.TlsSettings(
|
||||||
|
sni: appdata.settings['sni'] != false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static Map<String, List<String>> _getOverrides() {
|
static Map<String, List<String>> _getOverrides() {
|
||||||
if (!appdata.settings['enableDnsOverrides'] == true) {
|
if (!appdata.settings['enableDnsOverrides'] == true) {
|
||||||
@@ -231,22 +193,6 @@ class RHttpAdapter implements HttpClientAdapter {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
RHttpAdapter([this.settings = const rhttp.ClientSettings()]) {
|
|
||||||
settings = settings.copyWith(
|
|
||||||
redirectSettings: const rhttp.RedirectSettings.limited(5),
|
|
||||||
timeoutSettings: const rhttp.TimeoutSettings(
|
|
||||||
connectTimeout: Duration(seconds: 15),
|
|
||||||
keepAliveTimeout: Duration(seconds: 60),
|
|
||||||
keepAlivePing: Duration(seconds: 30),
|
|
||||||
),
|
|
||||||
throwOnStatusCode: false,
|
|
||||||
dnsSettings: rhttp.DnsSettings.static(overrides: _getOverrides()),
|
|
||||||
tlsSettings: rhttp.TlsSettings(
|
|
||||||
sni: appdata.settings['sni'] != false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void close({bool force = false}) {}
|
void close({bool force = false}) {}
|
||||||
|
|
||||||
@@ -256,10 +202,15 @@ class RHttpAdapter implements HttpClientAdapter {
|
|||||||
Stream<Uint8List>? requestStream,
|
Stream<Uint8List>? requestStream,
|
||||||
Future<void>? cancelFuture,
|
Future<void>? cancelFuture,
|
||||||
) async {
|
) async {
|
||||||
|
if (options.headers['User-Agent'] == null &&
|
||||||
|
options.headers['user-agent'] == null) {
|
||||||
|
options.headers['User-Agent'] = "venera/v${App.version}";
|
||||||
|
}
|
||||||
|
|
||||||
var res = await rhttp.Rhttp.request(
|
var res = await rhttp.Rhttp.request(
|
||||||
method: rhttp.HttpMethod(options.method),
|
method: rhttp.HttpMethod(options.method),
|
||||||
url: options.uri.toString(),
|
url: options.uri.toString(),
|
||||||
settings: settings,
|
settings: await settings,
|
||||||
expectBody: rhttp.HttpExpectBody.stream,
|
expectBody: rhttp.HttpExpectBody.stream,
|
||||||
body: requestStream == null ? null : rhttp.HttpBody.stream(requestStream),
|
body: requestStream == null ? null : rhttp.HttpBody.stream(requestStream),
|
||||||
headers: rhttp.HttpHeaders.rawMap(
|
headers: rhttp.HttpHeaders.rawMap(
|
||||||
@@ -299,9 +250,11 @@ class RHttpAdapter implements HttpClientAdapter {
|
|||||||
302 => "Found",
|
302 => "Found",
|
||||||
400 => "Invalid Status Code 400: The Request is invalid.",
|
400 => "Invalid Status Code 400: The Request is invalid.",
|
||||||
401 => "Invalid Status Code 401: The Request is unauthorized.",
|
401 => "Invalid Status Code 401: The Request is unauthorized.",
|
||||||
403 => "Invalid Status Code 403: No permission to access the resource. Check your account or network.",
|
403 =>
|
||||||
|
"Invalid Status Code 403: No permission to access the resource. Check your account or network.",
|
||||||
404 => "Invalid Status Code 404: Not found.",
|
404 => "Invalid Status Code 404: Not found.",
|
||||||
429 => "Invalid Status Code 429: Too many requests. Please try again later.",
|
429 =>
|
||||||
|
"Invalid Status Code 429: Too many requests. Please try again later.",
|
||||||
_ => "Invalid Status Code $statusCode",
|
_ => "Invalid Status Code $statusCode",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:dio/io.dart';
|
import 'package:dio/io.dart';
|
||||||
import 'package:venera/network/app_dio.dart';
|
import 'package:venera/network/app_dio.dart';
|
||||||
|
import 'package:venera/network/proxy.dart';
|
||||||
import 'package:venera/utils/ext.dart';
|
import 'package:venera/utils/ext.dart';
|
||||||
|
|
||||||
class FileDownloader {
|
class FileDownloader {
|
||||||
@@ -105,7 +106,7 @@ class FileDownloader {
|
|||||||
|
|
||||||
void _download(StreamController<DownloadingStatus> resultStream) async {
|
void _download(StreamController<DownloadingStatus> resultStream) async {
|
||||||
try {
|
try {
|
||||||
var proxy = await AppDio.getProxy();
|
var proxy = await getProxy();
|
||||||
_dio.httpClientAdapter = IOHttpClientAdapter(
|
_dio.httpClientAdapter = IOHttpClientAdapter(
|
||||||
createHttpClient: () {
|
createHttpClient: () {
|
||||||
return HttpClient()
|
return HttpClient()
|
||||||
|
60
lib/network/proxy.dart
Normal file
60
lib/network/proxy.dart
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:venera/foundation/app.dart';
|
||||||
|
import 'package:venera/foundation/appdata.dart';
|
||||||
|
import 'package:venera/utils/ext.dart';
|
||||||
|
|
||||||
|
String? _cachedProxy;
|
||||||
|
|
||||||
|
DateTime? _cachedProxyTime;
|
||||||
|
|
||||||
|
Future<String?> getProxy() async {
|
||||||
|
if (_cachedProxyTime != null &&
|
||||||
|
DateTime.now().difference(_cachedProxyTime!).inSeconds < 1) {
|
||||||
|
return _cachedProxy;
|
||||||
|
}
|
||||||
|
String? proxy = await _getProxy();
|
||||||
|
_cachedProxy = proxy;
|
||||||
|
_cachedProxyTime = DateTime.now();
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String?> _getProxy() async {
|
||||||
|
if ((appdata.settings['proxy'] as String).removeAllBlank == "direct") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (appdata.settings['proxy'] != "system") return appdata.settings['proxy'];
|
||||||
|
|
||||||
|
String res;
|
||||||
|
if (!App.isLinux) {
|
||||||
|
const channel = MethodChannel("venera/method_channel");
|
||||||
|
try {
|
||||||
|
res = await channel.invokeMethod("getProxy");
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res = "No Proxy";
|
||||||
|
}
|
||||||
|
if (res == "No Proxy") return null;
|
||||||
|
|
||||||
|
if (res.contains(";")) {
|
||||||
|
var proxies = res.split(";");
|
||||||
|
for (String proxy in proxies) {
|
||||||
|
proxy = proxy.removeAllBlank;
|
||||||
|
if (proxy.startsWith('https=')) {
|
||||||
|
return proxy.substring(6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final RegExp regex = RegExp(
|
||||||
|
r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$',
|
||||||
|
caseSensitive: false,
|
||||||
|
multiLine: false,
|
||||||
|
);
|
||||||
|
if (!regex.hasMatch(res)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
@@ -9,7 +9,7 @@ import 'package:url_launcher/url_launcher_string.dart';
|
|||||||
import 'package:venera/components/components.dart';
|
import 'package:venera/components/components.dart';
|
||||||
import 'package:venera/foundation/app.dart';
|
import 'package:venera/foundation/app.dart';
|
||||||
import 'package:venera/foundation/appdata.dart';
|
import 'package:venera/foundation/appdata.dart';
|
||||||
import 'package:venera/network/app_dio.dart';
|
import 'package:venera/network/proxy.dart';
|
||||||
import 'package:venera/utils/ext.dart';
|
import 'package:venera/utils/ext.dart';
|
||||||
import 'package:venera/utils/translations.dart';
|
import 'package:venera/utils/translations.dart';
|
||||||
import 'dart:io' as io;
|
import 'dart:io' as io;
|
||||||
@@ -308,7 +308,7 @@ class DesktopWebview {
|
|||||||
useWindowPositionAndSize: true,
|
useWindowPositionAndSize: true,
|
||||||
userDataFolderWindows: "${App.dataPath}\\webview",
|
userDataFolderWindows: "${App.dataPath}\\webview",
|
||||||
title: "webview",
|
title: "webview",
|
||||||
proxy: AppDio.proxy,
|
proxy: await getProxy(),
|
||||||
));
|
));
|
||||||
_webview!.addOnWebMessageReceivedCallback(onMessage);
|
_webview!.addOnWebMessageReceivedCallback(onMessage);
|
||||||
_webview!.setOnNavigation((s) {
|
_webview!.setOnNavigation((s) {
|
||||||
|
@@ -11,7 +11,6 @@ import 'package:venera/network/app_dio.dart';
|
|||||||
import 'package:venera/utils/data.dart';
|
import 'package:venera/utils/data.dart';
|
||||||
import 'package:venera/utils/ext.dart';
|
import 'package:venera/utils/ext.dart';
|
||||||
import 'package:webdav_client/webdav_client.dart' hide File;
|
import 'package:webdav_client/webdav_client.dart' hide File;
|
||||||
import 'package:rhttp/rhttp.dart' as rhttp;
|
|
||||||
import 'package:venera/utils/translations.dart';
|
import 'package:venera/utils/translations.dart';
|
||||||
|
|
||||||
import 'io.dart';
|
import 'io.dart';
|
||||||
@@ -119,19 +118,11 @@ class DataSync with ChangeNotifier {
|
|||||||
String user = config[1];
|
String user = config[1];
|
||||||
String pass = config[2];
|
String pass = config[2];
|
||||||
|
|
||||||
var proxy = await AppDio.getProxy();
|
|
||||||
|
|
||||||
var client = newClient(
|
var client = newClient(
|
||||||
url,
|
url,
|
||||||
user: user,
|
user: user,
|
||||||
password: pass,
|
password: pass,
|
||||||
adapter: RHttpAdapter(
|
adapter: RHttpAdapter(),
|
||||||
rhttp.ClientSettings(
|
|
||||||
proxySettings:
|
|
||||||
proxy == null ? null : rhttp.ProxySettings.proxy(proxy),
|
|
||||||
userAgent: "venera v${App.version}",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -192,19 +183,11 @@ class DataSync with ChangeNotifier {
|
|||||||
String user = config[1];
|
String user = config[1];
|
||||||
String pass = config[2];
|
String pass = config[2];
|
||||||
|
|
||||||
var proxy = await AppDio.getProxy();
|
|
||||||
|
|
||||||
var client = newClient(
|
var client = newClient(
|
||||||
url,
|
url,
|
||||||
user: user,
|
user: user,
|
||||||
password: pass,
|
password: pass,
|
||||||
adapter: RHttpAdapter(
|
adapter: RHttpAdapter(),
|
||||||
rhttp.ClientSettings(
|
|
||||||
proxySettings:
|
|
||||||
proxy == null ? null : rhttp.ProxySettings.proxy(proxy),
|
|
||||||
userAgent: "venera v${App.version}",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Reference in New Issue
Block a user