mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-03-11 13:15:36 +00:00
feat: enhance RhttpCompatibleClient with cancel token support and improve error handling; add new target for Windows ARM64
This commit is contained in:
parent
9d829a16e7
commit
099180bc34
3 changed files with 55 additions and 5 deletions
|
|
@ -1,7 +1,5 @@
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
import 'package:mangayomi/services/http/rhttp/src/client/rhttp_client.dart';
|
import 'package:mangayomi/services/http/rhttp/rhttp.dart';
|
||||||
import 'package:mangayomi/services/http/rhttp/src/model/exception.dart';
|
|
||||||
import 'package:mangayomi/services/http/rhttp/src/model/settings.dart';
|
|
||||||
import 'package:mangayomi/src/rust/api/rhttp/http.dart' as rust;
|
import 'package:mangayomi/src/rust/api/rhttp/http.dart' as rust;
|
||||||
|
|
||||||
/// An HTTP client that is compatible with the `http` package.
|
/// An HTTP client that is compatible with the `http` package.
|
||||||
|
|
@ -36,6 +34,17 @@ class RhttpCompatibleClient with BaseClient {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<StreamedResponse> send(BaseRequest request) async {
|
Future<StreamedResponse> send(BaseRequest request) async {
|
||||||
|
final CancelToken? cancelToken;
|
||||||
|
switch (request) {
|
||||||
|
case Abortable(abortTrigger: final trigger?):
|
||||||
|
cancelToken = CancelToken();
|
||||||
|
trigger.then((_) {
|
||||||
|
cancelToken?.cancel();
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case _:
|
||||||
|
cancelToken = null;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
final response = await client.requestStream(
|
final response = await client.requestStream(
|
||||||
method: switch (request.method) {
|
method: switch (request.method) {
|
||||||
|
|
@ -53,12 +62,30 @@ class RhttpCompatibleClient with BaseClient {
|
||||||
url: request.url.toString(),
|
url: request.url.toString(),
|
||||||
headers: rust.HttpHeaders.map(request.headers),
|
headers: rust.HttpHeaders.map(request.headers),
|
||||||
body: await request.finalize().toBytes(),
|
body: await request.finalize().toBytes(),
|
||||||
|
cancelToken: cancelToken,
|
||||||
);
|
);
|
||||||
|
|
||||||
final responseHeaderMap = response.headerMap;
|
final responseHeaderMap = response.headerMap;
|
||||||
|
|
||||||
return StreamedResponse(
|
return StreamedResponse(
|
||||||
response.body,
|
response.body.handleError((e, st) {
|
||||||
|
if (e is RhttpException) {
|
||||||
|
if (e is RhttpCancelException) {
|
||||||
|
Error.throwWithStackTrace(
|
||||||
|
RhttpWrappedRequestAbortedException(request.url, e),
|
||||||
|
st,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Error.throwWithStackTrace(
|
||||||
|
RhttpWrappedClientException(e.toString(), request.url, e),
|
||||||
|
st,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Error.throwWithStackTrace(
|
||||||
|
ClientException(e.toString(), request.url),
|
||||||
|
st,
|
||||||
|
);
|
||||||
|
}),
|
||||||
response.statusCode,
|
response.statusCode,
|
||||||
contentLength: switch (responseHeaderMap['content-length']) {
|
contentLength: switch (responseHeaderMap['content-length']) {
|
||||||
String s => int.parse(s),
|
String s => int.parse(s),
|
||||||
|
|
@ -71,6 +98,12 @@ class RhttpCompatibleClient with BaseClient {
|
||||||
reasonPhrase: null,
|
reasonPhrase: null,
|
||||||
);
|
);
|
||||||
} on RhttpException catch (e, st) {
|
} on RhttpException catch (e, st) {
|
||||||
|
if (e is RhttpCancelException) {
|
||||||
|
Error.throwWithStackTrace(
|
||||||
|
RhttpWrappedRequestAbortedException(request.url, e),
|
||||||
|
st,
|
||||||
|
);
|
||||||
|
}
|
||||||
Error.throwWithStackTrace(
|
Error.throwWithStackTrace(
|
||||||
RhttpWrappedClientException(e.toString(), request.url, e),
|
RhttpWrappedClientException(e.toString(), request.url, e),
|
||||||
st,
|
st,
|
||||||
|
|
@ -98,6 +131,16 @@ class RhttpWrappedClientException extends ClientException {
|
||||||
String toString() => rhttpException.toString();
|
String toString() => rhttpException.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RhttpWrappedRequestAbortedException extends RequestAbortedException {
|
||||||
|
/// The original exception that was thrown by rhttp.
|
||||||
|
final RhttpException rhttpException;
|
||||||
|
|
||||||
|
RhttpWrappedRequestAbortedException(super.uri, this.rhttpException);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => rhttpException.toString();
|
||||||
|
}
|
||||||
|
|
||||||
extension on ClientSettings {
|
extension on ClientSettings {
|
||||||
/// Makes sure that the settings conform to the requirements of [BaseClient].
|
/// Makes sure that the settings conform to the requirements of [BaseClient].
|
||||||
ClientSettings digest() {
|
ClientSettings digest() {
|
||||||
|
|
|
||||||
|
|
@ -326,7 +326,10 @@ async fn make_http_request_helper(
|
||||||
fn header_to_vec(headers: &reqwest::header::HeaderMap) -> Vec<(String, String)> {
|
fn header_to_vec(headers: &reqwest::header::HeaderMap) -> Vec<(String, String)> {
|
||||||
headers
|
headers
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(k, v)| (k.as_str().to_string(), v.to_str().unwrap().to_string()))
|
.filter_map(|(k, v)| match v.to_str() {
|
||||||
|
Ok(v_str) => Some((k.as_str().to_string(), v_str.to_string())),
|
||||||
|
Err(_) => None,
|
||||||
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,10 @@ class Target {
|
||||||
rust: 'x86_64-pc-windows-msvc',
|
rust: 'x86_64-pc-windows-msvc',
|
||||||
flutter: 'windows-x64',
|
flutter: 'windows-x64',
|
||||||
),
|
),
|
||||||
|
Target(
|
||||||
|
rust: 'aarch64-pc-windows-msvc',
|
||||||
|
flutter: 'windows-arm64',
|
||||||
|
),
|
||||||
Target(
|
Target(
|
||||||
rust: 'x86_64-unknown-linux-gnu',
|
rust: 'x86_64-unknown-linux-gnu',
|
||||||
flutter: 'linux-x64',
|
flutter: 'linux-x64',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue