Skip to content

Commit 2ae5510

Browse files
committed
feat(#16): Allow POST methods to be cached
1 parent 88ed14c commit 2ae5510

9 files changed

Lines changed: 60 additions & 17 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 2.3.0
2+
- feat: `allowPostMethod` added to `CacheOptions`.
3+
14
## 2.2.0
25
- feat: Cache-Control: max-age as cache trigger added.
36
- core: update README.md.

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
3434
// Global options
3535
final options = const CacheOptions(
3636
// A default store is required for interceptor.
37-
store: DbCacheStore(databasePath: 'a_path'),
37+
store: MemCacheStore(),
3838
// Default.
3939
policy: CachePolicy.request,
4040
// Optional. Returns a cached response on error but for statuses 401 & 403.
@@ -43,6 +43,13 @@ final options = const CacheOptions(
4343
maxStale: const Duration(days: 7),
4444
// Default. Allows 3 cache sets and ease cleanup.
4545
priority: CachePriority.normal,
46+
// Default. Body and headers encryption with your own algorithm.
47+
cipher: null,
48+
// Default. Key builder to retrieve requests.
49+
keyBuilder: CacheOptions.defaultCacheKeyBuilder,
50+
// Default. Allows to cache POST requests.
51+
// Overriding [keyBuilder] is strongly recommended.
52+
allowPostMethod: false,
4653
);
4754
4855
// Add cache interceptor with global/default options

example/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ buildscript {
55
}
66

77
dependencies {
8-
classpath 'com.android.tools.build:gradle:3.5.0'
8+
classpath 'com.android.tools.build:gradle:4.1.3'
99
}
1010
}
1111

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#Sat Jun 27 10:47:21 CEST 2020
1+
#Sat Apr 24 18:07:04 CEST 2021
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

lib/src/dio_cache_interceptor.dart

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'util/response_extension.dart';
1414
/// Cache interceptor
1515
class DioCacheInterceptor extends Interceptor {
1616
static const String _getMethodName = 'GET';
17+
static const String _postMethodName = 'POST';
1718

1819
final CacheOptions _options;
1920
final CacheStore _store;
@@ -28,13 +29,13 @@ class DioCacheInterceptor extends Interceptor {
2829
RequestOptions request,
2930
RequestInterceptorHandler handler,
3031
) async {
31-
if (_shouldSkipRequest(request)) {
32+
final options = _getCacheOptions(request);
33+
34+
if (_shouldSkipRequest(request, options: options)) {
3235
handler.next(request);
3336
return;
3437
}
3538

36-
final options = _getCacheOptions(request);
37-
3839
if (options.policy != CachePolicy.refresh &&
3940
options.policy != CachePolicy.refreshForceCache) {
4041
final cacheResp = await _getCacheResponse(request);
@@ -57,13 +58,14 @@ class DioCacheInterceptor extends Interceptor {
5758
Response response,
5859
ResponseInterceptorHandler handler,
5960
) async {
60-
if (_shouldSkipRequest(response.requestOptions) ||
61+
final options = _getCacheOptions(response.requestOptions);
62+
63+
if (_shouldSkipRequest(response.requestOptions, options: options) ||
6164
response.statusCode != 200) {
6265
handler.next(response);
6366
return;
6467
}
6568

66-
final options = _getCacheOptions(response.requestOptions);
6769
final policy = options.policy;
6870

6971
if (policy == CachePolicy.noCache) {
@@ -93,7 +95,9 @@ class DioCacheInterceptor extends Interceptor {
9395
DioError err,
9496
ErrorInterceptorHandler handler,
9597
) async {
96-
if (_shouldSkipRequest(err.requestOptions, error: err)) {
98+
final options = _getCacheOptions(err.requestOptions);
99+
100+
if (_shouldSkipRequest(err.requestOptions, options: options, error: err)) {
97101
handler.next(err);
98102
return;
99103
}
@@ -105,7 +109,6 @@ class DioCacheInterceptor extends Interceptor {
105109
returnResponse = true;
106110
} else {
107111
// Check if we can return cache
108-
final options = _getCacheOptions(err.requestOptions);
109112
final hcoeExcept = options.hitCacheOnErrorExcept;
110113

111114
if (hcoeExcept != null) {
@@ -184,9 +187,19 @@ class DioCacheInterceptor extends Interceptor {
184187
return options.store ?? _store;
185188
}
186189

187-
bool _shouldSkipRequest(RequestOptions? request, {DioError? error}) {
188-
var result = error?.type == DioErrorType.cancel;
189-
result |= (request?.method.toUpperCase() != _getMethodName);
190+
bool _shouldSkipRequest(
191+
RequestOptions? request, {
192+
required CacheOptions options,
193+
DioError? error,
194+
}) {
195+
if (error?.type == DioErrorType.cancel) {
196+
return true;
197+
}
198+
199+
final rqMethod = request?.method.toUpperCase();
200+
var result = (rqMethod != _getMethodName);
201+
result &= (!options.allowPostMethod || rqMethod != _postMethodName);
202+
190203
return result;
191204
}
192205

lib/src/model/cache_options.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ class CacheOptions {
7171
/// Optional method to decrypt/encrypt cache content
7272
final CacheCipher? cipher;
7373

74+
/// allow POST method request to be cached.
75+
final bool allowPostMethod;
76+
7477
// Key to retrieve options from request
7578
static const _extraKey = '@cache_options@';
7679

@@ -84,6 +87,7 @@ class CacheOptions {
8487
this.maxStale,
8588
this.priority = CachePriority.normal,
8689
this.cipher,
90+
this.allowPostMethod = false,
8791
required this.store,
8892
});
8993

@@ -111,6 +115,7 @@ class CacheOptions {
111115
CachePriority? priority,
112116
CacheStore? store,
113117
CacheCipher? cipher,
118+
bool? allowPostMethod,
114119
}) {
115120
return CacheOptions(
116121
policy: policy ?? this.policy,
@@ -121,6 +126,7 @@ class CacheOptions {
121126
priority: priority ?? this.priority,
122127
store: store ?? this.store,
123128
cipher: cipher ?? this.cipher,
129+
allowPostMethod: allowPostMethod ?? this.allowPostMethod,
124130
);
125131
}
126132
}

pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: Dio HTTP cache interceptor with multiple stores respecting HTTP dir
33
repository: https://github.com/llfbandit/dio_cache_interceptor
44
issue_tracker: https://github.com/llfbandit/dio_cache_interceptor/issues
55

6-
version: 2.2.0
6+
version: 2.3.0
77

88
environment:
99
sdk: ">=2.12.0 <3.0.0"
@@ -24,7 +24,7 @@ dev_dependencies:
2424
# https://pub.dev/packages/moor_generator
2525
moor_generator: ^4.2.1
2626
# https://pub.dev/packages/build_runner
27-
build_runner: ^1.12.2
27+
build_runner: ^2.0.1
2828
# https://pub.dev/packages/pedantic
2929
pedantic: ^1.11.0
3030
# https://pub.dev/packages/sqlite3

test/cache_interceptor_test.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,19 @@ void main() {
157157
expect(resp.extra[CacheResponse.cacheKey], isNull);
158158
});
159159

160+
test('Fetch post doesn\'t skip request', () async {
161+
final resp = await _dio.post(
162+
'${MockHttpClientAdapter.mockBase}/post',
163+
options: Options(
164+
extra: options.copyWith(allowPostMethod: true).toExtra(),
165+
),
166+
);
167+
168+
expect(resp.statusCode, equals(200));
169+
expect(resp.data['path'], equals('/post'));
170+
expect(resp.extra[CacheResponse.cacheKey], isNotNull);
171+
});
172+
160173
test('Fetch hitCacheOnErrorExcept 500', () async {
161174
final resp = await _dio.get('${MockHttpClientAdapter.mockBase}/ok');
162175
final cacheKey = resp.extra[CacheResponse.cacheKey];

test/mock_httpclient_adapter.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ class MockHttpClientAdapter extends HttpClientAdapter {
6262
jsonEncode({'path': uri.path}),
6363
200,
6464
headers: {
65-
Headers.contentTypeHeader: [Headers.jsonContentType]
65+
Headers.contentTypeHeader: [Headers.jsonContentType],
66+
'etag': ['1234'],
6667
},
6768
);
6869
case '/exception':

0 commit comments

Comments
 (0)