Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.0.x-dispatcher-fixes
This commit is contained in:
commit
f81bdc9711
|
@ -204,21 +204,9 @@ public class CachingContentFactory implements HttpContent.ContentFactory
|
|||
super(httpContent);
|
||||
_etag = precalculatedEtag;
|
||||
_contentLengthValue = httpContent.getContentLengthValue(); // TODO getContentLengthValue() could return -1
|
||||
ByteBuffer byteBuffer = null;
|
||||
|
||||
if (_useFileMappedBuffer)
|
||||
{
|
||||
// map the content into memory
|
||||
// TODO this is assuming the resource can be mapped! Inefficient to throw to test this
|
||||
try
|
||||
{
|
||||
byteBuffer = BufferUtil.toMappedBuffer(httpContent.getResource().getPath(), 0, _contentLengthValue);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOG.trace("ignored", t);
|
||||
}
|
||||
}
|
||||
// map the content into memory if possible
|
||||
ByteBuffer byteBuffer = _useFileMappedBuffer ? BufferUtil.toMappedBuffer(httpContent.getResource(), 0, _contentLengthValue) : null;
|
||||
|
||||
if (byteBuffer == null)
|
||||
{
|
||||
|
|
|
@ -381,7 +381,7 @@ public interface HttpURI
|
|||
public String getCanonicalPath()
|
||||
{
|
||||
if (_canonicalPath == null && _path != null)
|
||||
_canonicalPath = URIUtil.canonicalPath(URIUtil.normalizePath(_path));
|
||||
_canonicalPath = URIUtil.canonicalPath(_path);
|
||||
return _canonicalPath;
|
||||
}
|
||||
|
||||
|
@ -532,7 +532,7 @@ public interface HttpURI
|
|||
* <a href="https://tools.ietf.org/html/rfc3986#section-5.2.4">Remove Dot Segments</a>
|
||||
* algorithm. This results in some ambiguity as dot segments can result from later
|
||||
* parameter removal or % encoding expansion, that are not removed from the URI
|
||||
* by {@link URIUtil#canonicalPath(String)}. Thus this class flags such ambiguous
|
||||
* by {@link URIUtil#normalizePath(String)}. Thus this class flags such ambiguous
|
||||
* path segments, so that they may be rejected by the server if so configured.
|
||||
*/
|
||||
private static final Index<Boolean> __ambiguousSegments = new Index.Builder<Boolean>()
|
||||
|
@ -750,7 +750,7 @@ public interface HttpURI
|
|||
public String getCanonicalPath()
|
||||
{
|
||||
if (_canonicalPath == null && _path != null)
|
||||
_canonicalPath = URIUtil.canonicalPath(URIUtil.normalizePath(_path));
|
||||
_canonicalPath = URIUtil.canonicalPath(_path);
|
||||
return _canonicalPath;
|
||||
}
|
||||
|
||||
|
@ -1412,8 +1412,7 @@ public interface HttpURI
|
|||
{
|
||||
// The RFC requires this to be canonical before decoding, but this can leave dot segments and dot dot segments
|
||||
// which are not canonicalized and could be used in an attempt to bypass security checks.
|
||||
String decodedNonCanonical = URIUtil.normalizePath(_path);
|
||||
_canonicalPath = URIUtil.canonicalPath(decodedNonCanonical);
|
||||
_canonicalPath = URIUtil.canonicalPath(_path);
|
||||
if (_canonicalPath == null)
|
||||
throw new IllegalArgumentException("Bad URI");
|
||||
}
|
||||
|
|
|
@ -487,8 +487,8 @@ public class HttpURITest
|
|||
try
|
||||
{
|
||||
HttpURI uri = HttpURI.from(input);
|
||||
assertThat(uri.getCanonicalPath(), is(canonicalPath));
|
||||
assertThat(uri.getDecodedPath(), is(decodedPath));
|
||||
|
||||
EnumSet<Violation> ambiguous = EnumSet.copyOf(expected);
|
||||
ambiguous.retainAll(EnumSet.complementOf(EnumSet.of(Violation.UTF16_ENCODINGS)));
|
||||
|
||||
|
|
|
@ -339,8 +339,8 @@ public class CachedContentFactory implements HttpContent.ContentFactory
|
|||
// a non shared resource. Also ignore max buffer size
|
||||
try
|
||||
{
|
||||
if (_useFileMappedBuffer && resource.getPath() != null && resource.length() < Integer.MAX_VALUE)
|
||||
return BufferUtil.toMappedBuffer(resource.getPath());
|
||||
if (_useFileMappedBuffer && resource.getPath() != null && resource.length() <= Integer.MAX_VALUE)
|
||||
return BufferUtil.toMappedBuffer(resource);
|
||||
}
|
||||
catch (IOException | IllegalArgumentException e)
|
||||
{
|
||||
|
|
|
@ -393,14 +393,14 @@ public interface Request extends Attributes, Content.Source
|
|||
if (location.startsWith("/"))
|
||||
{
|
||||
// absolute in context
|
||||
location = URIUtil.canonicalURI(location);
|
||||
location = URIUtil.normalizePathQuery(location);
|
||||
}
|
||||
else
|
||||
{
|
||||
// relative to request
|
||||
String path = uri.getPath();
|
||||
String parent = (path.endsWith("/")) ? path : URIUtil.parentPath(path);
|
||||
location = URIUtil.canonicalURI(URIUtil.addEncodedPaths(parent, location));
|
||||
location = URIUtil.normalizePathQuery(URIUtil.addEncodedPaths(parent, location));
|
||||
if (location != null && !location.startsWith("/"))
|
||||
url.append('/');
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -1055,11 +1054,6 @@ public class BufferUtil
|
|||
return buf;
|
||||
}
|
||||
|
||||
public static ByteBuffer toMappedBuffer(File file) throws IOException
|
||||
{
|
||||
return toMappedBuffer(file.toPath(), 0, file.length());
|
||||
}
|
||||
|
||||
public static ByteBuffer toMappedBuffer(Path path) throws IOException
|
||||
{
|
||||
return toMappedBuffer(path, 0, Files.size(path));
|
||||
|
@ -1073,6 +1067,20 @@ public class BufferUtil
|
|||
}
|
||||
}
|
||||
|
||||
public static ByteBuffer toMappedBuffer(Resource resource) throws IOException
|
||||
{
|
||||
if (!resource.isMemoryMappable())
|
||||
return null;
|
||||
return toMappedBuffer(resource.getPath());
|
||||
}
|
||||
|
||||
public static ByteBuffer toMappedBuffer(Resource resource, long pos, long len) throws IOException
|
||||
{
|
||||
if (!resource.isMemoryMappable())
|
||||
return null;
|
||||
return toMappedBuffer(resource.getPath(), pos, len);
|
||||
}
|
||||
|
||||
public static String toSummaryString(ByteBuffer buffer)
|
||||
{
|
||||
if (buffer == null)
|
||||
|
|
|
@ -45,7 +45,7 @@ public class URIUtil
|
|||
public static final Charset __CHARSET = StandardCharsets.UTF_8;
|
||||
|
||||
/**
|
||||
* The characters that are supported by the URI class and that can be decoded by {@link #normalizePath(String)}
|
||||
* The characters that are supported by the URI class and that can be decoded by {@link #canonicalPath(String)}
|
||||
*/
|
||||
public static final boolean[] __uriSupportedCharacters = new boolean[]
|
||||
{
|
||||
|
@ -81,12 +81,12 @@ public class URIUtil
|
|||
false, // 0x1d is illegal
|
||||
false, // 0x1e is illegal
|
||||
false, // 0x1f is illegal
|
||||
false, // 0x20 is illegal
|
||||
false, // 0x20 space is illegal
|
||||
true, // 0x21
|
||||
false, // 0x22 is illegal
|
||||
false, // # is special
|
||||
false, // 0x22 " is illegal
|
||||
false, // 0x23 # is special
|
||||
true, // 0x24
|
||||
false, // % must remain encoded
|
||||
false, // 0x25 % must remain encoded
|
||||
true, // 0x26
|
||||
true, // 0x27
|
||||
true, // 0x28
|
||||
|
@ -96,7 +96,7 @@ public class URIUtil
|
|||
true, // 0x2c
|
||||
true, // 0x2d
|
||||
true, // 0x2e
|
||||
false, // / is a delimiter
|
||||
false, // 0x2f / is a delimiter
|
||||
true, // 0x30
|
||||
true, // 0x31
|
||||
true, // 0x32
|
||||
|
@ -108,11 +108,11 @@ public class URIUtil
|
|||
true, // 0x38
|
||||
true, // 0x39
|
||||
true, // 0x3a
|
||||
false, // ; is path parameter
|
||||
false, // 0x3c is illegal
|
||||
false, // 0x3b ; is path parameter
|
||||
false, // 0x3c < is illegal
|
||||
true, // 0x3d
|
||||
false, // 0x3e is illegal
|
||||
false, // ? is special
|
||||
false, // 0x3e > is illegal
|
||||
false, // 0x3f ? is special
|
||||
true, // 0x40
|
||||
true, // 0x41
|
||||
true, // 0x42
|
||||
|
@ -140,12 +140,12 @@ public class URIUtil
|
|||
true, // 0x58
|
||||
true, // 0x59
|
||||
true, // 0x5a
|
||||
false, // 0x5b is illegal
|
||||
false, // 0x5c is illegal
|
||||
false, // 0x5d is illegal
|
||||
false, // 0x5e is illegal
|
||||
false, // 0x5b [ is illegal
|
||||
false, // 0x5c \ is illegal
|
||||
false, // 0x5d ] is illegal
|
||||
false, // 0x5e ^ is illegal
|
||||
true, // 0x5f
|
||||
false, // 0x60 is illegal
|
||||
false, // 0x60 ` is illegal
|
||||
true, // 0x61
|
||||
true, // 0x62
|
||||
true, // 0x63
|
||||
|
@ -172,11 +172,11 @@ public class URIUtil
|
|||
true, // 0x78
|
||||
true, // 0x79
|
||||
true, // 0x7a
|
||||
false, // 0x7b is illegal
|
||||
false, // 0x7c is illegal
|
||||
false, // 0x7d is illegal
|
||||
false, // 0x7b { is illegal
|
||||
false, // 0x7c | is illegal
|
||||
false, // 0x7d } is illegal
|
||||
true, // 0x7e
|
||||
false, // 0x7f is illegal
|
||||
false, // 0x7f DEL is illegal
|
||||
};
|
||||
|
||||
private URIUtil()
|
||||
|
@ -576,8 +576,8 @@ public class URIUtil
|
|||
|
||||
/**
|
||||
* Decode a URI path and strip parameters
|
||||
* @see #normalizePath(String)
|
||||
* @see #canonicalPath(String)
|
||||
* @see #normalizePath(String)
|
||||
*/
|
||||
public static String decodePath(String path)
|
||||
{
|
||||
|
@ -586,8 +586,8 @@ public class URIUtil
|
|||
|
||||
/**
|
||||
* Decode a URI path and strip parameters of UTF-8 path
|
||||
* @see #normalizePath(String, int, int)
|
||||
* @see #canonicalPath(String)
|
||||
* @see #normalizePath(String)
|
||||
*/
|
||||
public static String decodePath(String path, int offset, int length)
|
||||
{
|
||||
|
@ -700,47 +700,32 @@ public class URIUtil
|
|||
}
|
||||
|
||||
/**
|
||||
* Normalize a URI path to a form that is unambiguous and safe to use with the JVM {@link URI} class.
|
||||
* Canonicalize a URI path to a form that is unambiguous and safe to use with the JVM {@link URI} class.
|
||||
* <p>
|
||||
* Decode only the safe characters in a URI path and strip parameters of UTF-8 path.
|
||||
* Safe characters are ones that are not special delimiters and that can be passed to the JVM {@link URI} class.
|
||||
* Unsafe characters, other than '/' will be encoded. Encodings will be uppercase hex.
|
||||
* The resulting URI path may be used in string comparisons with other normalized paths.
|
||||
* Canonical paths are also normalized and may be used in string comparisons with other canonical paths.
|
||||
* <p>
|
||||
* For example the path <code>/fo %2fo/b%61r</code> will be normalized to <code>/fo%20%2Fo/bar</code>,
|
||||
* whilst {@link #decodePath(String)} would result in the ambiguous and URI illegal <code>/fo /o/bar</code>.
|
||||
*
|
||||
* @return the canonical path or null if it is non-normal
|
||||
* @see #decodePath(String)
|
||||
* @see #canonicalPath(String)
|
||||
* @see #normalizePath(String)
|
||||
* @see URI
|
||||
*/
|
||||
public static String normalizePath(String path)
|
||||
{
|
||||
return normalizePath(path, 0, path.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a URI path to a form that is unambiguous and safe to use with the JVM {@link URI} class.
|
||||
* <p>
|
||||
* Decode only the safe characters in a URI path and strip parameters of UTF-8 path.
|
||||
* Safe characters are ones that are not special delimiters and that can be passed to the JVM {@link URI} class.
|
||||
* Unsafe characters, other than '/' will be encoded. Encodings will be uppercase hex.
|
||||
* The resulting URI path may be used in string comparisons with other normalized paths.
|
||||
* <p>
|
||||
* For example the path <code>/fo %2fo/b%61r</code> will be normalized to <code>/fo%20%2Fo/bar</code>,
|
||||
* whilst {@link #decodePath(String)} would result in the ambiguous and URI illegal <code>/fo /o/bar</code>.
|
||||
*
|
||||
* @see #decodePath(String, int, int)
|
||||
* @see #canonicalPath(String)
|
||||
* @see URI
|
||||
*/
|
||||
public static String normalizePath(String path, int offset, int length)
|
||||
public static String canonicalPath(String path)
|
||||
{
|
||||
if (path == null)
|
||||
return null;
|
||||
try
|
||||
{
|
||||
|
||||
Utf8StringBuilder builder = null;
|
||||
int end = offset + length;
|
||||
for (int i = offset; i < end; i++)
|
||||
int end = path.length();
|
||||
boolean slash = true;
|
||||
boolean normal = true;
|
||||
for (int i = 0; i < end; i++)
|
||||
{
|
||||
char c = path.charAt(i);
|
||||
switch (c)
|
||||
|
@ -749,7 +734,7 @@ public class URIUtil
|
|||
if (builder == null)
|
||||
{
|
||||
builder = new Utf8StringBuilder(path.length());
|
||||
builder.append(path, offset, i - offset);
|
||||
builder.append(path, 0, i);
|
||||
}
|
||||
if ((i + 2) < end)
|
||||
{
|
||||
|
@ -762,7 +747,12 @@ public class URIUtil
|
|||
{
|
||||
char[] chars = Character.toChars(code);
|
||||
for (char ch : chars)
|
||||
{
|
||||
builder.append(ch);
|
||||
if (slash && ch == '.')
|
||||
normal = false;
|
||||
slash = false;
|
||||
}
|
||||
}
|
||||
i += 5;
|
||||
}
|
||||
|
@ -770,7 +760,11 @@ public class URIUtil
|
|||
{
|
||||
int code = TypeUtil.convertHexDigit(u) * 16 + TypeUtil.convertHexDigit(path.charAt(i + 2));
|
||||
if (isSafeElseEncode(code, builder))
|
||||
{
|
||||
builder.append((byte)(0xff & code));
|
||||
if (slash && code == '.')
|
||||
normal = false;
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
@ -784,7 +778,7 @@ public class URIUtil
|
|||
if (builder == null)
|
||||
{
|
||||
builder = new Utf8StringBuilder(path.length());
|
||||
builder.append(path, offset, i - offset);
|
||||
builder.append(path, 0, i);
|
||||
}
|
||||
|
||||
while (++i < end)
|
||||
|
@ -802,29 +796,35 @@ public class URIUtil
|
|||
builder.append(c);
|
||||
break;
|
||||
|
||||
case '.':
|
||||
if (slash)
|
||||
normal = false;
|
||||
if (builder != null)
|
||||
builder.append(c);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (builder == null && !isSafe(c))
|
||||
{
|
||||
builder = new Utf8StringBuilder(path.length());
|
||||
builder.append(path, offset, i - offset);
|
||||
builder.append(path, 0, i);
|
||||
}
|
||||
|
||||
if (builder != null && isSafeElseEncode(c, builder))
|
||||
builder.append(c);
|
||||
break;
|
||||
}
|
||||
|
||||
slash = c == '/';
|
||||
}
|
||||
|
||||
if (builder != null)
|
||||
return builder.toString();
|
||||
if (offset == 0 && length == path.length())
|
||||
return path;
|
||||
return path.substring(offset, end);
|
||||
String canonical = (builder != null) ? builder.toString() : path;
|
||||
return normal ? canonical : normalizePath(canonical);
|
||||
}
|
||||
catch (NotUtf8Exception e)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} {}", path.substring(offset, offset + length), e.toString());
|
||||
LOG.debug("{} {}", path, e.toString());
|
||||
throw e;
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
|
@ -1078,29 +1078,28 @@ public class URIUtil
|
|||
}
|
||||
|
||||
/**
|
||||
* Convert a partial URI to a canonical form.
|
||||
* <p>
|
||||
* All segments of "." and ".." are factored out.
|
||||
* Null is returned if the path tries to .. above its root.
|
||||
* <p>Normalize a URI path and query by factoring out all segments of "." and ".."
|
||||
* up until any query or fragment.
|
||||
* Null is returned if the path is normalized above its root.
|
||||
* </p>
|
||||
*
|
||||
* @param uri the encoded URI from the path onwards, which may contain query strings and/or fragments
|
||||
* @return the canonical path, or null if path traversal above root.
|
||||
* @see #canonicalPath(String)
|
||||
* @param pathQuery the encoded URI from the path onwards, which may contain query strings and/or fragments
|
||||
* @return the normalized path, or null if path traversal above root.
|
||||
* @see #normalizePath(String)
|
||||
*/
|
||||
public static String canonicalURI(String uri)
|
||||
public static String normalizePathQuery(String pathQuery)
|
||||
{
|
||||
if (uri == null || uri.isEmpty())
|
||||
return uri;
|
||||
if (pathQuery == null || pathQuery.isEmpty())
|
||||
return pathQuery;
|
||||
|
||||
boolean slash = true;
|
||||
int end = uri.length();
|
||||
int end = pathQuery.length();
|
||||
int i = 0;
|
||||
|
||||
// Initially just loop looking if we may need to normalize
|
||||
loop: while (i < end)
|
||||
{
|
||||
char c = uri.charAt(i);
|
||||
char c = pathQuery.charAt(i);
|
||||
switch (c)
|
||||
{
|
||||
case '/':
|
||||
|
@ -1116,7 +1115,7 @@ public class URIUtil
|
|||
case '?':
|
||||
case '#':
|
||||
// Nothing to normalize so return original path
|
||||
return uri;
|
||||
return pathQuery;
|
||||
|
||||
default:
|
||||
slash = false;
|
||||
|
@ -1127,18 +1126,18 @@ public class URIUtil
|
|||
|
||||
// Nothing to normalize so return original path
|
||||
if (i == end)
|
||||
return uri;
|
||||
return pathQuery;
|
||||
|
||||
// We probably need to normalize, so copy to path so far into builder
|
||||
StringBuilder canonical = new StringBuilder(uri.length());
|
||||
canonical.append(uri, 0, i);
|
||||
StringBuilder canonical = new StringBuilder(pathQuery.length());
|
||||
canonical.append(pathQuery, 0, i);
|
||||
|
||||
// Loop looking for single and double dot segments
|
||||
int dots = 1;
|
||||
i++;
|
||||
loop : while (i < end)
|
||||
{
|
||||
char c = uri.charAt(i);
|
||||
char c = pathQuery.charAt(i);
|
||||
switch (c)
|
||||
{
|
||||
case '/':
|
||||
|
@ -1181,37 +1180,24 @@ public class URIUtil
|
|||
|
||||
// append any query
|
||||
if (i < end)
|
||||
canonical.append(uri, i, end);
|
||||
canonical.append(pathQuery, i, end);
|
||||
|
||||
return canonical.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path the encoded URI from the path onwards, which may contain query strings and/or fragments
|
||||
* @return the canonical path, or null if path traversal above root.
|
||||
* @deprecated Use {@link #canonicalURI(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String canonicalEncodedPath(String path)
|
||||
{
|
||||
return canonicalURI(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a decoded URI path to a canonical form.
|
||||
* <p>
|
||||
* All segments of "." and ".." are factored out.
|
||||
* Null is returned if the path tries to .. above its root.
|
||||
* <p>Normalize a URI path by factoring out all segments of "." and "..".
|
||||
* Null is returned if the path is normalized above its root.
|
||||
* </p>
|
||||
*
|
||||
* @param path the decoded URI path to convert. Any special characters (e.g. '?', "#") are assumed to be part of
|
||||
* the path segments.
|
||||
* @return the canonical path, or null if path traversal above root.
|
||||
* @see #canonicalURI(String)
|
||||
* @see #normalizePath(String)
|
||||
* @return the normalized path, or null if path traversal above root.
|
||||
* @see #normalizePathQuery(String)
|
||||
* @see #canonicalPath(String)
|
||||
* @see #decodePath(String)
|
||||
*/
|
||||
public static String canonicalPath(String path)
|
||||
public static String normalizePath(String path)
|
||||
{
|
||||
if (path == null || path.isEmpty())
|
||||
return path;
|
||||
|
|
|
@ -284,6 +284,12 @@ public class PathResource extends Resource
|
|||
return path.toAbsolutePath().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMemoryMappable()
|
||||
{
|
||||
return "file".equalsIgnoreCase(uri.getScheme());
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getURI()
|
||||
{
|
||||
|
|
|
@ -506,6 +506,16 @@ public abstract class Resource implements ResourceFactory
|
|||
return Files.newByteChannel(getPath(), StandardOpenOption.READ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the resource supports being loaded as a memory-mapped ByteBuffer.
|
||||
*
|
||||
* @return true if the resource supports memory-mapped ByteBuffer, false otherwise.
|
||||
*/
|
||||
public boolean isMemoryMappable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given resource
|
||||
* Equivalent to {@link Files#deleteIfExists(Path)} with the following parameter:
|
||||
|
@ -596,7 +606,8 @@ public abstract class Resource implements ResourceFactory
|
|||
// Check that the path is within the root,
|
||||
// but use the original path to create the
|
||||
// resource, to preserve aliasing.
|
||||
if (URIUtil.canonicalPath(subUriPath) == null)
|
||||
// TODO should we canonicalize here? Or perhaps just do a URI safe encoding
|
||||
if (URIUtil.normalizePath(subUriPath) == null)
|
||||
throw new IOException(subUriPath);
|
||||
|
||||
if (URIUtil.SLASH.equals(subUriPath))
|
||||
|
@ -677,7 +688,7 @@ public abstract class Resource implements ResourceFactory
|
|||
public String getListHTML(String base, boolean parent, String query) throws IOException
|
||||
{
|
||||
// This method doesn't check aliases, so it is OK to canonicalize here.
|
||||
base = URIUtil.canonicalPath(base);
|
||||
base = URIUtil.normalizePath(base);
|
||||
if (base == null || !isDirectory())
|
||||
return null;
|
||||
|
||||
|
|
|
@ -17,9 +17,12 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -29,6 +32,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
|||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.hamcrest.Matchers.sameInstance;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
@ -360,4 +364,26 @@ public class BufferUtilTest
|
|||
BufferUtil.writeTo(buffer.asReadOnlyBuffer(), out);
|
||||
assertThat("Bytes in out equal bytes in buffer", Arrays.equals(bytes, out.toByteArray()), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToMappedBufferResource() throws Exception
|
||||
{
|
||||
Path testZip = MavenTestingUtils.getTestResourcePathFile("TestData/test.zip");
|
||||
Path testTxt = MavenTestingUtils.getTestResourcePathFile("TestData/alphabet.txt");
|
||||
|
||||
Resource fileResource = Resource.newResource("file:" + testTxt.toAbsolutePath());
|
||||
ByteBuffer fileBuffer = BufferUtil.toMappedBuffer(fileResource);
|
||||
assertThat(fileBuffer, not(nullValue()));
|
||||
assertThat((long)fileBuffer.remaining(), is(fileResource.length()));
|
||||
|
||||
Resource jrtResource = Resource.newResource("jrt:/java.base/java/lang/Object.class");
|
||||
assertThat(jrtResource.exists(), is(true));
|
||||
assertThat(BufferUtil.toMappedBuffer(jrtResource), nullValue());
|
||||
|
||||
try (Resource.Mount mount = Resource.mountJar(testZip))
|
||||
{
|
||||
Resource jarResource = mount.root();
|
||||
assertThat(BufferUtil.toMappedBuffer(jarResource), nullValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,11 +24,11 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
|||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
public class URIUtilCanonicalPathTest
|
||||
public class URIUtilNormalizePathTest
|
||||
{
|
||||
public static Stream<Arguments> paths()
|
||||
{
|
||||
String[][] canonical =
|
||||
String[][] unNormalAndNormal =
|
||||
{
|
||||
// Examples from RFC
|
||||
{"/a/b/c/./../../g", "/a/g"},
|
||||
|
@ -130,7 +130,7 @@ public class URIUtilCanonicalPathTest
|
|||
};
|
||||
|
||||
ArrayList<Arguments> ret = new ArrayList<>();
|
||||
for (String[] args : canonical)
|
||||
for (String[] args : unNormalAndNormal)
|
||||
{
|
||||
ret.add(Arguments.of((Object[])args));
|
||||
}
|
||||
|
@ -139,23 +139,23 @@ public class URIUtilCanonicalPathTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("paths")
|
||||
public void testCanonicalPath(String input, String expectedResult)
|
||||
public void testNormalizePath(String input, String expectedResult)
|
||||
{
|
||||
// Check canonicalPath
|
||||
assertThat(URIUtil.canonicalPath(input), is(expectedResult));
|
||||
assertThat(URIUtil.normalizePath(input), is(expectedResult));
|
||||
|
||||
// Check canonicalURI
|
||||
if (expectedResult == null)
|
||||
{
|
||||
assertThat(URIUtil.canonicalURI(input), nullValue());
|
||||
assertThat(URIUtil.normalizePathQuery(input), nullValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
// mostly encodedURI will be the same
|
||||
assertThat(URIUtil.canonicalURI(input), is(expectedResult));
|
||||
assertThat(URIUtil.normalizePathQuery(input), is(expectedResult));
|
||||
// but will terminate on fragments and queries
|
||||
assertThat(URIUtil.canonicalURI(input + "?/foo/../bar/."), is(expectedResult + "?/foo/../bar/."));
|
||||
assertThat(URIUtil.canonicalURI(input + "#/foo/../bar/."), is(expectedResult + "#/foo/../bar/."));
|
||||
assertThat(URIUtil.normalizePathQuery(input + "?/foo/../bar/."), is(expectedResult + "?/foo/../bar/."));
|
||||
assertThat(URIUtil.normalizePathQuery(input + "#/foo/../bar/."), is(expectedResult + "#/foo/../bar/."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ public class URIUtilCanonicalPathTest
|
|||
@MethodSource("queries")
|
||||
public void testQuery(String input, String expectedPath)
|
||||
{
|
||||
String actual = URIUtil.canonicalURI(input);
|
||||
String actual = URIUtil.normalizePathQuery(input);
|
||||
assertThat(actual, is(expectedPath));
|
||||
}
|
||||
}
|
|
@ -136,20 +136,31 @@ public class URIUtilTest
|
|||
|
||||
// Deprecated Microsoft Percent-U encoding
|
||||
arguments.add(Arguments.of("abc%u3040", "abc\u3040", "abc\u3040"));
|
||||
|
||||
// Canonical paths are also normalized
|
||||
arguments.add(Arguments.of("./bar", "bar", "./bar"));
|
||||
arguments.add(Arguments.of("/foo/./bar", "/foo/bar", "/foo/./bar"));
|
||||
arguments.add(Arguments.of("/foo/../bar", "/bar", "/foo/../bar"));
|
||||
arguments.add(Arguments.of("/foo/.../bar", "/foo/.../bar", "/foo/.../bar"));
|
||||
arguments.add(Arguments.of("/foo/%2e/bar", "/foo/bar", "/foo/./bar")); // Not by the RFC, but safer
|
||||
arguments.add(Arguments.of("/foo/%2e%2e/bar", "/bar", "/foo/../bar")); // Not by the RFC, but safer
|
||||
arguments.add(Arguments.of("/foo/%2e%2e%2e/bar", "/foo/.../bar", "/foo/.../bar"));
|
||||
|
||||
return arguments.stream();
|
||||
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "[{index}] {0}")
|
||||
@MethodSource("decodePathSource")
|
||||
public void testNormalizePath(String encodedPath, String safePath, String decodedPath)
|
||||
public void testCanonicalEncodedPath(String encodedPath, String canonicalPath, String decodedPath)
|
||||
{
|
||||
String path = URIUtil.normalizePath(encodedPath);
|
||||
assertEquals(safePath, path);
|
||||
String path = URIUtil.canonicalPath(encodedPath);
|
||||
assertEquals(canonicalPath, path);
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "[{index}] {0}")
|
||||
@MethodSource("decodePathSource")
|
||||
public void testDecodePath(String encodedPath, String safePath, String decodedPath)
|
||||
public void testDecodePath(String encodedPath, String canonicalPath, String decodedPath)
|
||||
{
|
||||
String path = URIUtil.decodePath(encodedPath);
|
||||
assertEquals(decodedPath, path);
|
||||
|
|
|
@ -361,8 +361,8 @@ public class MavenWebAppContext extends WebAppContext
|
|||
// /WEB-INF/classes
|
||||
if ((resource == null || !resource.exists()) && pathInContext != null && _classes != null)
|
||||
{
|
||||
// Canonicalize again to look for the resource inside /WEB-INF subdirectories.
|
||||
String uri = URIUtil.canonicalPath(pathInContext);
|
||||
// Normalize again to look for the resource inside /WEB-INF subdirectories.
|
||||
String uri = URIUtil.normalizePath(pathInContext);
|
||||
if (uri == null)
|
||||
return null;
|
||||
|
||||
|
|
|
@ -13,12 +13,9 @@
|
|||
|
||||
package org.eclipse.jetty.ee10.maven.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
|
@ -165,7 +162,7 @@ public class SelectiveJarResource extends Resource
|
|||
|
||||
LOG.debug("Looking at {}", entryName);
|
||||
// make sure no access out of the root entry is present
|
||||
String dotCheck = URIUtil.canonicalPath(entryName);
|
||||
String dotCheck = URIUtil.normalizePath(entryName);
|
||||
if (dotCheck == null)
|
||||
{
|
||||
LOG.info("Invalid entry: {}", entryName);
|
||||
|
|
|
@ -398,7 +398,7 @@ public class ServletChannel implements Runnable
|
|||
{
|
||||
String contextPath = _request.getContext().getContextPath();
|
||||
HttpURI.Immutable dispatchUri = HttpURI.from(dispatchString);
|
||||
pathInContext = URIUtil.normalizePath(dispatchUri.getPath());
|
||||
pathInContext = URIUtil.canonicalPath(dispatchUri.getPath());
|
||||
uri = HttpURI.build(_request.getHttpURI())
|
||||
.path(URIUtil.addPaths(contextPath, pathInContext))
|
||||
.query(dispatchUri.getQuery());
|
||||
|
|
|
@ -3066,8 +3066,8 @@ public class ServletContextHandler extends ContextHandler implements Graceful
|
|||
@Override
|
||||
public String getRealPath(String path)
|
||||
{
|
||||
// This is an API call from the application which may have arbitrary non canonical paths passed
|
||||
// Thus we canonicalize here, to avoid the enforcement of only canonical paths in
|
||||
// This is an API call from the application which may pass non-canonical paths.
|
||||
// Thus, we canonicalize here, to avoid the enforcement of canonical paths in
|
||||
// ContextHandler.this.getResource(path).
|
||||
path = URIUtil.canonicalPath(path);
|
||||
if (path == null)
|
||||
|
@ -3098,8 +3098,8 @@ public class ServletContextHandler extends ContextHandler implements Graceful
|
|||
@Override
|
||||
public URL getResource(String path) throws MalformedURLException
|
||||
{
|
||||
// This is an API call from the application which may have arbitrary non canonical paths passed
|
||||
// Thus we canonicalize here, to avoid the enforcement of only canonical paths in
|
||||
// This is an API call from the application which may pass non-canonical paths.
|
||||
// Thus, we canonicalize here, to avoid the enforcement of canonical paths in
|
||||
// ContextHandler.this.getResource(path).
|
||||
path = URIUtil.canonicalPath(path);
|
||||
if (path == null)
|
||||
|
@ -3134,8 +3134,8 @@ public class ServletContextHandler extends ContextHandler implements Graceful
|
|||
@Override
|
||||
public Set<String> getResourcePaths(String path)
|
||||
{
|
||||
// This is an API call from the application which may have arbitrary non canonical paths passed
|
||||
// Thus we canonicalize here, to avoid the enforcement of only canonical paths in
|
||||
// This is an API call from the application which may pass non-canonical paths.
|
||||
// Thus, we canonicalize here, to avoid the enforcement of canonical paths in
|
||||
// ContextHandler.this.getResource(path).
|
||||
path = URIUtil.canonicalPath(path);
|
||||
if (path == null)
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.ee8</groupId>
|
||||
<artifactId>jetty-ee8</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-ee8-apache-jsp</artifactId>
|
||||
<name>EE8 :: Jetty :: Apache JSP Implementation</name>
|
||||
|
||||
<properties>
|
||||
<ee9.module>jetty-ee9-apache-jsp</ee9.module>
|
||||
<bundle-symbolic-name>${project.groupId}.apache-jsp</bundle-symbolic-name>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-Description>Jetty-specific ServletContainerInitializer for Jasper</Bundle-Description>
|
||||
<Export-Package>
|
||||
org.eclipse.jetty.ee8.apache.jsp.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}", org.eclipse.jetty.ee8.jsp.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}"
|
||||
</Export-Package>
|
||||
<Require-Capability>osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional
|
||||
</Require-Capability>
|
||||
<Provide-Capability>
|
||||
osgi.serviceloader;osgi.serviceloader=javax.servlet.ServletContainerInitializer,osgi.serviceloader;osgi.serviceloader=org.apache.juli.logging.Log
|
||||
</Provide-Capability>
|
||||
<_nouses>true</_nouses>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>nolog-jar</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<classifier>nolog</classifier>
|
||||
<excludes>
|
||||
<exclude>META-INF/services/org.apache.juli.logging.Log</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mortbay.jasper</groupId>
|
||||
<artifactId>apache-jsp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee8</groupId>
|
||||
<artifactId>jetty-ee8-servlet</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
<artifactId>jetty-servlet-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http-tools</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-slf4j-impl</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
<artifactId>jetty-test-helper</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,15 @@
|
|||
# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[description]
|
||||
Enables use of the apache implementation of JSP.
|
||||
|
||||
[environment]
|
||||
ee8
|
||||
|
||||
[depend]
|
||||
ee8-servlet
|
||||
ee8-annotations
|
||||
|
||||
[lib]
|
||||
lib/ee8-apache-jsp/*.jar
|
||||
lib/jetty-ee8-apache-jsp-${jetty.version}.jar
|
|
@ -0,0 +1,72 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.ee8</groupId>
|
||||
<artifactId>jetty-ee8</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-ee8-openid</artifactId>
|
||||
<name>EE8 :: Jetty :: OpenID</name>
|
||||
<description>Jetty OpenID Connect infrastructure</description>
|
||||
|
||||
<properties>
|
||||
<ee9.module>jetty-ee9-openid</ee9.module>
|
||||
<bundle-symbolic-name>${project.groupId}.openid</bundle-symbolic-name>
|
||||
<spotbugs.onlyAnalyze>org.eclipse.jetty.security.openid.*</spotbugs.onlyAnalyze>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Require-Capability>osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)"</Require-Capability>
|
||||
<Provide-Capability>osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.security.Authenticator$Factory</Provide-Capability>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee8</groupId>
|
||||
<artifactId>jetty-ee8-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util-ajax</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-slf4j-impl</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee8</groupId>
|
||||
<artifactId>jetty-ee8-servlet</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
<artifactId>jetty-test-helper</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
<Get id="ThreadPool" name="threadPool"/>
|
||||
<New id="HttpClient" class="org.eclipse.jetty.client.HttpClient">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.client.http.HttpClientTransportOverHTTP">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.io.ClientConnector">
|
||||
<Set name="sslContextFactory">
|
||||
<New class="org.eclipse.jetty.util.ssl.SslContextFactory$Client">
|
||||
<Set name="trustAll" type="boolean">
|
||||
<Property name="jetty.openid.sslContextFactory.trustAll" default="false"/>
|
||||
</Set>
|
||||
</New>
|
||||
</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</New>
|
||||
</Arg>
|
||||
<Set name="executor"><Ref refid="ThreadPool"/></Set>
|
||||
</New>
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<Ref refid="BaseLoginService"/>
|
||||
</Arg>
|
||||
</Call>
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New id="OpenIdConfiguration" class="org.eclipse.jetty.ee8.security.openid.OpenIdConfiguration">
|
||||
<Arg name="issuer"><Property name="jetty.openid.provider" deprecated="jetty.openid.openIdProvider"/></Arg>
|
||||
<Arg name="authorizationEndpoint"><Property name="jetty.openid.provider.authorizationEndpoint"/></Arg>
|
||||
<Arg name="tokenEndpoint"><Property name="jetty.openid.provider.tokenEndpoint"/></Arg>
|
||||
<Arg name="clientId"><Property name="jetty.openid.clientId"/></Arg>
|
||||
<Arg name="clientSecret"><Property name="jetty.openid.clientSecret"/></Arg>
|
||||
<Arg name="authMethod"><Property name="jetty.openid.authMethod" default="client_secret_post"/></Arg>
|
||||
<Arg name="httpClient"><Ref refid="HttpClient"/></Arg>
|
||||
<Set name="authenticateNewUsers">
|
||||
<Property name="jetty.openid.authenticateNewUsers" default="false"/>
|
||||
</Set>
|
||||
<Call name="addScopes">
|
||||
<Arg>
|
||||
<Call class="org.eclipse.jetty.util.StringUtil" name="csvSplit">
|
||||
<Arg><Property name="jetty.openid.scopes"/></Arg>
|
||||
</Call>
|
||||
</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Configure>
|
|
@ -0,0 +1,47 @@
|
|||
# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[description]
|
||||
Adds OpenId Connect authentication to the server.
|
||||
|
||||
[depend]
|
||||
security
|
||||
client
|
||||
|
||||
[lib]
|
||||
lib/jetty-ee8-openid-${jetty.version}.jar
|
||||
lib/jetty-util-ajax-${jetty.version}.jar
|
||||
|
||||
[files]
|
||||
basehome:modules/openid/jetty-ee8-openid-baseloginservice.xml|etc/openid-baseloginservice.xml
|
||||
|
||||
[xml]
|
||||
etc/openid-baseloginservice.xml
|
||||
etc/jetty-openid.xml
|
||||
|
||||
[ini-template]
|
||||
## The OpenID Identity Provider's issuer ID (the entire URL *before* ".well-known/openid-configuration")
|
||||
# jetty.openid.provider=https://id.example.com/
|
||||
|
||||
## The OpenID Identity Provider's authorization endpoint (optional if the metadata of the OP is accessible)
|
||||
# jetty.openid.provider.authorizationEndpoint=https://id.example.com/authorization
|
||||
|
||||
## The OpenID Identity Provider's token endpoint (optional if the metadata of the OP is accessible)
|
||||
# jetty.openid.provider.tokenEndpoint=https://id.example.com/token
|
||||
|
||||
## The Client Identifier
|
||||
# jetty.openid.clientId=test1234
|
||||
|
||||
## The Client Secret
|
||||
# jetty.openid.clientSecret=XT_Mafv_aUCGheuCaKY8P
|
||||
|
||||
## Additional Scopes to Request
|
||||
# jetty.openid.scopes=email,profile
|
||||
|
||||
## Whether to Authenticate users not found by base LoginService
|
||||
# jetty.openid.authenticateNewUsers=false
|
||||
|
||||
## True if all certificates should be trusted by the default SslContextFactory
|
||||
# jetty.openid.sslContextFactory.trustAll=false
|
||||
|
||||
## What authentication method to use with the Token Endpoint (client_secret_post, client_secret_basic).
|
||||
# jetty.openid.authMethod=client_secret_post
|
|
@ -18,6 +18,7 @@
|
|||
<jakarta.annotation.api.version>1.3.5</jakarta.annotation.api.version>
|
||||
<javax.mail.glassfish.version>1.4.1.v201005082020</javax.mail.glassfish.version>
|
||||
<jakarta.websocket.api.version>1.1.2</jakarta.websocket.api.version>
|
||||
<jsp.impl.version>9.0.52</jsp.impl.version>
|
||||
<!-- generated sources cannot follow exactly Jetty code style -->
|
||||
<checkstyle.skip>true</checkstyle.skip>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
|
@ -38,6 +39,8 @@
|
|||
<module>jetty-ee8-annotations</module>
|
||||
<module>jetty-ee8-websocket</module>
|
||||
<module>jetty-ee8-quickstart</module>
|
||||
<module>jetty-ee8-openid</module>
|
||||
<module>jetty-ee8-apache-jsp</module>
|
||||
<module>jetty-ee8-bom</module>
|
||||
<module>jetty-ee8-demos</module>
|
||||
<module>jetty-ee8-home</module>
|
||||
|
@ -206,6 +209,11 @@
|
|||
<artifactId>jakarta.annotation-api</artifactId>
|
||||
<version>${jakarta.annotation.api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mortbay.jasper</groupId>
|
||||
<artifactId>apache-jsp</artifactId>
|
||||
<version>${jsp.impl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
<artifactId>jetty-javax-websocket-api</artifactId>
|
||||
|
|
|
@ -64,7 +64,7 @@ public class TestJettyJspServlet
|
|||
public void setUp() throws Exception
|
||||
{
|
||||
JspFactory.setDefaultFactory(new JspFactoryImpl());
|
||||
File baseDir = MavenTestingUtils.getTestResourceDir("base");
|
||||
File baseDir = MavenTestingUtils.getTargetPath("test-classes/base").toFile();
|
||||
_server = new Server();
|
||||
_connector = new LocalConnector(_server);
|
||||
_server.addConnector(_connector);
|
||||
|
|
|
@ -43,8 +43,8 @@ public class TestJettyTldPreScanned
|
|||
public void testIt()
|
||||
throws Exception
|
||||
{
|
||||
File jar = MavenTestingUtils.getTestResourceFile("taglib.jar");
|
||||
File tld = MavenTestingUtils.getTestResourceFile("META-INF/foo-taglib.tld");
|
||||
File jar = MavenTestingUtils.getTargetFile("test-classes/taglib.jar");
|
||||
File tld = MavenTestingUtils.getTargetFile("test-classes/META-INF/foo-taglib.tld");
|
||||
|
||||
List<URL> list = new ArrayList<>();
|
||||
list.add(new URL("jar:" + jar.toURI().toURL().toString() + "!/META-INF/bar-taglib.tld"));
|
||||
|
|
|
@ -361,8 +361,8 @@ public class MavenWebAppContext extends WebAppContext
|
|||
// /WEB-INF/classes
|
||||
if ((resource == null || !resource.exists()) && pathInContext != null && _classes != null)
|
||||
{
|
||||
// Canonicalize again to look for the resource inside /WEB-INF subdirectories.
|
||||
String uri = URIUtil.canonicalPath(pathInContext);
|
||||
// Normalize again to look for the resource inside /WEB-INF subdirectories.
|
||||
String uri = URIUtil.normalizePath(pathInContext);
|
||||
if (uri == null)
|
||||
return null;
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ public class SelectiveJarResource extends Resource
|
|||
|
||||
LOG.debug("Looking at {}", entryName);
|
||||
// make sure no access out of the root entry is present
|
||||
String dotCheck = URIUtil.canonicalPath(entryName);
|
||||
String dotCheck = URIUtil.normalizePath(entryName);
|
||||
if (dotCheck == null)
|
||||
{
|
||||
LOG.info("Invalid entry: {}", entryName);
|
||||
|
|
|
@ -339,10 +339,10 @@ public class CachedContentFactory implements HttpContent.ContentFactory
|
|||
// a non shared resource. Also ignore max buffer size
|
||||
try
|
||||
{
|
||||
if (_useFileMappedBuffer && resource.getPath() != null && resource.length() < Integer.MAX_VALUE)
|
||||
return BufferUtil.toMappedBuffer(resource.getPath());
|
||||
if (_useFileMappedBuffer && resource.getPath() != null && resource.length() <= Integer.MAX_VALUE)
|
||||
return BufferUtil.toMappedBuffer(resource);
|
||||
}
|
||||
catch (IOException | IllegalArgumentException | UnsupportedOperationException e)
|
||||
catch (IOException | IllegalArgumentException e)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Unable to get Mapped Buffer for {}", resource, e);
|
||||
|
|
|
@ -68,12 +68,10 @@ import org.eclipse.jetty.http.HttpURI;
|
|||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.server.Context;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Handler.Nested;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.ContextRequest;
|
||||
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Index;
|
||||
|
@ -1660,7 +1658,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
: URIUtil.encodePath(servletContext.getContextPath());
|
||||
if (!StringUtil.isEmpty(encodedContextPath))
|
||||
{
|
||||
encodedPathQuery = URIUtil.canonicalPath(URIUtil.addEncodedPaths(encodedContextPath, encodedPathQuery));
|
||||
encodedPathQuery = URIUtil.normalizePath(URIUtil.addEncodedPaths(encodedContextPath, encodedPathQuery));
|
||||
if (encodedPathQuery == null)
|
||||
throw new BadMessageException(500, "Bad dispatch path");
|
||||
}
|
||||
|
@ -1832,8 +1830,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
@Override
|
||||
public String getRealPath(String path)
|
||||
{
|
||||
// This is an API call from the application which may have arbitrary non canonical paths passed
|
||||
// Thus we canonicalize here, to avoid the enforcement of only canonical paths in
|
||||
// This is an API call from the application which may pass non-canonical paths.
|
||||
// Thus, we canonicalize here, to avoid the enforcement of canonical paths in
|
||||
// ContextHandler.this.getResource(path).
|
||||
path = URIUtil.canonicalPath(path);
|
||||
if (path == null)
|
||||
|
@ -1864,8 +1862,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
@Override
|
||||
public URL getResource(String path) throws MalformedURLException
|
||||
{
|
||||
// This is an API call from the application which may have arbitrary non canonical paths passed
|
||||
// Thus we canonicalize here, to avoid the enforcement of only canonical paths in
|
||||
// This is an API call from the application which may pass non-canonical paths.
|
||||
// Thus, we canonicalize here, to avoid the enforcement of canonical paths in
|
||||
// ContextHandler.this.getResource(path).
|
||||
path = URIUtil.canonicalPath(path);
|
||||
if (path == null)
|
||||
|
@ -1900,8 +1898,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
@Override
|
||||
public Set<String> getResourcePaths(String path)
|
||||
{
|
||||
// This is an API call from the application which may have arbitrary non canonical paths passed
|
||||
// Thus we canonicalize here, to avoid the enforcement of only canonical paths in
|
||||
// This is an API call from the application which may pass non-canonical paths.
|
||||
// Thus, we canonicalize here, to avoid the enforcement of canonical paths in
|
||||
// ContextHandler.this.getResource(path).
|
||||
path = URIUtil.canonicalPath(path);
|
||||
if (path == null)
|
||||
|
|
|
@ -588,14 +588,14 @@ public class Response implements HttpServletResponse
|
|||
if (location.startsWith("/"))
|
||||
{
|
||||
// absolute in context
|
||||
location = URIUtil.canonicalURI(location);
|
||||
location = URIUtil.normalizePathQuery(location);
|
||||
}
|
||||
else
|
||||
{
|
||||
// relative to request
|
||||
String path = _channel.getRequest().getRequestURI();
|
||||
String parent = (path.endsWith("/")) ? path : URIUtil.parentPath(path);
|
||||
location = URIUtil.canonicalURI(URIUtil.addEncodedPaths(parent, location));
|
||||
location = URIUtil.normalizePathQuery(URIUtil.addEncodedPaths(parent, location));
|
||||
if (location != null && !location.startsWith("/"))
|
||||
buf.append('/');
|
||||
}
|
||||
|
|
|
@ -8,11 +8,11 @@ security
|
|||
client
|
||||
|
||||
[lib]
|
||||
lib/jetty-openid-${jetty.version}.jar
|
||||
lib/jetty-ee9-openid-${jetty.version}.jar
|
||||
lib/jetty-util-ajax-${jetty.version}.jar
|
||||
|
||||
[files]
|
||||
basehome:modules/openid/openid-baseloginservice.xml|etc/openid-baseloginservice.xml
|
||||
basehome:modules/openid/jetty-ee9-openid-baseloginservice.xml|etc/openid-baseloginservice.xml
|
||||
|
||||
[xml]
|
||||
etc/openid-baseloginservice.xml
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<Configure>
|
||||
<!-- Optional code to configure the base LoginService used by the OpenIdLoginService
|
||||
<New id="BaseLoginService" class="org.eclipse.jetty.security.HashLoginService">
|
||||
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
|
||||
<Set name="hotReload">true</Set>
|
||||
</New>
|
||||
-->
|
||||
</Configure>
|
Loading…
Reference in New Issue