Merge branch 'master' into release-9

This commit is contained in:
Jesse McConnell 2014-05-26 10:46:39 -05:00
commit 8936b160c2
28 changed files with 236 additions and 89 deletions

48
jetty-distribution/src/main/resources/bin/jetty.sh Normal file → Executable file
View File

@ -258,6 +258,29 @@ then
fi
fi
#####################################################
# Find a location for the pid file
#####################################################
if [ -z "$JETTY_RUN" ]
then
JETTY_RUN=$(findDirectory -w /var/run /usr/var/run $JETTY_BASE /tmp)
fi
#####################################################
# Find a pid and state file
#####################################################
if [ -z "$JETTY_PID" ]
then
JETTY_PID="$JETTY_RUN/${NAME}.pid"
fi
if [ -z "$JETTY_STATE" ]
then
JETTY_STATE=$JETTY_BASE/${NAME}.state
fi
JETTY_ARGS+=("jetty.state=$JETTY_STATE")
rm -f $JETTY_STATE
##################################################
# Get the list of config.xml files from jetty.conf
##################################################
@ -290,29 +313,6 @@ then
done < "$JETTY_CONF"
fi
#####################################################
# Find a location for the pid file
#####################################################
if [ -z "$JETTY_RUN" ]
then
JETTY_RUN=$(findDirectory -w /var/run /usr/var/run $JETTY_BASE /tmp)
fi
#####################################################
# Find a pid and state file
#####################################################
if [ -z "$JETTY_PID" ]
then
JETTY_PID="$JETTY_RUN/${NAME}.pid"
fi
if [ -z "$JETTY_STATE" ]
then
JETTY_STATE=$JETTY_BASE/${NAME}.state
fi
JAVA_OPTIONS+=("-Djetty.state=$JETTY_STATE")
rm -f $JETTY_STATE
##################################################
# Setup JAVA if unset
##################################################
@ -410,7 +410,7 @@ case "$ACTION" in
CH_USER="-c$JETTY_USER"
fi
start-stop-daemon -S -p"$JETTY_PID" $CH_USER -d"$JETTY_HOME" -b -m -a "$JAVA" -- "${RUN_ARGS[@]}" start-log-file="$JETTY_LOGS/start.log"
start-stop-daemon -S -p"$JETTY_PID" $CH_USER -d"$JETTY_BASE" -b -m -a "$JAVA" -- "${RUN_ARGS[@]}" start-log-file="$JETTY_LOGS/start.log"
else

View File

@ -8,7 +8,7 @@
<Call name="addLifeCycleListener">
<Arg>
<New class="org.eclipse.jetty.util.component.FileNoticeLifeCycleListener">
<Arg><SystemProperty name="jetty.state" default="./jetty.state"/></Arg>
<Arg><Property name="jetty.state" default="./jetty.state"/></Arg>
</New>
</Arg>
</Call>

View File

@ -443,13 +443,13 @@ public class HttpParser
else if (ch==0)
break;
else if (ch<0)
throw new BadMessage();
throw new BadMessage(-1);
// count this white space as a header byte to avoid DOS
if (_maxHeaderBytes>0 && ++_headerBytes>_maxHeaderBytes)
{
LOG.warn("padding is too large >"+_maxHeaderBytes);
throw new BadMessage(HttpStatus.BAD_REQUEST_400);
throw new BadMessage(-1);
}
}
return false;
@ -1283,7 +1283,7 @@ public class HttpParser
if (_headerBytes>_maxHeaderBytes)
{
// Don't want to waste time reading data of a closed request
throw new IllegalStateException("too much data after closed");
throw new BadMessage(-1,"too much data after closed");
}
}
}
@ -1333,12 +1333,16 @@ public class HttpParser
{
BufferUtil.clear(buffer);
LOG.warn("badMessage: "+e._code+(e._message!=null?" "+e._message:"")+" for "+_handler);
if (e._code>0)
LOG.warn("badMessage: "+e._code+(e._message!=null?" "+e._message:"")+" for "+_handler);
else
LOG.warn("badMessage: "+(e._message!=null?e._message+" ":"")+"for "+_handler);
if (DEBUG)
LOG.debug(e);
setState(State.CLOSED);
_handler.badMessage(e._code, e._message);
return false;
return true;
}
catch(Exception e)
{
@ -1359,7 +1363,7 @@ public class HttpParser
setState(State.CLOSED);
}
return false;
return true;
}
}
@ -1621,7 +1625,9 @@ public class HttpParser
/* ------------------------------------------------------------ */
/** Called to signal that a bad HTTP message has been received.
* @param status The bad status to send
* @param status The bad status to send. If the status is <0, this indicates
* that the message was so bad that a response should not be sent and the
* connection should be immediately closed.
* @param reason The textual reason for badness
*/
public void badMessage(int status, String reason);

