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(); + } +}