Skip to content

Commit d950525

Browse files
authored
Change *FileMappedHttpContent to delegate last modified to wrapped resource (#13889)
#13850 change *FileMappedHttpContent to delegate last modified to wrapped resource Signed-off-by: Ludovic Orban <[email protected]>
1 parent 82f11fd commit d950525

File tree

4 files changed

+42
-34
lines changed

4 files changed

+42
-34
lines changed

jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/FileMappingHttpContentFactory.java

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import java.io.IOException;
1717
import java.nio.ByteBuffer;
1818
import java.nio.file.Path;
19-
import java.time.Instant;
2019
import java.util.Objects;
2120

2221
import org.eclipse.jetty.http.HttpField;
@@ -93,8 +92,6 @@ private static class SingleBufferFileMappedHttpContent extends HttpContent.Wrapp
9392
{
9493
private final ByteBuffer _buffer;
9594
private final HttpField _contentLength;
96-
private final HttpField _lastModified;
97-
private final Instant _lastModifiedInstant;
9895

9996
private SingleBufferFileMappedHttpContent(HttpContent content) throws IOException
10097
{
@@ -106,16 +103,14 @@ private SingleBufferFileMappedHttpContent(HttpContent content) throws IOExceptio
106103
if (_buffer == null)
107104
throw new IOException("Cannot memory map Content (not supported by underlying FileSystem): " + content.getResource());
108105
_contentLength = new HttpField(HttpHeader.CONTENT_LENGTH, Integer.toString(_buffer.remaining()));
109-
_lastModified = content.getLastModified();
110-
_lastModifiedInstant = content.getLastModifiedInstant();
111106
}
112107

113108
@Override
114109
public void writeTo(Content.Sink sink, long offset, long length, Callback callback)
115110
{
116111
try
117112
{
118-
sink.write(true, BufferUtil.slice(_buffer, (int)offset, (int)length), callback);
113+
sink.write(true, BufferUtil.slice(_buffer, Math.toIntExact(offset), Math.toIntExact(length)), callback);
119114
}
120115
catch (Throwable x)
121116
{
@@ -134,18 +129,6 @@ public long getContentLengthValue()
134129
{
135130
return _buffer.remaining();
136131
}
137-
138-
@Override
139-
public Instant getLastModifiedInstant()
140-
{
141-
return _lastModifiedInstant;
142-
}
143-
144-
@Override
145-
public HttpField getLastModified()
146-
{
147-
return _lastModified;
148-
}
149132
}
150133

151134
private static class MultiBufferFileMappedHttpContent extends HttpContent.Wrapper
@@ -154,8 +137,6 @@ private static class MultiBufferFileMappedHttpContent extends HttpContent.Wrappe
154137
private final int maxBufferSize;
155138
private final HttpField _contentLength;
156139
private final long _contentLengthValue;
157-
private final HttpField _lastModified;
158-
private final Instant _lastModifiedInstant;
159140

160141
private MultiBufferFileMappedHttpContent(HttpContent content, int maxBufferSize) throws IOException
161142
{
@@ -187,8 +168,6 @@ private MultiBufferFileMappedHttpContent(HttpContent content, int maxBufferSize)
187168
}
188169
_contentLengthValue = total;
189170
_contentLength = new HttpField(HttpHeader.CONTENT_LENGTH, Long.toString(total));
190-
_lastModified = content.getLastModified();
191-
_lastModifiedInstant = content.getLastModifiedInstant();
192171
}
193172

194173
@Override
@@ -260,17 +239,5 @@ public long getContentLengthValue()
260239
{
261240
return _contentLengthValue;
262241
}
263-
264-
@Override
265-
public Instant getLastModifiedInstant()
266-
{
267-
return _lastModifiedInstant;
268-
}
269-
270-
@Override
271-
public HttpField getLastModified()
272-
{
273-
return _lastModified;
274-
}
275242
}
276243
}

jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/HttpContent.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public interface HttpContent
9090

