diff --git a/commitlint.yaml b/commitlint.yaml index 9d24a3b4c16..d7035150ecb 100644 --- a/commitlint.yaml +++ b/commitlint.yaml @@ -9,8 +9,6 @@ rules: - always - - ci - account_repository - - cookie_store - - cookie_store_conformance_tests - dashboard_app - deps - docs @@ -20,7 +18,6 @@ rules: - dynamite_runtime - example - files_app - - interceptor_http_client - neon_framework - neon_http_client - neon_lints diff --git a/packages/cookie_store/LICENSE b/packages/cookie_store/LICENSE deleted file mode 120000 index dc0786b028f..00000000000 --- a/packages/cookie_store/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../assets/BSD-3-Clause.txt \ No newline at end of file diff --git a/packages/cookie_store/analysis_options.yaml b/packages/cookie_store/analysis_options.yaml deleted file mode 100644 index 4db3c296b81..00000000000 --- a/packages/cookie_store/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: package:neon_lints/dart.yaml diff --git a/packages/cookie_store/dart_test.yaml b/packages/cookie_store/dart_test.yaml deleted file mode 100644 index 20d3df48b98..00000000000 --- a/packages/cookie_store/dart_test.yaml +++ /dev/null @@ -1,10 +0,0 @@ -platforms: - - vm - - chrome - -define_platforms: - chromium: - name: Chromium - extends: chrome - settings: - executable: chromium diff --git a/packages/cookie_store/lib/cookie_store.dart b/packages/cookie_store/lib/cookie_store.dart deleted file mode 100644 index 0b5e16798a1..00000000000 --- a/packages/cookie_store/lib/cookie_store.dart +++ /dev/null @@ -1,14 +0,0 @@ -/// An [RFC6265](https://httpwg.org/specs/rfc6265.html) compliant cookie store. -/// -/// Cookies are stored inside of `CookieStore`s parsing the received cookies -/// into `StorableCookie`s that can be saved in a `CookiePersistence`. -/// -/// This package has an implementation independent api and provides utilities -/// that make it easy to extend and implemented into existing storage backends -/// like SQLite databases. -library; - -export 'src/cookie_persistence.dart'; -export 'src/cookie_store.dart'; -export 'src/storable_cookie.dart'; -export 'src/utils.dart'; diff --git a/packages/cookie_store/lib/src/cookie_persistence.dart b/packages/cookie_store/lib/src/cookie_persistence.dart deleted file mode 100644 index eb95d2a865a..00000000000 --- a/packages/cookie_store/lib/src/cookie_persistence.dart +++ /dev/null @@ -1,178 +0,0 @@ -import 'dart:async'; -import 'dart:io' show Cookie; - -import 'package:cookie_store/src/storable_cookie.dart'; -import 'package:cookie_store/src/utils.dart'; -import 'package:timezone/timezone.dart' as tz; - -/// Interface for a Storage backend persisting [StorableCookie]s. -/// -/// ### Cookie value retrieval -/// {@macro CookieStore.valueRetrieval} -/// -/// ### Cookie management -/// {@macro CookieStore.cookieManagement} -/// -/// ### CookieStore limits, eviction policy -/// {@macro CookieStore.limits} -abstract interface class CookiePersistence { - /// Creates the default [MemoryCookiePersistence]. - factory CookiePersistence() { - return MemoryCookiePersistence(); - } - - /// Load the cookies for specified [uri]. - /// - /// Cookies SHOULD be sorted with the [sortCookies] function. - FutureOr> loadForRequest(Uri uri); - - /// Saves the serialized [cookies]. - /// - /// Returns whether the operation completed successfully. - FutureOr saveFromResponse(Set cookies, {required bool isHttpRequest}); - - /// Ends the current session deleting all session cookies. - /// - /// Returns whether the operation completed successfully. - FutureOr endSession(); - - /// Loads all cookies in the persistence. - /// - /// Implementing this method is optional. It must be documented if the - /// implementer does not support this operation. - FutureOr> loadAll(); - - /// Deletes all cookies in the persistence. - /// - /// Implementing this method is optional. It must be documented if the - /// implementer does not support this operation. - /// - /// Returns whether the operation completed successfully. - FutureOr deleteAll(); - - /// Removes all cookies in this persistence that satisfy the given [test]. - /// - /// Implementing this method is optional. It must be documented if the - /// implementer does not support this operation. - /// - /// Returns whether the operation completed successfully. - FutureOr deleteWhere(bool Function(Cookie cookie) test); -} - -/// Default cookie persistence. -/// -/// Cookies are stored synchronously in memory and NOT persisted on disk. -final class MemoryCookiePersistence implements CookiePersistence { - /// Created a new cookie persistence storing cookies in memory. - MemoryCookiePersistence(); - - final Set _cookieStore = {}; - - @override - bool endSession() { - _cookieStore.removeWhere((cookie) => !cookie.persistentFlag); - - return true; - } - - @override - List loadForRequest(Uri uri) { - final cookies = []; - - final now = tz.TZDateTime.now(tz.UTC); - final isHttpRequest = isHttpUri(uri); - final isSecureRequest = isSecureUri(uri); - - final requestHost = uri.host; - var requestPath = uri.path; - if (requestPath.isEmpty) { - requestPath = '/'; - } - - _cookieStore.removeWhere((cookie) => cookie.expiryTime.isBefore(now)); - - for (final cookie in _cookieStore) { - if (cookie.hostOnlyFlag && cookie.domain != requestHost) { - continue; - } - - if (!cookie.hostOnlyFlag && !isDomainMatch(requestHost, cookie.domain)) { - continue; - } - - if (!isPathMatch(requestPath, cookie.path)) { - continue; - } - - if (cookie.secureOnlyFlag && !isSecureRequest) { - continue; - } - - if (cookie.httpOnlyFlag && !isHttpRequest) { - continue; - } - - cookies.add(cookie); - } - - cookies.sort(sortCookies); - _cookieStore.addAll(cookies.map((cookie) => cookie.copyWith(lastAccessTime: now))); - - return cookies.map((cookie) { - return Cookie(cookie.name, cookie.value) - ..httpOnly = false - ..secure = false; - }).toList(); - } - - @override - bool saveFromResponse(Set cookies, {required bool isHttpRequest}) { - for (var cookie in cookies) { - final stored = _cookieStore.lookup(cookie); - if (stored != null) { - if (stored.httpOnlyFlag && !isHttpRequest) { - continue; - } - - _cookieStore.remove(stored); - cookie = cookie.copyWith(creationTime: stored.creationTime); - } - - _cookieStore.add(cookie); - } - - return true; - } - - @override - bool deleteWhere(bool Function(Cookie cookie) test) { - _cookieStore.removeWhere((storableCookie) { - final cookie = _storableCookieToCookie(storableCookie); - - return test(cookie); - }); - - return true; - } - - @override - bool deleteAll() { - _cookieStore.clear(); - - return true; - } - - @override - List loadAll() { - return _cookieStore.map(_storableCookieToCookie).toList(); - } - - static Cookie _storableCookieToCookie(StorableCookie storableCookie) { - return Cookie(storableCookie.name, storableCookie.value) - ..expires = storableCookie.expiryTime - ..domain = storableCookie.domain - ..path = storableCookie.path - ..secure = storableCookie.secureOnlyFlag - ..httpOnly = storableCookie.httpOnlyFlag; - } -} diff --git a/packages/cookie_store/lib/src/cookie_store.dart b/packages/cookie_store/lib/src/cookie_store.dart deleted file mode 100644 index af49e6c27ca..00000000000 --- a/packages/cookie_store/lib/src/cookie_store.dart +++ /dev/null @@ -1,249 +0,0 @@ -// ignore_for_file: prefer_final_locals, omit_local_variable_types - -import 'dart:async'; -import 'dart:io' show Cookie; - -import 'package:cookie_store/src/cookie_persistence.dart'; -import 'package:cookie_store/src/storable_cookie.dart'; -import 'package:cookie_store/src/utils.dart'; -import 'package:timezone/timezone.dart' as tz; - -// DateTimes can represent time values that are at a distance of at most 100,000,000 -// days from epoch (1970-01-01 UTC): -271821-04-20 to 275760-09-13. -final tz.TZDateTime _maxDateTime = tz.TZDateTime.utc(275760, 09, 13); - -/// [CookieStore] is a cookie container and manager for HTTP requests implementing [RFC6265](https://httpwg.org/specs/rfc6265.html). -/// -/// ## Implementation consideration -/// In most cases it is not needed to implement this interface. -/// To build a custom storage backend [CookiePersistence] can be used. -/// -/// ### Cookie value retrieval -/// {@template CookieStore.valueRetrieval} -/// A cookie store does not need to retrieve cookies with all attributes present. -/// Retrieved cookies only need to have a valid [Cookie.name] and [Cookie.value]. -/// It is up to the implementation to provide further information. -/// {@endtemplate} -/// -/// ### Cookie management -/// {@template CookieStore.cookieManagement} -/// According to [RFC6265 section 7.2](https://httpwg.org/specs/rfc6265.html#rfc.section.7.2) -/// user agents SHOULD provide users with a mechanism for managing the cookies stored in the cookie store. -/// It must be documented if an implementer does not provide any of the optional -/// [loadAll], [deleteAll] and [deleteWhere] method. -/// {@endtemplate} -/// -/// ### Public suffix validation -/// The default implementation does not validate the cookie domain against a public -/// suffix list: -/// {@template CookieStore.publicSuffix} -/// > NOTE: A "public suffix" is a domain that is controlled by a public -/// > registry, such as "com", "co.uk", and "pvt.k12.wy.us". This step is -/// > essential for preventing attacker.com from disrupting the integrity of -/// > example.com by setting a cookie with a Domain attribute of "com". -/// > Unfortunately, the set of public suffixes (also known as "registry controlled domains") -/// > changes over time. If feasible, user agents SHOULD use an up-to-date -/// > public suffix list, such as the one maintained by the Mozilla project at . -/// {@endtemplate} -/// -/// ### CookieStore limits, eviction policy -/// {@template CookieStore.limits} -/// If a cookie store has a limit to the number of cookies it can store, -/// the removal policy outlined in [RFC6265 section 5.3](https://httpwg.org/specs/rfc6265.html#rfc.section.5.3) -/// must be followed: -/// > At any time, the user agent MAY "remove excess cookies" from the cookie store -/// > if the number of cookies sharing a domain field exceeds some implementation-defined -/// > upper bound (such as 50 cookies). -/// > -/// > At any time, the user agent MAY "remove excess cookies" from the cookie store -/// > if the cookie store exceeds some predetermined upper bound (such as 3000 cookies). -/// > -/// > When the user agent removes excess cookies from the cookie store, the user agent MUST -/// > evict cookies in the following priority order: -/// > -/// > Expired cookies. -/// > Cookies that share a domain field with more than a predetermined number of other cookies. -/// > All cookies. -/// > -/// > If two cookies have the same removal priority, the user agent MUST evict the -/// > cookie with the earliest last-access date first. -/// -/// It is recommended to set an upper bound to the time a cookie is stored -/// as described in [RFC6265 section 7.3](https://httpwg.org/specs/rfc6265.html#rfc.section.7.3): -/// > Although servers can set the expiration date for cookies to the distant future, -/// > most user agents do not actually retain cookies for multiple decades. -/// > Rather than choosing gratuitously long expiration periods, servers SHOULD -/// > promote user privacy by selecting reasonable cookie expiration periods based on the purpose of the cookie. -/// > For example, a typical session identifier might reasonably be set to expire in two weeks. -/// {@endtemplate} -abstract interface class CookieStore { - /// Creates a [DefaultCookieStore] instance. - factory CookieStore() { - return DefaultCookieStore( - CookiePersistence(), - ); - } - - /// Save the [cookies] for specified [uri]. - FutureOr saveFromResponse(Uri uri, List cookies); - - /// Load the cookies for specified [uri]. - FutureOr> loadForRequest(Uri uri); - - /// Ends the current session deleting all session cookies. - FutureOr endSession(); - - /// Loads all cookies in the store. - /// - /// User agents SHOULD provide users with a mechanism for managing the cookies stored in the cookie store. - /// https://httpwg.org/specs/rfc6265.html#rfc.section.7.2 - /// - /// Implementing this method is optional. It must be documented if the - /// implementer does not support this operation. - FutureOr> loadAll(); - - /// Deletes all cookies in the store. - /// - /// User agents SHOULD provide users with a mechanism for managing the cookies stored in the cookie store. - /// https://httpwg.org/specs/rfc6265.html#rfc.section.7.2 - /// - /// Implementing this method is optional. It must be documented if the - /// implementer does not support this operation. - FutureOr deleteAll(); - - /// Removes all cookies in this store that satisfy the given [test]. - /// - /// User agents SHOULD provide users with a mechanism for managing the cookies stored in the cookie store. - /// https://httpwg.org/specs/rfc6265.html#rfc.section.7.2 - /// - /// Implementing this method is optional. It must be documented if the - /// implementer does not support this operation. - FutureOr deleteWhere(bool Function(Cookie cookie) test); -} - -/// The default cookie store implementation. -/// -/// This implementation does not validate the cookie domain against a public -/// suffix list: -/// {@macro CookieStore.publicSuffix} -/// -/// Cookies are parsed into a set of [StorableCookie]s and persisted in the given [persistence]. -final class DefaultCookieStore implements CookieStore { - /// Creates a new cookie store backed by the provided [persistence]. - DefaultCookieStore(this.persistence); - - /// The persistence storing the serialized [StorableCookie]. - final CookiePersistence persistence; - - @override - FutureOr saveFromResponse(Uri uri, List cookies) { - final now = tz.TZDateTime.now(tz.UTC); - final isHttpRequest = isHttpUri(uri); - - Set persistentCookies = {}; - - for (final cookie in cookies) { - // declare all variables upfront and only assign them as needed. - // Easier for comparing to the rfc algorithm. - String name = cookie.name; - String value = cookie.value; - tz.TZDateTime creationTime = now; - tz.TZDateTime lastAccessTime = now; - - tz.TZDateTime expiryTime; - String domain; - String path; - bool persistentFlag; - bool hostOnlyFlag; - bool secureOnlyFlag; - bool httpOnlyFlag; - - final maxAge = cookie.maxAge; - tz.TZDateTime? expires; - if (cookie.expires != null) { - expires = tz.TZDateTime.from(cookie.expires!, tz.UTC); - } - - if (maxAge != null) { - persistentFlag = true; - expiryTime = now.add(Duration(seconds: maxAge)); - } else if (expires != null) { - persistentFlag = true; - expiryTime = expires; - } else { - persistentFlag = false; - expiryTime = _maxDateTime; - } - - // perf: skip already expired cookies. - if (expiryTime.isBefore(now)) { - continue; - } - - // Validating the public suffix is out of scope for this implementation. - - if (cookie.domain == null || cookie.domain!.isEmpty) { - hostOnlyFlag = true; - domain = uri.host; - } else if (!isDomainMatch(uri.host, cookie.domain!)) { - continue; - } else { - hostOnlyFlag = false; - domain = cookie.domain!; - } - - path = cookie.path ?? defaultPath(uri); - secureOnlyFlag = cookie.secure; - httpOnlyFlag = cookie.httpOnly; - - if (httpOnlyFlag && !isHttpRequest) { - continue; - } - - final persistentCookie = StorableCookie( - name: name, - value: value, - expiryTime: expiryTime, - domain: domain, - path: path, - creationTime: creationTime, - lastAccessTime: lastAccessTime, - persistentFlag: persistentFlag, - hostOnlyFlag: hostOnlyFlag, - secureOnlyFlag: secureOnlyFlag, - httpOnlyFlag: httpOnlyFlag, - ); - persistentCookies.add(persistentCookie); - } - - return persistence.saveFromResponse( - persistentCookies, - isHttpRequest: isHttpRequest, - ); - } - - @override - FutureOr> loadForRequest(Uri uri) { - return persistence.loadForRequest(uri); - } - - @override - FutureOr endSession() { - return persistence.endSession(); - } - - @override - FutureOr> loadAll() { - return persistence.loadAll(); - } - - @override - FutureOr deleteAll() { - return persistence.deleteAll(); - } - - @override - FutureOr deleteWhere(bool Function(Cookie cookie) test) { - return persistence.deleteWhere(test); - } -} diff --git a/packages/cookie_store/lib/src/storable_cookie.dart b/packages/cookie_store/lib/src/storable_cookie.dart deleted file mode 100644 index 05b7fb46711..00000000000 --- a/packages/cookie_store/lib/src/storable_cookie.dart +++ /dev/null @@ -1,115 +0,0 @@ -// Upstream bug: https://github.com/dart-lang/linter/issues/5065 -// ignore_for_file: unintended_html_in_doc_comment - -import 'package:meta/meta.dart'; -import 'package:timezone/timezone.dart' as tz; - -/// A storable cookie. -/// -/// See: -/// * https://httpwg.org/specs/rfc6265.html#storage-model -@immutable -final class StorableCookie { - /// Creates a new cookie in the rfc6265 storage model. - const StorableCookie({ - required this.name, - required this.value, - required this.expiryTime, - required this.domain, - required this.path, - required this.creationTime, - required this.lastAccessTime, - required this.persistentFlag, - required this.hostOnlyFlag, - required this.secureOnlyFlag, - required this.httpOnlyFlag, - }); - - /// The name of the cookie. - /// - /// Must be a `token` as specified in RFC 6265. - /// - /// The allowed characters in a `token` are the visible ASCII characters, - /// U+0021 (`!`) through U+007E (`~`), except the separator characters: - /// `(`, `)`, `<`, `>`, `@`, `,`, `;`, `:`, `\`, `"`, `/`, `[`, `]`, `?`, `=`, - /// `{`, and `}`. - final String name; - - /// The value of the cookie. - /// - /// Must be a `cookie-value` as specified in RFC 6265. - /// - /// The allowed characters in a cookie value are the visible ASCII characters, - /// U+0021 (`!`) through U+007E (`~`) except the characters: - /// `"`, `,`, `;` and `\`. - /// Cookie values may be wrapped in a single pair of double quotes - /// (U+0022, `"`). - final String value; - - /// The time at which the cookie expires. - final tz.TZDateTime expiryTime; - - /// The domain that the cookie applies to. - final String domain; - - /// The path within the [domain] that the cookie applies to. - final String path; - - /// The time at which the cookie has been created. - final tz.TZDateTime creationTime; - - /// The time at which the cookie has been last accessed. - final tz.TZDateTime lastAccessTime; - - /// Whether the cookie is persisted between session. - /// - /// Will be `false` for session cookies. - final bool persistentFlag; - - /// Whether the cookie is only sent when the request `domain` is identical - /// to [domain]. - final bool hostOnlyFlag; - - /// Whether to only send this cookie on secure connections. - final bool secureOnlyFlag; - - /// Whether the cookie is only sent in the HTTP request and is not made - /// available to client side scripts. - final bool httpOnlyFlag; - - /// Creates a copy of this storable cookie with the given fields - /// replaced by the non-null parameter values. - StorableCookie copyWith({ - String? value, - tz.TZDateTime? expiryTime, - tz.TZDateTime? creationTime, - tz.TZDateTime? lastAccessTime, - bool? persistentFlag, - bool? hostOnlyFlag, - bool? secureOnlyFlag, - bool? httpOnlyFlag, - }) { - return StorableCookie( - name: name, - value: value ?? this.value, - expiryTime: expiryTime ?? this.expiryTime, - domain: domain, - path: path, - creationTime: creationTime ?? this.creationTime, - lastAccessTime: lastAccessTime ?? this.lastAccessTime, - persistentFlag: persistentFlag ?? this.persistentFlag, - hostOnlyFlag: hostOnlyFlag ?? this.hostOnlyFlag, - secureOnlyFlag: secureOnlyFlag ?? this.secureOnlyFlag, - httpOnlyFlag: httpOnlyFlag ?? this.httpOnlyFlag, - ); - } - - @override - int get hashCode { - return Object.hashAll([name, domain, path]); - } - - @override - bool operator ==(Object other) => - other is StorableCookie && name == other.name && domain == other.domain && path == other.path; -} diff --git a/packages/cookie_store/lib/src/utils.dart b/packages/cookie_store/lib/src/utils.dart deleted file mode 100644 index e00b120fe53..00000000000 --- a/packages/cookie_store/lib/src/utils.dart +++ /dev/null @@ -1,133 +0,0 @@ -// ignore_for_file: constant_identifier_names - -import 'package:cookie_store/src/storable_cookie.dart'; - -const int _DOT = 0x2E; -const int _SLASH = 0x2F; - -/// Computes the default cookie path for a [requestUri]. -/// -/// See: -/// * https://httpwg.org/specs/rfc6265.html#cookie-path -String defaultPath(Uri requestUri) { - // Let uri-path be the path portion of the request-uri if such a portion exists (and empty otherwise). - final path = requestUri.path; - - // If the uri-path is empty or if the first character of the uri-path is not a %x2F ("/") character, output %x2F ("/") and skip the remaining steps. - if (path.isEmpty || path.codeUnitAt(0) != _SLASH) { - return '/'; - } - - // If the uri-path contains no more than one %x2F ("/") character, output %x2F ("/") and skip the remaining step. - if ('/'.allMatches(path).length <= 1) { - return '/'; - } - - // Output the characters of the uri-path from the first character up to, but not including, the right-most %x2F ("/"). - if (path.endsWith('/')) { - return path.substring(0, path.length - 1); - } - - return path; -} - -/// Whether the [requestHost] domain matches the [cookieDomain]. -/// -/// It assumes that the given hosts are already canonicalized and punycode encoded. -/// -/// See: -/// * https://httpwg.org/specs/rfc6265.html#cookie-domain -bool isDomainMatch(String requestHost, String cookieDomain) { - assert( - requestHost.toLowerCase() == requestHost && cookieDomain.toLowerCase() == cookieDomain, - 'Both the requestHost and cookieDomain must be canonicalized to lower case.', - ); - - // The domain string and the string are identical. - if (requestHost == cookieDomain) { - return true; - } - - // The domain string is a suffix of the string. - if (requestHost.endsWith(cookieDomain)) { - // The last character of the string that is not included in the domain string is a %x2E (".") character. - final lastChar = requestHost.length - cookieDomain.length; - - if (requestHost.codeUnitAt(lastChar - 1) != _DOT) { - return false; - } - - return !_isIPAdress(requestHost); - } - - return false; -} - -/// Whether the given [host] represents a valid IPv4 or IPv6 address. -bool _isIPAdress(String host) { - try { - Uri.parseIPv4Address(host); - return true; - - // ignore: empty_catches - } on FormatException {} - - try { - Uri.parseIPv6Address(host); - return true; - - // ignore: empty_catches - } on FormatException {} - - return false; -} - -/// Whether the [requestPath] path matches the [cookiePath]. -/// -/// See: -/// * https://httpwg.org/specs/rfc6265.html#cookie-path -bool isPathMatch(String requestPath, String cookiePath) { - // The cookie-path and the request-path are identical. - if (requestPath == cookiePath) { - return true; - } - - if (requestPath.startsWith(cookiePath)) { - // The cookie-path is a prefix of the request-path, the last character of the cookie-path is %x2F ("/"). - if (cookiePath.codeUnitAt(cookiePath.length - 1) == _SLASH) { - return true; - } - - // The cookie-path is a prefix of the request-path, and the first character of the request-path that is not included in the cookie-path is a %x2F ("/") character. - return requestPath.codeUnitAt(cookiePath.length) == _SLASH; - } - - return false; -} - -/// Whether the given [uri] is using the `http` protocol. -/// -/// Implementations MAY want to define a custom check. -bool isHttpUri(Uri uri) { - return uri.isScheme('http') || uri.isScheme('https'); -} - -/// Whether the given [uri] is using a secure protocol. -/// -/// Checks whether the request scheme ends with a `s`. -/// -/// Implementations MAY want to define a custom check. -bool isSecureUri(Uri uri) { - return uri.scheme.codeUnits.lastOrNull == 0x73; -} - -/// Sorts cookies by path length and creation time. -int sortCookies(StorableCookie a, StorableCookie b) { - if (a.path.length < b.path.length) { - return 1; - } else if (a.path.length > b.path.length) { - return -1; - } else { - return a.creationTime.compareTo(b.creationTime); - } -} diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/LICENSE b/packages/cookie_store/packages/cookie_store_conformance_tests/LICENSE deleted file mode 120000 index 0fef81c998a..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../../assets/BSD-3-Clause.txt \ No newline at end of file diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/analysis_options.yaml b/packages/cookie_store/packages/cookie_store_conformance_tests/analysis_options.yaml deleted file mode 100644 index 4db3c296b81..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: package:neon_lints/dart.yaml diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/cookie_store_conformance_tests.dart b/packages/cookie_store/packages/cookie_store_conformance_tests/lib/cookie_store_conformance_tests.dart deleted file mode 100644 index b4ec1821cc6..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/cookie_store_conformance_tests.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'dart:async'; - -import 'package:cookie_store/cookie_store.dart' show CookieStore; -import 'package:cookie_store_conformance_tests/src/deletion_tests.dart'; -import 'package:cookie_store_conformance_tests/src/domain_matching_tests.dart'; -import 'package:cookie_store_conformance_tests/src/expiration_tests.dart'; -import 'package:cookie_store_conformance_tests/src/http_only_cookie_tests.dart'; -import 'package:cookie_store_conformance_tests/src/path_matching_tests.dart'; -import 'package:cookie_store_conformance_tests/src/persist_cookies_tests.dart'; -import 'package:cookie_store_conformance_tests/src/secure_cookie_tests.dart'; -import 'package:cookie_store_conformance_tests/src/sorting_tests.dart'; -import 'package:meta/meta.dart'; - -export 'package:cookie_store_conformance_tests/src/deletion_tests.dart' show deletionTests; -export 'package:cookie_store_conformance_tests/src/domain_matching_tests.dart' show domainMatching; -export 'package:cookie_store_conformance_tests/src/expiration_tests.dart' show expiration; -export 'package:cookie_store_conformance_tests/src/http_only_cookie_tests.dart' show httpOnly; -export 'package:cookie_store_conformance_tests/src/path_matching_tests.dart' show pathMatching; -export 'package:cookie_store_conformance_tests/src/persist_cookies_tests.dart' show persistCookies; -export 'package:cookie_store_conformance_tests/src/secure_cookie_tests.dart' show secure; -export 'package:cookie_store_conformance_tests/src/sorting_tests.dart' show sortTests; - -/// Runs the entire test suite against the given [CookieStore]. -/// -/// These tests require the otherwise optional method [CookieStore.loadAll] to -/// be implemented. -/// -/// If [canDeleteAll] is `false` then tests for [CookieStore.deleteAll] will -/// be skipped. -/// -/// If [canDeleteByTest] is `false` then tests for [CookieStore.deleteWhere] will -/// be skipped. -/// -/// If [canSortByPath] is `false` then tests for sorting the cookies loaded for -/// a request against the `Cookie.path` attribute will be skipped. -/// -/// If [canSortByCreationTime] is `false` then tests for sorting the cookies -/// loaded for a request against the creation time will be skipped. -/// Requires [canSortByPath] to be also `true`. -@isTestGroup -void testAll( - FutureOr Function() cookieStoreFactory, { - bool canDeleteAll = true, - bool canDeleteByTest = true, - bool canSortByPath = true, - bool canSortByCreationTime = true, -}) { - persistCookies(cookieStoreFactory); - domainMatching(cookieStoreFactory); - pathMatching(cookieStoreFactory); - httpOnly(cookieStoreFactory); - secure(cookieStoreFactory); - expiration(cookieStoreFactory); - sortTests( - cookieStoreFactory, - canSortByPath: canSortByPath, - canSortByCreationTime: canSortByCreationTime, - ); - deletionTests( - cookieStoreFactory, - canDeleteAll: canDeleteAll, - canDeleteByTest: canDeleteByTest, - ); -} diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/deletion_tests.dart b/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/deletion_tests.dart deleted file mode 100644 index ad4a1a3bcf4..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/deletion_tests.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'dart:async'; - -import 'package:cookie_store/cookie_store.dart'; -import 'package:cookie_store_conformance_tests/src/utils.dart'; -import 'package:meta/meta.dart'; -import 'package:test/test.dart'; - -/// Tests that the store correctly implements the optional cookie management interface. -@isTestGroup -void deletionTests( - FutureOr Function() cookieStoreFactory, { - bool canDeleteAll = true, - bool canDeleteByTest = true, -}) { - late CookieStore cookieStore; - - setUp(() async { - cookieStore = await cookieStoreFactory(); - }); - - group('delete cookies,', () { - test( - 'delete all', - () async { - final uri = Uri(); - - final cookies = [ - TestCookie('name0', 'value'), - TestCookie('name1', 'other-value'), - TestCookie('name2', 'value'), - TestCookie('name3', ''), - ]; - - await cookieStore.saveFromResponse(uri, cookies); - var stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'name0=value', - 'name1=other-value', - 'name2=value', - 'name3=', - ]), - ); - - await cookieStore.deleteAll(); - stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([]), - ); - }, - skip: canDeleteAll ? false : 'does not support deleting all cookies', - ); - - test( - 'delete by test', - () async { - final uri = Uri(); - - final cookies = [ - TestCookie('name0', 'value'), - TestCookie('name1', 'other-value'), - TestCookie('name2', 'value'), - TestCookie('name3', ''), - ]; - - await cookieStore.saveFromResponse(uri, cookies); - var stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'name0=value', - 'name1=other-value', - 'name2=value', - 'name3=', - ]), - ); - - await cookieStore.deleteWhere((cookie) { - return cookie.name == 'name1' || cookie.value.isEmpty; - }); - stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'name0=value', - 'name2=value', - ]), - ); - }, - skip: canDeleteByTest ? false : 'does not support deleting by test', - ); - }); -} diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/domain_matching_tests.dart b/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/domain_matching_tests.dart deleted file mode 100644 index ee0fda12ff3..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/domain_matching_tests.dart +++ /dev/null @@ -1,187 +0,0 @@ -import 'dart:async'; - -import 'package:cookie_store/cookie_store.dart'; -import 'package:cookie_store_conformance_tests/src/utils.dart'; -import 'package:meta/meta.dart'; -import 'package:test/test.dart'; - -/// Tests that the store correctly implements the domain-matching algorithm as -/// defined by [RFC6265 section 5.1.3](https://httpwg.org/specs/rfc6265.html#cookie-domain). -@isTestGroup -void domainMatching(FutureOr Function() cookieStoreFactory) { - late CookieStore cookieStore; - - setUp(() async { - cookieStore = await cookieStoreFactory(); - }); - - group('domain matching,', () { - test('do not store not matching domain', () async { - final cookies = [ - TestCookie('null', 'value')..domain = null, - TestCookie('example.com', 'value')..domain = 'example.com', - TestCookie('.example.com', 'value')..domain = '.example.com', - TestCookie('test.example.com', 'value')..domain = 'test.example.com', - TestCookie('testexample.com', 'value')..domain = 'testexample.com', - TestCookie('test.com', 'value')..domain = 'test.com', - ]; - - await cookieStore.saveFromResponse(Uri(host: 'test.example.com'), cookies); - final stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'example.com=value', - 'null=value', - 'test.example.com=value', - ]), - ); - }); - - test('do not load not matching domain', () async { - var cookies = [ - TestCookie('null', 'value')..domain = null, - TestCookie('example.com', 'value')..domain = 'example.com', - TestCookie('test.example.com', 'value')..domain = 'test.example.com', - ]; - await cookieStore.saveFromResponse(Uri(host: 'test.example.com'), cookies); - - cookies = [ - TestCookie('.example.com', 'value')..domain = '.example.com', - ]; - await cookieStore.saveFromResponse(Uri(host: '.example.com'), cookies); - - cookies = [ - TestCookie('testexample.com', 'value')..domain = 'testexample.com', - ]; - await cookieStore.saveFromResponse(Uri(host: 'testexample.com'), cookies); - - cookies = [ - TestCookie('test.com', 'value')..domain = 'test.com', - ]; - await cookieStore.saveFromResponse(Uri(host: 'test.com'), cookies); - - var stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - '.example.com=value', - 'example.com=value', - 'null=value', - 'test.com=value', - 'test.example.com=value', - 'testexample.com=value', - ]), - ); - - stored = await cookieStore.loadForRequest(Uri(host: 'example.com')); - expect( - toSortedStringList(stored), - equals([ - 'example.com=value', - ]), - ); - - stored = await cookieStore.loadForRequest(Uri(host: 'test.example.com')); - expect( - toSortedStringList(stored), - equals([ - 'example.com=value', - 'null=value', - 'test.example.com=value', - ]), - ); - - stored = await cookieStore.loadForRequest(Uri(host: 'testexample.com')); - expect( - toSortedStringList(stored), - equals([ - 'testexample.com=value', - ]), - ); - - stored = await cookieStore.loadForRequest(Uri(host: 'test..example.com')); - expect( - toSortedStringList(stored), - equals([ - '.example.com=value', - 'example.com=value', - ]), - ); - }); - - group('ip address matching', () { - test('storing', () async { - final uri = Uri(host: '1'); - - final cookies = [ - TestCookie('IPv4-address', 'value')..domain = '127.0.0.1', - TestCookie('IPv6-address', 'value')..domain = '::1', - ]; - - await cookieStore.saveFromResponse(uri, cookies); - final stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([]), - ); - }); - - test('do not load from similar domain', () async { - var cookies = [ - TestCookie('IPv4-address', 'value')..domain = '127.0.0.1', - ]; - await cookieStore.saveFromResponse(Uri(host: '127.0.0.1'), cookies); - - cookies = [ - TestCookie('IPv6-address', 'value')..domain = '::1', - ]; - await cookieStore.saveFromResponse(Uri(host: '::1'), cookies); - - var stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'IPv4-address=value', - 'IPv6-address=value', - ]), - ); - - final uri = Uri(host: '1'); - stored = await cookieStore.loadForRequest(uri); - expect( - toSortedStringList(stored), - equals([]), - ); - }); - - test('load when identical', () async { - var uri = Uri(host: '127.0.0.1'); - var cookies = [ - TestCookie('IPv4-address', 'value')..domain = '127.0.0.1', - ]; - await cookieStore.saveFromResponse(uri, cookies); - var stored = await cookieStore.loadForRequest(uri); - expect( - toSortedStringList(stored), - equals([ - 'IPv4-address=value', - ]), - ); - - uri = Uri(host: '::1'); - cookies = [ - TestCookie('IPv6-address', 'value')..domain = '::1', - ]; - await cookieStore.saveFromResponse(uri, cookies); - stored = await cookieStore.loadForRequest(uri); - expect( - toSortedStringList(stored), - equals([ - 'IPv6-address=value', - ]), - ); - }); - }); - }); -} diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/expiration_tests.dart b/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/expiration_tests.dart deleted file mode 100644 index cfa3af7eef6..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/expiration_tests.dart +++ /dev/null @@ -1,114 +0,0 @@ -import 'dart:async'; - -import 'package:cookie_store/cookie_store.dart'; -import 'package:cookie_store_conformance_tests/src/utils.dart'; -import 'package:meta/meta.dart'; -import 'package:test/test.dart'; - -/// Tests that the store does correctly handle cookie expiration. -/// -/// This also tests the eviction of session-cookies after calling -/// [CookieStore.endSession]. -@isTestGroup -void expiration(FutureOr Function() cookieStoreFactory) { - late CookieStore cookieStore; - - setUp(() async { - cookieStore = await cookieStoreFactory(); - }); - - group('expiration,', () { - test('do not store already expired', () async { - final uri = Uri(); - - const duration = Duration(seconds: 1); - final expiration = DateTime.timestamp().subtract(duration); - final cookies = [ - TestCookie('expired0', 'value')..expires = expiration, - TestCookie('expired1', 'value')..maxAge = -duration.inSeconds, - TestCookie('not-expired0', 'value'), - TestCookie('not-expired1', 'value'), - ]; - - await cookieStore.saveFromResponse(uri, cookies); - final stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'not-expired0=value', - 'not-expired1=value', - ]), - ); - }); - - test('expiration at a later point', () async { - final uri = Uri(); - - const duration = Duration(seconds: 2); - final expiration = DateTime.timestamp().add(duration); - final cookies = [ - TestCookie('will-expire0', 'value')..expires = expiration, - TestCookie('will-expire1', 'value')..maxAge = duration.inSeconds, - TestCookie('not-expired0', 'value'), - TestCookie('not-expired1', 'value'), - ]; - - await cookieStore.saveFromResponse(uri, cookies); - var stored = await cookieStore.loadForRequest(uri); - expect( - toSortedStringList(stored), - equals([ - 'not-expired0=value', - 'not-expired1=value', - 'will-expire0=value', - 'will-expire1=value', - ]), - ); - - await Future.delayed(duration * 2); - stored = await cookieStore.loadForRequest(uri); - expect( - toSortedStringList(stored), - equals([ - 'not-expired0=value', - 'not-expired1=value', - ]), - ); - }); - - test('session cookies', () async { - final uri = Uri(); - - const duration = Duration(days: 1); - final expiration = DateTime.timestamp().add(duration); - final cookies = [ - TestCookie('will-expire0', 'value')..expires = expiration, - TestCookie('will-expire1', 'value')..maxAge = duration.inSeconds, - TestCookie('session-cookie1', 'value'), - TestCookie('session-cookie2', 'value'), - ]; - - await cookieStore.saveFromResponse(uri, cookies); - var stored = await cookieStore.loadForRequest(uri); - expect( - toSortedStringList(stored), - equals([ - 'session-cookie1=value', - 'session-cookie2=value', - 'will-expire0=value', - 'will-expire1=value', - ]), - ); - - await cookieStore.endSession(); - stored = await cookieStore.loadForRequest(uri); - expect( - toSortedStringList(stored), - equals([ - 'will-expire0=value', - 'will-expire1=value', - ]), - ); - }); - }); -} diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/http_only_cookie_tests.dart b/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/http_only_cookie_tests.dart deleted file mode 100644 index e5daacc870f..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/http_only_cookie_tests.dart +++ /dev/null @@ -1,106 +0,0 @@ -import 'dart:async'; - -import 'package:cookie_store/cookie_store.dart'; -import 'package:cookie_store_conformance_tests/src/utils.dart'; -import 'package:meta/meta.dart'; -import 'package:test/test.dart'; - -/// Tests that the store does not load cookies with the httpOnly flag on non http -/// requests. -/// -/// Tested with the following Uris. -/// ```dart -/// var nonHttp = Uri(host: 'example.com'); -/// var http = Uri.http('example.com'); -/// ``` -/// -/// An implementation might not share the same definition of what protocols are `http`. -@isTestGroup -void httpOnly(FutureOr Function() cookieStoreFactory) { - late CookieStore cookieStore; - - setUp(() async { - cookieStore = await cookieStoreFactory(); - }); - - group('http only cookies,', () { - test('do not save when requestUri is not http', () async { - final uri = Uri(host: 'example.com'); - final httpUri = Uri.http('example.com'); - - final cookies = [ - TestCookie('httpOnly0', 'value')..httpOnly = true, - TestCookie('httpOnly1', 'value')..httpOnly = true, - TestCookie('not-httpOnly0', 'value'), - TestCookie('not-httpOnly1', 'value'), - ]; - - await cookieStore.saveFromResponse(uri, cookies); - var stored = await cookieStore.loadAll(); - - expect( - toSortedStringList(stored), - equals([ - 'not-httpOnly0=value', - 'not-httpOnly1=value', - ]), - ); - - await cookieStore.saveFromResponse(httpUri, cookies); - stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'httpOnly0=value', - 'httpOnly1=value', - 'not-httpOnly0=value', - 'not-httpOnly1=value', - ]), - ); - }); - - test('do not retrieve when requestUri is not http', () async { - final uri = Uri(host: 'example.com'); - final httpUri = Uri.http('example.com'); - - final cookies = [ - TestCookie('httpOnly0', 'value')..httpOnly = true, - TestCookie('httpOnly1', 'value')..httpOnly = true, - TestCookie('not-httpOnly0', 'value'), - TestCookie('not-httpOnly1', 'value'), - ]; - - await cookieStore.saveFromResponse(httpUri, cookies); - var stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'httpOnly0=value', - 'httpOnly1=value', - 'not-httpOnly0=value', - 'not-httpOnly1=value', - ]), - ); - - stored = await cookieStore.loadForRequest(uri); - expect( - toSortedStringList(stored), - equals([ - 'not-httpOnly0=value', - 'not-httpOnly1=value', - ]), - ); - - stored = await cookieStore.loadForRequest(httpUri); - expect( - toSortedStringList(stored), - equals([ - 'httpOnly0=value', - 'httpOnly1=value', - 'not-httpOnly0=value', - 'not-httpOnly1=value', - ]), - ); - }); - }); -} diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/path_matching_tests.dart b/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/path_matching_tests.dart deleted file mode 100644 index 98cf539f843..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/path_matching_tests.dart +++ /dev/null @@ -1,182 +0,0 @@ -import 'dart:async'; - -import 'package:cookie_store/cookie_store.dart'; -import 'package:cookie_store_conformance_tests/src/utils.dart'; -import 'package:meta/meta.dart'; -import 'package:test/test.dart'; - -/// Tests that the store correctly implements path and path-matching algorithms -/// as defined by [RFC6265 section 5.1.4](https://httpwg.org/specs/rfc6265.html#cookie-path). -@isTestGroup -void pathMatching(FutureOr Function() cookieStoreFactory) { - late CookieStore cookieStore; - - setUp(() async { - cookieStore = await cookieStoreFactory(); - }); - - group('path matching,', () { - test('with path attribute', () async { - final cookies = [ - TestCookie('docs', 'value')..path = '/docs', - ]; - - await cookieStore.saveFromResponse(Uri(), cookies); - var stored = await cookieStore.loadAll(); - expect(toStringList(stored), equals(['docs=value'])); - - // Not matching - stored = await cookieStore.loadForRequest(Uri()); - expect(stored, isEmpty); - stored = await cookieStore.loadForRequest(Uri(path: '/')); - expect(stored, isEmpty); - stored = await cookieStore.loadForRequest(Uri(path: '/docsTets')); - expect(stored, isEmpty); - stored = await cookieStore.loadForRequest(Uri(path: '/fr/docs')); - expect(stored, isEmpty); - - // Matching - stored = await cookieStore.loadForRequest(Uri(path: '/docs')); - expect(toStringList(stored), equals(['docs=value'])); - stored = await cookieStore.loadForRequest(Uri(path: '/docs/')); - expect(toStringList(stored), equals(['docs=value'])); - stored = await cookieStore.loadForRequest(Uri(path: '/docs/Web/')); - expect(toStringList(stored), equals(['docs=value'])); - stored = await cookieStore.loadForRequest(Uri(path: '/docs/Web/HTTP')); - expect(toStringList(stored), equals(['docs=value'])); - stored = await cookieStore.loadForRequest(Uri(path: '/docs', query: 'queryParam')); - expect(toStringList(stored), equals(['docs=value'])); - stored = await cookieStore.loadForRequest(Uri(path: '/docs', fragment: 'fragment')); - expect(toStringList(stored), equals(['docs=value'])); - }); - - test('default path check', () async { - var cookies = [ - TestCookie('no-path', '/'), - ]; - await cookieStore.saveFromResponse(Uri(), cookies); - - cookies = [ - TestCookie('no-path-query', '/'), - ]; - await cookieStore.saveFromResponse(Uri(query: 'queryParam'), cookies); - - cookies = [ - TestCookie('no-path-fragment', '/'), - ]; - await cookieStore.saveFromResponse(Uri(fragment: 'fragment'), cookies); - - cookies = [ - TestCookie('relative', '/'), - ]; - await cookieStore.saveFromResponse(Uri(path: 'docs'), cookies); - - cookies = [ - TestCookie('relative-one-slash', '/'), - ]; - await cookieStore.saveFromResponse(Uri(path: 'docs/Web'), cookies); - - cookies = [ - TestCookie('relative-multiple-slash', '/'), - ]; - await cookieStore.saveFromResponse(Uri(path: 'docs/Web/'), cookies); - - cookies = [ - TestCookie('absolute-path', '/'), - ]; - await cookieStore.saveFromResponse(Uri(path: '/docs'), cookies); - - cookies = [ - TestCookie('absolute-path-trailing-slash', '/docs'), - ]; - await cookieStore.saveFromResponse(Uri(path: '/docs/'), cookies); - - var stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'absolute-path-trailing-slash=/docs', - 'absolute-path=/', - 'no-path-fragment=/', - 'no-path-query=/', - 'no-path=/', - 'relative-multiple-slash=/', - 'relative-one-slash=/', - 'relative=/', - ]), - ); - - stored = await cookieStore.loadForRequest(Uri()); - expect( - toSortedStringList(stored), - equals([ - 'absolute-path=/', - 'no-path-fragment=/', - 'no-path-query=/', - 'no-path=/', - 'relative-multiple-slash=/', - 'relative-one-slash=/', - 'relative=/', - ]), - ); - stored = await cookieStore.loadForRequest(Uri(path: '/')); - expect( - toSortedStringList(stored), - equals([ - 'absolute-path=/', - 'no-path-fragment=/', - 'no-path-query=/', - 'no-path=/', - 'relative-multiple-slash=/', - 'relative-one-slash=/', - 'relative=/', - ]), - ); - - stored = await cookieStore.loadForRequest(Uri(path: '/docs')); - expect( - toSortedStringList(stored), - equals([ - 'absolute-path-trailing-slash=/docs', - 'absolute-path=/', - 'no-path-fragment=/', - 'no-path-query=/', - 'no-path=/', - 'relative-multiple-slash=/', - 'relative-one-slash=/', - 'relative=/', - ]), - ); - - stored = await cookieStore.loadForRequest(Uri(path: '/docs/')); - expect( - toSortedStringList(stored), - equals([ - 'absolute-path-trailing-slash=/docs', - 'absolute-path=/', - 'no-path-fragment=/', - 'no-path-query=/', - 'no-path=/', - 'relative-multiple-slash=/', - 'relative-one-slash=/', - 'relative=/', - ]), - ); - - stored = await cookieStore.loadForRequest(Uri(path: '/docs/Web')); - expect( - toSortedStringList(stored), - equals([ - 'absolute-path-trailing-slash=/docs', - 'absolute-path=/', - 'no-path-fragment=/', - 'no-path-query=/', - 'no-path=/', - 'relative-multiple-slash=/', - 'relative-one-slash=/', - 'relative=/', - ]), - ); - }); - }); -} diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/persist_cookies_tests.dart b/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/persist_cookies_tests.dart deleted file mode 100644 index 5c92e17b2bf..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/persist_cookies_tests.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'dart:async'; - -import 'package:cookie_store/cookie_store.dart'; -import 'package:cookie_store_conformance_tests/src/utils.dart'; -import 'package:meta/meta.dart'; -import 'package:test/test.dart'; - -/// Tests that the store can store and update cookies. -@isTestGroup -void persistCookies(FutureOr Function() cookieStoreFactory) { - late CookieStore cookieStore; - - setUp(() async { - cookieStore = await cookieStoreFactory(); - }); - - group('persist cookie,', () { - test('plain cookie', () async { - final uri = Uri(); - - final cookies = [ - TestCookie('name0', 'value'), - TestCookie('name1', 'other-value'), - TestCookie('name2', 'value'), - TestCookie('name3', ''), - ]; - - await cookieStore.saveFromResponse(uri, cookies); - final stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'name0=value', - 'name1=other-value', - 'name2=value', - 'name3=', - ]), - ); - }); - - test('update cookie', () async { - final uri = Uri(); - - var cookies = [ - TestCookie('name0', 'value'), - TestCookie('name1', 'value'), - TestCookie('name2', 'value'), - TestCookie('name3', 'value'), - ]; - - await cookieStore.saveFromResponse(uri, cookies); - var stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'name0=value', - 'name1=value', - 'name2=value', - 'name3=value', - ]), - ); - - cookies = [ - TestCookie('name0', 'value2'), - ]; - - await cookieStore.saveFromResponse(uri, cookies); - stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'name0=value2', - 'name1=value', - 'name2=value', - 'name3=value', - ]), - ); - }); - }); -} diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/secure_cookie_tests.dart b/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/secure_cookie_tests.dart deleted file mode 100644 index e7745ed0efd..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/secure_cookie_tests.dart +++ /dev/null @@ -1,70 +0,0 @@ -import 'dart:async'; - -import 'package:cookie_store/cookie_store.dart'; -import 'package:cookie_store_conformance_tests/src/utils.dart'; -import 'package:meta/meta.dart'; -import 'package:test/test.dart'; - -/// Tests that the store does not load cookies with the secure flag on insecure -/// requests. -/// -/// Tested with the following Uris. -/// ```dart -/// var insecure = Uri(host: 'example.com'); -/// var secure = Uri(scheme: 'ftps', host: 'example.com'); -/// ``` -/// -/// An implementation might not consider the `ftps` uri as secure. -@isTestGroup -void secure(FutureOr Function() cookieStoreFactory) { - late CookieStore cookieStore; - - setUp(() async { - cookieStore = await cookieStoreFactory(); - }); - - group('secure cookies,', () { - test('do not load secure cookies in insecure requests', () async { - final uri = Uri(host: 'example.com'); - - final cookies = [ - TestCookie('not-secure0', 'value'), - TestCookie('secure0', 'value')..secure = true, - TestCookie('not-secure1', 'value'), - TestCookie('secure1', 'value')..secure = true, - ]; - - await cookieStore.saveFromResponse(uri, cookies); - var stored = await cookieStore.loadAll(); - expect( - toSortedStringList(stored), - equals([ - 'not-secure0=value', - 'not-secure1=value', - 'secure0=value', - 'secure1=value', - ]), - ); - - stored = await cookieStore.loadForRequest(uri); - expect( - toSortedStringList(stored), - equals([ - 'not-secure0=value', - 'not-secure1=value', - ]), - ); - - stored = await cookieStore.loadForRequest(Uri(scheme: 'ftps', host: 'example.com')); - expect( - toSortedStringList(stored), - equals([ - 'not-secure0=value', - 'not-secure1=value', - 'secure0=value', - 'secure1=value', - ]), - ); - }); - }); -} diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/sorting_tests.dart b/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/sorting_tests.dart deleted file mode 100644 index 27ccd085e70..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/sorting_tests.dart +++ /dev/null @@ -1,93 +0,0 @@ -import 'dart:async'; - -import 'package:cookie_store/cookie_store.dart'; -import 'package:cookie_store_conformance_tests/src/utils.dart'; -import 'package:meta/meta.dart'; -import 'package:test/test.dart'; - -/// Tests that the store correctly sorts cookies on retrieval (optional). -/// -/// The user agent SHOULD sort the cookie-list in the following order: -/// * Cookies with longer paths are listed before cookies with shorter paths. -/// * Among cookies that have equal-length path fields, cookies with earlier -/// creation-times are listed before cookies with later creation-times. -@isTestGroup -void sortTests( - FutureOr Function() cookieStoreFactory, { - bool canSortByPath = true, - bool canSortByCreationTime = true, -}) { - late CookieStore cookieStore; - - setUp(() async { - cookieStore = await cookieStoreFactory(); - }); - - group('sort cookies,', () { - test( - 'by path length', - () async { - final cookies = [ - TestCookie('root', 'value')..path = '/', - TestCookie('docs', 'value')..path = '/docs/', - TestCookie('docs-Web', 'value')..path = '/docs/Web/', - TestCookie('docs-Web-HTTP', 'value')..path = '/docs/Web/HTTP', - ]; - - await cookieStore.saveFromResponse(Uri(path: '/'), cookies); - final stored = await cookieStore.loadForRequest(Uri(path: '/docs/Web/HTTP')); - expect( - toStringList(stored), - equals([ - 'docs-Web-HTTP=value', - 'docs-Web=value', - 'docs=value', - 'root=value', - ]), - ); - }, - skip: canSortByPath ? false : 'does not support sorting by path length', - ); - - test( - 'by access time', - () async { - var cookies = [ - TestCookie('root', 'value')..path = '/', - TestCookie('docs', 'value')..path = '/docs/', - TestCookie('docs-Web', 'value')..path = '/docs/Web/', - TestCookie('docs-Web-HTTP', 'value')..path = '/docs/Web/HTTP', - ]; - - await cookieStore.saveFromResponse(Uri(path: '/'), cookies); - var stored = await cookieStore.loadForRequest(Uri(path: '/docs/Web/HTTP')); - expect( - toStringList(stored), - equals([ - 'docs-Web-HTTP=value', - 'docs-Web=value', - 'docs=value', - 'root=value', - ]), - ); - - cookies = [ - TestCookie('later-written', 'value')..path = '/docs/Web/', - ]; - await cookieStore.saveFromResponse(Uri(path: '/'), cookies); - stored = await cookieStore.loadForRequest(Uri(path: '/docs/Web/HTTP')); - expect( - toStringList(stored), - equals([ - 'docs-Web-HTTP=value', - 'docs-Web=value', - 'later-written=value', - 'docs=value', - 'root=value', - ]), - ); - }, - skip: (canSortByPath && canSortByCreationTime) ? false : 'does not support sorting by creating time', - ); - }); -} diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/utils.dart b/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/utils.dart deleted file mode 100644 index e95feb26b52..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/lib/src/utils.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'dart:io' show Cookie, SameSite; - -import 'package:meta/meta.dart'; - -/// Converts the given cookies to strings containing only the [Cookie.name] and -/// `Cookie.vale` and sorts the resulting list. -@internal -List toSortedStringList(List cookies) { - return toStringList(cookies)..sort(); -} - -/// Converts the given cookies to strings containing only the [Cookie.name] and -/// `Cookie.vale`. -@internal -List toStringList(List cookies) { - return cookies.map((cookie) => '${cookie.name}=${cookie.value}').toList(); -} - -/// Cookie that sets the [secure] and [httpOnly] flag to false by default. -@internal -class TestCookie implements Cookie { - TestCookie(this.name, this.value); - - @override - String name; - - @override - String value; - - @override - String? domain; - - @override - DateTime? expires; - - @override - bool httpOnly = false; - - @override - int? maxAge; - - @override - String? path; - - @override - SameSite? sameSite; - - @override - bool secure = false; -} diff --git a/packages/cookie_store/packages/cookie_store_conformance_tests/pubspec.yaml b/packages/cookie_store/packages/cookie_store_conformance_tests/pubspec.yaml deleted file mode 100644 index e155630493f..00000000000 --- a/packages/cookie_store/packages/cookie_store_conformance_tests/pubspec.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: cookie_store_conformance_tests -description: >- - A library that tests whether implementations of package:cookie_store's `CookieStore` - class behave as expected. -publish_to: none -resolution: workspace - -environment: - sdk: ^3.5.0 - -dependencies: - cookie_store: - path: ../.. - meta: ^1.0.0 - test: ^1.21.2 - -dev_dependencies: - neon_lints: - path: ../../../neon_lints diff --git a/packages/cookie_store/pubspec.yaml b/packages/cookie_store/pubspec.yaml deleted file mode 100644 index ee61eecc591..00000000000 --- a/packages/cookie_store/pubspec.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: cookie_store -description: A RFC compliant cookie store -version: 0.1.0 -publish_to: none -resolution: workspace - -environment: - sdk: ^3.5.0 - -dependencies: - meta: ^1.0.0 - timezone: ^0.10.1 - -dev_dependencies: - cookie_store_conformance_tests: - path: packages/cookie_store_conformance_tests - neon_lints: - path: ../neon_lints - test: ^1.25.15 diff --git a/packages/cookie_store/test/cookie_store_conformance_test.dart b/packages/cookie_store/test/cookie_store_conformance_test.dart deleted file mode 100644 index b1eaf9ada55..00000000000 --- a/packages/cookie_store/test/cookie_store_conformance_test.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:cookie_store/cookie_store.dart'; -import 'package:cookie_store_conformance_tests/cookie_store_conformance_tests.dart' as conformance_tests; - -void main() { - conformance_tests.testAll(CookieStore.new); -} diff --git a/packages/cookie_store/test/storable_cookie_test.dart b/packages/cookie_store/test/storable_cookie_test.dart deleted file mode 100644 index 003be3cd374..00000000000 --- a/packages/cookie_store/test/storable_cookie_test.dart +++ /dev/null @@ -1,152 +0,0 @@ -import 'package:cookie_store/src/storable_cookie.dart'; -import 'package:test/test.dart'; -import 'package:timezone/timezone.dart' as tz; - -void main() { - group('StorableCookie equality', () { - test('same values', () { - final now = tz.TZDateTime.now(tz.UTC); - final cookie1 = StorableCookie( - name: 'name', - value: 'value', - expiryTime: now, - domain: 'example.com', - path: '/path', - creationTime: now, - lastAccessTime: now, - persistentFlag: false, - hostOnlyFlag: false, - secureOnlyFlag: false, - httpOnlyFlag: false, - ); - - final cookie2 = StorableCookie( - name: 'name', - value: 'value', - expiryTime: now, - domain: 'example.com', - path: '/path', - creationTime: now, - lastAccessTime: now, - persistentFlag: false, - hostOnlyFlag: false, - secureOnlyFlag: false, - httpOnlyFlag: false, - ); - - expect(cookie1, equals(cookie2)); - expect(cookie1.hashCode, equals(cookie2.hashCode)); - }); - - test('matching name, domain and path', () { - var now = tz.TZDateTime.now(tz.UTC); - final cookie1 = StorableCookie( - name: 'name', - value: 'value', - expiryTime: now, - domain: 'example.com', - path: '/path', - creationTime: now, - lastAccessTime: now, - persistentFlag: false, - hostOnlyFlag: false, - secureOnlyFlag: false, - httpOnlyFlag: false, - ); - - now = now.subtract(const Duration(days: 3)); - var cookie2 = StorableCookie( - name: 'name', - value: 'other-value', - expiryTime: now, - domain: 'example.com', - path: '/path', - creationTime: now, - lastAccessTime: now, - persistentFlag: true, - hostOnlyFlag: true, - secureOnlyFlag: true, - httpOnlyFlag: true, - ); - expect(cookie1, equals(cookie2)); - expect(cookie1.hashCode, equals(cookie2.hashCode)); - - cookie2 = StorableCookie( - name: 'name', - value: 'other-value', - expiryTime: now, - domain: 'example.com', - path: '/other-path', - creationTime: now, - lastAccessTime: now, - persistentFlag: true, - hostOnlyFlag: true, - secureOnlyFlag: true, - httpOnlyFlag: true, - ); - expect(cookie1, isNot(equals(cookie2))); - expect(cookie1.hashCode, isNot(equals(cookie2.hashCode))); - - cookie2 = StorableCookie( - name: 'name', - value: 'other-value', - expiryTime: now, - domain: 'other.example.com', - path: '/path', - creationTime: now, - lastAccessTime: now, - persistentFlag: true, - hostOnlyFlag: true, - secureOnlyFlag: true, - httpOnlyFlag: true, - ); - expect(cookie1, isNot(equals(cookie2))); - expect(cookie1.hashCode, isNot(equals(cookie2.hashCode))); - - cookie2 = StorableCookie( - name: 'other-name', - value: 'other-value', - expiryTime: now, - domain: 'example.com', - path: '/path', - creationTime: now, - lastAccessTime: now, - persistentFlag: true, - hostOnlyFlag: true, - secureOnlyFlag: true, - httpOnlyFlag: true, - ); - expect(cookie1, isNot(equals(cookie2))); - expect(cookie1.hashCode, isNot(equals(cookie2.hashCode))); - }); - }); - - test('StorableCookie copyWith', () { - final now = tz.TZDateTime.now(tz.UTC); - final cookie1 = StorableCookie( - name: 'name', - value: 'value', - expiryTime: now, - domain: 'example.com', - path: '/path', - creationTime: now, - lastAccessTime: now, - persistentFlag: false, - hostOnlyFlag: false, - secureOnlyFlag: false, - httpOnlyFlag: false, - ); - - var cookie2 = cookie1.copyWith( - value: 'different-value', - ); - expect(cookie1, equals(cookie2)); - expect(cookie1.hashCode, equals(cookie2.hashCode)); - - cookie2 = cookie1.copyWith( - lastAccessTime: now.subtract(const Duration(seconds: 2)), - ); - expect(cookie1, equals(cookie2)); - expect(cookie1.hashCode, equals(cookie2.hashCode)); - }); -} diff --git a/packages/cookie_store/test/utils_test.dart b/packages/cookie_store/test/utils_test.dart deleted file mode 100644 index bdd65327949..00000000000 --- a/packages/cookie_store/test/utils_test.dart +++ /dev/null @@ -1,267 +0,0 @@ -import 'package:cookie_store/src/storable_cookie.dart'; -import 'package:cookie_store/src/utils.dart'; -import 'package:test/test.dart'; -import 'package:timezone/timezone.dart' as tz; - -void main() { - group('defaultPath', () { - test('empty uri', () { - final uri = Uri(); - final result = defaultPath(uri); - - expect(result, '/'); - }); - - test('uri with query parameter or fragment', () { - var uri = Uri(scheme: 'http', host: 'example.com', query: 'query'); - var result = defaultPath(uri); - expect(result, '/'); - - uri = Uri(scheme: 'http', host: 'example.com', fragment: 'fragment'); - result = defaultPath(uri); - expect(result, '/'); - }); - - test('relative path', () { - var uri = Uri(path: 'docs'); - var result = defaultPath(uri); - expect(result, '/'); - - uri = Uri(path: 'docs/'); - result = defaultPath(uri); - expect(result, '/'); - - uri = Uri(path: 'docs/Web'); - result = defaultPath(uri); - expect(result, '/'); - - uri = Uri(path: 'docs/Web/'); - result = defaultPath(uri); - expect(result, '/'); - }); - - test('absolute path', () { - var uri = Uri(path: '/docs'); - var result = defaultPath(uri); - expect(result, '/'); - - uri = Uri(path: '/docs/'); - result = defaultPath(uri); - expect(result, '/docs'); - - uri = Uri(path: '/docs/Web'); - result = defaultPath(uri); - expect(result, '/docs/Web'); - - uri = Uri(path: '/docs/Web/'); - result = defaultPath(uri); - expect(result, '/docs/Web'); - }); - }); - - group('isDomainMatch', () { - test('identical domain', () { - const cookieDomain = 'example.com'; - const requestDomain = 'example.com'; - - final result = isDomainMatch(requestDomain, cookieDomain); - expect(result, isTrue); - }); - - test('IP address', () { - const cookieDomain = '1'; - - var requestDomain = '127.0.0.1'; - var result = isDomainMatch(requestDomain, cookieDomain); - expect(result, isFalse); - - requestDomain = '::1'; - result = isDomainMatch(requestDomain, cookieDomain); - expect(result, isFalse); - }); - - test('domain is suffix', () { - var cookieDomain = 'example.com'; - - var result = isDomainMatch('example.com', cookieDomain); - expect(result, isTrue); - result = isDomainMatch('.example.com', cookieDomain); - expect(result, isTrue); - result = isDomainMatch('test.example.com', cookieDomain); - expect(result, isTrue); - result = isDomainMatch('1example.com', cookieDomain); - expect(result, isFalse); - result = isDomainMatch('test.com', cookieDomain); - expect(result, isFalse); - - cookieDomain = '.leading.dot.example.com'; - - result = isDomainMatch('.leading.dot.example.com', cookieDomain); - expect(result, isTrue); - result = isDomainMatch('..leading.dot.example.com', cookieDomain); - expect(result, isTrue); - result = isDomainMatch('sub..leading.dot.example.com', cookieDomain); - expect(result, isTrue); - result = isDomainMatch('sub.leading.dot.example.com', cookieDomain); - expect(result, isFalse); - result = isDomainMatch('dot.example.com', cookieDomain); - expect(result, isFalse); - }); - }); - - group('isPathMatch', () { - test('identical path', () { - var cookiePath = '/'; - var requestPath = '/'; - var result = isPathMatch(requestPath, cookiePath); - expect(result, isTrue); - - cookiePath = '/file'; - requestPath = '/file'; - result = isPathMatch(requestPath, cookiePath); - expect(result, isTrue); - - cookiePath = '/directory/'; - requestPath = '/directory/'; - result = isPathMatch(requestPath, cookiePath); - expect(result, isTrue); - }); - - test('path is prefix', () { - const cookiePath = '/docs'; - - var result = isPathMatch('/docs', cookiePath); - expect(result, isTrue); - result = isPathMatch('/docs/', cookiePath); - expect(result, isTrue); - result = isPathMatch('/docs/Web/', cookiePath); - expect(result, isTrue); - result = isPathMatch('/docs/Web/HTTP', cookiePath); - expect(result, isTrue); - - result = isPathMatch('/', cookiePath); - expect(result, isFalse); - result = isPathMatch('/docsTets', cookiePath); - expect(result, isFalse); - result = isPathMatch('/fr/docs', cookiePath); - expect(result, isFalse); - }); - }); - - test('isHttpUri', () { - var uri = Uri.http('example.com'); - var result = isHttpUri(uri); - expect(result, isTrue); - - uri = Uri.https('example.com'); - result = isHttpUri(uri); - expect(result, isTrue); - - uri = Uri.file('example.com'); - result = isHttpUri(uri); - expect(result, isFalse); - - uri = Uri(host: 'example.com'); - result = isHttpUri(uri); - expect(result, isFalse); - }); - - test('isSecureUri', () { - var uri = Uri.http('example.com'); - var result = isSecureUri(uri); - expect(result, isFalse); - - uri = Uri.https('example.com'); - result = isSecureUri(uri); - expect(result, isTrue); - - uri = Uri.file('example.com'); - result = isSecureUri(uri); - expect(result, isFalse); - - uri = Uri.parse('ftp://example.com'); - result = isSecureUri(uri); - expect(result, isFalse); - - uri = Uri.parse('ftps://example.com'); - result = isSecureUri(uri); - expect(result, isTrue); - }); - - test('sortCookies', () { - var now = tz.TZDateTime.now(tz.UTC); - final shortPathCookie = StorableCookie( - name: 'short-path', - value: 'value', - expiryTime: now, - domain: 'example.com', - path: '/path', - creationTime: now, - lastAccessTime: now, - persistentFlag: false, - hostOnlyFlag: false, - secureOnlyFlag: false, - httpOnlyFlag: false, - ); - - final longerPathCookie = StorableCookie( - name: 'longer-path', - value: 'value', - expiryTime: now, - domain: 'example.com', - path: '/longerPath', - creationTime: now, - lastAccessTime: now, - persistentFlag: false, - hostOnlyFlag: false, - secureOnlyFlag: false, - httpOnlyFlag: false, - ); - - final earlyLongestPathCookie = StorableCookie( - name: 'longest-path-early', - value: 'value', - expiryTime: now, - domain: 'example.com', - path: '/longestPath', - creationTime: now, - lastAccessTime: now, - persistentFlag: false, - hostOnlyFlag: false, - secureOnlyFlag: false, - httpOnlyFlag: false, - ); - - now = now.add(const Duration(seconds: 1)); - final laterLongestPathCookie = StorableCookie( - name: 'longest-path-later', - value: 'value', - expiryTime: now, - domain: 'example.com', - path: '/longestPath', - creationTime: now, - lastAccessTime: now, - persistentFlag: false, - hostOnlyFlag: false, - secureOnlyFlag: false, - httpOnlyFlag: false, - ); - - final list = [ - laterLongestPathCookie, - longerPathCookie, - shortPathCookie, - earlyLongestPathCookie, - ]; - - expect( - list..sort(sortCookies), - orderedEquals([ - earlyLongestPathCookie, - laterLongestPathCookie, - longerPathCookie, - shortPathCookie, - ]), - ); - }); -} diff --git a/packages/interceptor_http_client/LICENSE b/packages/interceptor_http_client/LICENSE deleted file mode 120000 index af8c58b151a..00000000000 --- a/packages/interceptor_http_client/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../assets/AGPL-3.0.txt \ No newline at end of file diff --git a/packages/interceptor_http_client/analysis_options.yaml b/packages/interceptor_http_client/analysis_options.yaml deleted file mode 100644 index f0a42286945..00000000000 --- a/packages/interceptor_http_client/analysis_options.yaml +++ /dev/null @@ -1,6 +0,0 @@ -include: package:neon_lints/dart.yaml - -custom_lint: - rules: - - avoid_exports: false - - avoid_dart_io: false diff --git a/packages/interceptor_http_client/dart_test.yaml b/packages/interceptor_http_client/dart_test.yaml deleted file mode 100644 index 20d3df48b98..00000000000 --- a/packages/interceptor_http_client/dart_test.yaml +++ /dev/null @@ -1,10 +0,0 @@ -platforms: - - vm - - chrome - -define_platforms: - chromium: - name: Chromium - extends: chrome - settings: - executable: chromium diff --git a/packages/interceptor_http_client/lib/interceptor_http_client.dart b/packages/interceptor_http_client/lib/interceptor_http_client.dart deleted file mode 100644 index 4769fa678bd..00000000000 --- a/packages/interceptor_http_client/lib/interceptor_http_client.dart +++ /dev/null @@ -1,5 +0,0 @@ -/// A http client that allows to register interceptors for requests and responses. -library; - -export 'src/interceptor_http_client.dart'; -export 'src/interceptors/interceptors.dart'; diff --git a/packages/interceptor_http_client/lib/src/interceptor_http_client.dart b/packages/interceptor_http_client/lib/src/interceptor_http_client.dart deleted file mode 100644 index 622e3fbc556..00000000000 --- a/packages/interceptor_http_client/lib/src/interceptor_http_client.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'dart:async'; - -import 'package:built_collection/built_collection.dart'; -import 'package:http/http.dart' as http; -import 'package:interceptor_http_client/src/interceptors/interceptors.dart'; -import 'package:meta/meta.dart'; - -/// An exception caused by an error in a [InterceptorHttpClient]. -abstract class InterceptorHttpClientException extends http.ClientException { - /// An exception caused by an error in a [InterceptorHttpClient]. - InterceptorHttpClientException(super.message, [super.uri]); -} - -/// An exception caused by a [HttpInterceptor]. -final class InterceptionException extends InterceptorHttpClientException { - /// Creates a new interceptor failure exception. - InterceptionException(super.message, [super.uri]); -} - -/// A http client for intercepting requests and responses. -class InterceptorHttpClient with http.BaseClient { - /// Creates a new interceptor http client. - const InterceptorHttpClient({ - required http.Client baseClient, - required this.interceptors, - }) : _baseClient = baseClient; - - /// The underlying HTTP client. - final http.Client _baseClient; - - /// The list of enabled interceptors. - @visibleForTesting - @protected - final BuiltList interceptors; - - @override - Future send(http.BaseRequest request) async { - var interceptedRequest = request; - for (final interceptor in interceptors) { - if (interceptor.shouldInterceptRequest(interceptedRequest)) { - try { - interceptedRequest = await interceptor.interceptRequest( - request: interceptedRequest, - ); - } catch (error, stackTrace) { - if (error is http.ClientException) { - rethrow; - } - - Error.throwWithStackTrace( - InterceptionException('Failed to intercept request', request.url), - stackTrace, - ); - } - } - } - - var interceptedResponse = await _baseClient.send(interceptedRequest); - - Uri url; - if (interceptedResponse case http.BaseResponseWithUrl(url: final responseUrl)) { - url = responseUrl; - } else { - url = interceptedRequest.url; - } - - for (final interceptor in interceptors) { - if (interceptor.shouldInterceptResponse(interceptedResponse)) { - try { - interceptedResponse = await interceptor.interceptResponse( - response: interceptedResponse, - url: url, - ); - } catch (error, stackTrace) { - if (error is http.ClientException) { - rethrow; - } - Error.throwWithStackTrace( - InterceptionException('Failed to intercept response', request.url), - stackTrace, - ); - } - } - } - - return interceptedResponse; - } - - @override - void close() { - _baseClient.close(); - - super.close(); - } -} diff --git a/packages/interceptor_http_client/lib/src/interceptors/cookie_interceptor.dart b/packages/interceptor_http_client/lib/src/interceptors/cookie_interceptor.dart deleted file mode 100644 index 79997f905a1..00000000000 --- a/packages/interceptor_http_client/lib/src/interceptors/cookie_interceptor.dart +++ /dev/null @@ -1,100 +0,0 @@ -import 'dart:async'; -import 'dart:io' show Cookie, HttpHeaders; - -import 'package:cookie_store/cookie_store.dart'; -import 'package:http/http.dart' as http; -import 'package:interceptor_http_client/src/interceptors/interceptors.dart'; -import 'package:meta/meta.dart'; - -/// A HttpInterceptor to implement cookie persisting interceptors. -/// -/// If the request already contains a 'cookie' header the request will not be intercepted. -@immutable -abstract class CookieInterceptor implements HttpInterceptor { - /// Creates a new cookie interceptor. - const CookieInterceptor(); - - @override - bool shouldInterceptRequest(http.BaseRequest request) { - return !request.headers.containsKey(HttpHeaders.cookieHeader); - } - - @override - Future interceptRequest({required http.BaseRequest request}) async { - assert( - shouldInterceptRequest(request), - 'Request already contains a cookie header and should not be intercepted.', - ); - - final cookies = await loadForRequest(request.url); - if (cookies.isNotEmpty) { - final buffer = StringBuffer(); - final iterator = cookies.iterator..moveNext(); - - while (true) { - final cookie = iterator.current; - - buffer - ..write(cookie.name) - ..write('=') - ..write(cookie.value); - - if (iterator.moveNext()) { - buffer.write('; '); - } else { - break; - } - } - - request.headers[HttpHeaders.cookieHeader] = buffer.toString(); - } - - return request; - } - - @override - bool shouldInterceptResponse(http.StreamedResponse response) { - return response.headers.containsKey(HttpHeaders.setCookieHeader); - } - - @override - Future interceptResponse({required http.StreamedResponse response, required Uri url}) async { - assert( - shouldInterceptResponse(response), - 'Response should not be intercepted.', - ); - - final cookieHeader = response.headersSplitValues[HttpHeaders.setCookieHeader]!; - final cookies = cookieHeader.map(Cookie.fromSetCookieValue).toList(); - await saveFromResponse(url, cookies); - - return response; - } - - /// Load the cookies for specified [uri]. - FutureOr> loadForRequest(Uri uri); - - /// Save the [cookies] for specified [uri]. - FutureOr saveFromResponse(Uri uri, List cookies); -} - -/// A HttpInterceptor persisting cookies in the provided [cookieStore]. -final class CookieStoreInterceptor extends CookieInterceptor { - /// Creates a new interceptor persisting cookies. - const CookieStoreInterceptor({ - required this.cookieStore, - }); - - /// The cookie store instance backing this interceptor. - final CookieStore cookieStore; - - @override - FutureOr> loadForRequest(Uri uri) { - return cookieStore.loadForRequest(uri); - } - - @override - FutureOr saveFromResponse(Uri uri, List cookies) { - return cookieStore.saveFromResponse(uri, cookies); - } -} diff --git a/packages/interceptor_http_client/lib/src/interceptors/http_interceptor.dart b/packages/interceptor_http_client/lib/src/interceptors/http_interceptor.dart deleted file mode 100644 index e846667201b..00000000000 --- a/packages/interceptor_http_client/lib/src/interceptors/http_interceptor.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'dart:async'; - -import 'package:http/http.dart' as http; - -/// Interceptor that can manipulate http requests and responses. -abstract interface class HttpInterceptor { - /// Whether this interceptor should intercept requests. - bool shouldInterceptRequest(http.BaseRequest request); - - /// Intercepts the given [request]. - /// - /// Provided requests are not finalized yet. It is an error for an interceptor - /// to finalize it by executing them. - /// - /// Exceptions might be thrown during interception. - /// If the exception is an [http.ClientException] it will be thrown as is, - /// otherwise it is wrapped as an `InterceptionException`. - FutureOr interceptRequest({required http.BaseRequest request}); - - /// Whether this interceptor should intercept response. - bool shouldInterceptResponse(http.StreamedResponse response); - - /// Intercepts the given [response]. - /// - /// Until package:http 2.0 makes [http.BaseResponseWithUrl] mandatory the request url is used. - /// - /// Exceptions might be thrown during interception. - /// If the exception is an [http.ClientException] it will be thrown as is, - /// otherwise it is wrapped as an `InterceptionException`. - FutureOr interceptResponse({ - required http.StreamedResponse response, - required Uri url, - }); -} diff --git a/packages/interceptor_http_client/lib/src/interceptors/interceptors.dart b/packages/interceptor_http_client/lib/src/interceptors/interceptors.dart deleted file mode 100644 index 20b2373b314..00000000000 --- a/packages/interceptor_http_client/lib/src/interceptors/interceptors.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'cookie_interceptor.dart'; -export 'http_interceptor.dart'; diff --git a/packages/interceptor_http_client/pubspec.yaml b/packages/interceptor_http_client/pubspec.yaml deleted file mode 100644 index e12b2c277fe..00000000000 --- a/packages/interceptor_http_client/pubspec.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: interceptor_http_client -description: A http client with request and response interceptors. -version: 0.1.0 -publish_to: none -resolution: workspace - -environment: - sdk: ^3.5.0 - -dependencies: - built_collection: ^5.0.0 - cookie_store: - path: ../cookie_store - http: ^1.0.0 - meta: ^1.0.0 - -dev_dependencies: - http_client_conformance_tests: - git: - url: https://github.com/dart-lang/http - path: pkgs/http_client_conformance_tests - ref: 907782f5a792e7a5b0ed92f118c0ad91f3ecde51 - mocktail: ^1.0.4 - neon_lints: - path: ../neon_lints - test: ^1.25.15 diff --git a/packages/interceptor_http_client/test/client_conformance_test.dart b/packages/interceptor_http_client/test/client_conformance_test.dart deleted file mode 100644 index b03bbcfd954..00000000000 --- a/packages/interceptor_http_client/test/client_conformance_test.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:built_collection/built_collection.dart'; -import 'package:http/http.dart' as http; -import 'package:http_client_conformance_tests/http_client_conformance_tests.dart'; -import 'package:interceptor_http_client/src/interceptor_http_client.dart'; -import 'package:test/test.dart'; - -void main() { - group( - 'Interceptor Client VM conformance test', - () { - testAll( - () => InterceptorHttpClient( - baseClient: http.Client(), - interceptors: BuiltList(), - ), - canReceiveSetCookieHeaders: true, - canSendCookieHeaders: true, - ); - }, - onPlatform: const { - 'browser': [Skip()], - }, - ); - - group( - 'Interceptor Client browser conformance test', - () { - testAll( - () => InterceptorHttpClient( - baseClient: http.Client(), - interceptors: BuiltList(), - ), - redirectAlwaysAllowed: true, - canStreamRequestBody: false, - canStreamResponseBody: false, - canWorkInIsolates: false, - supportsMultipartRequest: false, - ); - }, - onPlatform: const { - 'dart-vm': [Skip()], - }, - ); -} diff --git a/packages/interceptor_http_client/test/interceptor_http_client_test.dart b/packages/interceptor_http_client/test/interceptor_http_client_test.dart deleted file mode 100644 index bcbe2ee469c..00000000000 --- a/packages/interceptor_http_client/test/interceptor_http_client_test.dart +++ /dev/null @@ -1,133 +0,0 @@ -import 'package:built_collection/built_collection.dart'; -import 'package:http/http.dart'; -import 'package:http/testing.dart'; -import 'package:interceptor_http_client/interceptor_http_client.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:test/test.dart'; - -class _MockInterceptor extends Mock implements HttpInterceptor {} - -class _FakeUri extends Fake implements Uri {} - -void main() { - final uri = Uri.parse('http://example.com'); - Request fakeRequest() { - return Request('PUT', uri); - } - - StreamedResponse fakeResponse() { - return StreamedResponse(const Stream.empty(), 200); - } - - final mockedClient = MockClient((request) async { - return Response.fromStream(fakeResponse()); - }); - late InterceptorHttpClient client; - - setUpAll(() { - registerFallbackValue(_FakeUri()); - registerFallbackValue(fakeResponse()); - registerFallbackValue(fakeRequest()); - }); - - tearDown(() { - client.close(); - }); - - group(InterceptorHttpClient, () { - group('interceptors', () { - late HttpInterceptor interceptor; - - setUp(() { - interceptor = _MockInterceptor(); - - client = InterceptorHttpClient( - baseClient: mockedClient, - interceptors: BuiltList([interceptor]), - ); - }); - - test('does not intercept', () async { - when(() => interceptor.shouldInterceptRequest(any())).thenReturn(false); - when(() => interceptor.shouldInterceptResponse(any())).thenReturn(false); - - final request = Request('GET', uri); - await client.send(request); - - verifyNever( - () => interceptor.interceptRequest( - request: any(named: 'request'), - ), - ); - verifyNever( - () => interceptor.interceptResponse( - response: any(named: 'response'), - url: any(named: 'url'), - ), - ); - }); - - test('does intercept', () async { - when(() => interceptor.shouldInterceptRequest(any())).thenReturn(true); - when(() => interceptor.shouldInterceptResponse(any())).thenReturn(true); - when( - () => interceptor.interceptRequest(request: any(named: 'request')), - ).thenReturn(fakeRequest()); - when( - () => interceptor.interceptResponse(response: any(named: 'response'), url: any(named: 'url')), - ).thenReturn(fakeResponse()); - - final request = Request('GET', uri); - await client.send(request); - - verify( - () => interceptor.interceptRequest( - request: any(named: 'request', that: equals(request)), - ), - ).called(1); - verify( - () => interceptor.interceptResponse( - response: any(named: 'response'), - url: any(named: 'url', that: equals(uri)), - ), - ).called(1); - }); - - test('rethrows errors as InterceptionFailure', () async { - when(() => interceptor.shouldInterceptRequest(any())).thenReturn(true); - when( - () => interceptor.interceptRequest(request: any(named: 'request')), - ).thenThrow(StateError('message')); - - expect( - client.get(uri), - throwsA( - isA().having( - (e) => e.uri, - 'uri', - uri, - ), - ), - ); - - when(() => interceptor.shouldInterceptRequest(any())).thenReturn(true); - when(() => interceptor.interceptRequest(request: any(named: 'request'))).thenReturn(fakeRequest()); - when(() => interceptor.shouldInterceptResponse(any())).thenReturn(true); - when( - () => interceptor.interceptResponse(response: any(named: 'response'), url: any(named: 'url')), - ).thenThrow(StateError('message')); - - expect( - client.get(uri), - throwsA( - isA().having( - (e) => e.uri, - 'uri', - uri, - ), - ), - ); - }); - }); - }); -} diff --git a/packages/interceptor_http_client/test/interceptors/cookie_interceptor_test.dart b/packages/interceptor_http_client/test/interceptors/cookie_interceptor_test.dart deleted file mode 100644 index 3ab4de79c22..00000000000 --- a/packages/interceptor_http_client/test/interceptors/cookie_interceptor_test.dart +++ /dev/null @@ -1,98 +0,0 @@ -import 'dart:async'; -import 'dart:io'; - -import 'package:cookie_store/cookie_store.dart'; -import 'package:http/http.dart' as http; -import 'package:interceptor_http_client/src/interceptors/cookie_interceptor.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:test/test.dart'; - -class _MockCookieStore extends Mock implements CookieStore {} - -void main() { - group('CookieInterceptor', () { - late CookieStore cookieStore; - late CookieStoreInterceptor interceptor; - - setUpAll(() { - registerFallbackValue(http.Request('PUT', Uri())); - registerFallbackValue(http.StreamedResponse(const Stream.empty(), 200)); - registerFallbackValue(Uri()); - }); - - setUp(() { - cookieStore = _MockCookieStore(); - interceptor = CookieStoreInterceptor(cookieStore: cookieStore); - }); - - test('does add cookies to request', () async { - when(() => cookieStore.loadForRequest(any())).thenAnswer((_) async { - return [ - Cookie('a', 'a2'), - Cookie('b', 'b2'), - Cookie('c', 'c2'), - ]; - }); - - final request = http.Request('GET', Uri(host: 'host')); - expect(interceptor.shouldInterceptRequest(request), isTrue); - - final intercepted = await interceptor.interceptRequest(request: request); - expect(intercepted.headers, equals({'cookie': 'a=a2; b=b2; c=c2'})); - - verify( - () => cookieStore.loadForRequest(any(that: equals(Uri(host: 'host')))), - ).called(1); - }); - - test('does not intercept request with "cookie" header', () async { - final request = http.Request( - 'GET', - Uri(host: 'host'), - )..headers['cookie'] = 'key=value'; - - expect(interceptor.shouldInterceptRequest(request), isFalse); - - expect( - () => interceptor.interceptRequest(request: request), - throwsA(isA()), - ); - }); - - test('does store response cookies', () async { - when(() => cookieStore.saveFromResponse(any(), any())).thenAnswer((_) async {}); - - final uri = Uri(host: 'host'); - final response = http.StreamedResponse( - const Stream.empty(), - 200, - headers: {'set-cookie': 'a=a2,b=b2,c=c2'}, - ); - expect(interceptor.shouldInterceptResponse(response), isTrue); - - final intercepted = await interceptor.interceptResponse(response: response, url: uri); - expect(intercepted.headers, equals({'set-cookie': 'a=a2,b=b2,c=c2'})); - - verify( - () => cookieStore.saveFromResponse( - any(that: equals(Uri(host: 'host'))), - any(that: hasLength(3)), - ), - ).called(1); - }); - - test('does not intercept responses without "set-cookie" header', () async { - final response = http.StreamedResponse( - const Stream.empty(), - 200, - headers: {'Set-Cookie': 'a=a2,b=b2,c=c2'}, - ); - expect(interceptor.shouldInterceptResponse(response), isFalse); - - expect( - () => interceptor.interceptResponse(response: response, url: Uri()), - throwsA(isA()), - ); - }); - }); -} diff --git a/packages/interceptor_http_client/test/interceptors/http_interceptor_test.dart b/packages/interceptor_http_client/test/interceptors/http_interceptor_test.dart deleted file mode 100644 index db1977128bf..00000000000 --- a/packages/interceptor_http_client/test/interceptors/http_interceptor_test.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:http/http.dart' as http; -import 'package:interceptor_http_client/src/interceptors/http_interceptor.dart'; -import 'package:test/test.dart'; - -class _TestHttpInterceptor implements HttpInterceptor { - @override - http.BaseRequest interceptRequest({required http.BaseRequest request}) { - throw UnimplementedError(); - } - - @override - http.StreamedResponse interceptResponse({ - required http.StreamedResponse response, - required Uri url, - }) { - throw UnimplementedError(); - } - - @override - bool shouldInterceptRequest(http.BaseRequest request) => throw UnimplementedError(); - - @override - bool shouldInterceptResponse(http.StreamedResponse response) => throw UnimplementedError(); -} - -void main() { - group('HttpInterceptor', () { - test('can be implemented', () { - expect(_TestHttpInterceptor(), isNotNull); - }); - }); -} diff --git a/packages/neon_framework/packages/neon_http_client/pubspec.yaml b/packages/neon_framework/packages/neon_http_client/pubspec.yaml index 06445a54a08..754015dacf2 100644 --- a/packages/neon_framework/packages/neon_http_client/pubspec.yaml +++ b/packages/neon_framework/packages/neon_http_client/pubspec.yaml @@ -10,10 +10,16 @@ environment: dependencies: built_collection: ^5.0.0 cookie_store: - path: ../../../cookie_store + git: + url: https://github.com/foldland/cookie_store + path: packages/cookie_store + ref: 4280ce0b73d1950a603f6ed78596666db1b59af6 http: ^1.6.0 interceptor_http_client: - path: ../../../interceptor_http_client + git: + url: https://github.com/foldland/cookie_store + path: packages/interceptor_http_client + ref: 4280ce0b73d1950a603f6ed78596666db1b59af6 logging: ^1.0.0 meta: ^1.0.0 nextcloud: ^9.0.0 diff --git a/packages/neon_framework/packages/neon_storage/pubspec.yaml b/packages/neon_framework/packages/neon_storage/pubspec.yaml index 86b3777ff54..40806046d37 100644 --- a/packages/neon_framework/packages/neon_storage/pubspec.yaml +++ b/packages/neon_framework/packages/neon_storage/pubspec.yaml @@ -10,7 +10,10 @@ environment: dependencies: built_collection: ^5.0.0 cookie_store: - path: ../../../cookie_store + git: + url: https://github.com/foldland/cookie_store + path: packages/cookie_store + ref: 4280ce0b73d1950a603f6ed78596666db1b59af6 http: ^1.0.0 logging: ^1.0.0 meta: ^1.0.0 @@ -22,7 +25,10 @@ dependencies: dev_dependencies: cookie_store_conformance_tests: - path: ../../../cookie_store/packages/cookie_store_conformance_tests + git: + url: https://github.com/foldland/cookie_store + path: packages/cookie_store_conformance_tests + ref: 4280ce0b73d1950a603f6ed78596666db1b59af6 mocktail: ^1.0.4 neon_lints: path: ../../../neon_lints diff --git a/packages/neon_framework/pubspec.yaml b/packages/neon_framework/pubspec.yaml index d07867e1238..94fd239fbc4 100644 --- a/packages/neon_framework/pubspec.yaml +++ b/packages/neon_framework/pubspec.yaml @@ -16,7 +16,10 @@ dependencies: built_value: ^8.9.0 collection: ^1.0.0 cookie_store: - path: ../cookie_store + git: + url: https://github.com/foldland/cookie_store + path: packages/cookie_store + ref: 4280ce0b73d1950a603f6ed78596666db1b59af6 crypto: ^3.0.0 cupertino_icons: ^1.0.0 # Do not remove this, is it needed on iOS/macOS. It will not include icons on other platforms because Apple forbids it. dynamic_color: @@ -79,7 +82,10 @@ dev_dependencies: built_value_generator: ^8.10.1 code_builder: ^4.11.1 cookie_store_conformance_tests: - path: ../cookie_store/packages/cookie_store_conformance_tests + git: + url: https://github.com/foldland/cookie_store + path: packages/cookie_store_conformance_tests + ref: 4280ce0b73d1950a603f6ed78596666db1b59af6 crypton: ^2.2.1 custom_lint: ^0.7.6 dart_style: ^3.1.0 diff --git a/packages/nextcloud/packages/nextcloud_test/pubspec.yaml b/packages/nextcloud/packages/nextcloud_test/pubspec.yaml index 26540e706f4..e6e9b824b0d 100644 --- a/packages/nextcloud/packages/nextcloud_test/pubspec.yaml +++ b/packages/nextcloud/packages/nextcloud_test/pubspec.yaml @@ -10,11 +10,17 @@ dependencies: built_collection: ^5.1.1 collection: ^1.0.0 cookie_store: - path: ../../../cookie_store + git: + url: https://github.com/foldland/cookie_store + path: packages/cookie_store + ref: 4280ce0b73d1950a603f6ed78596666db1b59af6 glob: ^2.1.2 http: ^1.2.0 interceptor_http_client: - path: ../../../interceptor_http_client + git: + url: https://github.com/foldland/cookie_store + path: packages/interceptor_http_client + ref: 4280ce0b73d1950a603f6ed78596666db1b59af6 matcher: ^0.12.0 meta: ^1.0.0 nextcloud: ^9.0.0 diff --git a/pubspec.lock b/pubspec.lock index 369e5f03725..1d245d25dcb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -321,6 +321,24 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" + cookie_store: + dependency: "direct overridden" + description: + path: "packages/cookie_store" + ref: "4280ce0b73d1950a603f6ed78596666db1b59af6" + resolved-ref: "4280ce0b73d1950a603f6ed78596666db1b59af6" + url: "https://github.com/foldland/cookie_store" + source: git + version: "0.1.0" + cookie_store_conformance_tests: + dependency: transitive + description: + path: "packages/cookie_store_conformance_tests" + ref: "4280ce0b73d1950a603f6ed78596666db1b59af6" + resolved-ref: "4280ce0b73d1950a603f6ed78596666db1b59af6" + url: "https://github.com/foldland/cookie_store" + source: git + version: "0.0.0" coverage: dependency: transitive description: @@ -762,10 +780,10 @@ packages: dependency: transitive description: name: hotreloader - sha256: bc167a1163807b03bada490bfe2df25b0d744df359227880220a5cbd04e5734b + sha256: "66871df468fc24eee81f1a0a7cb98acc104716f9b7376d355437b48d633c4ebf" url: "https://pub.dev" source: hosted - version: "4.3.0" + version: "4.4.0" html: dependency: transitive description: @@ -879,6 +897,15 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.2" + interceptor_http_client: + dependency: "direct overridden" + description: + path: "packages/interceptor_http_client" + ref: "4280ce0b73d1950a603f6ed78596666db1b59af6" + resolved-ref: "4280ce0b73d1950a603f6ed78596666db1b59af6" + url: "https://github.com/foldland/cookie_store" + source: git + version: "0.1.0" intersperse: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 13fece3518c..e757aaab241 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -6,13 +6,10 @@ environment: flutter: ^3.27.0 workspace: - - packages/cookie_store - - packages/cookie_store/packages/cookie_store_conformance_tests - packages/dynamite - packages/dynamite/example - packages/dynamite/packages/dynamite_end_to_end_test - packages/dynamite/packages/dynamite_runtime - - packages/interceptor_http_client - packages/neon_framework - packages/neon_framework/example - packages/neon_framework/packages/account_repository @@ -39,3 +36,15 @@ dependencies: dev_dependencies: melos: 6.0.0 + +dependency_overrides: + cookie_store: + git: + url: https://github.com/foldland/cookie_store + path: packages/cookie_store + ref: 4280ce0b73d1950a603f6ed78596666db1b59af6 + interceptor_http_client: + git: + url: https://github.com/foldland/cookie_store + path: packages/interceptor_http_client + ref: 4280ce0b73d1950a603f6ed78596666db1b59af6