Merge remote-tracking branch 'origin/jetty-8'

Conflicts:
	VERSION.txt
	jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java
	jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java
	jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java
	jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java
	jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java
	jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java
This commit is contained in:
Greg Wilkins 2012-11-30 12:04:00 +11:00
commit b3e1114313
10 changed files with 226 additions and 98 deletions

View File

@ -0,0 +1,113 @@
//
// ========================================================================
// 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.rewrite.handler;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.util.URIUtil;
/**
* This rule can be used to protect against invalid unicode characters in a url making it into applications.
*
* The logic is as follows.
*
* - if decoded uri character is an iso control character return code/reason
* - if no UnicodeBlock is found for character return code/reason
* - if character is in UnicodeBlock.SPECIALS return code/reason
*/
public class ValidUrlRule extends Rule
{
String _code = "400";
String _reason = "Illegal Url";
public ValidUrlRule()
{
_handling = true;
_terminating = true;
}
/* ------------------------------------------------------------ */
/**
* Sets the response status code.
*
* @param code
* response code
*/
public void setCode(String code)
{
_code = code;
}
/* ------------------------------------------------------------ */
/**
* Sets the reason for the response status code. Reasons will only reflect if the code value is greater or equal to 400.
*
* @param reason
*/
public void setReason(String reason)
{
_reason = reason;
}
@Override
public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
{
// best to decide the request uri and validate that
String uri = URIUtil.decodePath(request.getRequestURI());
for (int i = 0; i < uri.length(); ++i)
{
if (!isValidChar(uri.charAt(i)))
{
int code = Integer.parseInt(_code);
// status code 400 and up are error codes so include a reason
if (code >= 400)
{
response.sendError(code,_reason);
}
else
{
response.setStatus(code);
}
// we have matched, return target and consider it is handled
return target;
}
}
// we have not matched so return null
return null;
}
protected boolean isValidChar(char c)
{
Character.UnicodeBlock block = Character.UnicodeBlock.of(c);
return (!Character.isISOControl(c)) && block != null && block != Character.UnicodeBlock.SPECIALS;
}
public String toString()
{
return super.toString() + "[" + _code + ":" + _reason + "]";
}
}

View File

@ -0,0 +1,82 @@
//
// ========================================================================
// 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.rewrite.handler;
import static org.junit.Assert.assertEquals;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
public class ValidUrlRuleTest extends AbstractRuleTestCase
{
private ValidUrlRule _rule;
@Before
public void init() throws Exception
{
start(true);
_rule = new ValidUrlRule();
}
@Test
public void testValidUrl() throws Exception
{
_rule.setCode("404");
_request.setRequestURI("/valid/uri.html");
_rule.matchAndApply(_request.getRequestURI(), _request, _response);
assertEquals(0,_response.getStatus());
}
@Test
public void testInvalidUrl() throws Exception
{
_rule.setCode("404");
_request.setRequestURI("/invalid%0c/uri.html");
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
assertEquals(404,_response.getStatus());
}
@Test
public void testInvalidUrlWithReason() throws Exception
{
_rule.setCode("405");
_rule.setReason("foo");
_request.setRequestURI("/%00/");
String result = _rule.matchAndApply(_request.getRequestURI(), _request, _response);
assertEquals(405,_response.getStatus());
assertEquals("foo",_response.getReason());
}
@Test
public void testCharacters() throws Exception
{
// space
Assert.assertTrue( _rule.isValidChar("\u0020".charAt(0)));
// form feed
Assert.assertFalse( _rule.isValidChar("\u000c".charAt(0)));
}
}

View File

