diff --git a/packages/wyatt_http_client/example/pipeline.dart b/packages/wyatt_http_client/example/pipeline.dart
new file mode 100644
index 00000000..1ee6cade
--- /dev/null
+++ b/packages/wyatt_http_client/example/pipeline.dart
@@ -0,0 +1,149 @@
+// ignore_for_file: public_member_api_docs, sort_constructors_first
+// Copyright (C) 2022 WYATT GROUP
+// Please see the AUTHORS file for details.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import 'package:wyatt_http_client/src/middleware_client.dart';
+import 'package:wyatt_http_client/src/middlewares/body_to_json_middleware.dart';
+import 'package:wyatt_http_client/src/middlewares/refresh_token_middleware.dart';
+import 'package:wyatt_http_client/src/middlewares/simple_logger_middleware.dart';
+import 'package:wyatt_http_client/src/middlewares/uri_prefix_middleware.dart';
+import 'package:wyatt_http_client/src/pipeline.dart';
+import 'package:wyatt_http_client/src/utils/protocols.dart';
+
+// class RequestMutatorMiddleware implements Middleware {
+// @override
+// Middleware? parent;
+
+// @override
+// Middleware? child;
+
+// RequestMutatorMiddleware({
+// this.parent,
+// this.child,
+// });
+
+// @override
+// BaseRequest onRequest(BaseRequest request) {
+// print('RequestMutator::OnRequest: ${request.method} -> ${request.url}');
+// return child?.onRequest(request) ?? request;
+// }
+
+// @override
+// BaseResponse onResponse(BaseResponse response) {
+// final res = child?.onResponse(response) ?? response;
+// print(
+// 'RequestMutator::OnResponse: ${res.statusCode} -> ${res.contentLength} bytes',
+// );
+// return res;
+// }
+// }
+
+// typedef Middleware = Handler Function(Handler innerHandler);
+
+// Middleware createMiddleware({
+// FutureOr Function(Request)? requestHandler,
+// FutureOr Function(Response)? responseHandler,
+// FutureOr Function(Object error, StackTrace)? errorHandler,
+// }) {
+// requestHandler ??= (request) => null;
+// responseHandler ??= (response) => response;
+
+// FutureOr Function(Object, StackTrace)? onError;
+// if (errorHandler != null) {
+// onError = (error, stackTrace) {
+// if (error is Exception) throw error;
+// return errorHandler(error, stackTrace);
+// };
+// }
+
+// return (Handler innerHandler) {
+// return (request) {
+// return Future.sync(() => requestHandler!(request)).then((response) {
+// if (response != null) return response;
+
+// return Future.sync(() => innerHandler(request))
+// .then((response) => responseHandler!(response), onError: onError);
+// });
+// };
+// };
+// }
+
+// extension MiddlewareX on Middleware {
+// Middleware addMiddleware(Middleware other) =>
+// (Handler handler) => this(other(handler));
+// Handler addHandler(Handler handler) => this(handler);
+// }
+
+// typedef Handler = FutureOr Function(Request request);
+
+// final headerMutator = createMiddleware(
+// responseHandler: (response) {
+// print(response.headers);
+// return response;
+// },);
+
+// class Pipeline {
+// const Pipeline();
+
+// Pipeline addMiddleware(Middleware middleware) =>
+// _Pipeline(middleware, addHandler);
+
+// Handler addHandler(Handler handler) => handler;
+
+// Middleware get middleware => addHandler;
+// }
+
+// class _Pipeline extends Pipeline {
+// final Middleware _middleware;
+// final Middleware _parent;
+
+// _Pipeline(this._middleware, this._parent);
+
+// @override
+// Handler addHandler(Handler handler) => _parent(_middleware(handler));
+// }
+
+Future main(List args) async {
+ final Pipeline pipeline1 = Pipeline()
+ .addMiddleware(SimpleLoggerMiddleware())
+ .addMiddleware(
+ UriPrefixMiddleware(
+ protocol: Protocols.http,
+ authority: 'localhost:80',
+ ),
+ )
+ .addMiddleware(BodyToJsonMiddleware());
+
+ final Pipeline pipeline2 = Pipeline().addMiddleware(
+ RefreshTokenMiddleware(
+ authorizationEndpoint:
+ 'http://localhost:80/api/v1/account/test?action=authorize',
+ tokenEndpoint: 'http://localhost:80/api/v1/account/test?action=refresh',
+ innerClientMiddlewares: pipeline1.middleware,
+ ),
+ );
+
+ final Pipeline pipeline = pipeline1 + pipeline2;
+
+ print(pipeline.getLogic());
+ final client = MiddlewareClient(pipeline);
+ final r = await client.post(
+ Uri.parse('/api/v1/account/test'),
+ body: {
+ 'email': 'test@test.fr',
+ },
+ );
+}
diff --git a/packages/wyatt_http_client/lib/src/middleware.dart b/packages/wyatt_http_client/lib/src/middleware.dart
new file mode 100644
index 00000000..1c36442c
--- /dev/null
+++ b/packages/wyatt_http_client/lib/src/middleware.dart
@@ -0,0 +1,77 @@
+// Copyright (C) 2022 WYATT GROUP
+// Please see the AUTHORS file for details.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import 'package:http/http.dart';
+import 'package:wyatt_http_client/src/middleware_client.dart';
+import 'package:wyatt_http_client/src/models/middleware_request.dart';
+import 'package:wyatt_http_client/src/models/middleware_response.dart';
+
+class Middleware {
+ Middleware? child;
+
+ MiddlewareClient? _client;
+
+ Middleware({
+ this.child,
+ });
+
+ Middleware._({
+ this.child,
+ MiddlewareClient? client,
+ }) : _client = client;
+
+ String getName() => 'Middleware';
+
+ void setClient(MiddlewareClient? client) {
+ _client = client;
+ child?.setClient(client);
+ }
+
+ Client? getClient() {
+ return _client?.inner;
+ }
+
+ Middleware deepCopy() {
+ if (child != null) {
+ return Middleware._(child: child?.deepCopy(), client: _client);
+ } else {
+ return Middleware._(client: _client);
+ }
+ }
+
+ void addChild(Middleware middleware) {
+ if (child != null) {
+ child?.addChild(middleware);
+ } else {
+ child = middleware;
+ }
+ }
+
+ MiddlewareRequest onRequest(
+ MiddlewareRequest request,
+ ) {
+ return child?.onRequest(request) ?? request;
+ }
+
+ MiddlewareResponse onResponse(MiddlewareResponse response) {
+ return child?.onResponse(response) ?? response;
+ }
+
+ @override
+ String toString() {
+ return getName();
+ }
+}
diff --git a/packages/wyatt_http_client/lib/src/middleware_client.dart b/packages/wyatt_http_client/lib/src/middleware_client.dart
new file mode 100644
index 00000000..ce02e8da
--- /dev/null
+++ b/packages/wyatt_http_client/lib/src/middleware_client.dart
@@ -0,0 +1,117 @@
+// Copyright (C) 2022 WYATT GROUP
+// Please see the AUTHORS file for details.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import 'dart:convert';
+
+import 'package:http/http.dart';
+import 'package:wyatt_http_client/src/middleware.dart';
+import 'package:wyatt_http_client/src/models/middleware_request.dart';
+import 'package:wyatt_http_client/src/models/middleware_response.dart';
+import 'package:wyatt_http_client/src/models/unfreezed_request.dart';
+import 'package:wyatt_http_client/src/pipeline.dart';
+
+class MiddlewareClient extends BaseClient {
+ final Client inner;
+ final Middleware middleware;
+ final Pipeline pipeline;
+
+ MiddlewareClient(
+ this.pipeline, {
+ Middleware? middleware,
+ Client? inner,
+ }) : inner = inner ?? Client(),
+ middleware = middleware ?? pipeline.middleware {
+ this.middleware.setClient(this);
+ }
+
+ @override
+ Future head(Uri url, {Map? headers}) =>
+ _sendUnstreamed('HEAD', url, headers);
+
+ @override
+ Future get(Uri url, {Map? headers}) =>
+ _sendUnstreamed('GET', url, headers);
+
+ @override
+ Future post(
+ Uri url, {
+ Map? headers,
+ Object? body,
+ Encoding? encoding,
+ }) =>
+ _sendUnstreamed('POST', url, headers, body, encoding);
+
+ @override
+ Future put(
+ Uri url, {
+ Map? headers,
+ Object? body,
+ Encoding? encoding,
+ }) =>
+ _sendUnstreamed('PUT', url, headers, body, encoding);
+
+ @override
+ Future patch(
+ Uri url, {
+ Map? headers,
+ Object? body,
+ Encoding? encoding,
+ }) =>
+ _sendUnstreamed('PATCH', url, headers, body, encoding);
+
+ @override
+ Future delete(
+ Uri url, {
+ Map? headers,
+ Object? body,
+ Encoding? encoding,
+ }) =>
+ _sendUnstreamed('DELETE', url, headers, body, encoding);
+
+ @override
+ Future send(BaseRequest request) {
+ return inner.send(request);
+ }
+
+ Future _sendUnstreamed(
+ String method,
+ Uri url,
+ Map? headers, [
+ Object? body,
+ Encoding? encoding,
+ ]) async {
+ final modifiedRequest = middleware.onRequest(
+ MiddlewareRequest(
+ unfreezedRequest: UnfreezedRequest(
+ method: method,
+ url: url,
+ headers: headers,
+ body: body,
+ encoding: encoding,
+ ),
+ httpRequest: Request(method, url),
+ ),
+ );
+
+ final res = await Response.fromStream(
+ await send(modifiedRequest.httpRequest),
+ );
+ final response =
+ middleware.onResponse(MiddlewareResponse(httpResponse: res));
+
+ return response.httpResponse as Response;
+ }
+}
diff --git a/packages/wyatt_http_client/lib/src/middlewares/body_to_json_middleware.dart b/packages/wyatt_http_client/lib/src/middlewares/body_to_json_middleware.dart
new file mode 100644
index 00000000..99cc7bc8
--- /dev/null
+++ b/packages/wyatt_http_client/lib/src/middlewares/body_to_json_middleware.dart
@@ -0,0 +1,52 @@
+// Copyright (C) 2022 WYATT GROUP
+// Please see the AUTHORS file for details.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import 'dart:convert';
+
+import 'package:wyatt_http_client/src/middleware.dart';
+import 'package:wyatt_http_client/src/models/middleware_request.dart';
+
+class BodyToJsonMiddleware extends Middleware {
+ BodyToJsonMiddleware({
+ super.child,
+ });
+
+ @override
+ String getName() => 'BodyToJsonMiddleware';
+
+ @override
+ MiddlewareRequest onRequest(MiddlewareRequest request) {
+ print(
+ 'BodyToJson::OnRequest: transforms body in json if Map then update '
+ 'headers with right content-type',
+ );
+ var newReq = request.unfreezedRequest;
+ final mutation = {
+ 'content-type': 'application/json; charset=utf-8',
+ };
+ if (newReq.body is Map) {
+ Map? headers = newReq.headers;
+ if (headers != null) {
+ headers.addAll(mutation);
+ } else {
+ headers = mutation;
+ }
+ newReq = newReq.copyWith(body: jsonEncode(newReq.body), headers: headers);
+ request.updateUnfreezedRequest(newReq);
+ }
+ return super.onRequest(request);
+ }
+}
diff --git a/packages/wyatt_http_client/lib/src/middlewares/default_middleware.dart b/packages/wyatt_http_client/lib/src/middlewares/default_middleware.dart
new file mode 100644
index 00000000..7acd70a0
--- /dev/null
+++ b/packages/wyatt_http_client/lib/src/middlewares/default_middleware.dart
@@ -0,0 +1,26 @@
+// Copyright (C) 2022 WYATT GROUP
+// Please see the AUTHORS file for details.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import 'package:wyatt_http_client/src/middleware.dart';
+
+class DefaultMiddleware extends Middleware {
+ DefaultMiddleware({
+ super.child,
+ });
+
+ @override
+ String getName() => 'DefaultMiddleware';
+}
diff --git a/packages/wyatt_http_client/lib/src/middlewares/refresh_token_middleware.dart b/packages/wyatt_http_client/lib/src/middlewares/refresh_token_middleware.dart
new file mode 100644
index 00000000..7394acb0
--- /dev/null
+++ b/packages/wyatt_http_client/lib/src/middlewares/refresh_token_middleware.dart
@@ -0,0 +1,72 @@
+// Copyright (C) 2022 WYATT GROUP
+// Please see the AUTHORS file for details.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import 'package:wyatt_http_client/src/middleware.dart';
+import 'package:wyatt_http_client/src/middleware_client.dart';
+import 'package:wyatt_http_client/src/middlewares/default_middleware.dart';
+import 'package:wyatt_http_client/src/models/middleware_request.dart';
+import 'package:wyatt_http_client/src/pipeline.dart';
+
+class RefreshTokenMiddleware extends Middleware {
+ final String authorizationEndpoint;
+ final String tokenEndpoint;
+
+ String? accessToken;
+ String? refreshToken;
+
+ Middleware innerClientMiddlewares;
+
+ RefreshTokenMiddleware({
+ required this.authorizationEndpoint,
+ required this.tokenEndpoint,
+ Middleware? innerClientMiddlewares,
+ super.child,
+ }) : innerClientMiddlewares = innerClientMiddlewares ?? DefaultMiddleware();
+
+ @override
+ String getName() => 'RefreshTokenMiddleware';
+
+ @override
+ MiddlewareRequest onRequest(MiddlewareRequest request) {
+ print(
+ 'RefreshToken::OnRequest: accessToken: $accessToken',
+ );
+ if (accessToken == null) {
+ // Refresh token
+ final pipeline = Pipeline().addMiddleware(innerClientMiddlewares);
+ print(pipeline.getLogic());
+ final client = MiddlewareClient(
+ pipeline,
+ inner: getClient(),
+ );
+ final _ = client.post(Uri.parse(tokenEndpoint));
+ }
+ var newReq = request.unfreezedRequest;
+ final mutation = {
+ 'authorization': accessToken ?? '',
+ };
+ Map? headers = newReq.headers;
+ if (headers != null) {
+ headers.addAll(mutation);
+ } else {
+ headers = mutation;
+ }
+ newReq = newReq.copyWith(headers: headers);
+ request.updateUnfreezedRequest(newReq);
+
+ return super.onRequest(request);
+ }
+}
diff --git a/packages/wyatt_http_client/lib/src/middlewares/simple_logger_middleware.dart b/packages/wyatt_http_client/lib/src/middlewares/simple_logger_middleware.dart
new file mode 100644
index 00000000..d3c26aa0
--- /dev/null
+++ b/packages/wyatt_http_client/lib/src/middlewares/simple_logger_middleware.dart
@@ -0,0 +1,47 @@
+// Copyright (C) 2022 WYATT GROUP
+// Please see the AUTHORS file for details.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import 'package:wyatt_http_client/src/middleware.dart';
+import 'package:wyatt_http_client/src/models/middleware_request.dart';
+import 'package:wyatt_http_client/src/models/middleware_response.dart';
+
+class SimpleLoggerMiddleware extends Middleware {
+ SimpleLoggerMiddleware({
+ super.child,
+ });
+
+ @override
+ String getName() => 'SimpleLoggerMiddleware';
+
+ @override
+ MiddlewareRequest onRequest(MiddlewareRequest request) {
+ print(
+ 'Logger::OnRequest: ${request.httpRequest.method} '
+ '${request.httpRequest.url}',
+ );
+ return super.onRequest(request);
+ }
+
+ @override
+ MiddlewareResponse onResponse(MiddlewareResponse response) {
+ final res = super.onResponse(response);
+ print(
+ 'Logger::OnResponse: ${res.httpResponse.statusCode} -> '
+ 'received ${res.httpResponse.contentLength} bytes',
+ );
+ return res;
+ }
+}
diff --git a/packages/wyatt_http_client/lib/src/middlewares/uri_prefix_middleware.dart b/packages/wyatt_http_client/lib/src/middlewares/uri_prefix_middleware.dart
new file mode 100644
index 00000000..9a8ec2dc
--- /dev/null
+++ b/packages/wyatt_http_client/lib/src/middlewares/uri_prefix_middleware.dart
@@ -0,0 +1,42 @@
+// Copyright (C) 2022 WYATT GROUP
+// Please see the AUTHORS file for details.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import 'package:wyatt_http_client/src/middleware.dart';
+import 'package:wyatt_http_client/src/models/middleware_request.dart';
+import 'package:wyatt_http_client/src/utils/protocols.dart';
+
+class UriPrefixMiddleware extends Middleware {
+ final Protocols protocol;
+ final String? authority;
+
+ UriPrefixMiddleware({
+ required this.protocol,
+ required this.authority,
+ super.child,
+ });
+
+ @override
+ String getName() => 'UriPrefixMiddleware';
+
+ @override
+ MiddlewareRequest onRequest(MiddlewareRequest request) {
+ final Uri uri =
+ Uri.parse('${protocol.scheme}$authority${request.httpRequest.url}');
+ print('UriPrefix::OnRequest: ${request.httpRequest.url} -> $uri');
+ request.updateHttpRequest(url: uri);
+ return super.onRequest(request);
+ }
+}
diff --git a/packages/wyatt_http_client/lib/src/models/middleware_request.dart b/packages/wyatt_http_client/lib/src/models/middleware_request.dart
new file mode 100644
index 00000000..b55481ff
--- /dev/null
+++ b/packages/wyatt_http_client/lib/src/models/middleware_request.dart
@@ -0,0 +1,89 @@
+// ignore_for_file: public_member_api_docs, sort_constructors_first
+// Copyright (C) 2022 WYATT GROUP
+// Please see the AUTHORS file for details.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import 'package:http/http.dart';
+import 'package:wyatt_http_client/src/models/unfreezed_request.dart';
+import 'package:wyatt_http_client/src/utils/utils.dart';
+
+class MiddlewareRequest {
+ UnfreezedRequest unfreezedRequest;
+ Request httpRequest;
+
+ MiddlewareRequest({
+ required this.unfreezedRequest,
+ required this.httpRequest,
+ });
+
+ MiddlewareRequest copyWith({
+ UnfreezedRequest? unfreezedRequest,
+ Request? httpRequest,
+ }) {
+ return MiddlewareRequest(
+ unfreezedRequest: unfreezedRequest ?? this.unfreezedRequest,
+ httpRequest: httpRequest ?? this.httpRequest,
+ );
+ }
+
+ void updateUnfreezedRequest(UnfreezedRequest unfreezedRequest) {
+ final request = httpRequest;
+ if (unfreezedRequest.headers != null) {
+ request.headers.addAll(unfreezedRequest.headers!);
+ }
+ if (unfreezedRequest.encoding != null) {
+ request.encoding = unfreezedRequest.encoding!;
+ }
+ if (unfreezedRequest.body != null) {
+ final body = unfreezedRequest.body;
+ if (body is String) {
+ request.body = body;
+ } else if (body is List) {
+ request.bodyBytes = body.cast();
+ } else if (body is Map) {
+ request.bodyFields = body.cast();
+ } else {
+ throw ArgumentError('Invalid request body "$body".');
+ }
+ }
+ this.unfreezedRequest = unfreezedRequest;
+ httpRequest = request;
+ }
+
+ void updateHttpRequest({
+ String? method,
+ Uri? url,
+ Map? headers,
+ int? maxRedirects,
+ bool? followRedirects,
+ bool? persistentConnection,
+ String? body,
+ }) {
+ httpRequest = Utils.copyRequestWith(
+ httpRequest,
+ method: method,
+ url: url,
+ headers: headers,
+ maxRedirects: maxRedirects,
+ followRedirects: followRedirects,
+ persistentConnection: persistentConnection,
+ body: body,
+ ) as Request;
+ }
+
+ @override
+ String toString() => 'MiddlewareRequest(unfreezedRequest: '
+ '$unfreezedRequest, httpRequest: $httpRequest)';
+}
diff --git a/packages/wyatt_http_client/lib/src/models/middleware_response.dart b/packages/wyatt_http_client/lib/src/models/middleware_response.dart
new file mode 100644
index 00000000..5e67ae74
--- /dev/null
+++ b/packages/wyatt_http_client/lib/src/models/middleware_response.dart
@@ -0,0 +1,37 @@
+// ignore_for_file: public_member_api_docs, sort_constructors_first
+// Copyright (C) 2022 WYATT GROUP
+// Please see the AUTHORS file for details.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import 'package:http/http.dart';
+
+class MiddlewareResponse {
+ BaseResponse httpResponse;
+
+ MiddlewareResponse({
+ required this.httpResponse,
+ });
+
+ MiddlewareResponse copyWith({
+ BaseResponse? httpResponse,
+ }) {
+ return MiddlewareResponse(
+ httpResponse: httpResponse ?? this.httpResponse,
+ );
+ }
+
+ @override
+ String toString() => 'MiddlewareResponse(httpResponse: $httpResponse)';
+}
diff --git a/packages/wyatt_http_client/lib/src/models/unfreezed_request.dart b/packages/wyatt_http_client/lib/src/models/unfreezed_request.dart
new file mode 100644
index 00000000..9aa9790f
--- /dev/null
+++ b/packages/wyatt_http_client/lib/src/models/unfreezed_request.dart
@@ -0,0 +1,55 @@
+// Copyright (C) 2022 WYATT GROUP
+// Please see the AUTHORS file for details.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import 'dart:convert';
+
+class UnfreezedRequest {
+ final String method;
+ final Uri url;
+ final Map? headers;
+ final Object? body;
+ final Encoding? encoding;
+
+ UnfreezedRequest({
+ required this.method,
+ required this.url,
+ this.headers,
+ this.body,
+ this.encoding,
+ });
+
+ UnfreezedRequest copyWith({
+ String? method,
+ Uri? url,
+ Map? headers,
+ Object? body,
+ Encoding? encoding,
+ }) {
+ return UnfreezedRequest(
+ method: method ?? this.method,
+ url: url ?? this.url,
+ headers: headers ?? this.headers,
+ body: body ?? this.body,
+ encoding: encoding ?? this.encoding,
+ );
+ }
+
+ @override
+ String toString() {
+ return 'UnfreezedRequest(method: $method, url: $url, headers: '
+ '$headers, body: $body, encoding: $encoding)';
+ }
+}
diff --git a/packages/wyatt_http_client/lib/src/pipeline.dart b/packages/wyatt_http_client/lib/src/pipeline.dart
new file mode 100644
index 00000000..479c1f1b
--- /dev/null
+++ b/packages/wyatt_http_client/lib/src/pipeline.dart
@@ -0,0 +1,57 @@
+// Copyright (C) 2022 WYATT GROUP
+// Please see the AUTHORS file for details.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import 'package:wyatt_http_client/src/middleware.dart';
+import 'package:wyatt_http_client/src/middlewares/default_middleware.dart';
+
+class Pipeline {
+ final Middleware _middleware;
+
+ Pipeline() : _middleware = DefaultMiddleware();
+
+ Pipeline addMiddleware(Middleware middleware) {
+ _middleware.addChild(middleware);
+ return this;
+ }
+
+ Middleware get middleware {
+ return _middleware;
+ }
+
+ Pipeline operator +(Pipeline other) {
+ final copy = _middleware.deepCopy()..addChild(other.middleware);
+ return Pipeline()..addMiddleware(copy);
+ }
+
+ String getLogic() {
+ final req = [];
+ final res = [];
+ Middleware? m = _middleware;
+ while (m != null) {
+ if (m is! DefaultMiddleware) {
+ req.add('$m');
+ res.insert(0, '$m');
+ }
+ m = m.child;
+ }
+ return '[Req] -> ${req.join(' -> ')}\n[Res] -> ${res.join(' -> ')}';
+ }
+
+ @override
+ String toString() {
+ return middleware.toString();
+ }
+}