Skip to content

Commit

Permalink
feat: Introduce strongly-typed Relic Address (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
klkucaj authored Jan 3, 2025
1 parent c4a9eed commit 7fb71bb
Show file tree
Hide file tree
Showing 77 changed files with 278 additions and 1,778 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ void main() async {
var handler =
const Pipeline().addMiddleware(logRequests()).addHandler(_echoRequest);
var server = await serve(handler, 'localhost', 8080);
var server = await serve(
handler,
RelicAddress.fromHostname('localhost'),
8080,
);
// Enable content compression
server.autoCompress = true;
Expand Down
5 changes: 5 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
include: package:lints/recommended.yaml

linter:
rules:
- avoid_dynamic_calls
- unawaited_futures
6 changes: 5 additions & 1 deletion example/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ void main() async {
var handler =
const Pipeline().addMiddleware(logRequests()).addHandler(_echoRequest);

var server = await serve(handler, 'localhost', 8080);
var server = await serve(
handler,
RelicAddress.fromHostname('localhost'),
8080,
);

// Enable content compression
server.autoCompress = true;
Expand Down
2 changes: 2 additions & 0 deletions lib/relic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export 'src/middleware/middleware.dart' show Middleware, createMiddleware;
export 'src/middleware/middleware_extensions.dart' show MiddlewareExtensions;

/// Relic server related exports
export 'src/address/relic_address.dart' show RelicAddress;
export 'dart:io' show InternetAddress;
export 'src/relic_server.dart' show RelicServer;
export 'src/relic_server_serve.dart' show serve;

Expand Down
54 changes: 54 additions & 0 deletions lib/src/address/relic_address.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import 'dart:io';

/// A class that represents an address.
abstract final class RelicAddress<T> {
/// Returns the address as an [Object].
T get address;

/// Creates a [RelicAddress] from a [String].
static RelicAddress<String> fromHostname(String hostname) {
return _RelicHostnameAddress(hostname: hostname);
}

/// Creates a [RelicAddress] from an [InternetAddress].
static RelicAddress<InternetAddress> fromInternetAddress(
InternetAddress address,
) {
return _RelicInternetAddress(internetAddress: address);
}
}

/// A class that represents a hostname address.
final class _RelicHostnameAddress implements RelicAddress<String> {
/// The hostname of the address.
final String hostname;

_RelicHostnameAddress({
required this.hostname,
});

/// Returns the address as a [String].
@override
String get address => hostname;

@override
String toString() => 'RelicHostnameAddress(hostname: $hostname)';
}

/// A class that represents an internet address.
final class _RelicInternetAddress implements RelicAddress<InternetAddress> {
/// The internet address of the address.
final InternetAddress internetAddress;

_RelicInternetAddress({
required this.internetAddress,
});

/// Returns the address as an [InternetAddress].
@override
InternetAddress get address => internetAddress;

@override
String toString() =>
'RelicInternetAddress(internetAddress: $internetAddress)';
}
8 changes: 4 additions & 4 deletions lib/src/headers/headers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1389,7 +1389,7 @@ final class _HeadersImpl extends Headers {
return map;
}

/// Date-related headers
/// Date related headers
Map<String, DateTime?> get _dateHeadersMap => {
Headers.dateHeader: date ?? DateTime.now().toUtc(),
Headers.expiresHeader: expires,
Expand All @@ -1413,7 +1413,7 @@ final class _HeadersImpl extends Headers {
accessControlRequestMethod?.value,
};

/// List<String>-related headers
/// String list related headers
Map<String, List<String>?> get _listStringHeadersMap =>
<String, List<String>?>{
Headers.viaHeader: via,
Expand All @@ -1422,7 +1422,7 @@ final class _HeadersImpl extends Headers {
Headers.trailerHeader: trailer,
};

/// Uri-related headers
/// Uri related headers
Map<String, Uri?> get _uriHeadersMap => <String, Uri?>{
Headers.locationHeader: location,
Headers.refererHeader: referer,
Expand All @@ -1431,7 +1431,7 @@ final class _HeadersImpl extends Headers {
Headers.hostHeader: host,
};

/// TypedHeader-related headers
/// TypedHeader related headers
Map<String, TypedHeader?> get _typedHeadersMap => <String, TypedHeader?>{
Headers.fromHeader: from,
Headers.acceptEncodingHeader: acceptEncoding,
Expand Down
33 changes: 17 additions & 16 deletions lib/src/relic_server.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:io';

import 'package:relic/src/address/relic_address.dart';
import 'package:relic/src/body/body.dart';
import 'package:relic/src/hijack/exception/hijack_exception.dart';
import 'package:relic/src/headers/exception/invalid_header_exception.dart';
Expand Down Expand Up @@ -50,7 +51,7 @@ class RelicServer {

/// Creates a server with the given parameters.
static Future<RelicServer> createServer(
Object address,
RelicAddress address,
int port, {
SecurityContext? securityContext,
int? backlog,
Expand All @@ -59,21 +60,21 @@ class RelicServer {
String? poweredByHeader,
}) async {
backlog ??= 0;
var server = switch (securityContext == null) {
true => await HttpServer.bind(
address,
port,
backlog: backlog,
shared: shared,
),
false => await HttpServer.bindSecure(
address,
port,
securityContext!,
backlog: backlog,
shared: shared,
),
};
var server = securityContext == null
? await HttpServer.bind(
address.address,
port,
backlog: backlog,
shared: shared,
)
: await HttpServer.bindSecure(
address.address,
port,
securityContext,
backlog: backlog,
shared: shared,
);

return RelicServer._(
server,
strictHeaders: strictHeaders,
Expand Down
3 changes: 2 additions & 1 deletion lib/src/relic_server_serve.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ library;
import 'dart:async';
import 'dart:io' as io;

import 'package:relic/src/address/relic_address.dart';
import 'package:relic/src/relic_server.dart';

import 'handler/handler.dart';
Expand All @@ -43,7 +44,7 @@ import 'message/response.dart';
/// {@endtemplate}
Future<io.HttpServer> serve(
Handler handler,
Object address,
RelicAddress address,
int port, {
io.SecurityContext? securityContext,
int? backlog,
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dependencies:
convert: ^3.1.1

dev_dependencies:
dart_flutter_team_lints: ^3.0.0
lints: '>=3.0.0 <5.0.0'
http: '>=1.0.0 <2.0.0'
test: ^1.24.2
test_descriptor: ^2.0.1
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'dart:io';
import 'package:test/test.dart';
import 'package:relic/src/headers/headers.dart';
import 'package:relic/src/relic_server.dart';
Expand All @@ -21,19 +20,7 @@ void main() {
late RelicServer server;

setUp(() async {
try {
server = await RelicServer.createServer(
InternetAddress.loopbackIPv6,
0,
strictHeaders: true,
);
} on SocketException catch (_) {
server = await RelicServer.createServer(
InternetAddress.loopbackIPv4,
0,
strictHeaders: true,
);
}
server = await createServer(strictHeaders: true);
});

tearDown(() => server.close());
Expand Down Expand Up @@ -132,19 +119,7 @@ void main() {
late RelicServer server;

setUp(() async {
try {
server = await RelicServer.createServer(
InternetAddress.loopbackIPv6,
0,
strictHeaders: false,
);
} on SocketException catch (_) {
server = await RelicServer.createServer(
InternetAddress.loopbackIPv4,
0,
strictHeaders: false,
);
}
server = await createServer(strictHeaders: false);
});

tearDown(() => server.close());
Expand Down
29 changes: 2 additions & 27 deletions test/headers/basic/access_control_max_age_header_test.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'dart:io';
import 'package:test/test.dart';
import 'package:relic/src/headers/headers.dart';
import 'package:relic/src/relic_server.dart';
Expand All @@ -13,19 +12,7 @@ void main() {
late RelicServer server;

setUp(() async {
try {
server = await RelicServer.createServer(
InternetAddress.loopbackIPv6,
0,
strictHeaders: true,
);
} on SocketException catch (_) {
server = await RelicServer.createServer(
InternetAddress.loopbackIPv4,
0,
strictHeaders: true,
);
}
server = await createServer(strictHeaders: true);
});

tearDown(() => server.close());
Expand Down Expand Up @@ -113,19 +100,7 @@ void main() {
late RelicServer server;

setUp(() async {
try {
server = await RelicServer.createServer(
InternetAddress.loopbackIPv6,
0,
strictHeaders: false,
);
} on SocketException catch (_) {
server = await RelicServer.createServer(
InternetAddress.loopbackIPv4,
0,
strictHeaders: false,
);
}
server = await createServer(strictHeaders: false);
});

tearDown(() => server.close());
Expand Down
29 changes: 2 additions & 27 deletions test/headers/basic/access_control_request_headers_heder_test.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'dart:io';
import 'package:test/test.dart';
import 'package:relic/src/headers/headers.dart';
import 'package:relic/src/relic_server.dart';
Expand All @@ -15,19 +14,7 @@ void main() {
late RelicServer server;

setUp(() async {
try {
server = await RelicServer.createServer(
InternetAddress.loopbackIPv6,
0,
strictHeaders: true,
);
} on SocketException catch (_) {
server = await RelicServer.createServer(
InternetAddress.loopbackIPv4,
0,
strictHeaders: true,
);
}
server = await createServer(strictHeaders: true);
});

tearDown(() => server.close());
Expand Down Expand Up @@ -130,19 +117,7 @@ void main() {
late RelicServer server;

setUp(() async {
try {
server = await RelicServer.createServer(
InternetAddress.loopbackIPv6,
0,
strictHeaders: false,
);
} on SocketException catch (_) {
server = await RelicServer.createServer(
InternetAddress.loopbackIPv4,
0,
strictHeaders: false,
);
}
server = await createServer(strictHeaders: false);
});

tearDown(() => server.close());
Expand Down
Loading

0 comments on commit 7fb71bb

Please sign in to comment.