Skip to content

Commit

Permalink
feat: use RustOpaque for client
Browse files Browse the repository at this point in the history
  • Loading branch information
Tienisto committed Aug 28, 2024
1 parent 4b40d7d commit 4898abc
Show file tree
Hide file tree
Showing 20 changed files with 619 additions and 560 deletions.
5 changes: 5 additions & 0 deletions rhttp/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.7.0

- fix: creating a second client might overwrite the first client due to memory address conflict
- **BREAKING**: change `RhttpInvalidClientException` to `RhttpClientDisposedException`

## 0.6.2

- feat: add `baseUrl` setting to `ClientSettings`
Expand Down
2 changes: 1 addition & 1 deletion rhttp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ The following exceptions can be thrown:
| `RhttpStatusCodeException` | Response has 4xx or 5xx status code. |
| `RhttpInvalidCertificateException` | Server certificate is invalid. |
| `RhttpConnectionException` | Connection error. (no internet, server not reachable) |
| `RhttpInvalidClientException` | Request is made with an invalid client. |
| `RhttpClientDisposedException` | Client is already disposed. |
| `RhttpInterceptorException` | Interceptor threw an exception. |
| `RhttpUnknownException` | Unknown error occurred. |

Expand Down
2 changes: 1 addition & 1 deletion rhttp/lib/rhttp.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export 'src/model/exception.dart'
RhttpTimeoutException,
RhttpRedirectException,
RhttpStatusCodeException,
RhttpInvalidClientException,
RhttpClientDisposedException,
RhttpInterceptorException,
RhttpUnknownException;
export 'src/model/header.dart';
Expand Down
15 changes: 10 additions & 5 deletions rhttp/lib/src/client/rhttp_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:rhttp/src/model/request.dart';
import 'package:rhttp/src/model/response.dart';
import 'package:rhttp/src/model/settings.dart';
import 'package:rhttp/src/request.dart';
import 'package:rhttp/src/rust/api/client.dart' as rust_client;
import 'package:rhttp/src/rust/api/http.dart' as rust;

/// An HTTP client that is used to make requests.
Expand All @@ -21,7 +22,7 @@ class RhttpClient {

/// Internal reference to the Rust client.
@internal
final int ref;
final rust_client.RequestClient ref;

const RhttpClient._({
required this.settings,
Expand Down Expand Up @@ -71,11 +72,15 @@ class RhttpClient {
/// Disposes the client.
/// This frees the resources associated with the client.
/// After calling this method, the client should not be used anymore.
///
/// Note:
/// This might improve performance but it is not necessary since the client
/// is automatically disposed when the Dart object is garbage collected.
void dispose({bool cancelRunningRequests = false}) async {
await rust.removeClient(
address: ref,
cancelRunningRequests: cancelRunningRequests,
);
if (cancelRunningRequests) {
await rust.cancelRunningRequests(client: ref);
}
ref.dispose();
}

/// Makes an HTTP request.
Expand Down
7 changes: 3 additions & 4 deletions rhttp/lib/src/model/exception.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@ class RhttpConnectionException extends RhttpException {
}

/// An exception thrown a request is made with an invalid client.
class RhttpInvalidClientException extends RhttpException {
const RhttpInvalidClientException(super.request);
class RhttpClientDisposedException extends RhttpException {
const RhttpClientDisposedException(super.request);

@override
String toString() =>
'[$runtimeType] Invalid client. Is the client already disposed?';
'[$runtimeType] Client is already disposed. URL: ${request.url}';
}

/// An exception thrown by an interceptor.
Expand Down Expand Up @@ -148,7 +148,6 @@ RhttpException parseError(HttpRequest request, rust.RhttpError error) {
RhttpInvalidCertificateException(request: request, message: message),
rhttpConnectionError: (message) =>
RhttpConnectionException(request, message),
rhttpInvalidClientError: () => RhttpInvalidClientException(request),
rhttpUnknownError: (message) => RhttpUnknownException(request, message),
);
}
8 changes: 6 additions & 2 deletions rhttp/lib/src/request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import 'package:rhttp/src/util/stream_listener.dart';
/// the client and also by the static class.
@internal
Future<HttpResponse> requestInternalGeneric(HttpRequest request) async {
if (request.client?.ref.isDisposed ?? false) {
throw RhttpClientDisposedException(request);
}

final interceptors = request.interceptor;

if (interceptors != null) {
Expand Down Expand Up @@ -132,7 +136,7 @@ Future<HttpResponse> requestInternalGeneric(HttpRequest request) async {
final cancelRefCompleter = Completer<int>();
final responseCompleter = Completer<rust.HttpResponse>();
Stream<Uint8List> stream = rust.makeHttpRequestReceiveStream(
clientAddress: request.client?.ref,
client: request.client?.ref,
settings: request.settings?.toRustType(),
method: request.method._toRustType(),
url: url,
Expand Down Expand Up @@ -209,7 +213,7 @@ Future<HttpResponse> requestInternalGeneric(HttpRequest request) async {
} else {
final cancelRefCompleter = Completer<int>();
final responseFuture = rust.makeHttpRequest(
clientAddress: request.client?.ref,
client: request.client?.ref,
settings: request.settings?.toRustType(),
method: request.method._toRustType(),
url: url,
Expand Down
4 changes: 3 additions & 1 deletion rhttp/lib/src/rust/api/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import 'package:freezed_annotation/freezed_annotation.dart' hide protected;
part 'client.freezed.dart';

// These functions are ignored because they are not marked as `pub`: `create_client`, `new_default`, `new`
// These types are ignored because they are not used by any `pub` functions: `RequestClient`
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`

// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<RequestClient>>
abstract class RequestClient implements RustOpaqueInterface {}

class ClientCertificate {
final Uint8List certificate;
final Uint8List privateKey;
Expand Down
2 changes: 0 additions & 2 deletions rhttp/lib/src/rust/api/error.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ sealed class RhttpError with _$RhttpError implements FrbException {
const factory RhttpError.rhttpConnectionError(
String field0,
) = RhttpError_RhttpConnectionError;
const factory RhttpError.rhttpInvalidClientError() =
RhttpError_RhttpInvalidClientError;
const factory RhttpError.rhttpUnknownError(
String field0,
) = RhttpError_RhttpUnknownError;
Expand Down
Loading

0 comments on commit 4898abc

Please sign in to comment.