Jetty-12 : Testing for ResourceHandler / ResourceService (#8327)
* Overhaul of ResourceHandlerTest * Making ResourceHandlerTest more flexible for testing + Each test has it's own docroot + Each test decides what it's docroot contents are * Support QuotedQualityCSV(List<String>)
This commit is contained in:
parent
769bd5edd6
commit
131fd00285
|
@ -88,6 +88,28 @@ public class QuotedQualityCSV extends QuotedCSV implements Iterable<String>
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts values with equal quality according to given order.
|
||||
*
|
||||
* @param preferredOrder Array indicating the preferred order of known values
|
||||
*/
|
||||
public QuotedQualityCSV(List<String> preferredOrder)
|
||||
{
|
||||
this((s) ->
|
||||
{
|
||||
for (int i = 0; i < preferredOrder.size(); ++i)
|
||||
{
|
||||
if (preferredOrder.get(i).equals(s))
|
||||
return preferredOrder.size() - i;
|
||||
}
|
||||
|
||||
if ("*".equals(s))
|
||||
return preferredOrder.size();
|
||||
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Orders values with equal quality with the given function.
|
||||
*
|
||||
|
|
|
@ -16,7 +16,9 @@ package org.eclipse.jetty.server;
|
|||
import java.io.IOException;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jetty.http.CompressedContentFormat;
|
||||
import org.eclipse.jetty.http.HttpContent;
|
||||
|
@ -36,10 +38,11 @@ public class ResourceContentFactory implements ContentFactory
|
|||
{
|
||||
private final ResourceFactory _factory;
|
||||
private final MimeTypes _mimeTypes;
|
||||
private final CompressedContentFormat[] _precompressedFormats;
|
||||
private final List<CompressedContentFormat> _precompressedFormats;
|
||||
|
||||
public ResourceContentFactory(ResourceFactory factory, MimeTypes mimeTypes, CompressedContentFormat[] precompressedFormats)
|
||||
public ResourceContentFactory(ResourceFactory factory, MimeTypes mimeTypes, List<CompressedContentFormat> precompressedFormats)
|
||||
{
|
||||
Objects.requireNonNull(mimeTypes, "MimeTypes cannot be null");
|
||||
_factory = factory;
|
||||
_mimeTypes = mimeTypes;
|
||||
_precompressedFormats = precompressedFormats;
|
||||
|
@ -80,10 +83,10 @@ public class ResourceContentFactory implements ContentFactory
|
|||
|
||||
// Look for a precompressed resource or content
|
||||
String mt = _mimeTypes.getMimeByExtension(pathInContext);
|
||||
if (_precompressedFormats.length > 0)
|
||||
if (_precompressedFormats.size() > 0)
|
||||
{
|
||||
// Is there a compressed resource?
|
||||
Map<CompressedContentFormat, HttpContent> compressedContents = new HashMap<>(_precompressedFormats.length);
|
||||
Map<CompressedContentFormat, HttpContent> compressedContents = new HashMap<>(_precompressedFormats.size());
|
||||
for (CompressedContentFormat format : _precompressedFormats)
|
||||
{
|
||||
String compressedPathInContext = pathInContext + format.getExtension();
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.nio.channels.ReadableByteChannel;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
@ -45,8 +46,6 @@ import org.eclipse.jetty.util.URIUtil;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
|
||||
/**
|
||||
* Resource service, used by DefaultServlet and ResourceHandler
|
||||
*/
|
||||
|
@ -59,14 +58,14 @@ public class ResourceService
|
|||
// TODO: see if we can set this to private eventually
|
||||
public static final int USE_KNOWN_CONTENT_LENGTH = -2;
|
||||
|
||||
private CompressedContentFormat[] _precompressedFormats = new CompressedContentFormat[0];
|
||||
private List<CompressedContentFormat> _precompressedFormats = new ArrayList<>();
|
||||
private WelcomeFactory _welcomeFactory;
|
||||
private boolean _redirectWelcome = false;
|
||||
private boolean _etags = false;
|
||||
private List<String> _gzipEquivalentFileExtensions;
|
||||
private HttpContent.ContentFactory _contentFactory;
|
||||
private final Map<String, List<String>> _preferredEncodingOrderCache = new ConcurrentHashMap<>();
|
||||
private String[] _preferredEncodingOrder = new String[0];
|
||||
private List<String> _preferredEncodingOrder = new ArrayList<>();
|
||||
private int _encodingCacheSize = 100;
|
||||
private boolean _dirAllowed = true;
|
||||
private boolean _acceptRanges = true;
|
||||
|
@ -118,7 +117,7 @@ public class ResourceService
|
|||
reqRanges = null;
|
||||
|
||||
boolean endsWithSlash = pathInContext.endsWith(URIUtil.SLASH);
|
||||
boolean checkPrecompressedVariants = _precompressedFormats.length > 0 && !endsWithSlash && reqRanges == null;
|
||||
boolean checkPrecompressedVariants = _precompressedFormats.size() > 0 && !endsWithSlash && reqRanges == null;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -535,7 +534,7 @@ public class ResourceService
|
|||
putHeaders(response, content, USE_KNOWN_CONTENT_LENGTH);
|
||||
response.getHeaders().put(HttpHeader.CONTENT_RANGE,
|
||||
InclusiveByteRange.to416HeaderRangeString(contentLength));
|
||||
sendStatus(416, response, callback);
|
||||
writeHttpError(request, response, callback, HttpStatus.RANGE_NOT_SATISFIABLE_416);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -551,7 +550,7 @@ public class ResourceService
|
|||
response.getHeaders().addDateField(HttpHeader.DATE.asString(), System.currentTimeMillis());
|
||||
response.getHeaders().put(HttpHeader.CONTENT_RANGE,
|
||||
singleSatisfiableRange.toHeaderRangeString(contentLength));
|
||||
writeContent(content, out, singleSatisfiableRange.getFirst(), singleLength);
|
||||
writeHttpPartialContent(request, response, callback, content, singleSatisfiableRange);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -614,11 +613,21 @@ public class ResourceService
|
|||
}
|
||||
|
||||
multi.close();
|
||||
*/
|
||||
*/
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void writeHttpPartialContent(Request request, Response response, Callback callback, HttpContent content, InclusiveByteRange singleSatisfiableRange)
|
||||
{
|
||||
// TODO: implement this
|
||||
}
|
||||
|
||||
protected void writeHttpError(Request request, Response response, Callback callback, int statusCode)
|
||||
{
|
||||
Response.writeError(request, response, callback, statusCode);
|
||||
}
|
||||
|
||||
protected void writeHttpContent(Request request, Response response, Callback callback, HttpContent content)
|
||||
{
|
||||
try
|
||||
|
@ -720,7 +729,7 @@ public class ResourceService
|
|||
/**
|
||||
* @return Precompressed resources formats that can be used to serve compressed variant of resources.
|
||||
*/
|
||||
public CompressedContentFormat[] getPrecompressedFormats()
|
||||
public List<CompressedContentFormat> getPrecompressedFormats()
|
||||
{
|
||||
return _precompressedFormats;
|
||||
}
|
||||
|
@ -782,10 +791,12 @@ public class ResourceService
|
|||
* @param precompressedFormats The list of precompresed formats to serve in encoded format if matching resource found.
|
||||
* For example serve gzip encoded file if ".gz" suffixed resource is found.
|
||||
*/
|
||||
public void setPrecompressedFormats(CompressedContentFormat[] precompressedFormats)
|
||||
public void setPrecompressedFormats(List<CompressedContentFormat> precompressedFormats)
|
||||
{
|
||||
_precompressedFormats = precompressedFormats;
|
||||
_preferredEncodingOrder = stream(_precompressedFormats).map(CompressedContentFormat::getEncoding).toArray(String[]::new);
|
||||
_precompressedFormats.clear();
|
||||
_precompressedFormats.addAll(precompressedFormats);
|
||||
_preferredEncodingOrder.clear();
|
||||
_preferredEncodingOrder.addAll(_precompressedFormats.stream().map(CompressedContentFormat::getEncoding).toList());
|
||||
}
|
||||
|
||||
public void setEncodingCacheSize(int encodingCacheSize)
|
||||
|
|
|
@ -199,7 +199,7 @@ public class ResourceHandler extends Handler.Wrapper
|
|||
/**
|
||||
* @return Precompressed resources formats that can be used to serve compressed variant of resources.
|
||||
*/
|
||||
public CompressedContentFormat[] getPrecompressedFormats()
|
||||
public List<CompressedContentFormat> getPrecompressedFormats()
|
||||
{
|
||||
return _resourceService.getPrecompressedFormats();
|
||||
}
|
||||
|
@ -227,7 +227,6 @@ public class ResourceHandler extends Handler.Wrapper
|
|||
public void setBaseResource(Resource base)
|
||||
{
|
||||
_resourceBase = base;
|
||||
setupContentFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -266,7 +265,16 @@ public class ResourceHandler extends Handler.Wrapper
|
|||
* @param precompressedFormats The list of precompresed formats to serve in encoded format if matching resource found.
|
||||
* For example serve gzip encoded file if ".gz" suffixed resource is found.
|
||||
*/
|
||||
public void setPrecompressedFormats(CompressedContentFormat[] precompressedFormats)
|
||||
public void setPrecompressedFormats(CompressedContentFormat... precompressedFormats)
|
||||
{
|
||||
setPrecompressedFormats(List.of(precompressedFormats));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param precompressedFormats The list of precompresed formats to serve in encoded format if matching resource found.
|
||||
* For example serve gzip encoded file if ".gz" suffixed resource is found.
|
||||
*/
|
||||
public void setPrecompressedFormats(List<CompressedContentFormat> precompressedFormats)
|
||||
{
|
||||
_resourceService.setPrecompressedFormats(precompressedFormats);
|
||||
setupContentFactory();
|
||||
|
@ -307,6 +315,11 @@ public class ResourceHandler extends Handler.Wrapper
|
|||
// TODO
|
||||
}
|
||||
|
||||
public void setWelcomeFiles(String... welcomeFiles)
|
||||
{
|
||||
setWelcomeFiles(List.of(welcomeFiles));
|
||||
}
|
||||
|
||||
public void setWelcomeFiles(List<String> welcomeFiles)
|
||||
{
|
||||
_welcomes = welcomeFiles;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -115,7 +115,7 @@ public class DefaultServlet extends HttpServlet
|
|||
// TODO: should this come from context?
|
||||
MimeTypes mimeTypes = new MimeTypes();
|
||||
// TODO: this is configured further down below - see _resourceService.setPrecompressedFormats
|
||||
CompressedContentFormat[] precompressedFormats = new CompressedContentFormat[0];
|
||||
List<CompressedContentFormat> precompressedFormats = List.of();
|
||||
|
||||
_useFileMappedBuffer = getInitBoolean("useFileMappedBuffer", _useFileMappedBuffer);
|
||||
ResourceContentFactory resourceContentFactory = new ResourceContentFactory(_baseResource, mimeTypes, precompressedFormats);
|
||||
|
@ -237,7 +237,7 @@ public class DefaultServlet extends HttpServlet
|
|||
IO.close(_resourceBaseMount);
|
||||
}
|
||||
|
||||
private CompressedContentFormat[] parsePrecompressedFormats(String precompressed, Boolean gzip, CompressedContentFormat[] dft)
|
||||
private List<CompressedContentFormat> parsePrecompressedFormats(String precompressed, Boolean gzip, List<CompressedContentFormat> dft)
|
||||
{
|
||||
if (precompressed == null && gzip == null)
|
||||
{
|
||||
|
@ -269,7 +269,7 @@ public class DefaultServlet extends HttpServlet
|
|||
// gzip handling is for backwards compatibility with older Jetty
|
||||
ret.add(CompressedContentFormat.GZIP);
|
||||
}
|
||||
return ret.toArray(new CompressedContentFormat[ret.size()]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Boolean getInitBoolean(String name)
|
||||
|
|
|
@ -2688,11 +2688,11 @@ public class DefaultServletTest
|
|||
Files.writeString(docRoot.resolve("data0.txt.bz2"), "fake bzip2", UTF_8);
|
||||
|
||||
ResourceService resourceService = new ResourceService();
|
||||
resourceService.setPrecompressedFormats(new CompressedContentFormat[]{
|
||||
resourceService.setPrecompressedFormats(List.of(
|
||||
new CompressedContentFormat("bzip2", ".bz2"),
|
||||
new CompressedContentFormat("gzip", ".gz"),
|
||||
new CompressedContentFormat("br", ".br")
|
||||
});
|
||||
));
|
||||
ServletHolder defholder = new ServletHolder(new DefaultServlet()); // TODO: how to integrate resource service / precompressed format
|
||||
context.addServlet(defholder, "/");
|
||||
defholder.setInitParameter("resourceBase", docRoot.toString());
|
||||
|
|
Loading…
Reference in New Issue