Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Sohn2019-07-02 23:07:14 +0000
committerMatthias Sohn2019-07-18 01:27:52 +0000
commit95e8264cc8d2689cec10b58fbf15149856000df4 (patch)
tree02c5e1673058615c71778b436fd50855b96aed0f /org.eclipse.jgit.http.server
parent4db39f50742706091ee66207526cc801db40b780 (diff)
downloadjgit-95e8264cc8d2689cec10b58fbf15149856000df4.tar.gz
jgit-95e8264cc8d2689cec10b58fbf15149856000df4.tar.xz
jgit-95e8264cc8d2689cec10b58fbf15149856000df4.zip
Use Instant instead of milliseconds for filesystem timestamp handling
This enables higher file timestamp resolution on filesystems like ext4, Mac APFS (1ns) or NTFS (100ns) providing high timestamp resolution on filesystem level. Note: - on some OSes Java 8,9 truncate milliseconds, see https://bugs.openjdk.java.net/browse/JDK-8177809, fixed in Java 10 - UnixFileAttributes truncates timestamp resolution to microseconds when converting the internal representation to FileTime exposed in the API, see https://bugs.openjdk.java.net/browse/JDK-8181493 - WindowsFileAttributes also provides only microsecond resolution Change-Id: I25ffff31a3c6f725fc345d4ddc2f26da3b88f6f2 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Diffstat (limited to 'org.eclipse.jgit.http.server')
-rw-r--r--org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/FileSender.java8
-rw-r--r--org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java9
2 files changed, 12 insertions, 5 deletions
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/FileSender.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/FileSender.java
index 05510a05b0..946fb15a3d 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/FileSender.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/FileSender.java
@@ -58,12 +58,14 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.text.MessageFormat;
+import java.time.Instant;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.util.FS;
/**
* Dumps a file over HTTP GET (or its information via HEAD).
@@ -76,7 +78,7 @@ final class FileSender {
private final RandomAccessFile source;
- private final long lastModified;
+ private final Instant lastModified;
private final long fileLen;
@@ -89,7 +91,7 @@ final class FileSender {
this.source = new RandomAccessFile(path, "r");
try {
- this.lastModified = path.lastModified();
+ this.lastModified = FS.DETECTED.lastModifiedInstant(path);
this.fileLen = source.getChannel().size();
this.end = fileLen;
} catch (IOException e) {
@@ -114,7 +116,7 @@ final class FileSender {
}
}
- long getLastModified() {
+ Instant getLastModified() {
return lastModified;
}
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java
index 62f075c73c..5a27be6430 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java
@@ -54,6 +54,7 @@ import static org.eclipse.jgit.util.HttpSupport.HDR_LAST_MODIFIED;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.time.Instant;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -76,7 +77,9 @@ abstract class ObjectFileServlet extends HttpServlet {
@Override
String etag(FileSender sender) throws IOException {
- return Long.toHexString(sender.getLastModified());
+ Instant lastModified = sender.getLastModified();
+ return Long.toHexString(lastModified.getEpochSecond())
+ + Long.toHexString(lastModified.getNano());
}
}
@@ -145,7 +148,9 @@ abstract class ObjectFileServlet extends HttpServlet {
try {
final String etag = etag(sender);
- final long lastModified = (sender.getLastModified() / 1000) * 1000;
+ // HTTP header Last-Modified header has a resolution of 1 sec, see
+ // https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.29
+ final long lastModified = sender.getLastModified().getEpochSecond();
String ifNoneMatch = req.getHeader(HDR_IF_NONE_MATCH);
if (etag != null && etag.equals(ifNoneMatch)) {

Back to the top