Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(binding_http): add possibility to define a custom SecurityContext #194

Merged
merged 1 commit into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions lib/src/binding_http/http_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@

import "dart:convert";
import "dart:io";
import "dart:io" as io;

import "package:http/http.dart";
import "package:http/io_client.dart";

import "../../binding_http.dart";
import "../../core.dart";

import "http_request_method.dart";
Expand All @@ -31,6 +34,8 @@ const _authorizationHeader = "Authorization";
///
/// The use of Proxies is not supported yet, while support for the digest
/// security scheme has been temporarily removed.
/// Additional trusted certificates can be added via an (optional)
/// [HttpClientConfig].
///
/// [RFC 7617]: https://datatracker.ietf.org/doc/html/rfc7617
/// [RFC 7616]: https://datatracker.ietf.org/doc/html/rfc7616
Expand All @@ -40,12 +45,30 @@ final class HttpClient extends ProtocolClient
with DirectDiscoverer, CoreLinkFormatDiscoverer {
/// Creates a new [HttpClient].
HttpClient({
HttpClientConfig? httpClientConfig,
AsyncClientSecurityCallback<BasicCredentials>? basicCredentialsCallback,
AsyncClientSecurityCallback<BearerCredentials>? bearerCredentialsCallback,
}) : _basicCredentialsCallback = basicCredentialsCallback,
_bearerCredentialsCallback = bearerCredentialsCallback;
_bearerCredentialsCallback = bearerCredentialsCallback,
_client =
IOClient(io.HttpClient(context: _createContext(httpClientConfig)));

final _client = Client();
static SecurityContext _createContext(HttpClientConfig? httpClientConfig) {
final context = SecurityContext();

final trustedCertificates = httpClientConfig?.trustedCertificates ?? [];

for (final trustedCertificate in trustedCertificates) {
context.setTrustedCertificatesBytes(
trustedCertificate.certificate,
password: trustedCertificate.password,
);
}

return context;
}

final IOClient _client;

final AsyncClientSecurityCallback<BasicCredentials>?
_basicCredentialsCallback;
Expand Down
7 changes: 6 additions & 1 deletion lib/src/binding_http/http_client_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ import "http_config.dart";
final class HttpClientFactory implements ProtocolClientFactory {
/// Creates a new [HttpClientFactory] based on an optional [HttpConfig].
HttpClientFactory({
HttpClientConfig? httpClientConfig,
AsyncClientSecurityCallback<BasicCredentials>? basicCredentialsCallback,
AsyncClientSecurityCallback<BearerCredentials>? bearerCredentialsCallback,
}) : _basicCredentialsCallback = basicCredentialsCallback,
_bearerCredentialsCallback = bearerCredentialsCallback;
_bearerCredentialsCallback = bearerCredentialsCallback,
_httpClientConfig = httpClientConfig;

final HttpClientConfig? _httpClientConfig;

final AsyncClientSecurityCallback<BasicCredentials>?
_basicCredentialsCallback;
Expand All @@ -34,6 +38,7 @@ final class HttpClientFactory implements ProtocolClientFactory {

@override
ProtocolClient createClient() => HttpClient(
httpClientConfig: _httpClientConfig,
basicCredentialsCallback: _basicCredentialsCallback,
bearerCredentialsCallback: _bearerCredentialsCallback,
);
Expand Down
18 changes: 18 additions & 0 deletions lib/src/binding_http/http_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
//
// SPDX-License-Identifier: BSD-3-Clause

import "package:meta/meta.dart";

/// Allows for configuring the behavior of HTTP clients and servers.
class HttpConfig {
/// Creates a new [HttpConfig] object.
Expand All @@ -17,3 +19,19 @@ class HttpConfig {
/// Indicates if the client or server should use HTTPS.
bool? secure;
}

/// Configuration parameters specific to dart_wot's HTTP Client implementation.
@immutable
class HttpClientConfig {
/// Creates a new [HttpClientConfig] object.
const HttpClientConfig({
this.trustedCertificates,
});

/// List of trusted certificates that will be added to the security contexts
/// of newly created HTTP clients.
///
/// Certificates can either use the PEM or or the PKCS12 format, the latter of
/// which also supports the use of an optional password.
final List<({List<int> certificate, String? password})>? trustedCertificates;
}
Loading