Changeset 17505 in josm


Ignore:
Timestamp:
2021-02-21T13:23:35+01:00 (10 days ago)
Author:
wiktorn
Message:

Do not cache responses, that are not images.

When server returns content type and it's not an image, then do not put it into
cache and try to extract error message from response.

That way, errors will not be stored in on-disk cache and hopefully they will be
retried when user browses again to the same area (modulo MemoryTileCache).

See: #20443

Location:
trunk/src/org/openstreetmap/josm/data
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java

    r16913 r17505  
    77import java.net.URL;
    88import java.security.SecureRandom;
     9import java.util.Collections;
    910import java.util.List;
    1011import java.util.Map;
     
    187188     * Simple implementation. All errors should be cached as empty. Though some JDK (JDK8 on Windows for example)
    188189     * doesn't return 4xx error codes, instead they do throw an FileNotFoundException or IOException
     190     * @param responseCode
     191     * @param headerFields
    189192     *
    190193     * @return true if we should put empty object into cache, regardless of what remote resource has returned
    191194     */
    192     protected boolean cacheAsEmpty() {
     195    protected boolean cacheAsEmpty(Map<String, List<String>> headerFields, int responseCode) {
    193196        return attributes.getResponseCode() < 500;
    194197    }
     
    371374                            getCacheKey(), raw.length, getUrl());
    372375                    return true;
    373                 } else if (cacheAsEmpty()) {
     376                } else if (cacheAsEmpty(urlConn.getHeaderFields(), urlConn.getResponseCode())) {
    374377                    cacheData = createCacheEntry(new byte[]{});
    375378                    cache.put(getCacheKey(), cacheData, attributes);
     
    386389            attributes.setError(e);
    387390            attributes.setException(e);
    388             boolean doCache = isResponseLoadable(null, 404, null) || cacheAsEmpty();
     391            boolean doCache = isResponseLoadable(null, 404, null) || cacheAsEmpty(Collections.emptyMap(), 404);
    389392            if (doCache) {
    390393                cacheData = createCacheEntry(new byte[]{});
  • trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java

    r16692 r17505  
    135135            return false; // do no try to load data from no-tile at zoom, cache empty object instead
    136136        }
     137        if (isNotImage(headers, statusCode)) {
     138            String message = detectErrorMessage( new String(content, StandardCharsets.UTF_8));
     139            if (message != null && !message.isEmpty()) {
     140                tile.setError(message);
     141            }
     142            return false;
     143        }
    137144        return super.isResponseLoadable(headers, statusCode, content);
    138145    }
    139146
    140     @Override
    141     protected boolean cacheAsEmpty() {
    142         return isNoTileAtZoom() || super.cacheAsEmpty();
     147    private boolean isNotImage(Map<String, List<String>> headers, int statusCode) {
     148        if (statusCode == 200 && headers.containsKey("Content-Type") && !headers.get("Content-Type").isEmpty()) {
     149            String contentType = headers.get("Content-Type").stream().findAny().get();
     150            if (contentType !=null && !contentType.startsWith("image")) {
     151                Logging.warn("Image not returned for tile: " + url + " content type was: " + contentType);
     152                // not an image - do not store response in cache, so next time it will be queried again from the server
     153                return true;
     154            }
     155        }
     156        return false;
     157    }
     158
     159    @Override
     160    protected boolean cacheAsEmpty(Map<String, List<String>> headerFields, int responseCode) {
     161        if (isNotImage(headerFields, responseCode)) {
     162            return false;
     163        }
     164        return isNoTileAtZoom() || super.cacheAsEmpty(headerFields, responseCode);
    143165    }
    144166
     
    211233
    212234    private void handleError(CacheEntryAttributes attributes) {
     235        if (tile.hasError() && tile.getErrorMessage() != null) {
     236            // tile has already set error message, don't overwrite it
     237            return;
     238        }
    213239        if (attributes != null) {
    214240            int httpStatusCode = attributes.getResponseCode();
Note: See TracChangeset for help on using the changeset viewer.