@ -272,7 +272,9 @@ public class MultipartFilterTest
HttpTester.Request request = HttpTester.newRequest();
HttpTester.Response response;
// test GET
tester.setAttribute("fileName", "abc");
tester.setAttribute("desc", "123");
tester.setAttribute("title", "ttt");
request.setMethod("POST");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
@ -311,7 +313,8 @@ public class MultipartFilterTest
response = HttpTester.parseResponse(tester.getResponses(request.generate()));
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
}
@Test
public void testLFOnlyRequest() throws Exception
{

View File

@ -47,7 +47,6 @@ public class Loader
{
/* ------------------------------------------------------------ */
public static URL getResource(Class<?> loadClass,String name, boolean checkParents)
throws ClassNotFoundException
{
URL url =null;
ClassLoader loader=Thread.currentThread().getContextClassLoader();

View File

@ -470,7 +470,7 @@ public class MultiPartInputStreamParser
byte[] byteBoundary=(boundary+"--").getBytes(StringUtil.__ISO_8859_1);
// Get first boundary
String line = ((ReadLineInputStream)_in).readLine();
String line=((ReadLineInputStream)_in).readLine();
if(line==null || !line.equals(boundary))
{
throw new IOException("Missing initial multi part boundary");
@ -486,14 +486,14 @@ public class MultiPartInputStreamParser
MultiMap headers = new MultiMap();
while(true)
{
line = ((ReadLineInputStream)_in).readLine();
line=((ReadLineInputStream)_in).readLine();
//run out of input:
if (line == null)
//No more input
if(line==null)
break outer;
//end of headers:
if ("".equals(line))
if("".equals(line))
break;
total += line.length();
@ -619,7 +619,7 @@ public class MultiPartInputStreamParser
if (tmp!=10)
_in.reset();
else
state=tmp;
state=tmp;
}
break;
}

View File

@ -474,58 +474,6 @@ public class TypeUtil
}
/* ------------------------------------------------------------ */
@Deprecated
public static byte[] readLine(InputStream in) throws IOException
{
byte[] buf = new byte[256];
int i=0;
int loops=0;
int ch=0;
while (true)
{
ch=in.read();
if (ch<0)
break;
loops++;
// skip a leading LF's
if (loops==1 && ch==LF)
continue;
if (ch==CR || ch==LF)
break;
if (i>=buf.length)
{
byte[] old_buf=buf;
buf=new byte[old_buf.length+256];
System.arraycopy(old_buf, 0, buf, 0, old_buf.length);
}
buf[i++]=(byte)ch;
}
if (ch==-1 && i==0)
return null;
// skip a trailing LF if it exists
if (ch==CR && in.available()>=1 && in.markSupported())
{
in.mark(1);
ch=in.read();
if (ch!=LF)
in.reset();
}
byte[] old_buf=buf;
buf=new byte[i];
System.arraycopy(old_buf, 0, buf, 0, i);
return buf;
}
public static Object call(Class<?> oClass, String methodName, Object obj, Object[] arg)
throws InvocationTargetException, NoSuchMethodException
{

View File

@ -89,7 +89,7 @@ public class Log
* configuration of the Log class in situations where access to the System.properties are
* either too late or just impossible.
*/
URL testProps = Log.class.getClassLoader().getResource("jetty-logging.properties");
URL testProps = Loader.getResource(Log.class,"jetty-logging.properties",true);
if (testProps != null)
{
InputStream in = null;
@ -241,7 +241,7 @@ public class Log
public static void setLogToParent(String name)
{
ClassLoader loader = Log.class.getClassLoader();
if (loader.getParent()!=null)
if (loader!=null && loader.getParent()!=null)
{
try
{

View File

@ -299,16 +299,7 @@ public abstract class Resource implements ResourceFactory
URL url=Resource.class.getResource(name);
if (url==null)
{
try
{
url=Loader.getResource(Resource.class,name,checkParents);
}
catch(ClassNotFoundException e)
{
url=ClassLoader.getSystemResource(name);
}
}
url=Loader.getResource(Resource.class,name,checkParents);
if (url==null)
return null;
return newResource(url,useCaches);

View File

@ -376,7 +376,6 @@ public class MultiPartInputStreamTest
assertThat(baos.toString("UTF-8"), is("Other"));
}
public void testMulti ()
throws Exception
{

View File

@ -95,32 +95,25 @@ public class XmlConfiguration
private synchronized static XmlParser initParser()
{
XmlParser parser = new XmlParser();
try
{
URL config60 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_6_0.dtd",true);
URL config76 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_7_6.dtd",true);
URL config90 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_9_0.dtd",true);
parser.redirectEntity("configure.dtd",config90);
parser.redirectEntity("configure_1_0.dtd",config60);
parser.redirectEntity("configure_1_1.dtd",config60);
parser.redirectEntity("configure_1_2.dtd",config60);
parser.redirectEntity("configure_1_3.dtd",config60);
parser.redirectEntity("configure_6_0.dtd",config60);
parser.redirectEntity("configure_7_6.dtd",config76);
parser.redirectEntity("configure_9_0.dtd",config90);
URL config60 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_6_0.dtd",true);
URL config76 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_7_6.dtd",true);
URL config90 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_9_0.dtd",true);
parser.redirectEntity("configure.dtd",config90);
parser.redirectEntity("configure_1_0.dtd",config60);
parser.redirectEntity("configure_1_1.dtd",config60);
parser.redirectEntity("configure_1_2.dtd",config60);
parser.redirectEntity("configure_1_3.dtd",config60);
parser.redirectEntity("configure_6_0.dtd",config60);
parser.redirectEntity("configure_7_6.dtd",config76);
parser.redirectEntity("configure_9_0.dtd",config90);
parser.redirectEntity("http://jetty.mortbay.org/configure.dtd",config90);
parser.redirectEntity("http://jetty.eclipse.org/configure.dtd",config90);
parser.redirectEntity("http://www.eclipse.org/jetty/configure.dtd",config90);
parser.redirectEntity("http://jetty.mortbay.org/configure.dtd",config90);
parser.redirectEntity("http://jetty.eclipse.org/configure.dtd",config90);
parser.redirectEntity("http://www.eclipse.org/jetty/configure.dtd",config90);
parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN",config90);
parser.redirectEntity("-//Jetty//Configure//EN",config90);
parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN",config90);
parser.redirectEntity("-//Jetty//Configure//EN",config90);
}
catch (ClassNotFoundException e)
{
LOG.warn(e.toString());
LOG.debug(e);
}
return parser;
}