From f2a6c446ebc728ec5570651db29732befbc29b53 Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Sat, 30 Mar 2024 17:48:11 +0100 Subject: [PATCH] chore: remove deprecated http client package in favor of http/dio packages --- packages/wyatt_architecture/README.md | 10 +- .../lib/core/constants/constants.dart} | 13 +- .../lib/core/dependency_injection/get_it.dart | 16 +- .../remote/album_api_data_source_impl.dart | 15 +- .../remote/photo_api_data_source_impl.dart | 18 +- .../wyatt_architecture/example/pubspec.yaml | 4 +- packages/wyatt_http_client/.gitignore | 1 - packages/wyatt_http_client/.pubignore | 1 - .../wyatt_http_client/.vscode/extensions.json | 24 --- .../wyatt_http_client/.vscode/settings.json | 71 ------- packages/wyatt_http_client/AUTHORS | 1 - packages/wyatt_http_client/CHANGELOG.md | 25 --- packages/wyatt_http_client/LICENSE | 1 - packages/wyatt_http_client/README.md | 182 ---------------- .../wyatt_http_client/analysis_options.yaml | 1 - .../wyatt_http_client/example/example.dart | 78 ------- .../wyatt_http_client/lib/src/middleware.dart | 48 ----- .../lib/src/middleware_client.dart | 134 ------------ .../middlewares/basic_auth_middleware.dart | 65 ------ .../middlewares/body_to_json_middleware.dart | 50 ----- .../src/middlewares/default_middleware.dart | 28 --- .../middlewares/digest_auth_middleware.dart | 87 -------- .../lib/src/middlewares/middlewares.dart | 26 --- .../refresh_token_auth_middleware.dart | 184 ---------------- .../middlewares/simple_logger_middleware.dart | 72 ------- .../middlewares/unsafe_auth_middleware.dart | 56 ----- .../middlewares/uri_prefix_middleware.dart | 50 ----- .../lib/src/models/middleware_context.dart | 78 ------- .../lib/src/models/middleware_request.dart | 102 --------- .../lib/src/models/middleware_response.dart | 63 ------ .../lib/src/models/unfreezed_request.dart | 69 ------ .../wyatt_http_client/lib/src/pipeline.dart | 122 ----------- .../lib/src/utils/authentication_methods.dart | 27 --- .../lib/src/utils/convert.dart | 62 ------ .../lib/src/utils/crypto.dart | 30 --- .../lib/src/utils/delay.dart | 38 ---- .../lib/src/utils/digest_auth.dart | 196 ------------------ .../lib/src/utils/header_keys.dart | 27 --- .../lib/src/utils/http_methods.dart | 32 --- .../lib/src/utils/http_status.dart | 116 ----------- .../lib/src/utils/protocols.dart | 26 --- .../lib/src/utils/request_utils.dart | 95 --------- .../lib/src/utils/utils.dart | 23 -- .../lib/wyatt_http_client.dart | 24 --- packages/wyatt_http_client/pubspec.yaml | 18 -- 45 files changed, 34 insertions(+), 2375 deletions(-) rename packages/{wyatt_http_client/lib/src/models/models.dart => wyatt_architecture/example/lib/core/constants/constants.dart} (78%) delete mode 120000 packages/wyatt_http_client/.gitignore delete mode 120000 packages/wyatt_http_client/.pubignore delete mode 100644 packages/wyatt_http_client/.vscode/extensions.json delete mode 100644 packages/wyatt_http_client/.vscode/settings.json delete mode 120000 packages/wyatt_http_client/AUTHORS delete mode 100644 packages/wyatt_http_client/CHANGELOG.md delete mode 120000 packages/wyatt_http_client/LICENSE delete mode 100644 packages/wyatt_http_client/README.md delete mode 100644 packages/wyatt_http_client/analysis_options.yaml delete mode 100644 packages/wyatt_http_client/example/example.dart delete mode 100644 packages/wyatt_http_client/lib/src/middleware.dart delete mode 100644 packages/wyatt_http_client/lib/src/middleware_client.dart delete mode 100644 packages/wyatt_http_client/lib/src/middlewares/basic_auth_middleware.dart delete mode 100644 packages/wyatt_http_client/lib/src/middlewares/body_to_json_middleware.dart delete mode 100644 packages/wyatt_http_client/lib/src/middlewares/default_middleware.dart delete mode 100644 packages/wyatt_http_client/lib/src/middlewares/digest_auth_middleware.dart delete mode 100644 packages/wyatt_http_client/lib/src/middlewares/middlewares.dart delete mode 100644 packages/wyatt_http_client/lib/src/middlewares/refresh_token_auth_middleware.dart delete mode 100644 packages/wyatt_http_client/lib/src/middlewares/simple_logger_middleware.dart delete mode 100644 packages/wyatt_http_client/lib/src/middlewares/unsafe_auth_middleware.dart delete mode 100644 packages/wyatt_http_client/lib/src/middlewares/uri_prefix_middleware.dart delete mode 100644 packages/wyatt_http_client/lib/src/models/middleware_context.dart delete mode 100644 packages/wyatt_http_client/lib/src/models/middleware_request.dart delete mode 100644 packages/wyatt_http_client/lib/src/models/middleware_response.dart delete mode 100644 packages/wyatt_http_client/lib/src/models/unfreezed_request.dart delete mode 100644 packages/wyatt_http_client/lib/src/pipeline.dart delete mode 100644 packages/wyatt_http_client/lib/src/utils/authentication_methods.dart delete mode 100644 packages/wyatt_http_client/lib/src/utils/convert.dart delete mode 100644 packages/wyatt_http_client/lib/src/utils/crypto.dart delete mode 100644 packages/wyatt_http_client/lib/src/utils/delay.dart delete mode 100644 packages/wyatt_http_client/lib/src/utils/digest_auth.dart delete mode 100644 packages/wyatt_http_client/lib/src/utils/header_keys.dart delete mode 100644 packages/wyatt_http_client/lib/src/utils/http_methods.dart delete mode 100644 packages/wyatt_http_client/lib/src/utils/http_status.dart delete mode 100644 packages/wyatt_http_client/lib/src/utils/protocols.dart delete mode 100644 packages/wyatt_http_client/lib/src/utils/request_utils.dart delete mode 100644 packages/wyatt_http_client/lib/src/utils/utils.dart delete mode 100644 packages/wyatt_http_client/lib/wyatt_http_client.dart delete mode 100644 packages/wyatt_http_client/pubspec.yaml diff --git a/packages/wyatt_architecture/README.md b/packages/wyatt_architecture/README.md index 657355cb..f757d05d 100644 --- a/packages/wyatt_architecture/README.md +++ b/packages/wyatt_architecture/README.md @@ -177,13 +177,13 @@ Then implements your data sources: ```dart class PhotoApiDataSourceImpl extends PhotoRemoteDataSource { - final MiddlewareClient _client; + final Client _client; PhotoApiDataSourceImpl(this._client); @override Future getPhoto(int id) async { - final response = await _client.get(Uri.parse('/photos/$id')); + final response = await _client.get(Uri.parse('$kDefaultApiUrl/photos/$id')); final photo = PhotoModel.fromJson(jsonDecode(response.body) as Map); return photo; @@ -197,7 +197,7 @@ class PhotoApiDataSourceImpl extends PhotoRemoteDataSource { (startQuery.isNotEmpty || limitQuery.isNotEmpty) ? '?' : ''; final delimiter2 = (startQuery.isNotEmpty && limitQuery.isNotEmpty) ? '&' : ''; - final url = '/photos$delimiter1$startQuery$delimiter2$limitQuery'; + final url = '$kDefaultApiUrl/photos$delimiter1$startQuery$delimiter2$limitQuery'; final response = await _client.get(Uri.parse(url)); final photos = ListPhotoModel.fromJson({'photos': jsonDecode(response.body)}); @@ -206,9 +206,7 @@ class PhotoApiDataSourceImpl extends PhotoRemoteDataSource { } ``` -> 1: Note that here we use `MiddlewareClient` from our http package. - -> 2: You can create multiple implementations (one real and one mock for example). +> 1: You can create multiple implementations (one real and one mock for example). And implement the repositories: diff --git a/packages/wyatt_http_client/lib/src/models/models.dart b/packages/wyatt_architecture/example/lib/core/constants/constants.dart similarity index 78% rename from packages/wyatt_http_client/lib/src/models/models.dart rename to packages/wyatt_architecture/example/lib/core/constants/constants.dart index 95b3b377..679b9074 100644 --- a/packages/wyatt_http_client/lib/src/models/models.dart +++ b/packages/wyatt_architecture/example/lib/core/constants/constants.dart @@ -1,20 +1,17 @@ -// Copyright (C) 2022 WYATT GROUP +// Copyright (C) 2024 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 . -export 'middleware_context.dart'; -export 'middleware_request.dart'; -export 'middleware_response.dart'; -export 'unfreezed_request.dart'; +const String kDefaultApiUrl = 'https://jsonplaceholder.typicode.com/'; diff --git a/packages/wyatt_architecture/example/lib/core/dependency_injection/get_it.dart b/packages/wyatt_architecture/example/lib/core/dependency_injection/get_it.dart index a3e2bc25..8aaacaaa 100644 --- a/packages/wyatt_architecture/example/lib/core/dependency_injection/get_it.dart +++ b/packages/wyatt_architecture/example/lib/core/dependency_injection/get_it.dart @@ -26,7 +26,6 @@ import 'package:architecture_example/domain/data_sources/local/favorite_local_da import 'package:architecture_example/domain/data_sources/remote/album_remote_data_source.dart'; import 'package:architecture_example/domain/data_sources/remote/photo_remote_data_source.dart'; import 'package:get_it/get_it.dart'; -import 'package:wyatt_http_client/wyatt_http_client.dart'; final getIt = GetIt.I; @@ -50,22 +49,11 @@ abstract class GetItInitializer { ..registerLazySingleton( FavoriteHiveDataSource.new, ) - ..registerLazySingleton(() { - final Pipeline pipeline = Pipeline() - ..addMiddleware( - const UriPrefixMiddleware( - protocol: Protocols.https, - authority: 'jsonplaceholder.typicode.com', - ), - ) - ..addMiddleware(const BodyToJsonMiddleware()); - return MiddlewareClient(pipeline: pipeline); - }) ..registerLazySingleton( - () => PhotoApiDataSourceImpl(getIt()), + PhotoApiDataSourceImpl.new, ) ..registerLazySingleton( - () => AlbumApiDataSourceImpl(getIt()), + AlbumApiDataSourceImpl.new, ); } diff --git a/packages/wyatt_architecture/example/lib/data/data_sources/remote/album_api_data_source_impl.dart b/packages/wyatt_architecture/example/lib/data/data_sources/remote/album_api_data_source_impl.dart index 3c4cdcdf..d6e21175 100644 --- a/packages/wyatt_architecture/example/lib/data/data_sources/remote/album_api_data_source_impl.dart +++ b/packages/wyatt_architecture/example/lib/data/data_sources/remote/album_api_data_source_impl.dart @@ -16,20 +16,25 @@ import 'dart:convert'; +import 'package:architecture_example/core/constants/constants.dart'; import 'package:architecture_example/data/models/album_model.dart'; import 'package:architecture_example/data/models/list_album_model.dart'; import 'package:architecture_example/domain/data_sources/remote/album_remote_data_source.dart'; import 'package:architecture_example/domain/entities/album.dart'; -import 'package:wyatt_http_client/wyatt_http_client.dart'; +import 'package:http/http.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart'; class AlbumApiDataSourceImpl extends AlbumRemoteDataSource { - AlbumApiDataSourceImpl(this._client); - final MiddlewareClient _client; + AlbumApiDataSourceImpl({ + Client? client, + }) : _client = client ?? Client(); + + final Client _client; @override Future getAlbum(int id) async { - final response = await _client.get(Uri.parse('/albums/$id')); + final response = await _client + .get(Uri.parse('$kDefaultApiUrl/albums/$id')); final album = AlbumModel.fromJson(jsonDecode(response.body) as Map); return album; @@ -43,7 +48,7 @@ class AlbumApiDataSourceImpl extends AlbumRemoteDataSource { (startQuery.isNotEmpty || limitQuery.isNotEmpty) ? '?' : ''; final delimiter2 = (startQuery.isNotEmpty && limitQuery.isNotEmpty) ? '&' : ''; - final url = '/albums$delimiter1$startQuery$delimiter2$limitQuery'; + final url = '$kDefaultApiUrl/albums$delimiter1$startQuery$delimiter2$limitQuery'; final response = await _client.get(Uri.parse(url)); final albums = ListAlbumModel.fromJson({'albums': jsonDecode(response.body)}); diff --git a/packages/wyatt_architecture/example/lib/data/data_sources/remote/photo_api_data_source_impl.dart b/packages/wyatt_architecture/example/lib/data/data_sources/remote/photo_api_data_source_impl.dart index 3f559fe8..db726374 100644 --- a/packages/wyatt_architecture/example/lib/data/data_sources/remote/photo_api_data_source_impl.dart +++ b/packages/wyatt_architecture/example/lib/data/data_sources/remote/photo_api_data_source_impl.dart @@ -16,20 +16,24 @@ import 'dart:convert'; +import 'package:architecture_example/core/constants/constants.dart'; import 'package:architecture_example/data/models/list_photo_model.dart'; import 'package:architecture_example/data/models/photo_model.dart'; import 'package:architecture_example/domain/data_sources/remote/photo_remote_data_source.dart'; import 'package:architecture_example/domain/entities/photo.dart'; -import 'package:wyatt_http_client/wyatt_http_client.dart'; +import 'package:http/http.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart'; class PhotoApiDataSourceImpl extends PhotoRemoteDataSource { - PhotoApiDataSourceImpl(this._client); - final MiddlewareClient _client; + PhotoApiDataSourceImpl({ + Client? client, + }) : _client = client ?? Client(); + + final Client _client; @override Future getPhoto(int id) async { - final response = await _client.get(Uri.parse('/photos/$id')); + final response = await _client.get(Uri.parse('$kDefaultApiUrl/photos/$id')); final photo = PhotoModel.fromJson(jsonDecode(response.body) as Map); return photo; @@ -43,7 +47,8 @@ class PhotoApiDataSourceImpl extends PhotoRemoteDataSource { (startQuery.isNotEmpty || limitQuery.isNotEmpty) ? '?' : ''; final delimiter2 = (startQuery.isNotEmpty && limitQuery.isNotEmpty) ? '&' : ''; - final url = '/photos$delimiter1$startQuery$delimiter2$limitQuery'; + final url = + '$kDefaultApiUrl/photos$delimiter1$startQuery$delimiter2$limitQuery'; final response = await _client.get(Uri.parse(url)); final photos = ListPhotoModel.fromJson({'photos': jsonDecode(response.body)}); @@ -60,7 +65,8 @@ class PhotoApiDataSourceImpl extends PhotoRemoteDataSource { final limitQuery = limit.isNotNull ? '_limit=$limit' : ''; final delimiter = (startQuery.isNotEmpty && limitQuery.isNotEmpty) ? '&' : ''; - final url = '/photos?albumId=$albumId&$startQuery$delimiter$limitQuery'; + final url = + '$kDefaultApiUrl/photos?albumId=$albumId&$startQuery$delimiter$limitQuery'; final response = await _client.get(Uri.parse(url)); final photos = ListPhotoModel.fromJson({'photos': jsonDecode(response.body)}); diff --git a/packages/wyatt_architecture/example/pubspec.yaml b/packages/wyatt_architecture/example/pubspec.yaml index cb55c209..41f02db8 100644 --- a/packages/wyatt_architecture/example/pubspec.yaml +++ b/packages/wyatt_architecture/example/pubspec.yaml @@ -45,12 +45,10 @@ dependencies: wyatt_bloc_helper: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ version: ^2.0.2 - wyatt_http_client: - hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ - version: ^2.0.1 wyatt_type_utils: hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub version: ^0.0.5 + http: ^1.2.1 dev_dependencies: build_runner: ^2.3.2 diff --git a/packages/wyatt_http_client/.gitignore b/packages/wyatt_http_client/.gitignore deleted file mode 120000 index 6ef08f9d..00000000 --- a/packages/wyatt_http_client/.gitignore +++ /dev/null @@ -1 +0,0 @@ -../../.gitignore \ No newline at end of file diff --git a/packages/wyatt_http_client/.pubignore b/packages/wyatt_http_client/.pubignore deleted file mode 120000 index 52b2f28d..00000000 --- a/packages/wyatt_http_client/.pubignore +++ /dev/null @@ -1 +0,0 @@ -../../.pubignore \ No newline at end of file diff --git a/packages/wyatt_http_client/.vscode/extensions.json b/packages/wyatt_http_client/.vscode/extensions.json deleted file mode 100644 index 30cd2233..00000000 --- a/packages/wyatt_http_client/.vscode/extensions.json +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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 . - */ - -{ - "recommendations": [ - "psioniq.psi-header", - "blaugold.melos-code" - ] -} \ No newline at end of file diff --git a/packages/wyatt_http_client/.vscode/settings.json b/packages/wyatt_http_client/.vscode/settings.json deleted file mode 100644 index 708f5ba6..00000000 --- a/packages/wyatt_http_client/.vscode/settings.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "psi-header.changes-tracking": { - "isActive": true - }, - "psi-header.config": { - "blankLinesAfter": 1, - "forceToTop": true - }, - "psi-header.lang-config": [ - { - "beforeHeader": [ - "# -*- coding:utf-8 -*-", - "#!/usr/bin/env python3" - ], - "begin": "###", - "end": "###", - "language": "python", - "prefix": "# " - }, - { - "beforeHeader": [ - "#!/usr/bin/env sh", - "" - ], - "language": "shellscript", - "begin": "", - "end": "", - "prefix": "# " - }, - { - "begin": "", - "end": "", - "language": "dart", - "prefix": "// " - }, - { - "begin": "", - "end": "", - "language": "yaml", - "prefix": "# " - }, - { - "begin": "", - "language": "markdown", - }, - ], - "psi-header.templates": [ - { - "language": "*", - "template": [ - "Copyright (C) <> 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 ." - ], - } - ], - "dart.runPubGetOnPubspecChanges": false, -} \ No newline at end of file diff --git a/packages/wyatt_http_client/AUTHORS b/packages/wyatt_http_client/AUTHORS deleted file mode 120000 index f04b7e8a..00000000 --- a/packages/wyatt_http_client/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -../../AUTHORS \ No newline at end of file diff --git a/packages/wyatt_http_client/CHANGELOG.md b/packages/wyatt_http_client/CHANGELOG.md deleted file mode 100644 index 8f70a0a7..00000000 --- a/packages/wyatt_http_client/CHANGELOG.md +++ /dev/null @@ -1,25 +0,0 @@ -## 2.0.1 - - - **FIX**: apply dart fix --apply. - -## 2.0.0 - -> Note: This release has breaking changes. - - - **DOCS**: add simple example. - - **BREAKING** **REFACTOR**: fix cascade dart good practices + docs. - -## 1.2.0 - - - **FEAT**: add new middleware feature. - - **FEAT**: implements doublelinked list for middlewares. - - **FEAT**: [WIP] implements middleware system. - - **FEAT**: [WIP] work on middleware feature. - -## 1.1.0 - - - **FEAT**: add oauth2 refresh token client. - -## 1.0.0 - -- Initial version. diff --git a/packages/wyatt_http_client/LICENSE b/packages/wyatt_http_client/LICENSE deleted file mode 120000 index 30cff740..00000000 --- a/packages/wyatt_http_client/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../LICENSE \ No newline at end of file diff --git a/packages/wyatt_http_client/README.md b/packages/wyatt_http_client/README.md deleted file mode 100644 index aee439ed..00000000 --- a/packages/wyatt_http_client/README.md +++ /dev/null @@ -1,182 +0,0 @@ - - -# HTTP Client - -

