Changeset 31052 in osm for applications/viewer/jmapviewer


Ignore:
Timestamp:
2015-03-06T02:27:00+01:00 (9 years ago)
Author:
bastik
Message:

applied #11193 - Honor Expires/Cache-Control in OsmFileCacheTileLoader (patch by anonymous)

Location:
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmFileCacheTileLoader.java

    r30900 r31052  
    4949    private static final Charset TAGS_CHARSET = Charset.forName("UTF-8");
    5050
    51     public static final long FILE_AGE_ONE_DAY = 1000 * 60 * 60 * 24;
    52     public static final long FILE_AGE_ONE_WEEK = FILE_AGE_ONE_DAY * 7;
     51    private static final long DEFAULT_EXPIRES_TIME = 1000 * 60 * 60 * 24 * 7;
     52
    5353
    5454    protected String cacheDirBase;
     
    5757
    5858    protected long maxCacheFileAge = Long.MAX_VALUE;  // max. age not limited
    59     protected long recheckAfter = FILE_AGE_ONE_WEEK;
    6059
    6160    public static File getDefaultCacheDir() throws SecurityException {
     
    6766            log.log(Level.WARNING,
    6867                    "Failed to access system property ''java.io.tmpdir'' for security reasons. Exception was: "
    69                     + e.toString());
     68                        + e.toString());
    7069            throw e; // rethrow
    7170        }
     
    157156            tileCacheDir = getSourceCacheDir(tile.getSource());
    158157
    159             if (loadTileFromFile(recheckAfter)) {
     158            loadTagsFromFile();
     159
     160            if (isTileFileValid() && (isNoTileAtZoom() || loadTileFromFile())) {
    160161                log.log(Level.FINE, "TMS - found in tile cache: {0}", tile);
    161162                tile.setLoaded(true);
     
    163164                return;
    164165            }
     166
    165167            TileJob job = new TileJob() {
    166168
     
    172174                    } else {
    173175                        // failed to download - use old cache file if available
    174                         if (loadTileFromFile(maxCacheFileAge)) {
     176                        if (isNoTileAtZoom() || loadTileFromFile()) {
    175177                            tile.setLoaded(true);
    176178                            tile.error = false;
     
    243245                        break;
    244246                    }
    245                     if (loadTileFromFile(maxCacheFileAge)) {
    246                         tileFile.setLastModified(now);
    247                         return true;
    248                     }
     247                    loadTileFromFile();
     248                    tileFile.setLastModified(now);
     249                    return true;
    249250                }
    250251
     
    286287        }
    287288
    288         protected boolean loadTileFromFile(long maxAge) {
     289        protected boolean isTileFileValid() {
     290            Long expires = null;
    289291            try {
    290                 tileFile = getTileFile();
    291                 if (!tileFile.exists())
     292                expires = Long.parseLong(tile.getValue("expires"));
     293            } catch (NumberFormatException e) {}
     294
     295            if(expires != null && !expires.equals(0L)) {
     296                // check by expire date set by server
     297                if (now > expires) {
     298                    log.log(Level.FINE, "TMS - Tile has expired -> not valid {0}", tile);
    292299                    return false;
    293                 loadTagsFromFile();
    294 
    295                 fileMtime = tileFile.lastModified();
    296                 if (now - fileMtime > maxAge)
    297                     return false;
    298 
    299                 if ("no-tile".equals(tile.getValue("tile-info"))) {
    300                     tile.setError("No tile at this zoom level");
    301                     if (tileFile.exists()) {
    302                         tileFile.delete();
    303                     }
    304                     tileFile = null;
    305                 } else {
    306                     try (FileInputStream fin = new FileInputStream(tileFile)) {
    307                         if (fin.available() == 0)
    308                             throw new IOException("File empty");
    309                         tile.loadImage(fin);
    310                     }
    311                 }
     300                }
     301            } else {
     302                // check by file modification date
     303                if (tileFile.exists()) {
     304                    // check for modification date only when tile file exists
     305                    // so handle properly the case, when only tags file exists
     306                    fileMtime = tileFile.lastModified();
     307                    if (now - fileMtime > DEFAULT_EXPIRES_TIME) {
     308                        log.log(Level.FINE, "TMS - Tile has expired, maximum file age reached {0}", tile);
     309                        return false;
     310                    }
     311                }
     312            }
     313            return true;
     314        }
     315
     316        protected boolean isNoTileAtZoom() {
     317            if ("no-tile".equals(tile.getValue("tile-info"))) {
     318                // do not remove file - keep the information, that there is no tile, for further requests
     319                // the code above will check, if this information is still valid
     320                log.log(Level.FINE, "TMS - Tile valid, but no file, as no tiles at this level {0}", tile);
     321                tile.setError("No tile at this zoom level");
    312322                return true;
    313 
     323            }
     324            return false;
     325        }
     326
     327        protected boolean loadTileFromFile() {
     328            if (!tileFile.exists())
     329                return false;
     330
     331            try (FileInputStream fin = new FileInputStream(tileFile)) {
     332                if (fin.available() == 0)
     333                    throw new IOException("File empty");
     334                tile.loadImage(fin);
     335                return true;
    314336            } catch (Exception e) {
    315337                log.log(Level.WARNING, "TMS - Error while loading image from tile cache: {0}; {1}", new Object[]{e.getMessage(), tile});
    316338                tileFile.delete();
     339                File tileMetaData = getTagsFile();
     340                if (tileMetaData.exists())
     341                    tileMetaData.delete();
    317342                tileFile = null;
    318343                fileMtime = null;
     
    405430            File file = getTileFile();
    406431            file.getParentFile().mkdirs();
    407             try (
    408                 FileOutputStream f = new FileOutputStream(file)
    409             ) {
     432            try (FileOutputStream f = new FileOutputStream(file)) {
    410433                f.write(rawData);
    411434            } catch (Exception e) {
     
    430453        }
    431454
    432         protected void loadTagsFromFile() {
     455        protected boolean loadTagsFromFile() {
     456            tileFile = getTileFile();
    433457            File tagsFile = getTagsFile();
    434458            try (BufferedReader f = new BufferedReader(new InputStreamReader(new FileInputStream(tagsFile), TAGS_CHARSET))) {
     
    445469                System.err.println("Failed to load tile tags: " + e.getLocalizedMessage());
    446470            }
     471
     472            return true;
    447473        }
    448474    }
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java

    r30900 r31052  
    109109            tile.putValue("tile-info", str);
    110110        }
     111
     112        Long lng = urlConn.getExpiration();
     113        if (lng.equals(0L)) {
     114            try {
     115                str = urlConn.getHeaderField("Cache-Control");
     116                if (str != null) {
     117                    for (String token: str.split(",")) {
     118                        if (token.startsWith("max-age=")) {
     119                            lng = Math.min(
     120                                    Long.parseLong(token.substring(8)),
     121                                    86400 * 31 // cap max-age at one month
     122                                    ) * 1000 +
     123                                    System.currentTimeMillis();
     124                        }
     125                    }
     126                }
     127            } catch (NumberFormatException e) {} //ignore malformed Cache-Control headers
     128        }
     129        if (!lng.equals(0L)) {
     130            tile.putValue("expires", lng.toString());
     131        }
    111132    }
    112133
Note: See TracChangeset for help on using the changeset viewer.