Merge branch 'jetty-7' into jetty-8
This commit is contained in:
commit
9fde0c56ab
|
@ -22,9 +22,9 @@ import static org.junit.Assert.assertEquals;
|
|||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class ValidUrlRuleTest extends AbstractRuleTestCase
|
||||
{
|
||||
private ValidUrlRule _rule;
|
||||
|
@ -89,7 +89,7 @@ public class ValidUrlRuleTest extends AbstractRuleTestCase
|
|||
{
|
||||
_rule.setCode("405");
|
||||
_rule.setReason("foo");
|
||||
_request.setRequestURI("/jsp/shamrock-%002618.jsp");
|
||||
_request.setRequestURI("/jsp/shamrock-%00%E2%98%98.jsp");
|
||||
|
||||
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
|
||||
|
||||
|
@ -97,13 +97,12 @@ public class ValidUrlRuleTest extends AbstractRuleTestCase
|
|||
assertEquals("foo",_response.getReason());
|
||||
}
|
||||
|
||||
@Ignore("Not passing (yet), issue in uri decoding")
|
||||
@Test
|
||||
public void testValidShamrock() throws Exception
|
||||
{
|
||||
_rule.setCode("405");
|
||||
_rule.setReason("foo");
|
||||
_request.setRequestURI("/jsp/shamrock-%00%E2%98%98.jsp");
|
||||
_request.setRequestURI("/jsp/shamrock-%E2%98%98.jsp");
|
||||
|
||||
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
|
||||
|
||||
|
|
|
@ -75,6 +75,37 @@ public class FileResource extends URLResource
|
|||
return __checkAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform some basic validation of the characters in the string for invalid
|
||||
* codepoints and null characters.
|
||||
*
|
||||
* @param str the string to validate
|
||||
* @throws URISyntaxException thrown if invalid characters are encountered
|
||||
*/
|
||||
private static final String validateUri(String str) throws URISyntaxException
|
||||
{
|
||||
if (str == null)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
int len = str.length();
|
||||
int codepoint;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
codepoint = str.codePointAt(i);
|
||||
if (codepoint == 0)
|
||||
{
|
||||
throw new URISyntaxException(str,"Encountered NULL character");
|
||||
}
|
||||
if (Character.isISOControl(codepoint))
|
||||
{
|
||||
throw new URISyntaxException(str,"Encountered ISO Control Code");
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
public FileResource(URL url)
|
||||
throws IOException, URISyntaxException
|
||||
|
@ -84,8 +115,23 @@ public class FileResource extends URLResource
|
|||
try
|
||||
{
|
||||
// Try standard API to convert URL to file.
|
||||
|
||||
/* Note:
|
||||
* If the passed in URL has a null at the end of the string, then
|
||||
* url.toExternalForm() and url.toString() strip that knowledge out.
|
||||
* Which can lead to false positives for .exists() calls.
|
||||
*
|
||||
* The URL should be validated in parts, then passed to the File object.
|
||||
*/
|
||||
validateUri(url.getFile());
|
||||
validateUri(url.getPath());
|
||||
|
||||
_file =new File(new URI(url.toString()));
|
||||
}
|
||||
catch (URISyntaxException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.ignore(e);
|
||||
|
@ -98,7 +144,7 @@ public class FileResource extends URLResource
|
|||
if (uri.getAuthority()==null)
|
||||
_file = new File(uri);
|
||||
else
|
||||
_file = new File("//"+uri.getAuthority()+URIUtil.decodePath(url.getFile()));
|
||||
_file = new File(validateUri("//"+uri.getAuthority()+URIUtil.decodePath(url.getFile())));
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 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.util.resource;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.UrlEncoded;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
public class FileResourceTest
|
||||
{
|
||||
@Rule
|
||||
public TestingDir testdir = new TestingDir();
|
||||
|
||||
private URI createDummyFile(String name) throws IOException
|
||||
{
|
||||
File file = testdir.getFile(name);
|
||||
file.createNewFile();
|
||||
return file.toURI();
|
||||
}
|
||||
|
||||
private URL decode(URL url) throws MalformedURLException
|
||||
{
|
||||
String raw = url.toExternalForm();
|
||||
String decoded = UrlEncoded.decodeString(raw,0,raw.length(),StringUtil.__UTF8);
|
||||
return new URL(decoded);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExist_Normal() throws Exception
|
||||
{
|
||||
createDummyFile("a.jsp");
|
||||
|
||||
URI ref = testdir.getDir().toURI().resolve("a.jsp");
|
||||
FileResource fileres = new FileResource(decode(ref.toURL()));
|
||||
Assert.assertThat("FileResource: " + fileres,fileres.exists(),is(true));
|
||||
}
|
||||
|
||||
@Ignore("Cannot get null to be seen by FileResource")
|
||||
@Test
|
||||
public void testExist_BadNull() throws Exception
|
||||
{
|
||||
createDummyFile("a.jsp");
|
||||
|
||||
try {
|
||||
// request with null at end
|
||||
URI ref = testdir.getDir().toURI().resolve("a.jsp%00");
|
||||
FileResource fileres = new FileResource(decode(ref.toURL()));
|
||||
Assert.assertThat("FileResource: " + fileres,fileres.exists(),is(false));
|
||||
} catch(URISyntaxException e) {
|
||||
// Valid path
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExist_BadNullX() throws Exception
|
||||
{
|
||||
createDummyFile("a.jsp");
|
||||
|
||||
try {
|
||||
// request with null and x at end
|
||||
URI ref = testdir.getDir().toURI().resolve("a.jsp%00x");
|
||||
FileResource fileres = new FileResource(decode(ref.toURL()));
|
||||
Assert.assertThat("FileResource: " + fileres,fileres.exists(),is(false));
|
||||
} catch(URISyntaxException e) {
|
||||
// Valid path
|
||||
}
|
||||
}
|
||||
}
|
|
@ -201,7 +201,7 @@
|
|||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet.jsp</groupId>
|
||||
|
|
|
@ -77,6 +77,13 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<forkMode>always</forkMode>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
|
@ -105,11 +112,26 @@
|
|||
<artifactId>jetty-monitor</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet.jsp</groupId>
|
||||
<artifactId>jsp-api</artifactId>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
<artifactId>jetty-test-helper</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jsp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-webapp-rfc2616</artifactId>
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 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.test.jsp;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.jasper.servlet.JspServlet;
|
||||
import org.eclipse.jetty.security.HashLoginService;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.nio.SelectChannelConnector;
|
||||
import org.eclipse.jetty.servlet.DefaultServlet;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JspMatchingTest
|
||||
{
|
||||
private static Server server;
|
||||
private static URI serverURI;
|
||||
|
||||
@BeforeClass
|
||||
public static void startServer() throws Exception
|
||||
{
|
||||
server = new Server();
|
||||
SelectChannelConnector connector = new SelectChannelConnector();
|
||||
connector.setPort(0);
|
||||
server.addConnector(connector);
|
||||
|
||||
// Configure LoginService
|
||||
HashLoginService login = new HashLoginService();
|
||||
login.setName("Test Realm");
|
||||
File realmFile = MavenTestingUtils.getTestResourceFile("realm.properties");
|
||||
login.setConfig(realmFile.getAbsolutePath());
|
||||
server.addBean(login);
|
||||
|
||||
// Configure WebApp
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/");
|
||||
File webappBase = MavenTestingUtils.getTestResourceDir("docroots/jsp");
|
||||
context.setResourceBase(webappBase.getAbsolutePath());
|
||||
context.setClassLoader(Thread.currentThread().getContextClassLoader());
|
||||
|
||||
// add default servlet
|
||||
ServletHolder defaultServHolder = context.addServlet(DefaultServlet.class, "/");
|
||||
defaultServHolder.setInitParameter("aliases", "true"); // important!
|
||||
|
||||
// add jsp
|
||||
ServletHolder jsp = context.addServlet(JspServlet.class,"*.jsp");
|
||||
jsp.setInitParameter("classpath", context.getClassPath());
|
||||
|
||||
// add context
|
||||
server.setHandler(context);
|
||||
|
||||
server.start();
|
||||
|
||||
serverURI = new URI("http://localhost:" + connector.getLocalPort() + "/");
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopServer() throws Exception
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBeanRef() throws Exception
|
||||
{
|
||||
|
||||
URI uri = serverURI.resolve("/dump.jsp");
|
||||
|
||||
HttpURLConnection conn = null;
|
||||
try
|
||||
{
|
||||
conn = (HttpURLConnection)uri.toURL().openConnection();
|
||||
conn.setConnectTimeout(1000);
|
||||
conn.setReadTimeout(1000);
|
||||
Assert.assertThat(conn.getResponseCode(),is(200));
|
||||
System.err.printf("Response Code: %d%n", conn.getResponseCode());
|
||||
|
||||
// make sure that jsp actually ran, and didn't just get passed onto
|
||||
// the default servlet to return the jsp source
|
||||
String body = getResponseBody(conn);
|
||||
Assert.assertThat("Body", body, not(containsString("<%@")));
|
||||
Assert.assertThat("Body", body, not(containsString("<jsp:")));
|
||||
}
|
||||
finally
|
||||
{
|
||||
close(conn);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBeanRefInvalid_null() throws Exception
|
||||
{
|
||||
|
||||
URI uri = serverURI.resolve("/dump.jsp%00");
|
||||
|
||||
HttpURLConnection conn = null;
|
||||
try
|
||||
{
|
||||
conn = (HttpURLConnection)uri.toURL().openConnection();
|
||||
conn.setConnectTimeout(1000);
|
||||
conn.setReadTimeout(1000);
|
||||
Assert.assertThat(conn.getResponseCode(),is(404));
|
||||
System.err.printf("Response Code: %d%n", conn.getResponseCode());
|
||||
}
|
||||
finally
|
||||
{
|
||||
close(conn);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBeanRefInvalid_nullx() throws Exception
|
||||
{
|
||||
|
||||
URI uri = serverURI.resolve("/dump.jsp%00x");
|
||||
|
||||
HttpURLConnection conn = null;
|
||||
try
|
||||
{
|
||||
conn = (HttpURLConnection)uri.toURL().openConnection();
|
||||
conn.setConnectTimeout(1000);
|
||||
conn.setReadTimeout(1000);
|
||||
Assert.assertThat(conn.getResponseCode(),is(404));
|
||||
System.err.printf("Response Code: %d%n", conn.getResponseCode());
|
||||
}
|
||||
finally
|
||||
{
|
||||
close(conn);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getResponseBody(HttpURLConnection conn) throws IOException
|
||||
{
|
||||
InputStream in = null;
|
||||
try
|
||||
{
|
||||
in = conn.getInputStream();
|
||||
return IO.toString(in);
|
||||
}
|
||||
finally
|
||||
{
|
||||
IO.close(in);
|
||||
}
|
||||
}
|
||||
|
||||
private void close(HttpURLConnection conn)
|
||||
{
|
||||
conn.disconnect();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<html><head>
|
||||
<%@ page import="java.util.Enumeration" %>
|
||||
</head><body>
|
||||
<h1>JSP Dump</h1>
|
||||
|
||||
<table border="1">
|
||||
<tr><th>Request URI:</th><td><%= request.getRequestURI() %></td></tr>
|
||||
<tr><th>ServletPath:</th><td><%= request.getServletPath() %></td></tr>
|
||||
<tr><th>PathInfo:</th><td><%= request.getPathInfo() %></td></tr>
|
||||
|
||||
<%
|
||||
Enumeration e =request.getParameterNames();
|
||||
while(e.hasMoreElements())
|
||||
{
|
||||
String name = (String)e.nextElement();
|
||||
%>
|
||||
<tr>
|
||||
<th>getParameter("<%= name %>")</th>
|
||||
<td><%= request.getParameter(name) %></td></tr>
|
||||
<% } %>
|
||||
|
||||
</table>
|
||||
</body></html>
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# This file defines users passwords and roles for a HashUserRealm
|
||||
#
|
||||
# The format is
|
||||
# <username>: <password>[,<rolename> ...]
|
||||
#
|
||||
# Passwords may be clear text, obfuscated or checksummed. The class
|
||||
# org.eclipse.util.Password should be used to generate obfuscated
|
||||
# passwords or password checksums
|
||||
#
|
||||
# If DIGEST Authentication is used, the password must be in a recoverable
|
||||
# format, either plain text or OBF:.
|
||||
#
|
||||
jetty: MD5:164c88b302622e17050af52c89945d44,user
|
||||
admin: CRYPT:adpexzg3FUZAk,server-administrator,content-administrator,admin
|
||||
other: OBF:1xmk1w261u9r1w1c1xmq,user
|
||||
plain: plain,user
|
||||
user: password,user
|
||||
|
||||
# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password
|
||||
digest: MD5:6e120743ad67abfbc385bc2bb754e297,user
|
Loading…
Reference in New Issue