#9078 make HttpContent.getByteBuffer() implementations return new ByteBuffer instances and document that contract
Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
parent
8d6734cf78
commit
177bafbace
|
@ -381,7 +381,7 @@ public class CachingHttpContentFactory implements HttpContent.Factory
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer getByteBuffer()
|
public ByteBuffer getByteBuffer()
|
||||||
{
|
{
|
||||||
return _buffer;
|
return _buffer == null ? null : _buffer.asReadOnlyBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -86,13 +86,13 @@ public class FileMappingHttpContentFactory implements HttpContent.Factory
|
||||||
{
|
{
|
||||||
ByteBuffer buffer = _buffer;
|
ByteBuffer buffer = _buffer;
|
||||||
if (buffer != null)
|
if (buffer != null)
|
||||||
return (buffer == SENTINEL_BUFFER) ? super.getByteBuffer() : buffer;
|
return (buffer == SENTINEL_BUFFER) ? super.getByteBuffer() : buffer.asReadOnlyBuffer();
|
||||||
|
|
||||||
try (AutoLock lock = _lock.lock())
|
try (AutoLock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
if (_buffer == null)
|
if (_buffer == null)
|
||||||
_buffer = getMappedByteBuffer();
|
_buffer = getMappedByteBuffer();
|
||||||
return (_buffer == SENTINEL_BUFFER) ? super.getByteBuffer() : _buffer;
|
return (_buffer == SENTINEL_BUFFER) ? super.getByteBuffer() : _buffer.asReadOnlyBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,12 @@ public interface HttpContent
|
||||||
|
|
||||||
Resource getResource();
|
Resource getResource();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Get this HTTP content as a {@link ByteBuffer} if possible.</p>
|
||||||
|
* <p>Each invocation returns a new {@link ByteBuffer} instance that is
|
||||||
|
* read-only and contains valid data between the pos and the limit.</p>
|
||||||
|
* @return a {@link ByteBuffer} instance or null.
|
||||||
|
*/
|
||||||
ByteBuffer getByteBuffer();
|
ByteBuffer getByteBuffer();
|
||||||
|
|
||||||
default long getBytesOccupied()
|
default long getBytesOccupied()
|
||||||
|
|
|
@ -641,7 +641,7 @@ public class ResourceService
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ByteBuffer buffer = content.getByteBuffer();
|
ByteBuffer buffer = content.getByteBuffer(); // this buffer is going to be consumed by response.write()
|
||||||
if (buffer != null)
|
if (buffer != null)
|
||||||
response.write(true, buffer, callback);
|
response.write(true, buffer, callback);
|
||||||
else
|
else
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under the
|
||||||
|
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||||
|
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
package org.eclipse.jetty.ee10.webapp;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpTester;
|
||||||
|
import org.eclipse.jetty.server.LocalConnector;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class WebAppDefaultServletCacheTest
|
||||||
|
{
|
||||||
|
private LocalConnector connector;
|
||||||
|
private Server server;
|
||||||
|
private Path resourcePath;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
protected void setUp() throws Exception
|
||||||
|
{
|
||||||
|
server = new Server();
|
||||||
|
connector = new LocalConnector(server);
|
||||||
|
server.addConnector(connector);
|
||||||
|
|
||||||
|
URI uri = getClass().getResource("/org/acme").toURI();
|
||||||
|
resourcePath = Paths.get(uri);
|
||||||
|
server.addHandler(new WebAppContext(uri.toString(), "/"));
|
||||||
|
|
||||||
|
server.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
protected void tearDown() throws Exception
|
||||||
|
{
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCacheRefreshing() throws Exception
|
||||||
|
{
|
||||||
|
String fileName = "jetty-pic.png";
|
||||||
|
long fileSize = Files.size(resourcePath.resolve(fileName));
|
||||||
|
|
||||||
|
HttpTester.Response response1 = sendRequest(fileName);
|
||||||
|
assertEquals(response1.getLongField("Content-Length"), fileSize);
|
||||||
|
assertEquals(200, response1.getStatus());
|
||||||
|
|
||||||
|
HttpTester.Response response2 = sendRequest(fileName, "If-Modified-Since: " + response1.get("Last-Modified"));
|
||||||
|
assertEquals(response2.getLongField("Content-Length"), 0L);
|
||||||
|
assertEquals(304, response2.getStatus());
|
||||||
|
|
||||||
|
HttpTester.Response response3 = sendRequest(fileName, "Cache-Control: no-cache", "Pragma: no-cache");
|
||||||
|
assertEquals(response3.getLongField("Content-Length"), fileSize);
|
||||||
|
assertEquals(200, response3.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpTester.Response sendRequest(String file, String... extraHeaders) throws Exception
|
||||||
|
{
|
||||||
|
StringBuilder rawRequest = new StringBuilder();
|
||||||
|
rawRequest.append("GET /").append(file).append(" HTTP/1.1\r\n");
|
||||||
|
rawRequest.append("Host: local\r\n");
|
||||||
|
for (String extraHeader : extraHeaders)
|
||||||
|
{
|
||||||
|
rawRequest.append(extraHeader).append("\r\n");
|
||||||
|
}
|
||||||
|
rawRequest.append("\r\n");
|
||||||
|
String rawResponse = connector.getResponse(rawRequest.toString());
|
||||||
|
return HttpTester.parseResponse(rawResponse);
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 482 KiB |
Loading…
Reference in New Issue