View File

@ -66,6 +66,7 @@ public class HttpChannelState
WRITE_CALLBACK, // handle an IO write callback
READ_CALLBACK, // handle an IO read callback
WAIT, // Wait for further events
IO_WAIT, // Wait for further IO
COMPLETE // Complete the channel
}
@ -182,7 +183,7 @@ public class HttpChannelState
return Action.COMPLETE;
case COMPLETED:
return Action.WAIT;
return Action.IO_WAIT;
case ASYNC_WOKEN:
if (_asyncRead)

View File

@ -226,7 +226,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
filled = getEndPoint().fill(_requestBuffer);
if (filled==0) // Do a retry on fill 0 (optimization for SSL connections)
filled = getEndPoint().fill(_requestBuffer);
// tell parser
if (filled < 0)
_parser.atEOF();
@ -474,8 +474,21 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
@Override
public void badMessage(int status, String reason)
{
_generator.setPersistent(false);
super.badMessage(status,reason);
if (status<0)
{
EndPoint ep = getEndPoint();
while (ep.getTransport() instanceof EndPoint)
ep=(EndPoint)ep.getTransport();
ep.close();
_parser.atEOF();
LOG.debug("badMessage -1 close of {}",getEndPoint());
completed();
}
else
{
_generator.setPersistent(false);
super.badMessage(status,reason);
}
}
@Override

View File

