Ignore:
Timestamp:
2018-05-12T14:16:32+02:00 (18 months ago)
Author:
wiktorn
Message:

Fix caching long filenames and expiration

  • when long name is passed to CachedFile it will be truncated and some part will be substituted with hash of the filename
  • fix expiration time calculation where we were using seconds when miliseconds were expected

See: #16249

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/CachedFile.java

    r13728 r13731  
    1010import java.io.IOException;
    1111import java.io.InputStream;
     12import java.math.BigInteger;
    1213import java.net.HttpURLConnection;
    1314import java.net.MalformedURLException;
     
    1617import java.nio.file.Files;
    1718import java.nio.file.StandardCopyOption;
     19import java.security.MessageDigest;
     20import java.security.NoSuchAlgorithmException;
    1821import java.util.ArrayList;
    1922import java.util.Arrays;
     
    439442            urlStr = urlStr.replaceAll("%<(.*)>", "");
    440443        long age = 0L;
    441         long maxAgeMillis = maxAge;
     444        long maxAgeMillis = TimeUnit.SECONDS.toMillis(maxAge);
    442445        Long ifModifiedSince = null;
    443446        File localFile = null;
     
    497500        String a = urlStr.replaceAll("[^A-Za-z0-9_.-]", "_");
    498501        String localPath = "mirror_" + a;
     502        localPath = truncatePath(destDir, localPath);
    499503        destDirFile = new File(destDir, localPath + ".tmp");
    500504        try {
     
    546550    }
    547551
     552    private static String truncatePath(String directory, String fileName) {
     553        String ret = fileName;
     554        if (directory.length() + fileName.length() > 255) {
     555            // Windows doesn't support paths longer than 260, leave 5 chars as safe buffer, 4 will be used by ".tmp"
     556            // TODO: what about filename size on other systems? 255?
     557            if (directory.length() > 191 && Main.isPlatformWindows()) {
     558                // digest length + name prefix == 64
     559                // 255 - 64 = 191
     560                // TODO: use this check only on Windows?
     561                throw new IllegalArgumentException("Path " + directory + " too long to cached files");
     562            }
     563
     564            MessageDigest md;
     565            try {
     566                md = MessageDigest.getInstance("SHA-256");
     567                md.update(fileName.getBytes(StandardCharsets.UTF_8));
     568                String digest = String.format("%064x", new BigInteger(1, md.digest()));
     569                return fileName.substring(0, Math.min(fileName.length(), 32)) + digest.substring(0, 32);
     570            } catch (NoSuchAlgorithmException e) {
     571                Logging.error(e);
     572                // TODO: what better can we do here?
     573                throw new IllegalArgumentException("Missing digest algorithm SHA-256", e);
     574            }
     575        }
     576        return fileName;
     577    }
     578
    548579    /**
    549580     * Attempts to disconnect an URL connection.
Note: See TracChangeset for help on using the changeset viewer.