From 5fa62351f2724b9bdab20f2946024767bd7b2d7c Mon Sep 17 00:00:00 2001 From: xkeyC <3334969096@qq.com> Date: Wed, 7 Feb 2024 19:32:36 +0800 Subject: [PATCH] update RSHttp --- lib/api/analytics.dart | 7 +- lib/api/api.dart | 14 +- lib/api/rss.dart | 8 +- lib/common/io/rs_http.dart | 29 +++ lib/common/rust/api/http_api.dart | 53 +++- lib/common/rust/frb_generated.dart | 336 ++++++++++++++++++++---- lib/common/rust/frb_generated.io.dart | 129 ++++++++- lib/common/rust/frb_generated.web.dart | 117 ++++++++- lib/common/rust/http_package.dart | 51 ++++ lib/ui/home/home_ui_model.dart | 6 +- lib/ui/home/webview/webview.dart | 4 +- rust/Cargo.toml | 5 +- rust/src/api/http_api.rs | 66 ++--- rust/src/frb_generated.io.rs | 15 ++ rust/src/frb_generated.rs | 348 +++++++++++++++++++++---- rust/src/frb_generated.web.rs | 15 ++ rust/src/http_package/dns.rs | 58 +++++ rust/src/http_package/mod.rs | 109 ++++++++ rust/src/lib.rs | 1 + 19 files changed, 1202 insertions(+), 169 deletions(-) create mode 100644 lib/common/io/rs_http.dart create mode 100644 lib/common/rust/http_package.dart create mode 100644 rust/src/http_package/dns.rs create mode 100644 rust/src/http_package/mod.rs diff --git a/lib/api/analytics.dart b/lib/api/analytics.dart index e7a59ea..7c82c34 100644 --- a/lib/api/analytics.dart +++ b/lib/api/analytics.dart @@ -2,8 +2,8 @@ import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:starcitizen_doctor/common/conf/url_conf.dart'; +import 'package:starcitizen_doctor/common/io/rs_http.dart'; import 'package:starcitizen_doctor/common/utils/base_utils.dart'; -import 'package:starcitizen_doctor/common/rust/api/http_api.dart' as rust_http; class AnalyticsApi { static touch(String key) async { @@ -11,9 +11,8 @@ class AnalyticsApi { if (kDebugMode) return; dPrint("AnalyticsApi.touch === $key start"); try { - await rust_http.postJsonString( - url: "${URLConf.xkeycApiHome}/analytics/$key", - jsonData: json.encode({"test": "a"})); + await RSHttp.postData("${URLConf.xkeycApiHome}/analytics/$key", + data: utf8.encode(json.encode({"test": "a"})), contentType: "application/json"); dPrint("AnalyticsApi.touch === $key over"); } catch (e) { dPrint("AnalyticsApi.touch === $key Error:$e"); diff --git a/lib/api/api.dart b/lib/api/api.dart index d6d8f30..b1be573 100644 --- a/lib/api/api.dart +++ b/lib/api/api.dart @@ -1,7 +1,7 @@ import 'dart:convert'; import 'package:starcitizen_doctor/common/conf/url_conf.dart'; -import 'package:starcitizen_doctor/common/rust/api/http_api.dart' as rust_http; +import 'package:starcitizen_doctor/common/io/rs_http.dart'; import 'package:starcitizen_doctor/data/app_placard_data.dart'; import 'package:starcitizen_doctor/data/app_version_data.dart'; import 'package:starcitizen_doctor/data/countdown_festival_item_data.dart'; @@ -33,9 +33,8 @@ class Api { static Future> getAppReleaseDataByVersionName( String version) async { - final r = await rust_http.getString( - url: - "${URLConf.gitlabApiPath}/repos/SCToolBox/Release/releases/tags/$version"); + final r = await RSHttp.getText( + "${URLConf.gitlabApiPath}/repos/SCToolBox/Release/releases/tags/$version"); return json.decode(r); } @@ -52,8 +51,8 @@ class Api { } static Future getScServerStatus() async { - final r = await rust_http.getString( - url: "https://status.robertsspaceindustries.com/index.json"); + final r = await RSHttp.getText( + "https://status.robertsspaceindustries.com/index.json"); final map = json.decode(r); return map["systems"]; } @@ -65,8 +64,7 @@ class Api { } static Future getRepoData(String dir, String name) async { - final r = - await rust_http.getString(url: "${URLConf.apiRepoPath}/$dir/$name"); + final r = await RSHttp.getText("${URLConf.apiRepoPath}/$dir/$name"); return r; } } diff --git a/lib/api/rss.dart b/lib/api/rss.dart index 8e06145..98dbd51 100644 --- a/lib/api/rss.dart +++ b/lib/api/rss.dart @@ -1,20 +1,20 @@ import 'dart:io'; import 'package:dart_rss/dart_rss.dart'; -import 'package:starcitizen_doctor/common/rust/api/http_api.dart' as rust_http; +import 'package:starcitizen_doctor/common/io/rs_http.dart'; import 'package:starcitizen_doctor/common/conf/url_conf.dart'; class RSSApi { static Future> getRssVideo() async { - final r = await rust_http.getString(url: URLConf.rssVideoUrl); + final r = await RSHttp.getText(URLConf.rssVideoUrl); final f = RssFeed.parse(r); return f.items.sublist(0, 8); } static Future> getRssText() async { - final r1 = await rust_http.getString(url: URLConf.rssTextUrl1); + final r1 = await RSHttp.getText(URLConf.rssTextUrl1); final r1f = RssFeed.parse(r1); - final r2 = await rust_http.getString(url: URLConf.rssTextUrl2); + final r2 = await RSHttp.getText(URLConf.rssTextUrl2); final r2f = RssFeed.parse(r2); final items = r1f.items..addAll(r2f.items); items.sort((a, b) { diff --git a/lib/common/io/rs_http.dart b/lib/common/io/rs_http.dart new file mode 100644 index 0000000..0554d3b --- /dev/null +++ b/lib/common/io/rs_http.dart @@ -0,0 +1,29 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:starcitizen_doctor/common/rust/api/http_api.dart' as rust_http; +import 'package:starcitizen_doctor/common/rust/api/http_api.dart'; + +class RSHttp { + static Future getText(String url, + {Map? headers}) async { + final r = await rust_http.fetch( + method: MyMethod.gets, url: url, headers: headers); + if (r.data == null) return ""; + final str = utf8.decode(r.data!); + return str; + } + + static Future postData(String url, + {Map? headers, + String? contentType, + Uint8List? data}) async { + if (contentType != null) { + headers ??= {}; + headers["Content-Type"] = contentType; + } + final r = await rust_http.fetch( + method: MyMethod.post, url: url, headers: headers, inputData: data); + return r.statusCode == 200; + } +} diff --git a/lib/common/rust/api/http_api.dart b/lib/common/rust/api/http_api.dart index 553808d..3a4fba4 100644 --- a/lib/common/rust/api/http_api.dart +++ b/lib/common/rust/api/http_api.dart @@ -4,16 +4,53 @@ // ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import import '../frb_generated.dart'; +import '../http_package.dart'; import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; -Future getString( - {required String url, Map? headers, dynamic hint}) => - RustLib.instance.api.getString(url: url, headers: headers, hint: hint); +Future setDefaultHeader( + {required Map headers, dynamic hint}) => + RustLib.instance.api.setDefaultHeader(headers: headers, hint: hint); -Future postJsonString( - {required String url, +Future fetch( + {required MyMethod method, + required String url, Map? headers, - String? jsonData, + Uint8List? inputData, dynamic hint}) => - RustLib.instance.api.postJsonString( - url: url, headers: headers, jsonData: jsonData, hint: hint); + RustLib.instance.api.fetch( + method: method, + url: url, + headers: headers, + inputData: inputData, + hint: hint); + +// Rust type: RustOpaqueMoi> +@sealed +class ReqwestVersion extends RustOpaque { + ReqwestVersion.dcoDecode(List wire) + : super.dcoDecode(wire, _kStaticData); + + ReqwestVersion.sseDecode(int ptr, int externalSizeOnNative) + : super.sseDecode(ptr, externalSizeOnNative, _kStaticData); + + static final _kStaticData = RustArcStaticData( + rustArcIncrementStrongCount: + RustLib.instance.api.rust_arc_increment_strong_count_ReqwestVersion, + rustArcDecrementStrongCount: + RustLib.instance.api.rust_arc_decrement_strong_count_ReqwestVersion, + rustArcDecrementStrongCountPtr: + RustLib.instance.api.rust_arc_decrement_strong_count_ReqwestVersionPtr, + ); +} + +enum MyMethod { + options, + gets, + post, + put, + delete, + head, + trace, + connect, + patch, +} diff --git a/lib/common/rust/frb_generated.dart b/lib/common/rust/frb_generated.dart index d1536a6..95ffb9d 100644 --- a/lib/common/rust/frb_generated.dart +++ b/lib/common/rust/frb_generated.dart @@ -9,6 +9,7 @@ import 'dart:async'; import 'dart:convert'; import 'downloader.dart'; import 'frb_generated.io.dart' if (dart.library.html) 'frb_generated.web.dart'; +import 'http_package.dart'; import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; /// Main entrypoint of the Rust API @@ -73,14 +74,24 @@ abstract class RustLibApi extends BaseApi { required int connectionCount, dynamic hint}); - Future getString( - {required String url, Map? headers, dynamic hint}); - - Future postJsonString( - {required String url, + Future fetch( + {required MyMethod method, + required String url, Map? headers, - String? jsonData, + Uint8List? inputData, dynamic hint}); + + Future setDefaultHeader( + {required Map headers, dynamic hint}); + + RustArcIncrementStrongCountFnType + get rust_arc_increment_strong_count_ReqwestVersion; + + RustArcDecrementStrongCountFnType + get rust_arc_decrement_strong_count_ReqwestVersion; + + CrossPlatformFinalizerArg + get rust_arc_decrement_strong_count_ReqwestVersionPtr; } class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { @@ -150,63 +161,80 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); @override - Future getString( - {required String url, Map? headers, dynamic hint}) { - return handler.executeNormal(NormalTask( - callFfi: (port_) { - final serializer = SseSerializer(generalizedFrbRustBinding); - sse_encode_String(url, serializer); - sse_encode_opt_Map_String_String(headers, serializer); - pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 3, port: port_); - }, - codec: SseCodec( - decodeSuccessData: sse_decode_String, - decodeErrorData: null, - ), - constMeta: kGetStringConstMeta, - argValues: [url, headers], - apiImpl: this, - hint: hint, - )); - } - - TaskConstMeta get kGetStringConstMeta => const TaskConstMeta( - debugName: "get_string", - argNames: ["url", "headers"], - ); - - @override - Future postJsonString( - {required String url, + Future fetch( + {required MyMethod method, + required String url, Map? headers, - String? jsonData, + Uint8List? inputData, dynamic hint}) { return handler.executeNormal(NormalTask( callFfi: (port_) { final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_my_method(method, serializer); sse_encode_String(url, serializer); sse_encode_opt_Map_String_String(headers, serializer); - sse_encode_opt_String(jsonData, serializer); + sse_encode_opt_list_prim_u_8_strict(inputData, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 4, port: port_); }, codec: SseCodec( - decodeSuccessData: sse_decode_String, + decodeSuccessData: sse_decode_rust_http_response, decodeErrorData: null, ), - constMeta: kPostJsonStringConstMeta, - argValues: [url, headers, jsonData], + constMeta: kFetchConstMeta, + argValues: [method, url, headers, inputData], apiImpl: this, hint: hint, )); } - TaskConstMeta get kPostJsonStringConstMeta => const TaskConstMeta( - debugName: "post_json_string", - argNames: ["url", "headers", "jsonData"], + TaskConstMeta get kFetchConstMeta => const TaskConstMeta( + debugName: "fetch", + argNames: ["method", "url", "headers", "inputData"], ); + @override + Future setDefaultHeader( + {required Map headers, dynamic hint}) { + return handler.executeNormal(NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Map_String_String(headers, serializer); + pdeCallFfi(generalizedFrbRustBinding, serializer, + funcId: 3, port: port_); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: null, + ), + constMeta: kSetDefaultHeaderConstMeta, + argValues: [headers], + apiImpl: this, + hint: hint, + )); + } + + TaskConstMeta get kSetDefaultHeaderConstMeta => const TaskConstMeta( + debugName: "set_default_header", + argNames: ["headers"], + ); + + RustArcIncrementStrongCountFnType + get rust_arc_increment_strong_count_ReqwestVersion => wire + .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion; + + RustArcDecrementStrongCountFnType + get rust_arc_decrement_strong_count_ReqwestVersion => wire + .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion; + + @protected + ReqwestVersion + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return ReqwestVersion.dcoDecode(raw as List); + } + @protected Map dco_decode_Map_String_String(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -214,12 +242,26 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { .map((e) => MapEntry(e.$1, e.$2))); } + @protected + ReqwestVersion + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return ReqwestVersion.dcoDecode(raw as List); + } + @protected String dco_decode_String(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs return raw as String; } + @protected + int dco_decode_box_autoadd_u_64(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return dco_decode_u_64(raw); + } + @protected DownloadCallbackData dco_decode_download_callback_data(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -258,9 +300,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { // Codec=Dco (DartCObject based), see doc to use other codecs switch (raw[0]) { case 0: - return MyDownloaderStatus_NoStart(); + return const MyDownloaderStatus_NoStart(); case 1: - return MyDownloaderStatus_Running(); + return const MyDownloaderStatus_Running(); case 2: return MyDownloaderStatus_Pending( dco_decode_my_network_item_pending_type(raw[1]), @@ -270,12 +312,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { dco_decode_String(raw[1]), ); case 4: - return MyDownloaderStatus_Finished(); + return const MyDownloaderStatus_Finished(); default: throw Exception("unreachable"); } } + @protected + MyMethod dco_decode_my_method(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return MyMethod.values[raw as int]; + } + @protected MyNetworkItemPendingType dco_decode_my_network_item_pending_type( dynamic raw) { @@ -290,9 +338,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { } @protected - String? dco_decode_opt_String(dynamic raw) { + int? dco_decode_opt_box_autoadd_u_64(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs - return raw == null ? null : dco_decode_String(raw); + return raw == null ? null : dco_decode_box_autoadd_u_64(raw); + } + + @protected + Uint8List? dco_decode_opt_list_prim_u_8_strict(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return raw == null ? null : dco_decode_list_prim_u_8_strict(raw); } @protected @@ -308,6 +362,31 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + RustHttpResponse dco_decode_rust_http_response(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + final arr = raw as List; + if (arr.length != 7) + throw Exception('unexpected arr length: expect 7 but see ${arr.length}'); + return RustHttpResponse( + statusCode: dco_decode_u_16(arr[0]), + headers: dco_decode_Map_String_String(arr[1]), + url: dco_decode_String(arr[2]), + contentLength: dco_decode_opt_box_autoadd_u_64(arr[3]), + version: + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + arr[4]), + remoteAddr: dco_decode_String(arr[5]), + data: dco_decode_opt_list_prim_u_8_strict(arr[6]), + ); + } + + @protected + int dco_decode_u_16(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return raw as int; + } + @protected int dco_decode_u_64(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -326,6 +405,21 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return; } + @protected + int dco_decode_usize(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return dcoDecodeI64OrU64(raw); + } + + @protected + ReqwestVersion + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return ReqwestVersion.sseDecode( + sse_decode_usize(deserializer), sse_decode_i_32(deserializer)); + } + @protected Map sse_decode_Map_String_String( SseDeserializer deserializer) { @@ -334,6 +428,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return Map.fromEntries(inner.map((e) => MapEntry(e.$1, e.$2))); } + @protected + ReqwestVersion + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return ReqwestVersion.sseDecode( + sse_decode_usize(deserializer), sse_decode_i_32(deserializer)); + } + @protected String sse_decode_String(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -341,6 +444,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return utf8.decoder.convert(inner); } + @protected + int sse_decode_box_autoadd_u_64(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return (sse_decode_u_64(deserializer)); + } + @protected DownloadCallbackData sse_decode_download_callback_data( SseDeserializer deserializer) { @@ -392,9 +501,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { var tag_ = sse_decode_i_32(deserializer); switch (tag_) { case 0: - return MyDownloaderStatus_NoStart(); + return const MyDownloaderStatus_NoStart(); case 1: - return MyDownloaderStatus_Running(); + return const MyDownloaderStatus_Running(); case 2: var var_field0 = sse_decode_my_network_item_pending_type(deserializer); return MyDownloaderStatus_Pending(var_field0); @@ -402,12 +511,19 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { var var_field0 = sse_decode_String(deserializer); return MyDownloaderStatus_Error(var_field0); case 4: - return MyDownloaderStatus_Finished(); + return const MyDownloaderStatus_Finished(); default: throw UnimplementedError(''); } } + @protected + MyMethod sse_decode_my_method(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + var inner = sse_decode_i_32(deserializer); + return MyMethod.values[inner]; + } + @protected MyNetworkItemPendingType sse_decode_my_network_item_pending_type( SseDeserializer deserializer) { @@ -429,11 +545,22 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { } @protected - String? sse_decode_opt_String(SseDeserializer deserializer) { + int? sse_decode_opt_box_autoadd_u_64(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs if (sse_decode_bool(deserializer)) { - return (sse_decode_String(deserializer)); + return (sse_decode_box_autoadd_u_64(deserializer)); + } else { + return null; + } + } + + @protected + Uint8List? sse_decode_opt_list_prim_u_8_strict(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + + if (sse_decode_bool(deserializer)) { + return (sse_decode_list_prim_u_8_strict(deserializer)); } else { return null; } @@ -448,6 +575,34 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return (var_field0, var_field1); } + @protected + RustHttpResponse sse_decode_rust_http_response(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + var var_statusCode = sse_decode_u_16(deserializer); + var var_headers = sse_decode_Map_String_String(deserializer); + var var_url = sse_decode_String(deserializer); + var var_contentLength = sse_decode_opt_box_autoadd_u_64(deserializer); + var var_version = + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + deserializer); + var var_remoteAddr = sse_decode_String(deserializer); + var var_data = sse_decode_opt_list_prim_u_8_strict(deserializer); + return RustHttpResponse( + statusCode: var_statusCode, + headers: var_headers, + url: var_url, + contentLength: var_contentLength, + version: var_version, + remoteAddr: var_remoteAddr, + data: var_data); + } + + @protected + int sse_decode_u_16(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return deserializer.buffer.getUint16(); + } + @protected int sse_decode_u_64(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -465,12 +620,26 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { // Codec=Sse (Serialization based), see doc to use other codecs } + @protected + int sse_decode_usize(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return deserializer.buffer.getUint64(); + } + @protected bool sse_decode_bool(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs return deserializer.buffer.getUint8() != 0; } + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ReqwestVersion self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize(self.sseEncode(move: true), serializer); + } + @protected void sse_encode_Map_String_String( Map self, SseSerializer serializer) { @@ -479,12 +648,26 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { self.entries.map((e) => (e.key, e.value)).toList(), serializer); } + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ReqwestVersion self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize(self.sseEncode(move: null), serializer); + } + @protected void sse_encode_String(String self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs sse_encode_list_prim_u_8_strict(utf8.encoder.convert(self), serializer); } + @protected + void sse_encode_box_autoadd_u_64(int self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_u_64(self, serializer); + } + @protected void sse_encode_download_callback_data( DownloadCallbackData self, SseSerializer serializer) { @@ -540,6 +723,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { } } + @protected + void sse_encode_my_method(MyMethod self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_i_32(self.index, serializer); + } + @protected void sse_encode_my_network_item_pending_type( MyNetworkItemPendingType self, SseSerializer serializer) { @@ -559,12 +748,23 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { } @protected - void sse_encode_opt_String(String? self, SseSerializer serializer) { + void sse_encode_opt_box_autoadd_u_64(int? self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs sse_encode_bool(self != null, serializer); if (self != null) { - sse_encode_String(self, serializer); + sse_encode_box_autoadd_u_64(self, serializer); + } + } + + @protected + void sse_encode_opt_list_prim_u_8_strict( + Uint8List? self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + + sse_encode_bool(self != null, serializer); + if (self != null) { + sse_encode_list_prim_u_8_strict(self, serializer); } } @@ -576,6 +776,26 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_String(self.$2, serializer); } + @protected + void sse_encode_rust_http_response( + RustHttpResponse self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_u_16(self.statusCode, serializer); + sse_encode_Map_String_String(self.headers, serializer); + sse_encode_String(self.url, serializer); + sse_encode_opt_box_autoadd_u_64(self.contentLength, serializer); + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + self.version, serializer); + sse_encode_String(self.remoteAddr, serializer); + sse_encode_opt_list_prim_u_8_strict(self.data, serializer); + } + + @protected + void sse_encode_u_16(int self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + serializer.buffer.putUint16(self); + } + @protected void sse_encode_u_64(int self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -593,6 +813,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { // Codec=Sse (Serialization based), see doc to use other codecs } + @protected + void sse_encode_usize(int self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + serializer.buffer.putUint64(self); + } + @protected void sse_encode_bool(bool self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs diff --git a/lib/common/rust/frb_generated.io.dart b/lib/common/rust/frb_generated.io.dart index c220334..0700dc8 100644 --- a/lib/common/rust/frb_generated.io.dart +++ b/lib/common/rust/frb_generated.io.dart @@ -10,6 +10,7 @@ import 'dart:convert'; import 'dart:ffi' as ffi; import 'downloader.dart'; import 'frb_generated.dart'; +import 'http_package.dart'; import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_io.dart'; abstract class RustLibApiImplPlatform extends BaseApiImpl { @@ -20,12 +21,29 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { required super.portManager, }); + CrossPlatformFinalizerArg + get rust_arc_decrement_strong_count_ReqwestVersionPtr => wire + ._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersionPtr; + + @protected + ReqwestVersion + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + dynamic raw); + @protected Map dco_decode_Map_String_String(dynamic raw); + @protected + ReqwestVersion + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + dynamic raw); + @protected String dco_decode_String(dynamic raw); + @protected + int dco_decode_box_autoadd_u_64(dynamic raw); + @protected DownloadCallbackData dco_decode_download_callback_data(dynamic raw); @@ -41,6 +59,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected MyDownloaderStatus dco_decode_my_downloader_status(dynamic raw); + @protected + MyMethod dco_decode_my_method(dynamic raw); + @protected MyNetworkItemPendingType dco_decode_my_network_item_pending_type(dynamic raw); @@ -48,11 +69,20 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { Map? dco_decode_opt_Map_String_String(dynamic raw); @protected - String? dco_decode_opt_String(dynamic raw); + int? dco_decode_opt_box_autoadd_u_64(dynamic raw); + + @protected + Uint8List? dco_decode_opt_list_prim_u_8_strict(dynamic raw); @protected (String, String) dco_decode_record_string_string(dynamic raw); + @protected + RustHttpResponse dco_decode_rust_http_response(dynamic raw); + + @protected + int dco_decode_u_16(dynamic raw); + @protected int dco_decode_u_64(dynamic raw); @@ -62,13 +92,29 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void dco_decode_unit(dynamic raw); + @protected + int dco_decode_usize(dynamic raw); + + @protected + ReqwestVersion + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + SseDeserializer deserializer); + @protected Map sse_decode_Map_String_String( SseDeserializer deserializer); + @protected + ReqwestVersion + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + SseDeserializer deserializer); + @protected String sse_decode_String(SseDeserializer deserializer); + @protected + int sse_decode_box_autoadd_u_64(SseDeserializer deserializer); + @protected DownloadCallbackData sse_decode_download_callback_data( SseDeserializer deserializer); @@ -87,6 +133,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { MyDownloaderStatus sse_decode_my_downloader_status( SseDeserializer deserializer); + @protected + MyMethod sse_decode_my_method(SseDeserializer deserializer); + @protected MyNetworkItemPendingType sse_decode_my_network_item_pending_type( SseDeserializer deserializer); @@ -96,12 +145,21 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer); @protected - String? sse_decode_opt_String(SseDeserializer deserializer); + int? sse_decode_opt_box_autoadd_u_64(SseDeserializer deserializer); + + @protected + Uint8List? sse_decode_opt_list_prim_u_8_strict(SseDeserializer deserializer); @protected (String, String) sse_decode_record_string_string( SseDeserializer deserializer); + @protected + RustHttpResponse sse_decode_rust_http_response(SseDeserializer deserializer); + + @protected + int sse_decode_u_16(SseDeserializer deserializer); + @protected int sse_decode_u_64(SseDeserializer deserializer); @@ -111,16 +169,32 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_decode_unit(SseDeserializer deserializer); + @protected + int sse_decode_usize(SseDeserializer deserializer); + @protected bool sse_decode_bool(SseDeserializer deserializer); + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ReqwestVersion self, SseSerializer serializer); + @protected void sse_encode_Map_String_String( Map self, SseSerializer serializer); + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ReqwestVersion self, SseSerializer serializer); + @protected void sse_encode_String(String self, SseSerializer serializer); + @protected + void sse_encode_box_autoadd_u_64(int self, SseSerializer serializer); + @protected void sse_encode_download_callback_data( DownloadCallbackData self, SseSerializer serializer); @@ -140,6 +214,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { void sse_encode_my_downloader_status( MyDownloaderStatus self, SseSerializer serializer); + @protected + void sse_encode_my_method(MyMethod self, SseSerializer serializer); + @protected void sse_encode_my_network_item_pending_type( MyNetworkItemPendingType self, SseSerializer serializer); @@ -149,12 +226,23 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { Map? self, SseSerializer serializer); @protected - void sse_encode_opt_String(String? self, SseSerializer serializer); + void sse_encode_opt_box_autoadd_u_64(int? self, SseSerializer serializer); + + @protected + void sse_encode_opt_list_prim_u_8_strict( + Uint8List? self, SseSerializer serializer); @protected void sse_encode_record_string_string( (String, String) self, SseSerializer serializer); + @protected + void sse_encode_rust_http_response( + RustHttpResponse self, SseSerializer serializer); + + @protected + void sse_encode_u_16(int self, SseSerializer serializer); + @protected void sse_encode_u_64(int self, SseSerializer serializer); @@ -164,6 +252,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_unit(void self, SseSerializer serializer); + @protected + void sse_encode_usize(int self, SseSerializer serializer); + @protected void sse_encode_bool(bool self, SseSerializer serializer); } @@ -181,4 +272,36 @@ class RustLibWire implements BaseWire { /// The symbols are looked up in [dynamicLibrary]. RustLibWire(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup; + + void + rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ffi.Pointer ptr, + ) { + return _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ptr, + ); + } + + late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersionPtr = + _lookup)>>( + 'frbgen_starcitizen_doctor_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion'); + late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion = + _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersionPtr + .asFunction)>(); + + void + rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ffi.Pointer ptr, + ) { + return _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ptr, + ); + } + + late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersionPtr = + _lookup)>>( + 'frbgen_starcitizen_doctor_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion'); + late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion = + _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersionPtr + .asFunction)>(); } diff --git a/lib/common/rust/frb_generated.web.dart b/lib/common/rust/frb_generated.web.dart index 9f78068..eda2260 100644 --- a/lib/common/rust/frb_generated.web.dart +++ b/lib/common/rust/frb_generated.web.dart @@ -9,6 +9,7 @@ import 'dart:async'; import 'dart:convert'; import 'downloader.dart'; import 'frb_generated.dart'; +import 'http_package.dart'; import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_web.dart'; abstract class RustLibApiImplPlatform extends BaseApiImpl { @@ -19,12 +20,29 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { required super.portManager, }); + CrossPlatformFinalizerArg + get rust_arc_decrement_strong_count_ReqwestVersionPtr => wire + .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion; + + @protected + ReqwestVersion + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + dynamic raw); + @protected Map dco_decode_Map_String_String(dynamic raw); + @protected + ReqwestVersion + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + dynamic raw); + @protected String dco_decode_String(dynamic raw); + @protected + int dco_decode_box_autoadd_u_64(dynamic raw); + @protected DownloadCallbackData dco_decode_download_callback_data(dynamic raw); @@ -40,6 +58,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected MyDownloaderStatus dco_decode_my_downloader_status(dynamic raw); + @protected + MyMethod dco_decode_my_method(dynamic raw); + @protected MyNetworkItemPendingType dco_decode_my_network_item_pending_type(dynamic raw); @@ -47,11 +68,20 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { Map? dco_decode_opt_Map_String_String(dynamic raw); @protected - String? dco_decode_opt_String(dynamic raw); + int? dco_decode_opt_box_autoadd_u_64(dynamic raw); + + @protected + Uint8List? dco_decode_opt_list_prim_u_8_strict(dynamic raw); @protected (String, String) dco_decode_record_string_string(dynamic raw); + @protected + RustHttpResponse dco_decode_rust_http_response(dynamic raw); + + @protected + int dco_decode_u_16(dynamic raw); + @protected int dco_decode_u_64(dynamic raw); @@ -61,13 +91,29 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void dco_decode_unit(dynamic raw); + @protected + int dco_decode_usize(dynamic raw); + + @protected + ReqwestVersion + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + SseDeserializer deserializer); + @protected Map sse_decode_Map_String_String( SseDeserializer deserializer); + @protected + ReqwestVersion + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + SseDeserializer deserializer); + @protected String sse_decode_String(SseDeserializer deserializer); + @protected + int sse_decode_box_autoadd_u_64(SseDeserializer deserializer); + @protected DownloadCallbackData sse_decode_download_callback_data( SseDeserializer deserializer); @@ -86,6 +132,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { MyDownloaderStatus sse_decode_my_downloader_status( SseDeserializer deserializer); + @protected + MyMethod sse_decode_my_method(SseDeserializer deserializer); + @protected MyNetworkItemPendingType sse_decode_my_network_item_pending_type( SseDeserializer deserializer); @@ -95,12 +144,21 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer); @protected - String? sse_decode_opt_String(SseDeserializer deserializer); + int? sse_decode_opt_box_autoadd_u_64(SseDeserializer deserializer); + + @protected + Uint8List? sse_decode_opt_list_prim_u_8_strict(SseDeserializer deserializer); @protected (String, String) sse_decode_record_string_string( SseDeserializer deserializer); + @protected + RustHttpResponse sse_decode_rust_http_response(SseDeserializer deserializer); + + @protected + int sse_decode_u_16(SseDeserializer deserializer); + @protected int sse_decode_u_64(SseDeserializer deserializer); @@ -110,16 +168,32 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_decode_unit(SseDeserializer deserializer); + @protected + int sse_decode_usize(SseDeserializer deserializer); + @protected bool sse_decode_bool(SseDeserializer deserializer); + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ReqwestVersion self, SseSerializer serializer); + @protected void sse_encode_Map_String_String( Map self, SseSerializer serializer); + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ReqwestVersion self, SseSerializer serializer); + @protected void sse_encode_String(String self, SseSerializer serializer); + @protected + void sse_encode_box_autoadd_u_64(int self, SseSerializer serializer); + @protected void sse_encode_download_callback_data( DownloadCallbackData self, SseSerializer serializer); @@ -139,6 +213,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { void sse_encode_my_downloader_status( MyDownloaderStatus self, SseSerializer serializer); + @protected + void sse_encode_my_method(MyMethod self, SseSerializer serializer); + @protected void sse_encode_my_network_item_pending_type( MyNetworkItemPendingType self, SseSerializer serializer); @@ -148,12 +225,23 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { Map? self, SseSerializer serializer); @protected - void sse_encode_opt_String(String? self, SseSerializer serializer); + void sse_encode_opt_box_autoadd_u_64(int? self, SseSerializer serializer); + + @protected + void sse_encode_opt_list_prim_u_8_strict( + Uint8List? self, SseSerializer serializer); @protected void sse_encode_record_string_string( (String, String) self, SseSerializer serializer); + @protected + void sse_encode_rust_http_response( + RustHttpResponse self, SseSerializer serializer); + + @protected + void sse_encode_u_16(int self, SseSerializer serializer); + @protected void sse_encode_u_64(int self, SseSerializer serializer); @@ -163,6 +251,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_unit(void self, SseSerializer serializer); + @protected + void sse_encode_usize(int self, SseSerializer serializer); + @protected void sse_encode_bool(bool self, SseSerializer serializer); } @@ -171,6 +262,18 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { class RustLibWire implements BaseWire { RustLibWire.fromExternalLibrary(ExternalLibrary lib); + + void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + dynamic ptr) => + wasmModule + .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ptr); + + void rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + dynamic ptr) => + wasmModule + .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ptr); } @JS('wasm_bindgen') @@ -184,4 +287,12 @@ class RustLibWasmModule implements WasmModule { @override external RustLibWasmModule bind(dynamic thisArg, String moduleName); + + external void + rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + dynamic ptr); + + external void + rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + dynamic ptr); } diff --git a/lib/common/rust/http_package.dart b/lib/common/rust/http_package.dart new file mode 100644 index 0000000..8024b38 --- /dev/null +++ b/lib/common/rust/http_package.dart @@ -0,0 +1,51 @@ +// This file is automatically generated, so please do not edit it. +// Generated by `flutter_rust_bridge`@ 2.0.0-dev.23. + +// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import + +import 'api/http_api.dart'; +import 'frb_generated.dart'; +import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; + +class RustHttpResponse { + final int statusCode; + final Map headers; + final String url; + final int? contentLength; + final ReqwestVersion version; + final String remoteAddr; + final Uint8List? data; + + const RustHttpResponse({ + required this.statusCode, + required this.headers, + required this.url, + this.contentLength, + required this.version, + required this.remoteAddr, + this.data, + }); + + @override + int get hashCode => + statusCode.hashCode ^ + headers.hashCode ^ + url.hashCode ^ + contentLength.hashCode ^ + version.hashCode ^ + remoteAddr.hashCode ^ + data.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is RustHttpResponse && + runtimeType == other.runtimeType && + statusCode == other.statusCode && + headers == other.headers && + url == other.url && + contentLength == other.contentLength && + version == other.version && + remoteAddr == other.remoteAddr && + data == other.data; +} diff --git a/lib/ui/home/home_ui_model.dart b/lib/ui/home/home_ui_model.dart index 9647369..852d9b1 100644 --- a/lib/ui/home/home_ui_model.dart +++ b/lib/ui/home/home_ui_model.dart @@ -4,7 +4,7 @@ import 'dart:io'; import 'package:dart_rss/dart_rss.dart'; import 'package:desktop_webview_window/desktop_webview_window.dart'; -import 'package:starcitizen_doctor/common/rust/api/http_api.dart' as rust_http; +import 'package:starcitizen_doctor/common/io/rs_http.dart'; import 'package:hive/hive.dart'; import 'package:starcitizen_doctor/api/analytics.dart'; import 'package:starcitizen_doctor/api/api.dart'; @@ -107,8 +107,8 @@ class HomeUIModel extends BaseUIModel { updateSCServerStatus(); notifyListeners(); appWebLocalizationVersionsData = AppWebLocalizationVersionsData.fromJson( - json.decode((await rust_http.getString( - url: "${URLConf.webTranslateHomeUrl}/versions.json")))); + json.decode((await RSHttp.getText( + "${URLConf.webTranslateHomeUrl}/versions.json")))); countdownFestivalListData = await Api.getFestivalCountdownList(); notifyListeners(); _loadRRS(); diff --git a/lib/ui/home/webview/webview.dart b/lib/ui/home/webview/webview.dart index 22dc4da..c50df55 100644 --- a/lib/ui/home/webview/webview.dart +++ b/lib/ui/home/webview/webview.dart @@ -10,9 +10,9 @@ import 'package:hive/hive.dart'; import 'package:local_auth/local_auth.dart'; import 'package:starcitizen_doctor/common/conf/app_conf.dart'; import 'package:starcitizen_doctor/common/conf/url_conf.dart'; +import 'package:starcitizen_doctor/common/io/rs_http.dart'; import 'package:starcitizen_doctor/common/win32/credentials.dart'; import 'package:starcitizen_doctor/data/app_web_localization_versions_data.dart'; -import 'package:starcitizen_doctor/common/rust/api/http_api.dart' as rust_http; import '../../../base/ui.dart'; @@ -256,7 +256,7 @@ class WebViewModel { } } final startTime = DateTime.now(); - final r = await rust_http.getString(url: url); + final r = await RSHttp.getText(url); final endTime = DateTime.now(); final data = json.decode(r); if (cacheKey.isNotEmpty) { diff --git a/rust/Cargo.toml b/rust/Cargo.toml index bd66a3c..730c1a9 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -13,6 +13,7 @@ tokio = { version = "1", features = ["full"] } url = "2.5.0" uuid = { version = "1.7.0", features = ["v4", "fast-rng", "macro-diagnostics"] } async-std = "1.12.0" +hyper = { version = "0.14.28"} once_cell = "1.19.0" -reqwest = { version = "0.11", features = ["rustls-tls-native-roots", "cookies", "gzip", "brotli", "deflate", "multipart", "trust-dns", "json"] } -serde_json = { version = "1.0.1", features = [] } \ No newline at end of file +reqwest = { version = "0.11", features = ["rustls-tls-native-roots", "cookies", "gzip", "brotli", "deflate", "multipart", "trust-dns", "json","stream"] } +hickory-resolver = {version = "0.24.0", features = [ "dns-over-https-rustls","dns-over-rustls","native-certs"]} diff --git a/rust/src/api/http_api.rs b/rust/src/api/http_api.rs index fecfbab..281a811 100644 --- a/rust/src/api/http_api.rs +++ b/rust/src/api/http_api.rs @@ -1,40 +1,42 @@ use std::collections::HashMap; -use std::time::Duration; -use once_cell::sync::Lazy; -use reqwest; -use reqwest::header::{HeaderMap, HeaderValue}; -use reqwest::RequestBuilder; - -static HTTP_CLIENT: Lazy = Lazy::new(|| { - let mut header_map = HeaderMap::new(); - header_map.insert("User-Agent", HeaderValue::from_static("SCToolBox/2.10.x lib_rust_http")); - reqwest::Client::builder() - .use_rustls_tls() - .connect_timeout(Duration::from_secs(10)) - .timeout(Duration::from_secs(10)) - .default_headers(header_map).build().unwrap() -}); +use hyper::Method; +use crate::http_package; +use crate::http_package::RustHttpResponse; -#[tokio::main] -pub async fn get_string(url: String, headers: Option>) -> String { - let mut req = _append_header(HTTP_CLIENT.get(url), headers); - req.send().await.unwrap().text().await.unwrap() +pub enum MyMethod { + Options, + Gets, + Post, + Put, + Delete, + Head, + Trace, + Connect, + Patch, } -pub async fn post_json_string(url: String, headers: Option>, json_data: Option) -> String { - let mut req = _append_header(HTTP_CLIENT.post(url), headers); - if json_data.is_some() { - req = req.body(json_data.unwrap()).header(reqwest::header::CONTENT_TYPE, "application/json"); - } - req.send().await.unwrap().text().await.unwrap() +fn _my_method_to_hyper_method(m: MyMethod) -> Method { + return match m { + MyMethod::Options => { Method::OPTIONS } + MyMethod::Gets => { Method::GET } + MyMethod::Post => { Method::POST } + MyMethod::Put => { Method::PUT } + MyMethod::Delete => { Method::DELETE } + MyMethod::Head => { Method::HEAD } + MyMethod::Trace => { Method::TRACE } + MyMethod::Connect => { Method::CONNECT } + MyMethod::Patch => { Method::PATCH } + }; } -fn _append_header(mut req: RequestBuilder, headers: Option>) -> RequestBuilder { - if headers.is_some() { - for x in headers.unwrap() { - req = req.header(x.0, x.1); - } - } - req +pub fn set_default_header(headers: HashMap) { + http_package::set_default_header(headers) +} + +pub async fn fetch(method: MyMethod, + url: String, + headers: Option>, + input_data: Option>) -> RustHttpResponse { + http_package::fetch(_my_method_to_hyper_method(method), url, headers, input_data).await.unwrap() } \ No newline at end of file diff --git a/rust/src/frb_generated.io.rs b/rust/src/frb_generated.io.rs index a8a3b15..202bd3b 100644 --- a/rust/src/frb_generated.io.rs +++ b/rust/src/frb_generated.io.rs @@ -4,6 +4,7 @@ // Section: imports use super::*; +use crate::api::http_api::*; use flutter_rust_bridge::for_generated::byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt}; use flutter_rust_bridge::for_generated::transform_result_dco; use flutter_rust_bridge::{Handler, IntoIntoDart}; @@ -11,3 +12,17 @@ use flutter_rust_bridge::{Handler, IntoIntoDart}; // Section: boilerplate flutter_rust_bridge::frb_generated_boilerplate_io!(); + +#[no_mangle] +pub extern "C" fn frbgen_starcitizen_doctor_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ptr: *const std::ffi::c_void, +) { + MoiArc::>::increment_strong_count(ptr as _); +} + +#[no_mangle] +pub extern "C" fn frbgen_starcitizen_doctor_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ptr: *const std::ffi::c_void, +) { + MoiArc::>::decrement_strong_count(ptr as _); +} diff --git a/rust/src/frb_generated.rs b/rust/src/frb_generated.rs index d1e90ae..a87fef6 100644 --- a/rust/src/frb_generated.rs +++ b/rust/src/frb_generated.rs @@ -19,6 +19,7 @@ // Section: imports +use crate::api::http_api::*; use flutter_rust_bridge::for_generated::byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt}; use flutter_rust_bridge::for_generated::transform_result_dco; use flutter_rust_bridge::{Handler, IntoIntoDart}; @@ -120,41 +121,7 @@ fn wire_start_download_impl( }, ) } -fn wire_get_string_impl( - port_: flutter_rust_bridge::for_generated::MessagePort, - ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, - rust_vec_len_: i32, - data_len_: i32, -) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( - flutter_rust_bridge::for_generated::TaskInfo { - debug_name: "get_string", - port: Some(port_), - mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, - }, - move || { - let message = unsafe { - flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( - ptr_, - rust_vec_len_, - data_len_, - ) - }; - let mut deserializer = - flutter_rust_bridge::for_generated::SseDeserializer::new(message); - let api_url = ::sse_decode(&mut deserializer); - let api_headers = - >>::sse_decode(&mut deserializer); - deserializer.end(); - move |context| { - transform_result_sse((move || { - Result::<_, ()>::Ok(crate::api::http_api::get_string(api_url, api_headers)) - })()) - } - }, - ) -} -fn wire_post_json_string_impl( +fn wire_fetch_impl( port_: flutter_rust_bridge::for_generated::MessagePort, ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, rust_vec_len_: i32, @@ -162,7 +129,7 @@ fn wire_post_json_string_impl( ) { FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::( flutter_rust_bridge::for_generated::TaskInfo { - debug_name: "post_json_string", + debug_name: "fetch", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, }, @@ -176,19 +143,21 @@ fn wire_post_json_string_impl( }; let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_method = ::sse_decode(&mut deserializer); let api_url = ::sse_decode(&mut deserializer); let api_headers = >>::sse_decode(&mut deserializer); - let api_json_data = >::sse_decode(&mut deserializer); + let api_input_data = >>::sse_decode(&mut deserializer); deserializer.end(); move |context| async move { transform_result_sse( (move || async move { Result::<_, ()>::Ok( - crate::api::http_api::post_json_string( + crate::api::http_api::fetch( + api_method, api_url, api_headers, - api_json_data, + api_input_data, ) .await, ) @@ -199,9 +168,58 @@ fn wire_post_json_string_impl( }, ) } +fn wire_set_default_header_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "set_default_header", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_headers = + >::sse_decode(&mut deserializer); + deserializer.end(); + move |context| { + transform_result_sse((move || { + Result::<_, ()>::Ok(crate::api::http_api::set_default_header(api_headers)) + })()) + } + }, + ) +} + +// Section: related_funcs + +flutter_rust_bridge::frb_generated_moi_arc_impl_value!( + flutter_rust_bridge::for_generated::rust_async::RwLock +); // Section: dart2rust +impl SseDecode for reqwest::Version { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = , + >>::sse_decode(deserializer); + return inner.rust_auto_opaque_decode_owned(); + } +} + impl SseDecode for std::collections::HashMap { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -210,6 +228,16 @@ impl SseDecode for std::collections::HashMap { } } +impl SseDecode + for RustOpaqueMoi> +{ + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = ::sse_decode(deserializer); + return decode_rust_opaque_moi(inner); + } +} + impl SseDecode for String { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -297,6 +325,25 @@ impl SseDecode for crate::downloader::MyDownloaderStatus { } } +impl SseDecode for crate::api::http_api::MyMethod { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = ::sse_decode(deserializer); + return match inner { + 0 => crate::api::http_api::MyMethod::Options, + 1 => crate::api::http_api::MyMethod::Gets, + 2 => crate::api::http_api::MyMethod::Post, + 3 => crate::api::http_api::MyMethod::Put, + 4 => crate::api::http_api::MyMethod::Delete, + 5 => crate::api::http_api::MyMethod::Head, + 6 => crate::api::http_api::MyMethod::Trace, + 7 => crate::api::http_api::MyMethod::Connect, + 8 => crate::api::http_api::MyMethod::Patch, + _ => unreachable!("Invalid variant for MyMethod: {}", inner), + }; + } +} + impl SseDecode for crate::downloader::MyNetworkItemPendingType { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -324,11 +371,22 @@ impl SseDecode for Option> { } } -impl SseDecode for Option { +impl SseDecode for Option { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { if (::sse_decode(deserializer)) { - return Some(::sse_decode(deserializer)); + return Some(::sse_decode(deserializer)); + } else { + return None; + } + } +} + +impl SseDecode for Option> { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + if (::sse_decode(deserializer)) { + return Some(>::sse_decode(deserializer)); } else { return None; } @@ -344,6 +402,35 @@ impl SseDecode for (String, String) { } } +impl SseDecode for crate::http_package::RustHttpResponse { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut var_statusCode = ::sse_decode(deserializer); + let mut var_headers = >::sse_decode(deserializer); + let mut var_url = ::sse_decode(deserializer); + let mut var_contentLength = >::sse_decode(deserializer); + let mut var_version = ::sse_decode(deserializer); + let mut var_remoteAddr = ::sse_decode(deserializer); + let mut var_data = >>::sse_decode(deserializer); + return crate::http_package::RustHttpResponse { + status_code: var_statusCode, + headers: var_headers, + url: var_url, + content_length: var_contentLength, + version: var_version, + remote_addr: var_remoteAddr, + data: var_data, + }; + } +} + +impl SseDecode for u16 { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + deserializer.cursor.read_u16::().unwrap() + } +} + impl SseDecode for u64 { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -363,6 +450,13 @@ impl SseDecode for () { fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {} } +impl SseDecode for usize { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + deserializer.cursor.read_u64::().unwrap() as _ + } +} + impl SseDecode for bool { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -381,8 +475,8 @@ fn pde_ffi_dispatcher_primary_impl( match func_id { 2 => wire_cancel_download_impl(port, ptr, rust_vec_len, data_len), 1 => wire_start_download_impl(port, ptr, rust_vec_len, data_len), - 3 => wire_get_string_impl(port, ptr, rust_vec_len, data_len), - 4 => wire_post_json_string_impl(port, ptr, rust_vec_len, data_len), + 4 => wire_fetch_impl(port, ptr, rust_vec_len, data_len), + 3 => wire_set_default_header_impl(port, ptr, rust_vec_len, data_len), _ => unreachable!(), } } @@ -401,6 +495,36 @@ fn pde_ffi_dispatcher_sync_impl( // Section: rust2dart +pub struct Local_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + reqwest::Version, +); +// Codec=Dco (DartCObject based), see doc to use other codecs +impl flutter_rust_bridge::IntoDart + for Local_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion +{ + fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { + flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self.0) + .into_dart() + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive + for Local_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion +{ +} +impl + flutter_rust_bridge::IntoIntoDart< + Local_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion, + > for reqwest::Version +{ + fn into_into_dart( + self, + ) -> Local_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion + { + Local_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + self, + ) + } +} // Codec=Dco (DartCObject based), see doc to use other codecs impl flutter_rust_bridge::IntoDart for crate::downloader::DownloadCallbackData { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { @@ -453,6 +577,33 @@ impl flutter_rust_bridge::IntoIntoDart } } // Codec=Dco (DartCObject based), see doc to use other codecs +impl flutter_rust_bridge::IntoDart for crate::api::http_api::MyMethod { + fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { + match self { + Self::Options => 0.into_dart(), + Self::Gets => 1.into_dart(), + Self::Post => 2.into_dart(), + Self::Put => 3.into_dart(), + Self::Delete => 4.into_dart(), + Self::Head => 5.into_dart(), + Self::Trace => 6.into_dart(), + Self::Connect => 7.into_dart(), + Self::Patch => 8.into_dart(), + } + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive + for crate::api::http_api::MyMethod +{ +} +impl flutter_rust_bridge::IntoIntoDart + for crate::api::http_api::MyMethod +{ + fn into_into_dart(self) -> crate::api::http_api::MyMethod { + self + } +} +// Codec=Dco (DartCObject based), see doc to use other codecs impl flutter_rust_bridge::IntoDart for crate::downloader::MyNetworkItemPendingType { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { match self { @@ -474,6 +625,39 @@ impl flutter_rust_bridge::IntoIntoDart flutter_rust_bridge::for_generated::DartAbi { + [ + self.status_code.into_into_dart().into_dart(), + self.headers.into_into_dart().into_dart(), + self.url.into_into_dart().into_dart(), + self.content_length.into_into_dart().into_dart(), + self.version.into_into_dart().into_dart(), + self.remote_addr.into_into_dart().into_dart(), + self.data.into_into_dart().into_dart(), + ] + .into_dart() + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive + for crate::http_package::RustHttpResponse +{ +} +impl flutter_rust_bridge::IntoIntoDart + for crate::http_package::RustHttpResponse +{ + fn into_into_dart(self) -> crate::http_package::RustHttpResponse { + self + } +} + +impl SseEncode for reqwest::Version { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + >>::sse_encode(flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self), serializer); + } +} impl SseEncode for std::collections::HashMap { // Codec=Sse (Serialization based), see doc to use other codecs @@ -482,6 +666,17 @@ impl SseEncode for std::collections::HashMap { } } +impl SseEncode + for RustOpaqueMoi> +{ + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + let (ptr, size) = self.sse_encode_raw(); + ::sse_encode(ptr, serializer); + ::sse_encode(size, serializer); + } +} + impl SseEncode for String { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { @@ -552,6 +747,29 @@ impl SseEncode for crate::downloader::MyDownloaderStatus { } } +impl SseEncode for crate::api::http_api::MyMethod { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + ::sse_encode( + match self { + crate::api::http_api::MyMethod::Options => 0, + crate::api::http_api::MyMethod::Gets => 1, + crate::api::http_api::MyMethod::Post => 2, + crate::api::http_api::MyMethod::Put => 3, + crate::api::http_api::MyMethod::Delete => 4, + crate::api::http_api::MyMethod::Head => 5, + crate::api::http_api::MyMethod::Trace => 6, + crate::api::http_api::MyMethod::Connect => 7, + crate::api::http_api::MyMethod::Patch => 8, + _ => { + unimplemented!(""); + } + }, + serializer, + ); + } +} + impl SseEncode for crate::downloader::MyNetworkItemPendingType { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { @@ -580,12 +798,22 @@ impl SseEncode for Option> { } } -impl SseEncode for Option { +impl SseEncode for Option { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { ::sse_encode(self.is_some(), serializer); if let Some(value) = self { - ::sse_encode(value, serializer); + ::sse_encode(value, serializer); + } + } +} + +impl SseEncode for Option> { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + ::sse_encode(self.is_some(), serializer); + if let Some(value) = self { + >::sse_encode(value, serializer); } } } @@ -598,6 +826,26 @@ impl SseEncode for (String, String) { } } +impl SseEncode for crate::http_package::RustHttpResponse { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + ::sse_encode(self.status_code, serializer); + >::sse_encode(self.headers, serializer); + ::sse_encode(self.url, serializer); + >::sse_encode(self.content_length, serializer); + ::sse_encode(self.version, serializer); + ::sse_encode(self.remote_addr, serializer); + >>::sse_encode(self.data, serializer); + } +} + +impl SseEncode for u16 { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + serializer.cursor.write_u16::(self).unwrap(); + } +} + impl SseEncode for u64 { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { @@ -617,6 +865,16 @@ impl SseEncode for () { fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {} } +impl SseEncode for usize { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + serializer + .cursor + .write_u64::(self as _) + .unwrap(); + } +} + impl SseEncode for bool { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { diff --git a/rust/src/frb_generated.web.rs b/rust/src/frb_generated.web.rs index 9ab62ad..98e14a3 100644 --- a/rust/src/frb_generated.web.rs +++ b/rust/src/frb_generated.web.rs @@ -4,6 +4,7 @@ // Section: imports use super::*; +use crate::api::http_api::*; use flutter_rust_bridge::for_generated::byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt}; use flutter_rust_bridge::for_generated::transform_result_dco; use flutter_rust_bridge::for_generated::wasm_bindgen; @@ -13,3 +14,17 @@ use flutter_rust_bridge::{Handler, IntoIntoDart}; // Section: boilerplate flutter_rust_bridge::frb_generated_boilerplate_web!(); + +#[wasm_bindgen] +pub fn rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ptr: *const std::ffi::c_void, +) { + MoiArc::>::increment_strong_count(ptr as _); +} + +#[wasm_bindgen] +pub fn rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockreqwestVersion( + ptr: *const std::ffi::c_void, +) { + MoiArc::>::decrement_strong_count(ptr as _); +} diff --git a/rust/src/http_package/dns.rs b/rust/src/http_package/dns.rs new file mode 100644 index 0000000..3568a00 --- /dev/null +++ b/rust/src/http_package/dns.rs @@ -0,0 +1,58 @@ +use hickory_resolver::config::{NameServerConfigGroup, ResolverConfig, ResolverOpts}; +use hickory_resolver::{lookup_ip::LookupIpIntoIter, TokioAsyncResolver}; +use hyper::client::connect::dns::Name; +use once_cell::sync::OnceCell; +use reqwest::dns::{Addrs, Resolve, Resolving}; + +use std::io; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; +use std::sync::Arc; + +/// Wrapper around an `AsyncResolver`, which implements the `Resolve` trait. +#[derive(Debug, Default, Clone)] +pub(crate) struct MyHickoryDnsResolver { + /// Since we might not have been called in the context of a + /// Tokio Runtime in initialization, so we must delay the actual + /// construction of the resolver. + state: Arc>, +} + +struct SocketAddrs { + iter: LookupIpIntoIter, +} + +impl Resolve for MyHickoryDnsResolver { + fn resolve(&self, name: Name) -> Resolving { + let resolver = self.clone(); + Box::pin(async move { + let resolver = resolver.state.get_or_try_init(new_resolver)?; + let lookup = resolver.lookup_ip(name.as_str()).await?; + let addrs: Addrs = Box::new(SocketAddrs { + iter: lookup.into_iter(), + }); + Ok(addrs) + }) + } +} + +impl Iterator for SocketAddrs { + type Item = SocketAddr; + + fn next(&mut self) -> Option { + self.iter.next().map(|ip_addr| SocketAddr::new(ip_addr, 0)) + } +} + +fn new_resolver() -> io::Result { + let ali_ips: &[IpAddr] = &[ + IpAddr::V4(Ipv4Addr::new(223, 5, 5, 5)), + IpAddr::V4(Ipv4Addr::new(223, 6, 6, 6)), + IpAddr::V6("2400:3200::1".parse::().unwrap()), + IpAddr::V6("2400:3200:baba::1".parse::().unwrap()), + ]; + + let group = + NameServerConfigGroup::from_ips_https(ali_ips, 443, "dns.alidns.com".to_string(), true); + let cfg = ResolverConfig::from_parts(None, vec![], group); + Ok(TokioAsyncResolver::tokio(cfg, ResolverOpts::default())) +} diff --git a/rust/src/http_package/mod.rs b/rust/src/http_package/mod.rs new file mode 100644 index 0000000..b19123c --- /dev/null +++ b/rust/src/http_package/mod.rs @@ -0,0 +1,109 @@ +pub mod dns; + +use reqwest::header::{HeaderMap, HeaderName, HeaderValue}; +use reqwest::{Method, RequestBuilder}; +use std::collections::HashMap; +use std::str::FromStr; +use std::sync::{Arc, RwLock}; +use std::time::Duration; +use flutter_rust_bridge::for_generated::lazy_static; + +#[derive(Debug)] +pub struct RustHttpResponse { + pub status_code: u16, + pub headers: HashMap, + pub url: String, + pub content_length: Option, + pub version: reqwest::Version, + pub remote_addr: String, + pub data: Option>, +} + +lazy_static! { + static ref DEFAULT_HEADER: RwLock = RwLock::from(HeaderMap::new()); + static ref HTTP_CLIENT: reqwest::Client = { + reqwest::Client::builder() + .use_rustls_tls() + .connect_timeout(Duration::from_secs(10)) + .timeout(Duration::from_secs(10)) + .dns_resolver(Arc::from(dns::MyHickoryDnsResolver::default())) + .build() + .unwrap() + }; +} + +pub fn set_default_header(headers: HashMap) { + let mut dh = DEFAULT_HEADER.write().unwrap(); + dh.clear(); + for ele in headers { + dh.append( + HeaderName::from_str(ele.0.as_str()).unwrap(), + HeaderValue::from_str(ele.1.as_str()).unwrap(), + ); + } +} + +pub async fn fetch( + method: Method, + url: String, + headers: Option>, + input_data: Option>, +) -> reqwest::Result { + let mut req = _mix_header(HTTP_CLIENT.request(method, url), headers); + if input_data.is_some() { + req = req.body(input_data.unwrap()); + } + let resp = req.send().await?; + + let url = resp.url().to_string(); + let status_code = resp.status().as_u16(); + let resp_headers = _reade_resp_header(resp.headers()); + let content_length = resp.content_length(); + let version = resp.version(); + let mut remote_addr = "".to_string(); + if resp.remote_addr().is_some() { + remote_addr = resp.remote_addr().unwrap().to_string(); + } + let mut data: Option> = None; + + let bytes = resp.bytes().await; + if bytes.is_ok() { + data = Some(bytes.unwrap().to_vec()); + } + + let resp = RustHttpResponse { + status_code, + headers: resp_headers, + url, + content_length, + version, + remote_addr, + data, + }; + Ok(resp) +} + +fn _reade_resp_header(r_header: &HeaderMap) -> HashMap { + let mut resp_headers = HashMap::new(); + for ele in r_header { + resp_headers.insert( + ele.0.as_str().to_string(), + ele.1.to_str().unwrap().to_string(), + ); + } + resp_headers +} + +fn _mix_header( + mut req: RequestBuilder, + headers: Option>, +) -> RequestBuilder { + if headers.is_some() { + for x in headers.unwrap() { + req = req.header(x.0, x.1); + } + } + let dh = DEFAULT_HEADER.read().unwrap(); + req = req.headers(dh.clone()); + req +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs index a465255..9563ac5 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,3 +1,4 @@ mod frb_generated; mod api; mod downloader; +mod http_package;