llfbandit / dio_cache_interceptor

Dio HTTP cache interceptor with multiple stores respecting HTTP directives (ETag, Last-Modified, Cache-Control) with options.
https://pub.dev/packages/dio_cache_interceptor
120 stars 70 forks source link

Exception thrown when no-cache directive has arguments #158

Open kmueller-gis opened 4 months ago

kmueller-gis commented 4 months ago

I am seeing an issue where a server response has cache-control: no-cache="set-cookie" as one of the headers. The double-quotes fail the token regular expression match used in DioCacheInterceptor resulting in a thrown exception.

Error on line 1, column 10: expected /[^()<>@,;:"\\/[\]?={} \t\x00-\x1F\x7F]+/.
  ╷
1 │ no-cache="Set-Cookie"
  │          ^
  ╵
package:string_scanner/src/string_scanner.dart 263:5                     StringScanner.error
package:string_scanner/src/string_scanner.dart 270:5                     StringScanner._fail
package:string_scanner/src/string_scanner.dart 212:5                     StringScanner.expect
package:dio_cache_interceptor/src/model/cache_control.dart 82:19         new CacheControl.fromHeader.parseHeaderValue
package:dio_cache_interceptor/src/model/cache_control.dart 105:9         new CacheControl.fromHeader
package:dio_cache_interceptor/src/model/cache_strategy.dart 108:40       CacheStrategyFactory._isCacheable
package:dio_cache_interceptor/src/model/cache_strategy.dart 58:41        CacheStrategyFactory.compute
package:dio_cache_interceptor/src/dio_cache_interceptor.dart 220:7       DioCacheInterceptor._saveResponse
package:dio_cache_interceptor/src/dio_cache_interceptor.dart 102:11      DioCacheInterceptor.onResponse
package:dio/src/dio_mixin.dart 409:17                                    DioMixin.fetch.responseInterceptorWrapper.<fn>.<fn>
...

I understand that DioCacheInterceptor does not process the additional attributes, but the interceptor is failing on legal syntax as described in RFC 2616 Section 14.9 and RFC 9111 Section 5.2.2.4

This unit test will trigger the issue:

    test('HTTP GET with qualified cache-control no-cache directive', () async {
      final testHttpServer = await HttpServer.bind(InternetAddress.anyIPv6, 0);
      testHttpServer.listen((request) {
        // Set header that causes crash in DioCacheInterceptor
        request.response.headers.add('cache-control', 'no-cache="Set-Cookie"');
        request.response.write('Hello test!');
        request.response.close();
      });

      final uriStr = 'http://localhost:${testHttpServer.port}';

      // The error happens in this call
      final responseInfo = await MyHttpClient.get(Uri.parse(uriStr));

      expect(responseInfo.statusCode, 200);
    });

In the test, MyHttpClient is an HTTP client that uses the DioCacheInterceptor to handle caching.

llfbandit commented 4 months ago

Thanks for the report