- Style: Wyatt Analysis - SDK: Dart & Flutter -

- -HTTP Client for Dart with Middlewares ! - -## Getting started - -Simply add wyatt_http_client in pubspec.yaml, then - -```dart -import 'package:wyatt_http_client/wyatt_http_client.dart'; -``` - -## Usage - -Firstly you have to understand **Middleware** and **Pipeline** concepts. - -In `wyatt_http_client` a middleware is an object where requests and responses -pass through. And a pipeline is basicaly a list of middlewares. - -In a pipeline with middlewares A and B, if request pass through A, then B, -the response will pass through B then A. - -> You can `print(pipeline)` to get full process order of a pipeline. - -For example, if you want to log every request, and simplify an url you can use provided `SimpleLogger` and `UriPrefix` . - -```dart -// Create the Pipeline -final Pipeline pipeline = Pipeline() - ..addMiddleware( - const UriPrefixMiddleware( - protocol: Protocols.http, - authority: 'localhost:80', - ), - ) - ..addMiddleware(const SimpleLoggerMiddleware()); -``` - -Then if you print the pipeline, - -``` -[Req] -> UriPrefix -> SimpleLogger -[Res] -> SimpleLogger -``` - -> The `response` doesn't pass through `UriPrefix` because it's an `OnRequestMiddleware` only. - -And you can create a client. - -```dart -final client = MiddlewareClient(pipeline: pipeline); -``` - -At this point you can use `client` like every Client from `package:http/http.dart` . - -## Recipes - -### Rest API with URL Authentication - -Let's build a client for a REST API where the (bad) authentication is through the URL. -We need some middlewares: - -* SimpleLogger, to log every request and response (useful for debug). -* BodyToJson, to automaticaly transform Map object to JSON. -* UriPrefix, to simplify the build of an API Object (save protocol and API prefix). -* UnsafeAuth, to use url based authentication. - -Let's start by creating the Pipeline: - -```dart -final Pipeline pipeline = Pipeline() - ..addMiddleware( - const UriPrefixMiddleware( - protocol: Protocols.http, - authority: 'localhost:80', - ), - ) - ..addMiddleware(const BodyToJsonMiddleware()) - ..addMiddleware( - const UnsafeAuthMiddleware( - username: 'wyatt', - password: 'motdepasse', - ), - ) - ..addMiddleware(SimpleLoggerMiddleware()); -``` - -Then simply create a client and make a call. - -```dart -final client = MiddlewareClient(pipeline: pipeline); - -await client.get(Uri.parse('/protected')); -``` - -> Here it make a `GET` call on `http://localhost:80/protected?username=wyatt&password=motdepasse` - -And voilà. - -### Rest API with Oauth2 - -So now we want a real authentication. - -```dart -final Pipeline pipeline = Pipeline() - ..addMiddleware( - const UriPrefixMiddleware( - protocol: Protocols.http, - authority: 'localhost:80', - ), - ) - ..addMiddleware(const BodyToJsonMiddleware()) - ..addMiddleware( - RefreshTokenAuthMiddleware( - authorizationEndpoint: '/auth/sign-in', - tokenEndpoint: '/auth/refresh', - accessTokenParser: (body) => body['access_token']! as String, - refreshTokenParser: (body) => body['refresh_token']! as String, - unauthorized: HttpStatus.forbidden, - ), - ) - ..addMiddleware(const SimpleLoggerMiddleware()); -``` - -> Here we just change `UnsafeAuthMiddleware` by `RefreshTokenAuthMiddleware` and the whole app while adapt to a new authentication system. - -### Create a new Middleware - -You can create your own middleware by implementing `Middleware` class, and use mixins to add `OnRequest` and/or `OnResponse` methods. - -```dart -class SimpleLoggerMiddleware - with OnRequestMiddleware, OnResponseMiddleware - implements Middleware { - - const SimpleLoggerMiddleware(); - - @override - String getName() => 'SimpleLogger'; - - @override - Future onRequest( - MiddlewareContext context, - MiddlewareRequest request, - ) async { - print('${getName()}::OnRequest'); - return request; - } - - @override - Future onResponse( - MiddlewareContext context, - MiddlewareResponse response, - ) async { - print('${getName()}::OnResponse'); - return response; - } -} -``` diff --git a/packages/wyatt_http_client/analysis_options.yaml b/packages/wyatt_http_client/analysis_options.yaml deleted file mode 100644 index e1caf220..00000000 --- a/packages/wyatt_http_client/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: package:wyatt_analysis/analysis_options.yaml diff --git a/packages/wyatt_http_client/example/example.dart b/packages/wyatt_http_client/example/example.dart deleted file mode 100644 index a5c529ea..00000000 --- a/packages/wyatt_http_client/example/example.dart +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2023 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/wyatt_http_client.dart'; - -Future testSimpleGet() async { - print('testSimpleGet'); - final pipeline = Pipeline() - ..addMiddleware(const BodyToJsonMiddleware()) - ..addMiddleware(const SimpleLoggerMiddleware()); - - final client = MiddlewareClient(pipeline: pipeline); - - final response = await client - .get(Uri.parse('https://jsonplaceholder.typicode.com/todos/1')); - print(response.body); -} - -Future testUriPrefix() async { - print('testUriPrefix'); - final pipeline = Pipeline() - ..addMiddleware( - const UriPrefixMiddleware( - protocol: Protocols.https, - authority: 'jsonplaceholder.typicode.com', - ), - ) - ..addMiddleware(const BodyToJsonMiddleware()) - ..addMiddleware(const SimpleLoggerMiddleware()); - - final client = MiddlewareClient(pipeline: pipeline); - - final response = await client.get(Uri.parse('/todos/1')); - print(response.body); -} - -Future testBasicAuth() async { - print('testBasicAuth'); - final pipeline = Pipeline() - ..addMiddleware( - const BasicAuthMiddleware( - username: 'guest', - password: 'guest', - ), - ) - ..addMiddleware(const BodyToJsonMiddleware()) - ..addMiddleware(const SimpleLoggerMiddleware()); - - final client = MiddlewareClient(pipeline: pipeline); - - final response = - await client.get(Uri.parse('https://jigsaw.w3.org/HTTP/Basic/')); - - if (HttpStatus.from(response.statusCode).isSuccess()) { - print("🎉 You're in!"); - } else { - print("⭕️ Nope, you're not in."); - } -} - -void main(List args) { - testSimpleGet(); - testUriPrefix(); - testBasicAuth(); -} diff --git a/packages/wyatt_http_client/lib/src/middleware.dart b/packages/wyatt_http_client/lib/src/middleware.dart deleted file mode 100644 index 9f0c9d67..00000000 --- a/packages/wyatt_http_client/lib/src/middleware.dart +++ /dev/null @@ -1,48 +0,0 @@ -// 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/models/middleware_context.dart'; -import 'package:wyatt_http_client/src/models/middleware_request.dart'; -import 'package:wyatt_http_client/src/models/middleware_response.dart'; - -/// {@template middleware} -/// A middleware is a class that can intercept requests and responses -/// and modify them before they are sent to the server or before they -/// are returned to the client. -/// {@endtemplate} -abstract class Middleware { - /// {@macro middleware} - const Middleware(); - - /// The name of the middleware. - String getName(); -} - -mixin OnRequestMiddleware { - /// Performs an action before the request is sent to the server. - Future onRequest( - MiddlewareContext context, - MiddlewareRequest request, - ); -} - -mixin OnResponseMiddleware { - /// Performs an action before the response is returned to the client. - Future onResponse( - MiddlewareContext context, - MiddlewareResponse response, - ); -} diff --git a/packages/wyatt_http_client/lib/src/middleware_client.dart b/packages/wyatt_http_client/lib/src/middleware_client.dart deleted file mode 100644 index 23c1f064..00000000 --- a/packages/wyatt_http_client/lib/src/middleware_client.dart +++ /dev/null @@ -1,134 +0,0 @@ -// 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/models/middleware_context.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'; -import 'package:wyatt_http_client/src/utils/http_methods.dart'; - -/// {@template middleware_client} -/// A custom [Client] implementation that allows you to intercept requests -/// and responses and modify them before they are sent to the server or -/// before they are returned to the client. -/// {@endtemplate} -class MiddlewareClient extends BaseClient { - /// {@macro middleware_client} - MiddlewareClient({ - Pipeline? pipeline, - Client? inner, - }) : pipeline = pipeline ?? Pipeline(), - inner = inner ?? Client(); - - /// The [Client] that will be used to send requests. - final Client inner; - - /// The [Pipeline] that will be used to intercept requests and responses. - final Pipeline pipeline; - - @override - Future head(Uri url, {Map? headers}) => - _sendUnstreamed(HttpMethods.head.method, url, headers); - - @override - Future get(Uri url, {Map? headers}) => - _sendUnstreamed(HttpMethods.get.method, url, headers); - - @override - Future post( - Uri url, { - Map? headers, - Object? body, - Encoding? encoding, - }) => - _sendUnstreamed(HttpMethods.post.method, url, headers, body, encoding); - - @override - Future put( - Uri url, { - Map? headers, - Object? body, - Encoding? encoding, - }) => - _sendUnstreamed(HttpMethods.put.method, url, headers, body, encoding); - - @override - Future patch( - Uri url, { - Map? headers, - Object? body, - Encoding? encoding, - }) => - _sendUnstreamed(HttpMethods.patch.method, url, headers, body, encoding); - - @override - Future delete( - Uri url, { - Map? headers, - Object? body, - Encoding? encoding, - }) => - _sendUnstreamed(HttpMethods.delete.method, url, headers, body, encoding); - - @override - Future send(BaseRequest request) => inner.send(request); - - Future _sendUnstreamed( - String method, - Uri url, - Map? headers, [ - Object? body, - Encoding? encoding, - ]) async { - final originalRequest = MiddlewareRequest( - unfreezedRequest: UnfreezedRequest( - method: method, - url: url, - headers: headers, - body: body, - encoding: encoding, - ), - ); - final requestContext = MiddlewareContext( - pipeline: pipeline, - client: this, - originalRequest: originalRequest, - ); - - final modifiedRequest = await pipeline.onRequest( - requestContext, - originalRequest.copyWith(), - ); - - final originalResponse = MiddlewareResponse( - httpResponse: await Response.fromStream( - await send(modifiedRequest.request), - ), - ); - - final responseContext = - requestContext.copyWith(originalResponse: originalResponse); - - final modifiedResponse = - await pipeline.onResponse(responseContext, originalResponse.copyWith()); - - return modifiedResponse.httpResponse as Response; - } -} diff --git a/packages/wyatt_http_client/lib/src/middlewares/basic_auth_middleware.dart b/packages/wyatt_http_client/lib/src/middlewares/basic_auth_middleware.dart deleted file mode 100644 index 37bf033a..00000000 --- a/packages/wyatt_http_client/lib/src/middlewares/basic_auth_middleware.dart +++ /dev/null @@ -1,65 +0,0 @@ -// 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_context.dart'; -import 'package:wyatt_http_client/src/models/middleware_request.dart'; -import 'package:wyatt_http_client/src/utils/authentication_methods.dart'; -import 'package:wyatt_http_client/src/utils/header_keys.dart'; - -/// {@template basic_auth_middleware} -/// A middleware that adds basic authentication to the request. -/// {@endtemplate} -class BasicAuthMiddleware with OnRequestMiddleware implements Middleware { - /// {@macro basic_auth_middleware} - const BasicAuthMiddleware({ - this.username, - this.password, - this.authenticationHeader = HeaderKeys.authorization, - }); - - /// The username to use for authentication. - final String? username; - - /// The password to use for authentication. - final String? password; - - /// The header to use for authentication. - final String authenticationHeader; - - @override - String getName() => 'BasicAuth'; - - @override - Future onRequest( - MiddlewareContext context, - MiddlewareRequest request, - ) async { - if (username == null || password == null) { - return request; - } - - final mutation = { - authenticationHeader: '${AuthenticationMethods.basic} ' - '${base64Encode(utf8.encode('$username:$password'))}', - }; - final Map headers = request.headers..addAll(mutation); - request.modifyRequest(request.unfreezedRequest.copyWith(headers: headers)); - return request; - } -} 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 deleted file mode 100644 index e9aaaba7..00000000 --- a/packages/wyatt_http_client/lib/src/middlewares/body_to_json_middleware.dart +++ /dev/null @@ -1,50 +0,0 @@ -// 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_context.dart'; -import 'package:wyatt_http_client/src/models/middleware_request.dart'; - -/// {@template body_to_json_middleware} -/// A middleware that transforms the body in json if it's a [Map]. -/// {@endtemplate} -class BodyToJsonMiddleware with OnRequestMiddleware implements Middleware { - /// {@macro body_to_json_middleware} - const BodyToJsonMiddleware(); - - @override - String getName() => 'BodyToJson'; - - @override - Future onRequest( - MiddlewareContext context, - MiddlewareRequest request, - ) async { - final mutation = { - 'content-type': 'application/json; charset=utf-8', - }; - if (request.body is Map) { - final Map headers = request.headers..addAll(mutation); - request.modifyRequest( - request.unfreezedRequest - .copyWith(headers: headers, body: jsonEncode(request.body)), - ); - } - return 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 deleted file mode 100644 index 456a07b5..00000000 --- a/packages/wyatt_http_client/lib/src/middlewares/default_middleware.dart +++ /dev/null @@ -1,28 +0,0 @@ -// 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'; - -/// {@template default_middleware} -/// A default middleware that does nothing. -/// {@endtemplate} -class DefaultMiddleware implements Middleware { - /// {@macro default_middleware} - const DefaultMiddleware(); - - @override - String getName() => 'DefaultMiddleware'; -} diff --git a/packages/wyatt_http_client/lib/src/middlewares/digest_auth_middleware.dart b/packages/wyatt_http_client/lib/src/middlewares/digest_auth_middleware.dart deleted file mode 100644 index 55c17030..00000000 --- a/packages/wyatt_http_client/lib/src/middlewares/digest_auth_middleware.dart +++ /dev/null @@ -1,87 +0,0 @@ -// 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_context.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/utils/digest_auth.dart'; -import 'package:wyatt_http_client/src/utils/header_keys.dart'; -import 'package:wyatt_http_client/src/utils/http_status.dart'; - -/// {@template digest_auth_middleware} -/// A middleware that handles digest authentication. -/// {@endtemplate} -class DigestAuthMiddleware - with OnRequestMiddleware, OnResponseMiddleware - implements Middleware { - /// {@macro digest_auth_middleware} - DigestAuthMiddleware({ - required this.username, - required this.password, - this.authenticationHeader = HeaderKeys.authorization, - this.wwwAuthenticateHeader = HeaderKeys.wwwAuthenticate, - this.unauthorized = HttpStatus.unauthorized, - }) : _digestAuth = DigestAuth(username, password); - final String username; - final String password; - final DigestAuth _digestAuth; - final String authenticationHeader; - final String wwwAuthenticateHeader; - final HttpStatus unauthorized; - - @override - String getName() => 'DigestAuth'; - - @override - Future onRequest( - MiddlewareContext context, - MiddlewareRequest request, - ) async { - if (_digestAuth.isReady()) { - final mutation = { - authenticationHeader: _digestAuth.getAuthString( - request.method, - request.url, - ), - }; - final Map headers = request.headers..addAll(mutation); - request - .modifyRequest(request.unfreezedRequest.copyWith(headers: headers)); - } - return request; - } - - @override - Future onResponse( - MiddlewareContext context, - MiddlewareResponse response, - ) async { - if (response.status == unauthorized) { - final authInfo = - response.headers[HeaderKeys.wwwAuthenticate.toLowerCase()]; - _digestAuth.initFromAuthenticateHeader(authInfo); - - final MiddlewareRequest? newRequest = context.lastRequest?.copyWith(); - - if (newRequest != null) { - final newResponse = await context.client.send(newRequest.request); - return MiddlewareResponse(httpResponse: newResponse); - } - } - return response; - } -} diff --git a/packages/wyatt_http_client/lib/src/middlewares/middlewares.dart b/packages/wyatt_http_client/lib/src/middlewares/middlewares.dart deleted file mode 100644 index 29bbf147..00000000 --- a/packages/wyatt_http_client/lib/src/middlewares/middlewares.dart +++ /dev/null @@ -1,26 +0,0 @@ -// 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 . - -// All built-in middlewares - -export 'basic_auth_middleware.dart'; -export 'body_to_json_middleware.dart'; -export 'default_middleware.dart'; -export 'digest_auth_middleware.dart'; -export 'refresh_token_auth_middleware.dart'; -export 'simple_logger_middleware.dart'; -export 'unsafe_auth_middleware.dart'; -export 'uri_prefix_middleware.dart'; diff --git a/packages/wyatt_http_client/lib/src/middlewares/refresh_token_auth_middleware.dart b/packages/wyatt_http_client/lib/src/middlewares/refresh_token_auth_middleware.dart deleted file mode 100644 index 50f5005d..00000000 --- a/packages/wyatt_http_client/lib/src/middlewares/refresh_token_auth_middleware.dart +++ /dev/null @@ -1,184 +0,0 @@ -// 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/middleware_client.dart'; -import 'package:wyatt_http_client/src/models/middleware_context.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/utils/authentication_methods.dart'; -import 'package:wyatt_http_client/src/utils/delay.dart'; -import 'package:wyatt_http_client/src/utils/header_keys.dart'; -import 'package:wyatt_http_client/src/utils/http_status.dart'; - -typedef TokenParser = String Function(Map); - -/// {@template refresh_token_auth_middleware} -/// A middleware that refreshes the access token when it expires. -/// This middleware is useful for OAuth2. -/// {@endtemplate} -class RefreshTokenAuthMiddleware - with OnRequestMiddleware, OnResponseMiddleware - implements Middleware { - /// {@macro refresh_token_auth_middleware} - RefreshTokenAuthMiddleware({ - required this.authorizationEndpoint, - required this.tokenEndpoint, - required this.accessTokenParser, - required this.refreshTokenParser, - this.authenticationHeader = HeaderKeys.authorization, - this.authenticationMethod = AuthenticationMethods.bearer, - this.unauthorized = HttpStatus.unauthorized, - this.maxAttempts = 8, - }); - final String authorizationEndpoint; - final String tokenEndpoint; - - String? accessToken; - final TokenParser accessTokenParser; - String? refreshToken; - final TokenParser refreshTokenParser; - - final String authenticationHeader; - final String authenticationMethod; - final HttpStatus unauthorized; - final int maxAttempts; - - @override - String getName() => 'RefreshToken'; - - Future refresh(MiddlewareContext context) async { - final subPipeline = context.pipeline.sub(this); - final httpClient = MiddlewareClient( - pipeline: subPipeline, - inner: context.client.inner, - ); - final headers = { - authenticationHeader: '$authenticationMethod $refreshToken', - }; - final response = MiddlewareResponse( - httpResponse: await httpClient.get( - Uri.parse(tokenEndpoint), - headers: headers, - ), - ); - if (response.status.isSuccess()) { - final body = jsonDecode(response.body) as Map; - accessToken = accessTokenParser(body); - - // Then modify current request with accessToken - final mutation = { - authenticationHeader: '$authenticationMethod $accessToken', - }; - final Map? headers = context.lastRequest?.headers - ?..addAll(mutation); - final newRequest = context.lastRequest?.copyWith( - unfreezedRequest: - context.lastRequest?.unfreezedRequest.copyWith(headers: headers), - ); - - return newRequest; - } - return null; - } - - Future retry(MiddlewareContext context) async { - // Retry - int attempt = 1; - while (attempt <= maxAttempts) { - // Delayed before retry - await Future.delayed(Delay.getRetryDelay(attempt)); - - final newRequest = await refresh(context); - if (newRequest != null) { - return newRequest; - } - attempt++; - } - return null; - } - - @override - Future onRequest( - MiddlewareContext context, - MiddlewareRequest request, - ) async { - // Check if it is authorization - if (context.originalRequest?.url == Uri.parse(authorizationEndpoint)) { - return request; - } - // Check if it is refresh - if (context.originalRequest?.url == Uri.parse(tokenEndpoint)) { - return request; - } - // If AccessToken not null then return request with authorization header - if (accessToken != null) { - final mutation = { - authenticationHeader: '$authenticationMethod $accessToken', - }; - final Map headers = request.headers..addAll(mutation); - request - .modifyRequest(request.unfreezedRequest.copyWith(headers: headers)); - return request; - } - // If AccessToken is null BUT there is a refreshToken, then try refreshing - if (refreshToken != null) { - MiddlewareRequest? newRequest = await refresh(context); - newRequest ??= await retry(context); - return newRequest ?? request; - } - // Pass - return request; - } - - @override - Future onResponse( - MiddlewareContext context, - MiddlewareResponse response, - ) async { - // Check if it is authorization - if (context.originalRequest?.url == Uri.parse(authorizationEndpoint)) { - // If success, then update tokens - if (response.status.isSuccess()) { - final body = jsonDecode(response.body) as Map; - final accessToken = accessTokenParser(body); - final refreshToken = refreshTokenParser(body); - - if (accessToken.isNotEmpty) { - this.accessToken = accessToken; - } - if (refreshToken.isNotEmpty) { - this.refreshToken = refreshToken; - } - } - } - - if (response.status == unauthorized) { - // Refresh - MiddlewareRequest? newRequest = await refresh(context); - newRequest ??= await retry(context); - - if (newRequest != null) { - return response.copyWith( - httpResponse: await context.client.send(newRequest.request), - ); - } - } - return response; - } -} 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 deleted file mode 100644 index 31492b8f..00000000 --- a/packages/wyatt_http_client/lib/src/middlewares/simple_logger_middleware.dart +++ /dev/null @@ -1,72 +0,0 @@ -// 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_context.dart'; -import 'package:wyatt_http_client/src/models/middleware_request.dart'; -import 'package:wyatt_http_client/src/models/middleware_response.dart'; - -/// {@template simple_logger_middleware} -/// A simple logger middleware that logs the request and response. -/// {@endtemplate} -class SimpleLoggerMiddleware - with OnRequestMiddleware, OnResponseMiddleware - implements Middleware { - /// {@macro simple_logger_middleware} - const SimpleLoggerMiddleware(); - - @override - String getName() => 'SimpleLogger'; - - @override - Future onRequest( - MiddlewareContext context, - MiddlewareRequest request, - ) async { - final log = StringBuffer() - ..writeln('${getName()}::OnRequest') - ..writeln('>> ${request.method} ${request.url}'); - if (request.headers.isNotEmpty) { - log.writeln('>> Headers:'); - request.headers.forEach((key, value) { - log.writeln('>> $key: $value'); - }); - } - if (request.encodedBody.isNotEmpty) { - log - ..writeln('>> Body:') - ..writeln(request.encodedBody); - } - print(log); - - return request; - } - - @override - Future onResponse( - MiddlewareContext context, - MiddlewareResponse response, - ) async { - final log = StringBuffer() - ..writeln('${getName()}::OnResponse') - ..writeln('>> Status: ${response.status.name.toUpperCase()}') - ..writeln('>> Length: ${response.contentLength ?? '0'} bytes'); - - print(log); - - return response; - } -} diff --git a/packages/wyatt_http_client/lib/src/middlewares/unsafe_auth_middleware.dart b/packages/wyatt_http_client/lib/src/middlewares/unsafe_auth_middleware.dart deleted file mode 100644 index f4481877..00000000 --- a/packages/wyatt_http_client/lib/src/middlewares/unsafe_auth_middleware.dart +++ /dev/null @@ -1,56 +0,0 @@ -// 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_context.dart'; -import 'package:wyatt_http_client/src/models/middleware_request.dart'; -import 'package:wyatt_http_client/src/utils/convert.dart'; - -/// {@template unsafe_auth_middleware} -/// A middleware that appends the username and password to the URL. -/// -/// This is not recommended to use in production. -/// {@endtemplate} -class UnsafeAuthMiddleware with OnRequestMiddleware implements Middleware { - const UnsafeAuthMiddleware({ - this.username, - this.password, - this.usernameField = 'username', - this.passwordField = 'password', - }); - final String? username; - final String? password; - - final String usernameField; - final String passwordField; - - @override - String getName() => 'UnsafeAuth'; - - @override - Future onRequest( - MiddlewareContext context, - MiddlewareRequest request, - ) async { - if (username == null || password == null) { - return request; - } - final Uri uri = - request.url + '?$usernameField=$username&$passwordField=$password'; - request.modifyRequest(request.unfreezedRequest.copyWith(url: uri)); - return request; - } -} 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 deleted file mode 100644 index f02cff99..00000000 --- a/packages/wyatt_http_client/lib/src/middlewares/uri_prefix_middleware.dart +++ /dev/null @@ -1,50 +0,0 @@ -// 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_context.dart'; -import 'package:wyatt_http_client/src/models/middleware_request.dart'; -import 'package:wyatt_http_client/src/utils/protocols.dart'; - -/// {@template uri_prefix_middleware} -/// A middleware that adds a prefix to the request's URI. -/// {@endtemplate} -class UriPrefixMiddleware with OnRequestMiddleware implements Middleware { - /// {@macro uri_prefix_middleware} - const UriPrefixMiddleware({ - required this.protocol, - required this.authority, - }); - - /// The protocol of the prefix. - final Protocols protocol; - - /// The authority of the prefix. - final String? authority; - - @override - String getName() => 'UriPrefix'; - - @override - Future onRequest( - MiddlewareContext context, - MiddlewareRequest request, - ) async { - final Uri uri = Uri.parse('${protocol.scheme}$authority${request.url}'); - request.modifyRequest(request.unfreezedRequest.copyWith(url: uri)); - return request; - } -} diff --git a/packages/wyatt_http_client/lib/src/models/middleware_context.dart b/packages/wyatt_http_client/lib/src/models/middleware_context.dart deleted file mode 100644 index 5071b39e..00000000 --- a/packages/wyatt_http_client/lib/src/models/middleware_context.dart +++ /dev/null @@ -1,78 +0,0 @@ -// 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/models/middleware_request.dart'; -import 'package:wyatt_http_client/src/models/middleware_response.dart'; -import 'package:wyatt_http_client/src/pipeline.dart'; - -/// {@template middleware_context} -/// A class that contains the context of the middleware. -/// {@endtemplate} -class MiddlewareContext { - /// {@macro middleware_context} - const MiddlewareContext({ - required this.pipeline, - required this.client, - this.originalRequest, - this.lastRequest, - this.originalResponse, - this.lastResponse, - }); - - /// The pipeline that the middleware is in. - final Pipeline pipeline; - - /// The client that the middleware is in. - final MiddlewareClient client; - - /// The original request that the middleware is in. - final MiddlewareRequest? originalRequest; - - /// The last request that the middleware is in. - final MiddlewareRequest? lastRequest; - - /// The original response that the middleware is in. - final MiddlewareResponse? originalResponse; - - /// The last response that the middleware is in. - final MiddlewareResponse? lastResponse; - - /// Create a copy of this [MiddlewareContext] with the given fields replaced - /// with the new values. - MiddlewareContext copyWith({ - Pipeline? pipeline, - MiddlewareClient? client, - MiddlewareRequest? originalRequest, - MiddlewareRequest? lastRequest, - MiddlewareResponse? originalResponse, - MiddlewareResponse? lastResponse, - }) => - MiddlewareContext( - pipeline: pipeline ?? this.pipeline, - client: client ?? this.client, - originalRequest: originalRequest ?? this.originalRequest, - lastRequest: lastRequest ?? this.lastRequest, - originalResponse: originalResponse ?? this.originalResponse, - lastResponse: lastResponse ?? this.lastResponse, - ); - - @override - String toString() => - 'MiddlewareContext(pipeline: $pipeline, client: $client, ' - 'originalRequest: $originalRequest, lastRequest: $lastRequest, ' - 'originalResponse: $originalResponse, lastResponse: $lastResponse)'; -} diff --git a/packages/wyatt_http_client/lib/src/models/middleware_request.dart b/packages/wyatt_http_client/lib/src/models/middleware_request.dart deleted file mode 100644 index e7c93703..00000000 --- a/packages/wyatt_http_client/lib/src/models/middleware_request.dart +++ /dev/null @@ -1,102 +0,0 @@ -// 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/models/unfreezed_request.dart'; -import 'package:wyatt_http_client/src/utils/convert.dart'; -import 'package:wyatt_http_client/src/utils/request_utils.dart'; - -/// {@template middleware_request} -/// A class that represents a middleware request. -/// {@endtemplate} -class MiddlewareRequest { - /// {@macro middleware_request} - MiddlewareRequest({ - required this.unfreezedRequest, - }) : _httpRequest = Request(unfreezedRequest.method, unfreezedRequest.url); - - /// The unfreezed request. - UnfreezedRequest unfreezedRequest; - - Request _httpRequest; - - /// The http request. (Read-only) - Request get request => _httpRequest; - - /// The request method (proxy, read-only). - String get method => _httpRequest.method; - - /// The request url (proxy, read-only). - Uri get url => _httpRequest.url; - - /// The request headers (proxy, read-only). - Map get headers => _httpRequest.headers; - - /// The request body (proxy, read-only). - Encoding get encoding => _httpRequest.encoding; - - /// The request body (proxy, read-only). - String get encodedBody => _httpRequest.body; - - /// The request body (proxy, read-only). - Object? get body => unfreezedRequest.body; - - /// Copies this request and returns a new request with the given - /// [unfreezedRequest]. - MiddlewareRequest copyWith({ - UnfreezedRequest? unfreezedRequest, - }) => - MiddlewareRequest( - unfreezedRequest: unfreezedRequest ?? this.unfreezedRequest, - ); - - /// Modifies the request with the given [unfreezedRequest]. - void modifyRequest(UnfreezedRequest unfreezedRequest) { - String? body; - if (unfreezedRequest.body != null) { - var body = unfreezedRequest.body; - if (body is String) { - body = body; - } else if (body is List) { - body = String.fromCharCodes(body.cast()); - } else if (body is Map) { - body = Convert.mapToQuery(body.cast()); - } - } - _httpRequest = RequestUtils.copyRequestWith( - _httpRequest, - method: unfreezedRequest.method, - url: unfreezedRequest.url, - headers: unfreezedRequest.headers, - body: body, - ) as Request; - if (unfreezedRequest.encoding != null) { - _httpRequest.encoding = unfreezedRequest.encoding!; - } - this.unfreezedRequest = unfreezedRequest; - } - - /// Applies the changes made to the request by modifying it with the - /// [unfreezedRequest]. - void apply() { - modifyRequest(unfreezedRequest); - } - - @override - String toString() => 'MiddlewareRequest(unfreezedRequest: $unfreezedRequest)'; -} diff --git a/packages/wyatt_http_client/lib/src/models/middleware_response.dart b/packages/wyatt_http_client/lib/src/models/middleware_response.dart deleted file mode 100644 index 19781901..00000000 --- a/packages/wyatt_http_client/lib/src/models/middleware_response.dart +++ /dev/null @@ -1,63 +0,0 @@ -// 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/utils/http_status.dart'; - -/// {@template middleware_response} -/// A class that represents a middleware response. -/// {@endtemplate} -class MiddlewareResponse { - /// {@macro middleware_response} - const MiddlewareResponse({ - required this.httpResponse, - }); - - /// {@macro middleware_response} - final BaseResponse httpResponse; - - /// The status code of the response. (proxy) - int get statusCode => httpResponse.statusCode; - - /// The status of the response. (proxy) - HttpStatus get status => HttpStatus.from(statusCode); - - /// The body of the response. (proxy or empty string) - String get body { - if (httpResponse is Response) { - return (httpResponse as Response).body; - } else { - return ''; - } - } - - /// The content length of the response. (proxy) - int? get contentLength => httpResponse.contentLength; - - /// The headers of the response. (proxy) - Map get headers => httpResponse.headers; - - /// Returns a copy of this response with the given [httpResponse]. - MiddlewareResponse copyWith({ - BaseResponse? httpResponse, - }) => - 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 deleted file mode 100644 index 6779a5b6..00000000 --- a/packages/wyatt_http_client/lib/src/models/unfreezed_request.dart +++ /dev/null @@ -1,69 +0,0 @@ -// 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'; - -/// {@template unfreezed_request} -/// A class that represents an unfreezed request. -/// It is used to unfreeze a Request object, and allows you to -/// modify the request before sending it. -/// {@endtemplate} -class UnfreezedRequest { - /// {@macro unfreezed_request} - const UnfreezedRequest({ - required this.method, - required this.url, - this.headers, - this.body, - this.encoding, - }); - - /// The request method. - final String method; - - /// The request url. - final Uri url; - - /// The request headers. - final Map? headers; - - /// The request body. - final Object? body; - - /// The request encoding. - final Encoding? encoding; - - /// Copies this request and returns a new request with the given [method], - /// [url], [headers], [body] and [encoding]. - UnfreezedRequest copyWith({ - String? method, - Uri? url, - Map? headers, - Object? body, - Encoding? encoding, - }) => - UnfreezedRequest( - method: method ?? this.method, - url: url ?? this.url, - headers: headers ?? this.headers, - body: body ?? this.body, - encoding: encoding ?? this.encoding, - ); - - @override - String toString() => '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 deleted file mode 100644 index d68e7e39..00000000 --- a/packages/wyatt_http_client/lib/src/pipeline.dart +++ /dev/null @@ -1,122 +0,0 @@ -// 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_context.dart'; -import 'package:wyatt_http_client/src/models/middleware_request.dart'; -import 'package:wyatt_http_client/src/models/middleware_response.dart'; - -/// {@template pipeline} -/// A [Pipeline] is a list of [Middleware]s that are executed in order. -/// {@endtemplate} -class Pipeline { - /// {@macro pipeline} - Pipeline() : _middlewares = []; - - /// {@macro pipeline} - Pipeline.fromIterable(Iterable middlewares) - : _middlewares = middlewares.toList(); - - final List _middlewares; - - /// The length of the [Pipeline]. - /// - /// This is the number of [Middleware]s in the [Pipeline]. - int get length => _middlewares.length; - - /// Add a [Middleware] to this [Pipeline] - void addMiddleware(Middleware middleware) { - _middlewares.add(middleware); - } - - /// Create new [Pipeline] from the start or end to a specified [Middleware]. - Pipeline sub( - Middleware middleware, { - bool include = false, - bool fromEnd = false, - }) { - final nodes = []; - final list = fromEnd ? _middlewares.reversed : _middlewares; - for (final m in list) { - if (m != middleware) { - nodes.add(m); - } - if (m == middleware) { - if (include) { - nodes.add(m); - } - break; - } - } - return Pipeline.fromIterable(fromEnd ? nodes.reversed : nodes); - } - - /// Call the [onRequest] method of all [OnRequestMiddleware]s in the - /// [Pipeline]. - /// - /// The [MiddlewareRequest] returned by the last [OnRequestMiddleware] is - /// returned. - Future onRequest( - MiddlewareContext context, - MiddlewareRequest request, - ) async { - MiddlewareRequest req = request..apply(); - MiddlewareContext ctx = context.copyWith(lastRequest: req); - for (final middleware in _middlewares) { - if (middleware is OnRequestMiddleware) { - req = await (middleware as OnRequestMiddleware).onRequest(ctx, request); - ctx = context.copyWith(lastRequest: req); - } - } - return req; - } - - /// Call the [onResponse] method of all [OnResponseMiddleware]s in the - /// [Pipeline]. - /// - /// The [MiddlewareResponse] returned by the last [OnResponseMiddleware] is - /// returned. - Future onResponse( - MiddlewareContext context, - MiddlewareResponse response, - ) async { - MiddlewareResponse res = response; - MiddlewareContext ctx = context.copyWith(lastResponse: res); - for (final middleware in _middlewares.reversed) { - if (middleware is OnResponseMiddleware) { - res = await (middleware as OnResponseMiddleware) - .onResponse(ctx, response); - ctx = context.copyWith(lastResponse: res); - } - } - return res; - } - - @override - String toString() { - final req = []; - final res = []; - for (final middleware in _middlewares) { - if (middleware is OnRequestMiddleware) { - req.add(middleware.getName()); - } - if (middleware is OnResponseMiddleware) { - res.insert(0, middleware.getName()); - } - } - return '[Req] -> ${req.join(' -> ')}\n[Res] -> ${res.join(' -> ')}'; - } -} diff --git a/packages/wyatt_http_client/lib/src/utils/authentication_methods.dart b/packages/wyatt_http_client/lib/src/utils/authentication_methods.dart deleted file mode 100644 index d8f028c2..00000000 --- a/packages/wyatt_http_client/lib/src/utils/authentication_methods.dart +++ /dev/null @@ -1,27 +0,0 @@ -// 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 . - -/// Defines some authentication methods -abstract class AuthenticationMethods { - /// The `Basic` authentication method. - static const String basic = 'Basic'; - - /// The `Bearer` authentication method. - static const String bearer = 'Bearer'; - - /// The `Digest` authentication method. - static const String digest = 'Digest'; -} diff --git a/packages/wyatt_http_client/lib/src/utils/convert.dart b/packages/wyatt_http_client/lib/src/utils/convert.dart deleted file mode 100644 index 81808e91..00000000 --- a/packages/wyatt_http_client/lib/src/utils/convert.dart +++ /dev/null @@ -1,62 +0,0 @@ -// 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'; - -/// Defines some convert functions. -abstract class Convert { - /// Converts a list of bytes to a hex string. - /// - /// If [upperCase] is `true`, the hex string will be in uppercase. - static String toHex(List bytes, {bool upperCase = false}) { - final buffer = StringBuffer(); - for (final int part in bytes) { - if (part & 0xff != part) { - throw const FormatException('Non-byte integer detected'); - } - buffer.write('${part < 16 ? '0' : ''}${part.toRadixString(16)}'); - } - if (upperCase) { - return buffer.toString().toUpperCase(); - } else { - return buffer.toString(); - } - } - - /// Converts a map to a query string. - /// - /// If [encoding] is `null`, the default encoding is `utf8`. - /// - /// For example, the map `{a: 1, b: 2}` will be converted to `a=1&b=2`. - static String mapToQuery(Map map, {Encoding? encoding}) { - final pairs = >[]; - map.forEach( - (key, value) => pairs.add([ - Uri.encodeQueryComponent(key, encoding: encoding ?? utf8), - Uri.encodeQueryComponent(value, encoding: encoding ?? utf8), - ]), - ); - return pairs.map((pair) => '${pair[0]}=${pair[1]}').join('&'); - } -} - -extension UriX on Uri { - /// Returns a new [Uri] by appending the given [path] to this [Uri]. - Uri operator +(String path) { - final thisPath = toString(); - return Uri.parse(thisPath + path); - } -} diff --git a/packages/wyatt_http_client/lib/src/utils/crypto.dart b/packages/wyatt_http_client/lib/src/utils/crypto.dart deleted file mode 100644 index bf7fa5a6..00000000 --- a/packages/wyatt_http_client/lib/src/utils/crypto.dart +++ /dev/null @@ -1,30 +0,0 @@ -// 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:crypto/crypto.dart'; - -/// Defines some crypto functions. -abstract class Crypto { - /// Hash a string using MD5 - static String md5Hash(String data) { - final content = const Utf8Encoder().convert(data); - const md5Crypto = md5; - final digest = md5Crypto.convert(content).toString(); - return digest; - } -} diff --git a/packages/wyatt_http_client/lib/src/utils/delay.dart b/packages/wyatt_http_client/lib/src/utils/delay.dart deleted file mode 100644 index cc9d4193..00000000 --- a/packages/wyatt_http_client/lib/src/utils/delay.dart +++ /dev/null @@ -1,38 +0,0 @@ -// 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:core'; -import 'dart:math'; - -/// Defines some delay functions. -abstract class Delay { - /// Returns a delay based on the [attempt]. - static Duration getRetryDelay(int attempt) { - assert(attempt >= 0, 'attempt cannot be negative'); - if (attempt <= 0) { - return Duration.zero; - } - final rand = Random(); - const Duration delayFactor = Duration(milliseconds: 200); - const double randomizationFactor = 0.25; - const Duration maxDelay = Duration(seconds: 30); - - final rf = randomizationFactor * (rand.nextDouble() * 2 - 1) + 1; - final exp = min(attempt, 31); // prevent overflows. - final delay = delayFactor * pow(2.0, exp) * rf; - return delay < maxDelay ? delay : maxDelay; - } -} diff --git a/packages/wyatt_http_client/lib/src/utils/digest_auth.dart b/packages/wyatt_http_client/lib/src/utils/digest_auth.dart deleted file mode 100644 index 065eeef0..00000000 --- a/packages/wyatt_http_client/lib/src/utils/digest_auth.dart +++ /dev/null @@ -1,196 +0,0 @@ -// 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:math'; - -import 'package:wyatt_http_client/src/utils/convert.dart'; -import 'package:wyatt_http_client/src/utils/crypto.dart'; - -/// A class for digest authentication. -class DigestAuth { - // request counter - - DigestAuth(this.username, this.password); - final String username; - final String password; - - // must get from first response - String? _algorithm; - String? _qop; - String? _realm; - String? _nonce; - String? _opaque; - - int _nc = 0; - - /// Splits WWW-Authenticate header into a map. - Map? splitWWWAuthenticateHeader(String header) { - if (!header.startsWith('Digest ')) { - throw ArgumentError.value( - header, - 'header', - 'Header must start with "Digest "', - ); - } - final h = header.substring(7); // remove 'Digest ' - final ret = {}; - - final components = h.split(',').map((token) => token.trim()); - for (final component in components) { - final kv = component.split('='); - ret[kv[0]] = kv.getRange(1, kv.length).join('=').replaceAll('"', ''); - } - return ret; - } - - String _computeNonce() { - final rnd = Random.secure(); - final values = List.generate(16, (i) => rnd.nextInt(256)); - - return Convert.toHex(values); - } - - String _formatNonceCount(int nc) => nc.toRadixString(16).padLeft(8, '0'); - - String _computeHA1( - String realm, - String? algorithm, - String username, - String password, - String? nonce, - String? cnonce, - ) { - if (algorithm == null || algorithm == 'MD5') { - final token1 = '$username:$realm:$password'; - return Crypto.md5Hash(token1); - } else if (algorithm == 'MD5-sess') { - final token1 = '$username:$realm:$password'; - final md51 = Crypto.md5Hash(token1); - final token2 = '$md51:$nonce:$cnonce'; - return Crypto.md5Hash(token2); - } else { - throw ArgumentError.value( - algorithm, - 'algorithm', - 'Unsupported algorithm', - ); - } - } - - Map _computeResponse( - String method, - String path, - String body, - String? algorithm, - String? qop, - String? opaque, - String realm, - String? cnonce, - String? nonce, - int nc, - String username, - String password, - ) { - final ret = {}; - - final ha1 = - _computeHA1(realm, algorithm, username, password, nonce, cnonce); - - String ha2; - - if (qop == 'auth-int') { - final bodyHash = Crypto.md5Hash(body); - final token2 = '$method:$path:$bodyHash'; - ha2 = Crypto.md5Hash(token2); - } else { - // qop in [null, auth] - final token2 = '$method:$path'; - ha2 = Crypto.md5Hash(token2); - } - - final nonceCount = _formatNonceCount(nc); - ret['username'] = username; - ret['realm'] = realm; - ret['nonce'] = nonce; - ret['uri'] = path; - if (qop != null) { - ret['qop'] = qop; - } - ret['nc'] = nonceCount; - ret['cnonce'] = cnonce; - if (opaque != null) { - ret['opaque'] = opaque; - } - ret['algorithm'] = algorithm; - - if (qop == null) { - final token3 = '$ha1:$nonce:$ha2'; - ret['response'] = Crypto.md5Hash(token3); - } else if (qop == 'auth' || qop == 'auth-int') { - final token3 = '$ha1:$nonce:$nonceCount:$cnonce:$qop:$ha2'; - ret['response'] = Crypto.md5Hash(token3); - } - - return ret; - } - - String getAuthString(String method, Uri url) { - final cnonce = _computeNonce(); - _nc += 1; - // if url has query parameters, append query to path - final path = url.hasQuery ? '${url.path}?${url.query}' : url.path; - - // after the first request we have the nonce, so we can provide credentials - final authValues = _computeResponse( - method, - path, - '', - _algorithm, - _qop, - _opaque, - _realm!, - cnonce, - _nonce, - _nc, - username, - password, - ); - final authValuesString = authValues.entries - .where((e) => e.value != null) - .map((e) => [e.key, '="', e.value, '"'].join()) - .toList() - .join(', '); - final authString = 'Digest $authValuesString'; - return authString; - } - - void initFromAuthenticateHeader(String? authInfo) { - if (authInfo == null) { - throw ArgumentError.notNull('authInfo'); - } - final values = splitWWWAuthenticateHeader(authInfo); - if (values != null) { - _algorithm = values['algorithm'] ?? _algorithm; - _qop = values['qop'] ?? _qop; - _realm = values['realm'] ?? _realm; - _nonce = values['nonce'] ?? _nonce; - _opaque = values['opaque'] ?? _opaque; - _nc = 0; - } - } - - bool isReady() => _nonce != null && (_nc == 0 || _qop != null); -} diff --git a/packages/wyatt_http_client/lib/src/utils/header_keys.dart b/packages/wyatt_http_client/lib/src/utils/header_keys.dart deleted file mode 100644 index c1c9e986..00000000 --- a/packages/wyatt_http_client/lib/src/utils/header_keys.dart +++ /dev/null @@ -1,27 +0,0 @@ -// 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 . - -/// Defines some header keys. -abstract class HeaderKeys { - /// The `Authorization` header key. - static const String authorization = 'Authorization'; - - /// The `WWW-Authenticate` header key. - static const String wwwAuthenticate = 'WWW-Authenticate'; - - /// The `Content-Type` header key. - static const String contentType = 'Content-Type'; -} diff --git a/packages/wyatt_http_client/lib/src/utils/http_methods.dart b/packages/wyatt_http_client/lib/src/utils/http_methods.dart deleted file mode 100644 index efef38c4..00000000 --- a/packages/wyatt_http_client/lib/src/utils/http_methods.dart +++ /dev/null @@ -1,32 +0,0 @@ -// 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 . - -/// Defines http verb methods. -enum HttpMethods { - head('HEAD'), - get('GET'), - post('POST'), - put('PUT'), - patch('PATCH'), - delete('DELETE'); - - const HttpMethods(this.method); - - /// Returns the method of the http verb. - /// - /// For example, the method of [HttpMethods.get] is `GET`. - final String method; -} diff --git a/packages/wyatt_http_client/lib/src/utils/http_status.dart b/packages/wyatt_http_client/lib/src/utils/http_status.dart deleted file mode 100644 index f5a5c488..00000000 --- a/packages/wyatt_http_client/lib/src/utils/http_status.dart +++ /dev/null @@ -1,116 +0,0 @@ -// 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 . - -/// Status codes for HTTP responses. Extracted from dart:io -enum HttpStatus { - continue_(100), - switchingProtocols(101), - processing(102), - ok(200), - created(201), - accepted(202), - nonAuthoritativeInformation(203), - noContent(204), - resetContent(205), - partialContent(206), - multiStatus(207), - alreadyReported(208), - imUsed(226), - multipleChoices(300), - movedPermanently(301), - found(302), - movedTemporarily(302), // Common alias for found. - seeOther(303), - notModified(304), - useProxy(305), - temporaryRedirect(307), - permanentRedirect(308), - badRequest(400), - unauthorized(401), - paymentRequired(402), - forbidden(403), - notFound(404), - methodNotAllowed(405), - notAcceptable(406), - proxyAuthenticationRequired(407), - requestTimeout(408), - conflict(409), - gone(410), - lengthRequired(411), - preconditionFailed(412), - requestEntityTooLarge(413), - requestUriTooLong(414), - unsupportedMediaType(415), - requestedRangeNotSatisfiable(416), - expectationFailed(417), - misdirectedRequest(421), - unprocessableEntity(422), - locked(423), - failedDependency(424), - upgradeRequired(426), - preconditionRequired(428), - tooManyRequests(429), - requestHeaderFieldsTooLarge(431), - connectionClosedWithoutResponse(444), - unavailableForLegalReasons(451), - clientClosedRequest(499), - internalServerError(500), - notImplemented(501), - badGateway(502), - serviceUnavailable(503), - gatewayTimeout(504), - httpVersionNotSupported(505), - variantAlsoNegotiates(506), - insufficientStorage(507), - loopDetected(508), - notExtended(510), - networkAuthenticationRequired(511), - // Client generated status code. - networkConnectTimeoutError(599); - - const HttpStatus(this.statusCode); - - /// Returns the [HttpStatus] with the given [statusCode]. - factory HttpStatus.from(int status) => - HttpStatus.values.firstWhere((element) => element.statusCode == status); - - final int statusCode; - - bool equals(Object other) { - if (other is HttpStatus) { - return statusCode == other.statusCode; - } - if (other is int) { - return statusCode == other; - } - return false; - } - - /// Checks if the status code is in the range of 100-199. - bool isInfo() => statusCode >= 100 && statusCode < 200; - - /// Checks if the status code is in the range of 200-299. - bool isSuccess() => statusCode >= 200 && statusCode < 300; - - /// Checks if the status code is in the range of 300-399. - bool isRedirection() => statusCode >= 300 && statusCode < 400; - - /// Checks if the status code is in the range of 400-499. - bool isClientError() => statusCode >= 400 && statusCode < 500; - - /// Checks if the status code is in the range of 500-599. - bool isServerError() => statusCode >= 500 && statusCode < 600; -} diff --git a/packages/wyatt_http_client/lib/src/utils/protocols.dart b/packages/wyatt_http_client/lib/src/utils/protocols.dart deleted file mode 100644 index bf41a5d6..00000000 --- a/packages/wyatt_http_client/lib/src/utils/protocols.dart +++ /dev/null @@ -1,26 +0,0 @@ -// 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 . - -/// Defines few protocols -enum Protocols { - http, - https; - - /// Returns the scheme of the protocol. - /// - /// For example, the scheme of [Protocols.http] is `http://`. - String get scheme => '$name://'; -} diff --git a/packages/wyatt_http_client/lib/src/utils/request_utils.dart b/packages/wyatt_http_client/lib/src/utils/request_utils.dart deleted file mode 100644 index 01794757..00000000 --- a/packages/wyatt_http_client/lib/src/utils/request_utils.dart +++ /dev/null @@ -1,95 +0,0 @@ -// 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'; - -/// Defines some request utils. -abstract class RequestUtils { - static Request _copyNormalRequestWith( - Request original, { - String? method, - Uri? url, - Map? headers, - int? maxRedirects, - bool? followRedirects, - bool? persistentConnection, - String? body, - }) { - final request = Request(method ?? original.method, url ?? original.url) - ..followRedirects = followRedirects ?? original.followRedirects - ..headers.addAll(headers ?? original.headers) - ..maxRedirects = maxRedirects ?? original.maxRedirects - ..persistentConnection = - persistentConnection ?? original.persistentConnection - ..body = body ?? original.body; - - return request; - } - - /// Copies the given [original] request and returns a new request with the - /// given [method], [url], [headers], [maxRedirects], [followRedirects], - /// [persistentConnection] and [body]. - static BaseRequest copyRequestWith( - BaseRequest original, { - String? method, - Uri? url, - Map? headers, - int? maxRedirects, - bool? followRedirects, - bool? persistentConnection, - String? body, - }) { - if (original is Request) { - return _copyNormalRequestWith( - original, - method: method, - url: url, - headers: headers, - maxRedirects: maxRedirects, - followRedirects: followRedirects, - persistentConnection: persistentConnection, - body: body, - ); - } else { - throw UnimplementedError( - 'Cannot handle requests of type ${original.runtimeType}', - ); - } - } - - static Request _copyNormalRequest(Request original) { - final request = Request(original.method, original.url) - ..followRedirects = original.followRedirects - ..headers.addAll(original.headers) - ..maxRedirects = original.maxRedirects - ..persistentConnection = original.persistentConnection - ..body = original.body; - - return request; - } - - /// Copies the given [original] request and returns a new request. - /// This method is useful when you want to modify the request - static BaseRequest copyRequest(BaseRequest original) { - if (original is Request) { - return _copyNormalRequest(original); - } else { - throw UnimplementedError( - 'Cannot handle requests of type ${original.runtimeType}', - ); - } - } -} diff --git a/packages/wyatt_http_client/lib/src/utils/utils.dart b/packages/wyatt_http_client/lib/src/utils/utils.dart deleted file mode 100644 index 91d8efc1..00000000 --- a/packages/wyatt_http_client/lib/src/utils/utils.dart +++ /dev/null @@ -1,23 +0,0 @@ -// 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 . - -export 'authentication_methods.dart'; -export 'digest_auth.dart'; -export 'header_keys.dart'; -export 'http_methods.dart'; -export 'http_status.dart'; -export 'protocols.dart'; -export 'request_utils.dart'; diff --git a/packages/wyatt_http_client/lib/wyatt_http_client.dart b/packages/wyatt_http_client/lib/wyatt_http_client.dart deleted file mode 100644 index e728cf6a..00000000 --- a/packages/wyatt_http_client/lib/wyatt_http_client.dart +++ /dev/null @@ -1,24 +0,0 @@ -// 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 . - -library wyatt_http_client; - -export 'src/middleware.dart'; -export 'src/middleware_client.dart'; -export 'src/middlewares/middlewares.dart'; -export 'src/models/models.dart'; -export 'src/pipeline.dart'; -export 'src/utils/utils.dart'; diff --git a/packages/wyatt_http_client/pubspec.yaml b/packages/wyatt_http_client/pubspec.yaml deleted file mode 100644 index f541c93f..00000000 --- a/packages/wyatt_http_client/pubspec.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: wyatt_http_client -description: A Dart client for RESTful APIs with authentication. -repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_http_client -version: 2.0.1 - -publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub - -environment: - sdk: '>=2.17.0 <3.0.0' - -dependencies: - crypto: ^3.0.2 - http: ^1.1.0 - -dev_dependencies: - wyatt_analysis: - hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub - version: ^2.5.0