9191
/**
9292
* Get the last modified instant of this resource.
93+
* Always return the most up-to-date value.
9394
*
9495
* @return the last modified instant, or null if that instant of this content is not known.
9596
* @see #getLastModified()

jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/ValidatingCachingHttpContentFactory.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
* a positive value indicates the number of milliseconds of the minimum time between validation checks.
3939
* </p>
4040
* <p>
41+
* When the wrapped {@link HttpContent}'s {@link HttpContent#getLastModifiedInstant() last modification time} did not change,
42+
* it is considered that the resource did not change too and is therefore not refreshed.
43+
* </p>
44+
* <p>
4145
* This also remember a missed entry for the time set by {@code validationTime}ms. After this has
4246
* elapsed the entry will be invalid and will be evicted from the cache at the next access.
4347
* </p>

jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/content/FileMappingHttpContentFactoryTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import java.nio.file.Files;
2121
import java.nio.file.Path;
2222
import java.nio.file.StandardOpenOption;
23+
import java.nio.file.attribute.FileTime;
24+
import java.time.Instant;
2325

2426
import org.eclipse.jetty.http.MimeTypes;
2527
import org.eclipse.jetty.io.ByteBufferPool;
@@ -37,13 +39,47 @@
3739

3840
import static org.hamcrest.MatcherAssert.assertThat;
3941
import static org.hamcrest.Matchers.is;
42+
import static org.hamcrest.Matchers.lessThan;
4043
import static org.junit.jupiter.api.Assertions.assertThrows;
4144

4245
@ExtendWith(WorkDirExtension.class)
4346
public class FileMappingHttpContentFactoryTest
4447
{
4548
public WorkDir workDir;
4649

50+
@Test
51+
public void testSingleBufferFileMappedLastModified() throws Exception
52+
{
53+
Path file = Files.writeString(workDir.getEmptyPathDir().resolve("file.txt"), "0123456789abcdefghijABCDEFGHIJ");
54+
FileMappingHttpContentFactory fileMappingHttpContentFactory = new FileMappingHttpContentFactory(
55+
new ResourceHttpContentFactory(ResourceFactory.root().newResource(file.getParent()), MimeTypes.DEFAULTS, ByteBufferPool.SIZED_NON_POOLING));
56+
57+
HttpContent content = fileMappingHttpContentFactory.getContent("file.txt");
58+
Instant originalLastModifiedInstant = content.getLastModifiedInstant();
59+
60+
// Set the file's last modified time to 10s into the future.
61+
Files.setLastModifiedTime(file, FileTime.from(Instant.now().plusSeconds(10)));
62+
63+
assertThat(originalLastModifiedInstant, lessThan(content.getLastModifiedInstant()));
64+
}
65+
66+
@Test
67+
public void testMultiBufferFileMappedLastModified() throws Exception
68+
{
69+
Path file = Files.writeString(workDir.getEmptyPathDir().resolve("file.txt"), "0123456789abcdefghijABCDEFGHIJ");
70+
FileMappingHttpContentFactory fileMappingHttpContentFactory = new FileMappingHttpContentFactory(
71+
new ResourceHttpContentFactory(ResourceFactory.root().newResource(file.getParent()), MimeTypes.DEFAULTS, ByteBufferPool.SIZED_NON_POOLING),
72+
0, 10);
73+
74+
HttpContent content = fileMappingHttpContentFactory.getContent("file.txt");
75+
Instant originalLastModifiedInstant = content.getLastModifiedInstant();
76+
77+
// Set the file's last modified time to 10s into the future.
78+
Files.setLastModifiedTime(file, FileTime.from(Instant.now().plusSeconds(10)));
79+
80+
assertThat(originalLastModifiedInstant, lessThan(content.getLastModifiedInstant()));
81+
}
82+
4783
@Test
4884
public void testMultiBufferFileMappedOffsetAndLength() throws Exception
4985
{

0 commit comments

Comments
 (0)