Comments (19)
As a kludgy workaround, you can use application and network interceptors to modify what gets evaluated for caching, and what gets sent on the wire.
But we should consider a proper cache key API. Or learn from browsers on transient params?
data class OriginalUrl(val url: HttpUrl)
val client = OkHttpClient.Builder().eventListener(object : EventListener() {
override fun cacheMiss(call: Call) {
println("cacheMiss ${call.request().url}")
}
override fun cacheHit(call: Call, response: Response) {
println("cacheHit ${call.request().url}")
}
override fun cacheConditionalHit(call: Call, cachedResponse: Response) {
println("cacheConditionalHit ${call.request().url}")
}
}).addInterceptor {
val request = it.request()
val url = request.url
// only strip the key param for caching, not other params
val newRequest = if (url.queryParameter("key") != null) {
request.newBuilder().tag<OriginalUrl>(OriginalUrl(url)).url(url.newBuilder().removeAllQueryParameters("key").build()).build()
} else {
request
}
it.proceed(newRequest).newBuilder().request(request).build()
}.addNetworkInterceptor {
val request = it.request()
val originalUrl = request.tag<OriginalUrl>()?.url
// if we modified the url for caching, send the real one
if (originalUrl != null) {
val networkRequest = request.newBuilder().url(originalUrl).build()
it.proceed(networkRequest).newBuilder().request(request).build()
} else {
it.proceed(request)
}
}.cache(Cache("/cache".toPath(), Long.MAX_VALUE, FakeFileSystem())).build()
// cache miss - first request
client.newCall(Request("https://httpbin.org/cache/3600?key=123".toHttpUrl())).execute().use {
println(it.body.string())
}
// cache hit - cached without key
client.newCall(Request("https://httpbin.org/cache/3600?key=345".toHttpUrl())).execute().use {
println(it.body.string())
}
// cache miss - another=123
client.newCall(Request("https://httpbin.org/cache/3600?another=123".toHttpUrl())).execute().use {
println(it.body.string())
}
// cache miss - another=345
client.newCall(Request("https://httpbin.org/cache/3600?another=345".toHttpUrl())).execute().use {
println(it.body.string())
}
from okhttp.
Iām glad this issue was reported before we proceeded on #8113.
Iām tempted to do a cacheKey: ByteString
parameter on the Request
itself: if specified, we hash that instead of the request URL. We could even cache POST requests that have a cache key.
from okhttp.
Can you link to how browsers remove the transient params?
from okhttp.
Can you link to how browsers remove the transient params?
See ignoreSearch
in Cache.match()
:
https://developer.mozilla.org/en-US/docs/Web/API/Cache/match#ignoresearch
from okhttp.
As a kludgy workaround, you can use application and network interceptors to modify what gets evaluated for caching, and what gets sent on the wire.
Thank you for the suggestion. I'll see if I can make it work.
from okhttp.
That Cache seems like a specific web workers thing, slightly detached from fetch.
https://developer.mozilla.org/en-US/docs/Web/API/Cache
So not sure we want to make our Cache the same thing. And it doesn't seem like it applies to the fetch API calls.
But still worth working out how to support
from okhttp.
That Cache seems like a specific web workers thing, slightly detached from fetch.
https://developer.mozilla.org/en-US/docs/Web/API/Cache
So not sure we want to make our Cache the same thing. And it doesn't seem like it applies to the fetch API calls.
But still worth working out how to support
Here is an example how ignoreSearch
is used to check cache while executing HTTP GET (an event is sent to the service worker, service worker looks up cached response first):
self.addEventListener('fetch', event => {
if (event.request.method != 'GET') {
return;
}
event.respondWith((async _ => {
// Try to find the response in the cache.
const cache = await caches.open(PACKAGE_VERSION);
const reqUrl = new URL(event.request.url);
// Using ignoreSearch=true to read cached images and docs despite different auth signatures.
const cachedResponse = await cache.match(event.request, {ignoreSearch: (self.location.origin == reqUrl.origin)});
if (cachedResponse) {
return cachedResponse;
}
// Not found in cache.
const response = await fetch(event.request);
if (!response || response.status != 200 || response.type != 'basic') {
return response;
}
if (reqUrl.protocol == 'http:' || reqUrl.protocol == 'https:') {
await cache.put(event.request, response.clone());
}
return response;
})());
});
from okhttp.
Yep, understood.
It's not a HTTP cache (honouring cache headers)
It's a specific web worker cache for Request/Response.
Might be interesting to allow for a cache only request without going through with a call.
from okhttp.
I'm going to close, I don't think we can copy the WebWorker Cache, and there is an ugly workaround.
from okhttp.
I'm going to close, I don't think we can copy the WebWorker Cache, and there is an ugly workaround.
Is there a plan to address it in any ("right") way or no plan at all? I need to make the decision to keep Picasso (which relies on okhttp cache) or switch to Glide. If there is no plan then I have to byte the bullet and switch.
Thanks.
from okhttp.
The fix in okhttp could be trivially simple. Make class Cache
open and make key
method not static.
from okhttp.
We have a similar requirement for a cache key for DoH DNS caching. #8113
So maybe as part of that.
This might be some optional tag for a cache key if it's not just POST.
from okhttp.
We have a similar requirement for a cache key for DoH DNS caching. #8113
So maybe as part of that.
@swankjesse any thoughts?
from okhttp.
Yes, looks similar. The simplest solution would be to allow users to provide a custom implementation of the Cache.key()
.
from okhttp.
Similar requests #1605
from okhttp.
I'll reopen for further discussion
from okhttp.
BTW, #8113 would likely require passing the entire Request
to Cache.key
which I guess should not be a problem.
from okhttp.
BTW, #8113 would likely require passing the entire
Request
toCache.key
which I guess should not be a problem.
It's unlikely we would open up Cache for subclassing, we are very careful about new public API surface. So more likely some way to specify the cache key for a request.
from okhttp.
Yep, let's do it.
Does the override on otherwise non cacheable requests affect just the initial cache search, or also update the cache if a miss? or stays uncacheable?
from okhttp.
Related Issues (20)
- Unable to parse TLS packet header exception when using specific socks5 proxys HOT 1
- Potential failure on CallServerInterceptor if writeRequestHeader fails HOT 1
- Virtual thread pinning with 5.0.0-alpha.12 HOT 6
- Websocket connection failing few seconds after getting connected HOT 1
- How to cleanly pin a network HOT 1
- Dependency convergence issue with kotlin-stdlib-jdk8 (via okio) HOT 8
- Documentation: Is it possible to update the comment with more info HOT 1
- Check Cache headers against spec
- IllegalStateException: closed : HttpLoggingInterceptor.kt:248 HOT 1
- MockWebServer Dispatcher bug HOT 1
- Multiple async request do not store anything to cache HOT 1
- Add a means to reset Postponed Routes HOT 3
- Lets changes our OkHttp 5 async DNS APIs HOT 3
- Test MockWebServer with Loom
- Review tests failing on windows HOT 1
- The request body data added in the NetworkInterceptor was found not included in the capture by Charles. HOT 1
- The request body data added in the NetworkInterceptor was found not included in the capture by Charles
- Gzip/Deflate/Bortli not workin okhttp3 4.12.0/5.0.0-alpha12 HOT 5
- DiskLruCache entry?.currentEditor is allways not null for async requests HOT 1
- Documentation: Clearly state that OkHttpClient should be a singleton HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
š Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ššš
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ā¤ļø Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from okhttp.