diff --git a/client_cookie/lib/src/client_cookie_base.dart b/client_cookie/lib/src/client_cookie_base.dart index a32700d..b7fe143 100644 --- a/client_cookie/lib/src/client_cookie_base.dart +++ b/client_cookie/lib/src/client_cookie_base.dart @@ -59,7 +59,13 @@ class ClientCookie { } /// Parses one 'set-cookie' item - factory ClientCookie.fromSetCookie(String cookieItem) { + /// + /// Parameters: + /// - [enableExtendedDirectiveParsing] + /// When enabled and a directive is not recognized, the parser will try extended methods to find the right directive. These methods are: + /// - Comparing Case-insensitive + factory ClientCookie.fromSetCookie(String cookieItem, + {bool enableExtendedDirectiveParsing = true}) { final List parts = cookieItem.split(';').reversed.map((String str) => str.trim()).toList(); @@ -81,14 +87,25 @@ class ClientCookie { } for (String directive in parts) { - final List points = - directive.split('=').map((String str) => str.trim()).toList(); - if (points.length == 0 || points.length > 2) + final List points = directive // + .split('=') + .map((String str) => str.trim()) + .toList(); + + if (points.length == 0 || points.length > 2) { throw Exception('Invalid directive!'); - final String key = points.first; + } + + String key = points.first; final String val = points.length == 2 ? points.last : ''; if (!_parsers.containsKey(key)) { - throw _invalidDirective; + if (!enableExtendedDirectiveParsing) { + throw _invalidDirective; + } + key = _parsers.keys.firstWhere( + (e) => e.toLowerCase() == key.toLowerCase(), + orElse: () => throw _invalidDirective, + ); } map[key] = _parsers[key](val); } @@ -234,11 +251,19 @@ class ClientCookie { /// A store for Cookies class CookieStore { + /// Influences the parsing of the 'set-cookie' header. + /// + /// When enabled and a directive is not recognized, the parser will try extended methods to find the right directive. These methods are: + /// - Comparing Case-insensitive + bool enableExtendedDirectiveParsing; + /// The actual storeage Map cookieMap = {}; List get cookies => cookieMap.values.toList(); + CookieStore({this.enableExtendedDirectiveParsing = true}); + /// Returns a cookie by [name] /// /// Returns [null] if cookie with name is not present @@ -272,23 +297,41 @@ class CookieStore { for (String rem in removes) cookieMap.remove(rem); - return rets.join(', '); + return rets.join('; '); } /// Parses and adds all 'set-cookies' from [http.Response] to the Cookie store - void addFromResponse(http.Response resp) { + /// + /// Parameters: + /// - [enableExtendedDirectiveParsing] + /// When enabled and a directive is not recognized, the parser will try extended methods to find the right directive. These methods are: + /// - Comparing Case-insensitive + /// + /// overrides [CookieStore.enableExtendedDirectiveParsing] + void addFromResponse(http.Response resp, + {bool? enableExtendedDirectiveParsing}) { if (resp.headers.containsKey('set-cookie')) { addFromHeader(resp.headers['set-cookie']!); } } /// Parses and adds all 'set-cookies' from [http.Response] to the Cookie store - void addFromHeader(String? setCookieLine) { + /// + /// Parameters: + /// - [enableExtendedDirectiveParsing] + /// When enabled and a directive is not recognized, the parser will try extended methods to find the right directive. These methods are: + /// - Comparing Case-insensitive + /// + /// overrides [CookieStore.enableExtendedDirectiveParsing] + void addFromHeader(String? setCookieLine, + {bool? enableExtendedDirectiveParsing}) { if (setCookieLine == null || setCookieLine.isEmpty) { return; } - final map = parseSetCookie(setCookieLine); + final map = parseSetCookie(setCookieLine, + enableExtendedDirectiveParsing: enableExtendedDirectiveParsing ?? + this.enableExtendedDirectiveParsing); for (String name in map.keys) { final ClientCookie cookie = map[name]!; @@ -304,16 +347,25 @@ class CookieStore { String toString() => 'CookieStore($cookieMap)'; } -/// Parses and adds all 'set-cookies' from [http.Response] to the Cookiewqa parseSetCookie(String? setCookieLine) { +/// Parses and adds all 'set-cookies' from [http.Response] to the Cookie store +/// +/// Parameters: +/// - [enableExtendedDirectiveParsing] +/// When enabled and a directive is not recognized, the parser will try extended methods to find the right directive. These methods are: +/// - Comparing Case-insensitive +Map parseSetCookie(String? setCookieLine, + {bool enableExtendedDirectiveParsing = true}) { final cookieMap = {}; if (setCookieLine == null || setCookieLine.isEmpty) { return cookieMap; } - for (String itemStr in setCookieLine.split(',')) { - final cookie = ClientCookie.fromSetCookie(itemStr); + final cookieStrings = + setCookieLine.split(RegExp(r',(?=[A-Za-z0-9._-]+\s*=)')); + for (String itemStr in cookieStrings) { + final cookie = ClientCookie.fromSetCookie(itemStr, + enableExtendedDirectiveParsing: enableExtendedDirectiveParsing); cookieMap[cookie.name] = cookie; }