Merge remote-tracking branch 'origin/master' into jetty-9.1
Conflicts: VERSION.txt aggregates/jetty-all/pom.xml examples/async-rest/async-rest-jar/pom.xml examples/async-rest/async-rest-webapp/pom.xml examples/async-rest/pom.xml examples/embedded/pom.xml examples/pom.xml jetty-annotations/pom.xml jetty-ant/pom.xml jetty-client/pom.xml jetty-continuation/pom.xml jetty-deploy/pom.xml jetty-distribution/pom.xml jetty-http-spi/pom.xml jetty-http/pom.xml jetty-io/pom.xml jetty-jaas/pom.xml jetty-jaspi/pom.xml jetty-jmx/pom.xml jetty-jndi/pom.xml jetty-jsp/pom.xml jetty-jspc-maven-plugin/pom.xml jetty-maven-plugin/pom.xml jetty-monitor/pom.xml jetty-nosql/pom.xml jetty-osgi/jetty-osgi-boot-jsp/pom.xml jetty-osgi/jetty-osgi-boot-warurl/pom.xml jetty-osgi/jetty-osgi-boot/pom.xml jetty-osgi/jetty-osgi-httpservice/pom.xml jetty-osgi/jetty-osgi-npn/pom.xml jetty-osgi/pom.xml jetty-osgi/test-jetty-osgi-context/pom.xml jetty-osgi/test-jetty-osgi-webapp/pom.xml jetty-overlay-deployer/pom.xml jetty-plus/pom.xml jetty-proxy/pom.xml jetty-rewrite/pom.xml jetty-runner/pom.xml jetty-security/pom.xml jetty-server/pom.xml jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java jetty-servlet/pom.xml jetty-servlets/pom.xml jetty-spdy/pom.xml jetty-spdy/spdy-client/pom.xml jetty-spdy/spdy-core/pom.xml jetty-spdy/spdy-example-webapp/pom.xml jetty-spdy/spdy-http-server/pom.xml jetty-spdy/spdy-server/pom.xml jetty-spring/pom.xml jetty-start/pom.xml jetty-util-ajax/pom.xml jetty-util/pom.xml jetty-webapp/pom.xml jetty-websocket/pom.xml jetty-websocket/websocket-api/pom.xml jetty-websocket/websocket-client/pom.xml jetty-websocket/websocket-common/pom.xml jetty-websocket/websocket-server/pom.xml jetty-websocket/websocket-servlet/pom.xml jetty-xml/pom.xml pom.xml tests/pom.xml tests/test-continuation/pom.xml tests/test-loginservice/pom.xml tests/test-sessions/pom.xml tests/test-sessions/test-hash-sessions/pom.xml tests/test-sessions/test-jdbc-sessions/pom.xml tests/test-sessions/test-sessions-common/pom.xml tests/test-webapps/pom.xml tests/test-webapps/test-jaas-webapp/pom.xml tests/test-webapps/test-jetty-webapp/pom.xml tests/test-webapps/test-jetty-webapp/src/main/config/demo/webapps/test.xml tests/test-webapps/test-jndi-webapp/pom.xml tests/test-webapps/test-mock-resources/pom.xml tests/test-webapps/test-proxy-webapp/pom.xml tests/test-webapps/test-servlet-spec/pom.xml tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml tests/test-webapps/test-webapp-rfc2616/pom.xml
This commit is contained in:
commit
280000e88a
|
@ -76,7 +76,9 @@ jetty-9.1.0.M0 - 13 August 2013
|
|||
generation/writing
|
||||
+ 414923 CompactPathRule needs to also compact the uri
|
||||
|
||||
jetty-9.0.5.v20130813 - 13 August 2013
|
||||
jetty-9.0.5.v20130815 - 15 August 2013
|
||||
+ 414898 Only upgrade v0 to v1 cookies on dquote , ; backslash space and tab
|
||||
in the value
|
||||
+ 404468 Ported jetty-http-spi to Jetty-9
|
||||
+ 405424 add X-Powered-By and Server header to SPDY
|
||||
+ 405535 implement Request.isUserInRole(role) check security-role-refs
|
||||
|
@ -157,7 +159,7 @@ jetty-9.0.5.v20130813 - 13 August 2013
|
|||
+ 414833 HttpSessionListener.destroy must be invoked in reverse order
|
||||
+ 414840 Request.login() throws NPE if username is null
|
||||
+ 414951 QueuedThreadPool fix constructor that missed to pass the idleTimeout
|
||||
+ 414972 HttpClient may read bytes with pre-tunnelled connection.i
|
||||
+ 414972 HttpClient may read bytes with pre-tunnelled connection.
|
||||
|
||||
jetty-9.0.4.v20130625 - 25 June 2013
|
||||
+ 396706 CGI support parameters
|
||||
|
|
|
@ -43,6 +43,11 @@ public class DumpServlet extends HttpServlet
|
|||
response.getWriter().println("servletPath=" + request.getServletPath());
|
||||
response.getWriter().println("pathInfo=" + request.getPathInfo());
|
||||
response.getWriter().println("session=" + request.getSession(true).getId());
|
||||
|
||||
String r=request.getParameter("resource");
|
||||
if (r!=null)
|
||||
response.getWriter().println("resource("+r+")=" + getServletContext().getResource(r));
|
||||
|
||||
response.getWriter().println("</pre>");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>9.0.5-SNAPSHOT</version>
|
||||
<version>9.1.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -832,6 +832,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
|
|||
if (_eof)
|
||||
{
|
||||
// Handle EOF
|
||||
_in.close();
|
||||
closed();
|
||||
_channel.getByteBufferPool().release(_buffer);
|
||||
return true;
|
||||
|
@ -843,7 +844,6 @@ public class HttpOutput extends ServletOutputStream implements Runnable
|
|||
{
|
||||
_eof=true;
|
||||
len=0;
|
||||
_in.close();
|
||||
}
|
||||
else if (len<_buffer.capacity())
|
||||
{
|
||||
|
@ -907,6 +907,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
|
|||
{
|
||||
if (_eof)
|
||||
{
|
||||
_in.close();
|
||||
closed();
|
||||
_channel.getByteBufferPool().release(_buffer);
|
||||
return true;
|
||||
|
@ -918,6 +919,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
|
|||
if (len<0)
|
||||
{
|
||||
_eof=true;
|
||||
len=0;
|
||||
_in.close();
|
||||
}
|
||||
else if (len<_buffer.capacity())
|
||||
|
|
|
@ -1597,7 +1597,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
{
|
||||
path = URIUtil.canonicalPath(path);
|
||||
Resource resource = _baseResource.addPath(path);
|
||||
|
||||
|
||||
// Is the resource aliased?
|
||||
if (resource.getAlias() != null)
|
||||
{
|
||||
|
@ -2645,8 +2645,13 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
* Eg. a symbolic link from /foobar.html to /somewhere/wibble.html would be
|
||||
* approved because both the resource and alias end with ".html".
|
||||
*/
|
||||
@Deprecated
|
||||
public static class ApproveSameSuffixAliases implements AliasCheck
|
||||
{
|
||||
{
|
||||
LOG.warn("ApproveSameSuffixAlias is not safe for production");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(String path, Resource resource)
|
||||
{
|
||||
|
@ -2664,8 +2669,13 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
* Eg. a symbolic link from /dirA/foobar.html to /dirB/foobar.html would be
|
||||
* approved because both the resource and alias end with "/foobar.html".
|
||||
*/
|
||||
@Deprecated
|
||||
public static class ApprovePathPrefixAliases implements AliasCheck
|
||||
{
|
||||
{
|
||||
LOG.warn("ApprovePathPrefixAliases is not safe for production");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(String path, Resource resource)
|
||||
{
|
||||
|
@ -2676,6 +2686,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
return resource.toString().endsWith(suffix);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Approve Aliases of a non existent directory.
|
||||
* If a directory "/foobar/" does not exist, then the resource is
|
||||
|
@ -2686,11 +2697,17 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
@Override
|
||||
public boolean check(String path, Resource resource)
|
||||
{
|
||||
int slash = path.lastIndexOf('/');
|
||||
if (slash<0 || resource.exists())
|
||||
if (resource.exists())
|
||||
return false;
|
||||
String suffix=path.substring(slash);
|
||||
return resource.getAlias().toString().endsWith(suffix);
|
||||
|
||||
String a=resource.getAlias().toString();
|
||||
String r=resource.getURL().toString();
|
||||
|
||||
if (a.length()>r.length())
|
||||
return a.startsWith(r) && a.length()==r.length()+1 && a.endsWith("/");
|
||||
else
|
||||
return r.startsWith(a) && r.length()==a.length()+1 && r.endsWith("/");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,311 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server.handler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.eclipse.jetty.toolchain.test.OS;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ContextHandlerGetResourceTest
|
||||
{
|
||||
private static Server server;
|
||||
private static ContextHandler context;
|
||||
private static File docroot;
|
||||
private final static AtomicBoolean allowAliases= new AtomicBoolean(false);
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception
|
||||
{
|
||||
docroot = new File("target/tests/docroot").getCanonicalFile().getAbsoluteFile();
|
||||
FS.ensureDirExists(docroot);
|
||||
FS.ensureEmpty(docroot);
|
||||
File index = new File(docroot,"index.html");
|
||||
index.createNewFile();
|
||||
File sub = new File(docroot,"subdir");
|
||||
sub.mkdir();
|
||||
File data = new File(sub,"data.txt");
|
||||
data.createNewFile();
|
||||
File verylong = new File(sub,"TextFile.Long.txt");
|
||||
verylong.createNewFile();
|
||||
|
||||
if (!OS.IS_WINDOWS)
|
||||
{
|
||||
// Create alias as 8.3 name so same test will produce an alias on both windows an normal systems
|
||||
File eightDotThree=new File(sub,"TEXTFI~1.TXT");
|
||||
Files.createSymbolicLink(eightDotThree.toPath(),verylong.toPath());
|
||||
}
|
||||
|
||||
|
||||
server = new Server();
|
||||
context =new ContextHandler("/");
|
||||
context.setBaseResource(Resource.newResource(docroot));
|
||||
context.addAliasCheck(new ContextHandler.AliasCheck()
|
||||
{
|
||||
@Override
|
||||
public boolean check(String path, Resource resource)
|
||||
{
|
||||
return allowAliases.get();
|
||||
}
|
||||
});
|
||||
|
||||
server.setHandler(context);
|
||||
server.start();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBadPath() throws Exception
|
||||
{
|
||||
final String path="bad";
|
||||
try
|
||||
{
|
||||
context.getResource(path);
|
||||
fail();
|
||||
}
|
||||
catch(MalformedURLException e)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
context.getServletContext().getResource(path);
|
||||
fail();
|
||||
}
|
||||
catch(MalformedURLException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnknown() throws Exception
|
||||
{
|
||||
final String path="/unknown.txt";
|
||||
Resource resource=context.getResource(path);
|
||||
assertEquals("unknown.txt",resource.getFile().getName());
|
||||
assertEquals(docroot,resource.getFile().getParentFile());
|
||||
assertFalse(resource.exists());
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertNull(url);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnknownDir() throws Exception
|
||||
{
|
||||
final String path="/unknown/";
|
||||
Resource resource=context.getResource(path);
|
||||
assertEquals("unknown",resource.getFile().getName());
|
||||
assertEquals(docroot,resource.getFile().getParentFile());
|
||||
assertFalse(resource.exists());
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertNull(url);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoot() throws Exception
|
||||
{
|
||||
final String path="/";
|
||||
Resource resource=context.getResource(path);
|
||||
assertEquals(docroot,resource.getFile());
|
||||
assertTrue(resource.exists());
|
||||
assertTrue(resource.isDirectory());
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertEquals(docroot,new File(url.toURI()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubdir() throws Exception
|
||||
{
|
||||
final String path="/subdir";
|
||||
Resource resource=context.getResource(path);
|
||||
assertEquals(docroot,resource.getFile().getParentFile());
|
||||
assertTrue(resource.exists());
|
||||
assertTrue(resource.isDirectory());
|
||||
assertTrue(resource.toString().endsWith("/"));
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertEquals(docroot,new File(url.toURI()).getParentFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubdirSlash() throws Exception
|
||||
{
|
||||
final String path="/subdir/";
|
||||
Resource resource=context.getResource(path);
|
||||
assertEquals(docroot,resource.getFile().getParentFile());
|
||||
assertTrue(resource.exists());
|
||||
assertTrue(resource.isDirectory());
|
||||
assertTrue(resource.toString().endsWith("/"));
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertEquals(docroot,new File(url.toURI()).getParentFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetKnown() throws Exception
|
||||
{
|
||||
final String path="/index.html";
|
||||
Resource resource=context.getResource(path);
|
||||
assertEquals("index.html",resource.getFile().getName());
|
||||
assertEquals(docroot,resource.getFile().getParentFile());
|
||||
assertTrue(resource.exists());
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertEquals(docroot,new File(url.toURI()).getParentFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalize() throws Exception
|
||||
{
|
||||
final String path="/down/.././index.html";
|
||||
Resource resource=context.getResource(path);
|
||||
assertEquals("index.html",resource.getFile().getName());
|
||||
assertEquals(docroot,resource.getFile().getParentFile());
|
||||
assertTrue(resource.exists());
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertEquals(docroot,new File(url.toURI()).getParentFile());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testTooNormal() throws Exception
|
||||
{
|
||||
final String path="/down/.././../";
|
||||
Resource resource=context.getResource(path);
|
||||
assertNull(resource);
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertNull(url);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeep() throws Exception
|
||||
{
|
||||
final String path="/subdir/data.txt";
|
||||
Resource resource=context.getResource(path);
|
||||
assertEquals("data.txt",resource.getFile().getName());
|
||||
assertEquals(docroot,resource.getFile().getParentFile().getParentFile());
|
||||
assertTrue(resource.exists());
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertEquals(docroot,new File(url.toURI()).getParentFile().getParentFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodedSlash() throws Exception
|
||||
{
|
||||
final String path="/subdir%2Fdata.txt";
|
||||
|
||||
Resource resource=context.getResource(path);
|
||||
assertEquals("subdir%2Fdata.txt",resource.getFile().getName());
|
||||
assertEquals(docroot,resource.getFile().getParentFile());
|
||||
assertFalse(resource.exists());
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertNull(url);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodedSlosh() throws Exception
|
||||
{
|
||||
final String path="/subdir%5Cdata.txt";
|
||||
|
||||
Resource resource=context.getResource(path);
|
||||
assertEquals("subdir%5Cdata.txt",resource.getFile().getName());
|
||||
assertEquals(docroot,resource.getFile().getParentFile());
|
||||
assertFalse(resource.exists());
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertNull(url);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodedNull() throws Exception
|
||||
{
|
||||
final String path="/subdir/data.txt%00";
|
||||
|
||||
Resource resource=context.getResource(path);
|
||||
assertEquals("data.txt%00",resource.getFile().getName());
|
||||
assertEquals(docroot,resource.getFile().getParentFile().getParentFile());
|
||||
assertFalse(resource.exists());
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertNull(url);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAliasedFile() throws Exception
|
||||
{
|
||||
final String path="/subdir/TEXTFI~1.TXT";
|
||||
|
||||
Resource resource=context.getResource(path);
|
||||
assertNull(resource);
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertNull(url);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAliasedFileAllowed() throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
allowAliases.set(true);
|
||||
final String path="/subdir/TEXTFI~1.TXT";
|
||||
|
||||
Resource resource=context.getResource(path);
|
||||
assertNotNull(resource);
|
||||
assertEquals(context.getResource("/subdir/TextFile.Long.txt").getURL(),resource.getAlias());
|
||||
|
||||
URL url=context.getServletContext().getResource(path);
|
||||
assertNotNull(url);
|
||||
assertEquals(docroot,new File(url.toURI()).getParentFile().getParentFile());
|
||||
}
|
||||
finally
|
||||
{
|
||||
allowAliases.set(false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -45,7 +45,6 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* This class can check for aliasing in the filesystem (eg case
|
||||
* insensitivity). By default this is turned on, or it can be controlled
|
||||
* by calling the static method @see FileResource#setCheckAliases(boolean)
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class FileResource extends Resource
|
||||
|
@ -169,7 +168,7 @@ public class FileResource extends Resource
|
|||
return this;
|
||||
|
||||
path=URIUtil.encodePath(path);
|
||||
|
||||
// The encoded path should be a suffix of the resource (give or take a directory / )
|
||||
URI uri;
|
||||
try
|
||||
{
|
||||
|
|
|
@ -28,19 +28,7 @@ detected.
|
|||
<Set name="copyWebDir">false</Set>
|
||||
<Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>
|
||||
<Set name="overrideDescriptor"><Property name="jetty.base" default="."/>/demo/override-web.xml</Set>
|
||||
|
||||
<!-- Allow directory symbolic links -->
|
||||
<Call name="addAliasCheck">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.handler.ContextHandler$ApprovePathPrefixAliases"/>
|
||||
</Arg>
|
||||
</Call>
|
||||
<!-- Allow file symbolic links -->
|
||||
<Call name="addAliasCheck">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.handler.ContextHandler$ApproveSameSuffixAliases"/>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
|
||||
<!-- virtual hosts
|
||||
<Set name="virtualHosts">
|
||||
|
|
Loading…
Reference in New Issue