@ -40,6 +40,7 @@ import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.servlet.ServletException;
@ -133,6 +134,90 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
}
/*
* Feed a full header method
*/
@Test
public void testFullWhite() throws Exception
{
configureServer(new HelloWorldHandler());
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
{
client.setSoTimeout(10000);
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
((StdErrLog) Log.getLogger(HttpConnection.class)).info("expect request is too large...");
OutputStream os = client.getOutputStream();
byte[] buffer = new byte[64 * 1024];
Arrays.fill(buffer, (byte)' ');
os.write(buffer);
os.flush();
// Read the close.
readClose(client);
}
finally
{
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
}
}
/*
* Feed a full header method
*/
@Test
public void testFullWhiteAfter() throws Exception
{
configureServer(new HelloWorldHandler());
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
{
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
((StdErrLog)Log.getLogger(HttpConnection.class)).info("expect Bad Message close ...");
OutputStream os = client.getOutputStream();
byte[] buffer = new byte[64 * 1024];
buffer[0]='G';
buffer[1]='E';
buffer[2]='T';
buffer[3]=' ';
buffer[4]='/';
buffer[5]=' ';
buffer[6]='H';
buffer[7]='T';
buffer[8]='T';
buffer[9]='P';
buffer[10]='/';
buffer[11]='1';
buffer[12]='.';
buffer[13]='0';
buffer[14]='\n';
buffer[15]='\n';
Arrays.fill(buffer,16,buffer.length-1,(byte)' ');
os.write(buffer);
os.flush();
// Read the response.
long start = System.nanoTime();
String response = readResponse(client);
long end = System.nanoTime();
Assert.assertThat(response, Matchers.containsString("HTTP/1.1 200 OK"));
Assert.assertThat(TimeUnit.NANOSECONDS.toSeconds(end-start),Matchers.lessThan(1L));
}
finally
{
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
}
}
/*
* Feed a full header method
*/
@ -1374,6 +1459,29 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
throw e;
}
}
/**
* Read Close.
*
* @param client Open client socket.
* @throws IOException in case of I/O problems
*/
protected static void readClose(Socket client) throws IOException
{
try (BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream())))
{
String line;
if ((line = br.readLine()) != null)
throw new IllegalStateException("unexpected data: "+line);
return;
}
catch (IOException e)
{
// expected
}
}
protected void writeFragments(byte[] bytes, int[] points, StringBuilder message, OutputStream os) throws IOException, InterruptedException
{

View File

@ -64,7 +64,7 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
public void testFullMethod() throws Exception
{
// Don't run on Windows (buggy JVM)
Assume.assumeTrue(!OS.IS_WINDOWS);
// Assume.assumeTrue(!OS.IS_WINDOWS);
try
{
@ -80,7 +80,7 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
public void testFullURI() throws Exception
{
// Don't run on Windows (buggy JVM)
Assume.assumeTrue(!OS.IS_WINDOWS);
// Assume.assumeTrue(!OS.IS_WINDOWS);
try
{
super.testFullURI();

View File

@ -130,12 +130,16 @@ public class BaseHome
public BaseHome(CommandLineConfigSource cmdLineSource) throws IOException
{
StartLog.getInstance().initialize(this,cmdLineSource);
sources = new ConfigSources();
sources.add(cmdLineSource);
this.homeDir = cmdLineSource.getHomePath();
this.baseDir = cmdLineSource.getBasePath();
// TODO this is cyclic construction as start log uses BaseHome, but BaseHome constructor
// calls other constructors that log. This appears to be a workable sequence.
StartLog.getInstance().initialize(this,cmdLineSource);
sources.add(new JettyBaseConfigSource(cmdLineSource.getBasePath()));
sources.add(new JettyHomeConfigSource(cmdLineSource.getHomePath()));

View File

@ -227,6 +227,7 @@ public class Main
private void dumpClasspathWithVersions(Classpath classpath)
{
StartLog.endStartLog();
System.out.println();
System.out.println("Jetty Server Classpath:");
System.out.println("-----------------------");
@ -301,11 +302,14 @@ public class Main
Method main = invoked_class.getDeclaredMethod("main",method_param_types);
Object[] method_params = new Object[]
{ argArray };
StartLog.endStartLog();
main.invoke(null,method_params);
}
public void listConfig(StartArgs args)
{
StartLog.endStartLog();
// Dump Jetty Home / Base
args.dumpEnvironment(baseHome);
@ -327,6 +331,7 @@ public class Main
private void listModules(StartArgs args)
{
StartLog.endStartLog();
System.out.println();
System.out.println("Jetty All Available Modules:");
System.out.println("----------------------------");
@ -714,6 +719,7 @@ public class Main
CommandLineBuilder cmd = args.getMainArgs(baseHome,true);
cmd.debug();
ProcessBuilder pbuilder = new ProcessBuilder(cmd.getArgs());
StartLog.endStartLog();
final Process process = pbuilder.start();
Runtime.getRuntime().addShutdownHook(new Thread()
{
@ -825,6 +831,7 @@ public class Main
public void usage(boolean exit)
{
StartLog.endStartLog();
String usageResource = "org/eclipse/jetty/start/usage.txt";
boolean usagePresented = false;
try (InputStream usageStream = getClass().getClassLoader().getResourceAsStream(usageResource))

View File

@ -486,6 +486,7 @@ public class StartArgs
cmd.addRawArg(x);
}
cmd.addRawArg("-Djava.io.tmpdir=" + System.getProperty("java.io.tmpdir"));
cmd.addRawArg("-Djetty.home=" + baseHome.getHome());
cmd.addRawArg("-Djetty.base=" + baseHome.getBase());
@ -506,14 +507,16 @@ public class StartArgs
ensureSystemPropertySet("STOP.KEY");
ensureSystemPropertySet("STOP.WAIT");
// Check if we need to pass properties as a file
if (properties.size() > 0)
// pass properties as args or as a file
if (dryRun || isExec())
{
for (Prop p : properties)
cmd.addRawArg(CommandLineBuilder.quote(p.key)+"="+CommandLineBuilder.quote(p.value));
}
else if (properties.size() > 0)
{
File prop_file = File.createTempFile("start",".properties");
if (!dryRun)
{
prop_file.deleteOnExit();
}
prop_file.deleteOnExit();
try (FileOutputStream out = new FileOutputStream(prop_file))
{
properties.store(out,"start.jar properties");

View File

@ -37,13 +37,17 @@ import org.eclipse.jetty.start.config.CommandLineConfigSource;
*/
public class StartLog
{
private final static PrintStream stdout = System.out;
private final static PrintStream stderr = System.err;
private static volatile PrintStream out = System.out;
private static volatile PrintStream err = System.err;
private final static StartLog INSTANCE = new StartLog();
public static void debug(String format, Object... args)
{
if (INSTANCE.debug)
{
System.out.printf(format + "%n",args);
out.printf(format + "%n",args);
}
}
@ -51,7 +55,7 @@ public class StartLog
{
if (INSTANCE.debug)
{
t.printStackTrace(System.out);
t.printStackTrace(out);
}
}
@ -62,17 +66,17 @@ public class StartLog
public static void info(String format, Object... args)
{
System.err.printf("INFO: " + format + "%n",args);
err.printf("INFO: " + format + "%n",args);
}
public static void warn(String format, Object... args)
{
System.err.printf("WARNING: " + format + "%n",args);
err.printf("WARNING: " + format + "%n",args);
}
public static void warn(Throwable t)
{
t.printStackTrace(System.err);
t.printStackTrace(err);
}
public static boolean isDebugEnabled()
@ -137,13 +141,14 @@ public class StartLog
throw new UsageException(UsageException.ERR_LOGGING,new IOException("Unable to write to: " + startLog.toAbsolutePath()));
}
System.out.println("Logging to " + logfile);
OutputStream out = Files.newOutputStream(startLog,StandardOpenOption.CREATE,StandardOpenOption.APPEND);
PrintStream logger = new PrintStream(out);
System.setOut(logger);
err.println("StartLog to " + logfile);
OutputStream fileout = Files.newOutputStream(startLog,StandardOpenOption.CREATE,StandardOpenOption.APPEND);
PrintStream logger = new PrintStream(fileout);
out=logger;
err=logger;
System.setErr(logger);
System.out.println("Establishing " + logfile + " on " + new Date());
System.setOut(logger);
err.println("StartLog Establishing " + logfile + " on " + new Date());
}
catch (IOException e)
{
@ -156,4 +161,15 @@ public class StartLog
{
getInstance().debug = true;
}
public static void endStartLog()
{
if (stderr!=err && getInstance().debug)
{
err.println("StartLog ended");
stderr.println("StartLog ended");
}
System.setErr(stderr);
System.setOut(stdout);
}
}

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.0.v20120525/npn-boot-1.1.0.v20120525.jar:lib/npn/npn-boot-1.1.0.v20120525.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.0.v20120525.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.0.v20120525/npn-boot-1.1.0.v20120525.jar:lib/npn/npn-boot-1.1.0.v20120525.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.0.v20120525.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.1.v20121030/npn-boot-1.1.1.v20121030.jar:lib/npn/npn-boot-1.1.1.v20121030.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.1.v20121030.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.1.v20121030/npn-boot-1.1.1.v20121030.jar:lib/npn/npn-boot-1.1.1.v20121030.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.1.v20121030.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.3.v20130313/npn-boot-1.1.3.v20130313.jar:lib/npn/npn-boot-1.1.3.v20130313.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.3.v20130313.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.3.v20130313/npn-boot-1.1.3.v20130313.jar:lib/npn/npn-boot-1.1.3.v20130313.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.3.v20130313.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.3.v20130313/npn-boot-1.1.3.v20130313.jar:lib/npn/npn-boot-1.1.3.v20130313.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.3.v20130313.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.4.v20130313/npn-boot-1.1.4.v20130313.jar:lib/npn/npn-boot-1.1.4.v20130313.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.4.v20130313.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.5.v20130313/npn-boot-1.1.5.v20130313.jar:lib/npn/npn-boot-1.1.5.v20130313.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.5.v20130313.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.5.v20130313/npn-boot-1.1.5.v20130313.jar:lib/npn/npn-boot-1.1.5.v20130313.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.5.v20130313.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.5.v20130313/npn-boot-1.1.5.v20130313.jar:lib/npn/npn-boot-1.1.5.v20130313.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.5.v20130313.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.5.v20130313/npn-boot-1.1.5.v20130313.jar:lib/npn/npn-boot-1.1.5.v20130313.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.5.v20130313.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.6.v20130911/npn-boot-1.1.6.v20130911.jar:lib/npn/npn-boot-1.1.6.v20130911.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.6.v20130911.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.6.v20130911/npn-boot-1.1.6.v20130911.jar:lib/npn/npn-boot-1.1.6.v20130911.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.6.v20130911.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.6.v20130911/npn-boot-1.1.6.v20130911.jar:lib/npn/npn-boot-1.1.6.v20130911.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.6.v20130911.jar

View File

@ -4,6 +4,5 @@ npn-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.7.v20140316/npn-boot-1.1.7.v20140316.jar:lib/npn/npn-boot-1.1.7.v20140316.jar
[ini-template]
--exec
[exec]
-Xbootclasspath/p:lib/npn/npn-boot-1.1.7.v20140316.jar

View File

@ -1214,6 +1214,11 @@ public class XmlConfiguration
{
if (arg.toLowerCase(Locale.ENGLISH).endsWith(".properties"))
properties.load(Resource.newResource(arg).getInputStream());
else if (arg.indexOf('=')>=0)
{
int i=arg.indexOf('=');
properties.put(arg.substring(0,i),arg.substring(i+1));
}
}
// For all arguments, parse XMLs
@ -1221,7 +1226,7 @@ public class XmlConfiguration
Object[] obj = new Object[args.length];
for (int i = 0; i < args.length; i++)
{
if (!args[i].toLowerCase(Locale.ENGLISH).endsWith(".properties"))
if (!args[i].toLowerCase(Locale.ENGLISH).endsWith(".properties") && (args[i].indexOf('=')<0))
{
XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(args[i]).getURL());
if (last != null)