Merge remote-tracking branch 'origin/master' into bug-359329
This commit is contained in:
commit
9228a3f8dc
59
VERSION.txt
59
VERSION.txt
|
@ -1,7 +1,58 @@
|
|||
jetty-7.5.2-SNAPSHOT
|
||||
+ 358121 Implement new UTF8 Algorithm to UTF8Appendable.java
|
||||
+ 353839 ajp component error when upload file
|
||||
+ JETTY-1378 new system property to for the use of the JDTCompiler when using the latest jsp-impl
|
||||
jetty-7.5.4-SNAPSHOT
|
||||
|
||||
jetty-7.5.3.v20111011 - 11 October 2011
|
||||
+ 348978 migrate jetty-http-spi
|
||||
+ 358649 StdErrLog system properties for package/class logging LEVEL.
|
||||
|
||||
jetty-7.5.2.v20111006 - 06 October 2011
|
||||
+ 336443 add missing comma in DigestAuthenticator string
|
||||
+ 342161 ScannerTest fails intermittently on Mac OS X
|
||||
+ 346419 testing HttpClient FDs
|
||||
+ 353267 Request._parameters initialization bug
|
||||
+ 353509 jetty-client unit tests are running too long
|
||||
+ 353627 Basic Auth checks that Basic method has been send
|
||||
+ 356144 Allow SelectorManager thread priority to be set
|
||||
+ 356274 Start SSL socket factory in call to open()
|
||||
+ 357178 websockets draft 14 support
|
||||
+ 357188 Send content buffer directly
|
||||
+ 357216 Logging via Log4J does not expand braces in format strings
|
||||
+ 357240 more half close refinements
|
||||
+ 357338 remove debug
|
||||
+ 357672 resolve issue with serializing pojos with mongodb session manager,
|
||||
thanks to john simone for the discovery and fix
|
||||
+ 357959 Include javadoc in distribution
|
||||
+ 358027 NullPointerException in ResourceHandler with jetty-stylesheet.css
|
||||
+ 358035 idle time only active if > 0
|
||||
+ 358147 Add catch for UnknownHostException to fix leaky file descriptor in
|
||||
client
|
||||
+ 358164 Dispatch from servlet to handler
|
||||
+ 358263 add method for osgi users to register a driver as Class.forName does
|
||||
not work for them
|
||||
+ 358649 StdErrLog system properties for package/class logging LEVEL.
|
||||
+ 358674 Still allows sslv3 for now
|
||||
+ 358687 Updated jsp does not scan for system tlds Fixed pattern.
|
||||
+ 358784 JSP broken on Java 1.5
|
||||
+ 358925 bit more javadoc on usage
|
||||
+ 358959 File descriptor leak with UnresolvedAddressException
|
||||
+ 359309 adjust previous test for servletPath to include pathInfo
|
||||
+ 359673 updated websocket version handling
|
||||
+ 359675 Principal != String, fix for issue in property file login manager
|
||||
+ 360051 SocketConnectionTest.testServerClosedConnection is excluded.
|
||||
+ 360066 jsps referenced in web.xml <jsp-file> elements do not compile
|
||||
+ JETTY-1130 Access Sessions from HashSessionIdManager
|
||||
+ JETTY-1277 Fixed sendRedirect encoding of relative locations
|
||||
+ JETTY-1322 idle sweeper checks for closed endp
|
||||
+ JETTY-1377 extra logging for busy selector
|
||||
+ JETTY-1378 new sys property for the latest jsp-impl to force the use of the
|
||||
JDTCompiler when running in OSGi.
|
||||
+ JETTY-1414 applied to PropertyUserStore
|
||||
+ JETTY-1415 Start/Stop Server and Client only once in test, code format
|
||||
+ JETTY-1420 Set Host header for new request in RedirectListener
|
||||
+ JETTY-1421 Implement RedirectListener.onException,onConnectionFailed
|
||||
+ JETTY-1423 force connection to be closed returned
|
||||
+ JETTY-1430 local JNDI contexts don't carry environment
|
||||
+ JETTY-1434 Add a jsp that exercises jstl.
|
||||
+ JETTY-1439 space in directory installation path causes classloader problem
|
||||
|
||||
jetty-7.5.1.v20110908 - 08 September 2011
|
||||
+ 350634 Added Resource.newResource(File)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>example-jetty-embedded</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-all-server</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-all</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-client</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-plus</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-ajp</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-annotations</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -73,7 +73,7 @@ public class HttpConnection extends AbstractConnection implements Dumpable
|
|||
HttpConnection(Buffers requestBuffers, Buffers responseBuffers, EndPoint endp)
|
||||
{
|
||||
super(endp);
|
||||
|
||||
|
||||
_generator = new HttpGenerator(requestBuffers,endp);
|
||||
_parser = new HttpParser(responseBuffers,endp,new Handler());
|
||||
}
|
||||
|
@ -277,6 +277,9 @@ public class HttpConnection extends AbstractConnection implements Dumpable
|
|||
{
|
||||
long filled = _parser.parseAvailable();
|
||||
io += filled;
|
||||
|
||||
if (_parser.isIdle() && (_endp.isInputShutdown() || !_endp.isOpen()))
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
if (io > 0)
|
||||
|
@ -353,33 +356,35 @@ public class HttpConnection extends AbstractConnection implements Dumpable
|
|||
complete = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if the endpoint is closed, but the parser incomplete
|
||||
if (!_endp.isOpen() && !(_parser.isComplete()||_parser.isIdle()))
|
||||
{
|
||||
// we wont be called again so let the parser see the close
|
||||
complete=true;
|
||||
_parser.parseAvailable();
|
||||
// TODO should not need this
|
||||
if (!(_parser.isComplete()||_parser.isIdle()))
|
||||
{
|
||||
LOG.warn("Incomplete {} {}",_parser,_endp);
|
||||
if (_exchange!=null)
|
||||
_exchange.cancel();
|
||||
if (_exchange!=null && !_exchange.isDone())
|
||||
{
|
||||
_exchange.setStatus(HttpExchange.STATUS_EXCEPTED);
|
||||
_exchange.getEventListener().onException(new EOFException("Incomplete"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO - is this needed ?
|
||||
if (_generator.isComplete() && !_parser.isComplete())
|
||||
if (_endp.isInputShutdown() && !_parser.isComplete() && !_parser.isIdle())
|
||||
{
|
||||
if (!_endp.isOpen() || _endp.isInputShutdown())
|
||||
if (_exchange!=null && !_exchange.isDone())
|
||||
{
|
||||
complete=true;
|
||||
close=true;
|
||||
close();
|
||||
_exchange.setStatus(HttpExchange.STATUS_EXCEPTED);
|
||||
_exchange.getEventListener().onException(new EOFException("Incomplete"));
|
||||
}
|
||||
_endp.close();
|
||||
}
|
||||
*/
|
||||
|
||||
if (complete || failed)
|
||||
{
|
||||
|
@ -447,7 +452,7 @@ public class HttpConnection extends AbstractConnection implements Dumpable
|
|||
finally
|
||||
{
|
||||
_parser.returnBuffers();
|
||||
|
||||
|
||||
// Do we have more stuff to write?
|
||||
if (!_generator.isComplete() && _generator.getBytesBuffered()>0 && _endp.isOpen() && _endp instanceof AsyncEndPoint)
|
||||
{
|
||||
|
@ -565,6 +570,8 @@ public class HttpConnection extends AbstractConnection implements Dumpable
|
|||
|
||||
private boolean shouldClose()
|
||||
{
|
||||
if (_endp.isInputShutdown())
|
||||
return true;
|
||||
if (_connectionHeader!=null)
|
||||
{
|
||||
if (HttpHeaderValues.CLOSE_BUFFER.equals(_connectionHeader))
|
||||
|
@ -743,7 +750,7 @@ public class HttpConnection extends AbstractConnection implements Dumpable
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.util.component.Dumpable#dump()
|
||||
|
@ -765,7 +772,7 @@ public class HttpConnection extends AbstractConnection implements Dumpable
|
|||
AggregateLifeCycle.dump(out,indent,Collections.singletonList(_endp));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private class ConnectionIdleTask extends Timeout.Task
|
||||
{
|
||||
|
@ -780,14 +787,14 @@ public class HttpConnection extends AbstractConnection implements Dumpable
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private class NonFinalResponseListener implements HttpEventListener
|
||||
{
|
||||
final HttpExchange _exchange;
|
||||
final HttpEventListener _next;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public NonFinalResponseListener(HttpExchange exchange)
|
||||
{
|
||||
|
@ -832,7 +839,7 @@ public class HttpConnection extends AbstractConnection implements Dumpable
|
|||
{
|
||||
_exchange.setEventListener(_next);
|
||||
_exchange.setStatus(HttpExchange.STATUS_WAITING_FOR_RESPONSE);
|
||||
_parser.reset();
|
||||
_parser.reset();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -113,7 +113,12 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector
|
|||
_httpClient.schedule(connectTimeout,_httpClient.getConnectTimeout());
|
||||
_connectingChannels.put(channel,connectTimeout);
|
||||
}
|
||||
|
||||
}
|
||||
catch (UnresolvedAddressException ex)
|
||||
{
|
||||
if (channel != null)
|
||||
channel.close();
|
||||
destination.onConnectionFailed(ex);
|
||||
}
|
||||
catch(IOException ex)
|
||||
{
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
@ -25,6 +25,9 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
|
@ -37,7 +40,7 @@ public abstract class AbstractConnectionTest
|
|||
// httpClient.setConnectorType(HttpClient.CONNECTOR_SOCKET);
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testServerClosedConnection() throws Exception
|
||||
{
|
||||
|
@ -57,6 +60,19 @@ public abstract class AbstractConnectionTest
|
|||
httpClient.send(exchange);
|
||||
|
||||
Socket remote = serverSocket.accept();
|
||||
|
||||
// HttpClient.send() above is async, so if we write the response immediately
|
||||
// there is a chance that it arrives before the request is being sent, so we
|
||||
// read the request before sending the response to avoid the race
|
||||
InputStream input = remote.getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
if (line.length() == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
OutputStream output = remote.getOutputStream();
|
||||
output.write("HTTP/1.1 200 OK\r\n".getBytes("UTF-8"));
|
||||
output.write("Content-Length: 0\r\n".getBytes("UTF-8"));
|
||||
|
@ -80,6 +96,15 @@ public abstract class AbstractConnectionTest
|
|||
httpClient.send(exchange);
|
||||
|
||||
remote = serverSocket.accept();
|
||||
|
||||
input = remote.getInputStream();
|
||||
reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
if (line.length() == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
output = remote.getOutputStream();
|
||||
output.write("HTTP/1.1 200 OK\r\n".getBytes("UTF-8"));
|
||||
output.write("Content-Length: 0\r\n".getBytes("UTF-8"));
|
||||
|
@ -94,6 +119,105 @@ public abstract class AbstractConnectionTest
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerClosedIncomplete() throws Exception
|
||||
{
|
||||
ServerSocket serverSocket = new ServerSocket();
|
||||
serverSocket.bind(null);
|
||||
int port=serverSocket.getLocalPort();
|
||||
|
||||
HttpClient httpClient = newHttpClient();
|
||||
httpClient.setMaxConnectionsPerAddress(1);
|
||||
httpClient.start();
|
||||
try
|
||||
{
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
HttpExchange exchange = new ConnectionExchange(latch);
|
||||
exchange.setAddress(new Address("localhost", port));
|
||||
exchange.setRequestURI("/");
|
||||
httpClient.send(exchange);
|
||||
|
||||
Socket remote = serverSocket.accept();
|
||||
|
||||
// HttpClient.send() above is async, so if we write the response immediately
|
||||
// there is a chance that it arrives before the request is being sent, so we
|
||||
// read the request before sending the response to avoid the race
|
||||
InputStream input = remote.getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
if (line.length() == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
OutputStream output = remote.getOutputStream();
|
||||
output.write("HTTP/1.1 200 OK\r\n".getBytes("UTF-8"));
|
||||
output.write("Content-Length: 10\r\n".getBytes("UTF-8"));
|
||||
output.write("\r\n".getBytes("UTF-8"));
|
||||
output.flush();
|
||||
|
||||
remote.close();
|
||||
|
||||
assertEquals(HttpExchange.STATUS_EXCEPTED, exchange.waitForDone());
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
httpClient.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerHalfClosedIncomplete() throws Exception
|
||||
{
|
||||
ServerSocket serverSocket = new ServerSocket();
|
||||
serverSocket.bind(null);
|
||||
int port=serverSocket.getLocalPort();
|
||||
|
||||
HttpClient httpClient = newHttpClient();
|
||||
httpClient.setIdleTimeout(10000);
|
||||
httpClient.setMaxConnectionsPerAddress(1);
|
||||
httpClient.start();
|
||||
try
|
||||
{
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
HttpExchange exchange = new ConnectionExchange(latch);
|
||||
exchange.setAddress(new Address("localhost", port));
|
||||
exchange.setRequestURI("/");
|
||||
httpClient.send(exchange);
|
||||
|
||||
Socket remote = serverSocket.accept();
|
||||
|
||||
// HttpClient.send() above is async, so if we write the response immediately
|
||||
// there is a chance that it arrives before the request is being sent, so we
|
||||
// read the request before sending the response to avoid the race
|
||||
InputStream input = remote.getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
if (line.length() == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
OutputStream output = remote.getOutputStream();
|
||||
output.write("HTTP/1.1 200 OK\r\n".getBytes("UTF-8"));
|
||||
output.write("Content-Length: 10\r\n".getBytes("UTF-8"));
|
||||
output.write("\r\n".getBytes("UTF-8"));
|
||||
output.flush();
|
||||
|
||||
remote.shutdownOutput();
|
||||
|
||||
assertEquals(HttpExchange.STATUS_EXCEPTED, exchange.waitForDone());
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
httpClient.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionFailed() throws Exception
|
||||
{
|
||||
|
@ -262,16 +386,16 @@ public abstract class AbstractConnectionTest
|
|||
}
|
||||
}
|
||||
|
||||
private class ConnectionExchange extends HttpExchange
|
||||
protected class ConnectionExchange extends HttpExchange
|
||||
{
|
||||
private final CountDownLatch latch;
|
||||
|
||||
private ConnectionExchange()
|
||||
protected ConnectionExchange()
|
||||
{
|
||||
this.latch = null;
|
||||
}
|
||||
|
||||
private ConnectionExchange(CountDownLatch latch)
|
||||
protected ConnectionExchange(CountDownLatch latch)
|
||||
{
|
||||
this.latch = latch;
|
||||
}
|
||||
|
|
|
@ -22,4 +22,12 @@ public class AsyncSelectConnectionTest extends AbstractConnectionTest
|
|||
httpClient.setConnectBlocking(false);
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testServerHalfClosedIncomplete() throws Exception
|
||||
{
|
||||
super.testServerHalfClosedIncomplete();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -32,12 +32,4 @@ public class AsyncSslHttpExchangeTest extends SslHttpExchangeTest
|
|||
_port = _server.getConnectors()[0].getLocalPort();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPerf1() throws Exception
|
||||
{
|
||||
sender(10,true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,16 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class SocketConnectionTest extends AbstractConnectionTest
|
||||
{
|
||||
protected HttpClient newHttpClient()
|
||||
|
@ -21,10 +31,61 @@ public class SocketConnectionTest extends AbstractConnectionTest
|
|||
httpClient.setConnectorType(HttpClient.CONNECTOR_SOCKET);
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void testServerClosedConnection()
|
||||
public void testServerClosedConnection() throws Exception
|
||||
{
|
||||
// TODO work out why this does not work
|
||||
// Differently from the SelectConnector, the SocketConnector cannot detect server closes.
|
||||
// Therefore, upon a second send, the exchange will fail.
|
||||
// Applications needs to retry it explicitly.
|
||||
|
||||
ServerSocket serverSocket = new ServerSocket();
|
||||
serverSocket.bind(null);
|
||||
int port=serverSocket.getLocalPort();
|
||||
|
||||
HttpClient httpClient = this.newHttpClient();
|
||||
httpClient.setMaxConnectionsPerAddress(1);
|
||||
httpClient.start();
|
||||
try
|
||||
{
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
HttpExchange exchange = new ConnectionExchange(latch);
|
||||
exchange.setAddress(new Address("localhost", port));
|
||||
exchange.setRequestURI("/");
|
||||
httpClient.send(exchange);
|
||||
|
||||
Socket remote = serverSocket.accept();
|
||||
|
||||
// HttpClient.send() above is async, so if we write the response immediately
|
||||
// there is a chance that it arrives before the request is being sent, so we
|
||||
// read the request before sending the response to avoid the race
|
||||
InputStream input = remote.getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
if (line.length() == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
OutputStream output = remote.getOutputStream();
|
||||
output.write("HTTP/1.1 200 OK\r\n".getBytes("UTF-8"));
|
||||
output.write("Content-Length: 0\r\n".getBytes("UTF-8"));
|
||||
output.write("\r\n".getBytes("UTF-8"));
|
||||
output.flush();
|
||||
|
||||
assertEquals(HttpExchange.STATUS_COMPLETED, exchange.waitForDone());
|
||||
|
||||
remote.close();
|
||||
|
||||
exchange.reset();
|
||||
httpClient.send(exchange);
|
||||
|
||||
assertEquals(HttpExchange.STATUS_EXCEPTED, exchange.waitForDone());
|
||||
}
|
||||
finally
|
||||
{
|
||||
httpClient.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-continuation</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-deploy</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jetty-distribution</artifactId>
|
||||
<name>Jetty :: Distribution Assemblies</name>
|
||||
|
|
|
@ -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</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-http-spi</artifactId>
|
||||
<name>Jetty :: Http Service Provider Interface</name>
|
||||
<properties>
|
||||
<bundle-symbolic-name>${project.groupId}.http.spi</bundle-symbolic-name>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.net.httpserver</groupId>
|
||||
<artifactId>http</artifactId>
|
||||
<version>20070405</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>manifest</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>artifact-jar</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>findbugs-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<onlyAnalyze>org.eclipse.jetty.http.spi.*</onlyAnalyze>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,121 @@
|
|||
package org.eclipse.jetty.http.spi;
|
||||
//========================================================================
|
||||
//Copyright (c) 2004-2009 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.
|
||||
//========================================================================
|
||||
|
||||
import com.sun.net.httpserver.Authenticator;
|
||||
import com.sun.net.httpserver.Authenticator.Result;
|
||||
import com.sun.net.httpserver.HttpContext;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpPrincipal;
|
||||
import org.eclipse.jetty.server.HttpConnection;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Jetty handler that bridges requests to {@link HttpHandler}.
|
||||
*/
|
||||
public class HttpSpiContextHandler extends ContextHandler
|
||||
{
|
||||
|
||||
private HttpContext _httpContext;
|
||||
|
||||
private HttpHandler _httpHandler;
|
||||
|
||||
|
||||
public HttpSpiContextHandler(HttpContext httpContext, HttpHandler httpHandler)
|
||||
{
|
||||
this._httpContext = httpContext;
|
||||
this._httpHandler = httpHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doScope(String target, Request baseRequest, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
|
||||
{
|
||||
if (!target.startsWith(getContextPath())) return;
|
||||
|
||||
JettyHttpExchange jettyHttpExchange = new JettyHttpExchange(_httpContext, req, resp);
|
||||
|
||||
// TODO: add filters processing
|
||||
|
||||
try
|
||||
{
|
||||
Authenticator auth = _httpContext.getAuthenticator();
|
||||
if (auth != null)
|
||||
handleAuthentication(resp, jettyHttpExchange, auth);
|
||||
else
|
||||
_httpHandler.handle(jettyHttpExchange);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
PrintWriter writer = new PrintWriter(jettyHttpExchange.getResponseBody());
|
||||
|
||||
resp.setStatus(500);
|
||||
writer.println("<h2>HTTP ERROR: 500</h2>");
|
||||
writer.println("<pre>INTERNAL_SERVER_ERROR</pre>");
|
||||
writer.println("<p>RequestURI=" + req.getRequestURI() + "</p>");
|
||||
|
||||
writer.println("<pre>");
|
||||
ex.printStackTrace(writer);
|
||||
writer.println("</pre>");
|
||||
|
||||
writer.println("<p><i><small><a href=\"http://jetty.mortbay.org\">Powered by jetty://</a></small></i></p>");
|
||||
|
||||
writer.close();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Request base_request = (req instanceof Request) ? (Request)req:HttpConnection.getCurrentConnection().getRequest();
|
||||
base_request.setHandled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void handleAuthentication(HttpServletResponse resp, JettyHttpExchange jettyHttpExchange, Authenticator auth) throws IOException
|
||||
{
|
||||
Result result = auth.authenticate(jettyHttpExchange);
|
||||
if (result instanceof Authenticator.Failure)
|
||||
{
|
||||
int rc = ((Authenticator.Failure)result).getResponseCode();
|
||||
resp.sendError(rc);
|
||||
}
|
||||
else if (result instanceof Authenticator.Retry)
|
||||
{
|
||||
int rc = ((Authenticator.Retry)result).getResponseCode();
|
||||
resp.sendError(rc);
|
||||
}
|
||||
else if (result instanceof Authenticator.Success)
|
||||
{
|
||||
HttpPrincipal principal = ((Authenticator.Success)result).getPrincipal();
|
||||
jettyHttpExchange.setPrincipal(principal);
|
||||
_httpHandler.handle(jettyHttpExchange);
|
||||
}
|
||||
}
|
||||
|
||||
public HttpHandler getHttpHandler()
|
||||
{
|
||||
return _httpHandler;
|
||||
}
|
||||
|
||||
public void setHttpHandler(HttpHandler handler)
|
||||
{
|
||||
this._httpHandler = handler;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package org.eclipse.jetty.http.spi;
|
||||
|
||||
//========================================================================
|
||||
//Copyright (c) 2004-2009 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.
|
||||
//========================================================================
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.net.httpserver.Authenticator;
|
||||
import com.sun.net.httpserver.Filter;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
|
||||
/**
|
||||
* Jetty implementation of {@link com.sun.net.httpserver.HttpContext}
|
||||
*/
|
||||
public class JettyHttpContext extends com.sun.net.httpserver.HttpContext
|
||||
{
|
||||
|
||||
private HttpSpiContextHandler _jettyContextHandler;
|
||||
|
||||
private HttpServer _server;
|
||||
|
||||
private Map<String,Object> _attributes = new HashMap<String,Object>();
|
||||
|
||||
private List<Filter> _filters = new ArrayList<Filter>();
|
||||
|
||||
private Authenticator _authenticator;
|
||||
|
||||
|
||||
protected JettyHttpContext(HttpServer server, String path,
|
||||
HttpHandler handler)
|
||||
{
|
||||
this._server = server;
|
||||
_jettyContextHandler = new HttpSpiContextHandler(this, handler);
|
||||
_jettyContextHandler.setContextPath(path);
|
||||
}
|
||||
|
||||
protected HttpSpiContextHandler getJettyContextHandler()
|
||||
{
|
||||
return _jettyContextHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHandler getHandler()
|
||||
{
|
||||
return _jettyContextHandler.getHttpHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHandler(HttpHandler h)
|
||||
{
|
||||
_jettyContextHandler.setHttpHandler(h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath()
|
||||
{
|
||||
return _jettyContextHandler.getContextPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpServer getServer()
|
||||
{
|
||||
return _server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAttributes()
|
||||
{
|
||||
return _attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Filter> getFilters()
|
||||
{
|
||||
return _filters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authenticator setAuthenticator(Authenticator auth)
|
||||
{
|
||||
Authenticator previous = _authenticator;
|
||||
_authenticator = auth;
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authenticator getAuthenticator()
|
||||
{
|
||||
return _authenticator;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
package org.eclipse.jetty.http.spi;
|
||||
|
||||
//========================================================================
|
||||
//Copyright (c) 2004-2009 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.
|
||||
//========================================================================
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.sun.net.httpserver.Headers;
|
||||
import com.sun.net.httpserver.HttpContext;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpPrincipal;
|
||||
|
||||
/**
|
||||
* Jetty implementation of {@link com.sun.net.httpserver.HttpExchange}
|
||||
*/
|
||||
public class JettyHttpExchange extends HttpExchange
|
||||
{
|
||||
|
||||
private HttpContext _httpContext;
|
||||
|
||||
private HttpServletRequest _req;
|
||||
|
||||
private HttpServletResponse _resp;
|
||||
|
||||
private Headers _responseHeaders = new Headers();
|
||||
|
||||
private int _responseCode = 0;
|
||||
|
||||
private InputStream _is;
|
||||
|
||||
private OutputStream _os;
|
||||
|
||||
private HttpPrincipal _httpPrincipal;
|
||||
|
||||
|
||||
public JettyHttpExchange(HttpContext jaxWsContext , HttpServletRequest req,
|
||||
HttpServletResponse resp)
|
||||
{
|
||||
this._httpContext = jaxWsContext;
|
||||
this._req = req;
|
||||
this._resp = resp;
|
||||
try
|
||||
{
|
||||
this._is = req.getInputStream();
|
||||
this._os = resp.getOutputStream();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Headers getRequestHeaders()
|
||||
{
|
||||
Headers headers = new Headers();
|
||||
Enumeration<?> en = _req.getHeaderNames();
|
||||
while (en.hasMoreElements())
|
||||
{
|
||||
String name = (String) en.nextElement();
|
||||
Enumeration<?> en2 = _req.getHeaders(name);
|
||||
while (en2.hasMoreElements())
|
||||
{
|
||||
String value = (String) en2.nextElement();
|
||||
headers.add(name, value);
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Headers getResponseHeaders()
|
||||
{
|
||||
return _responseHeaders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getRequestURI()
|
||||
{
|
||||
try
|
||||
{
|
||||
String uriAsString = _req.getRequestURI();
|
||||
if (_req.getQueryString() != null)
|
||||
uriAsString += "?" + _req.getQueryString();
|
||||
|
||||
return new URI(uriAsString);
|
||||
}
|
||||
catch (URISyntaxException ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestMethod()
|
||||
{
|
||||
return _req.getMethod();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpContext getHttpContext()
|
||||
{
|
||||
return _httpContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
try
|
||||
{
|
||||
_resp.getOutputStream().close();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getRequestBody()
|
||||
{
|
||||
return _is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getResponseBody()
|
||||
{
|
||||
return _os;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendResponseHeaders(int rCode, long responseLength)
|
||||
throws IOException
|
||||
{
|
||||
this._responseCode = rCode;
|
||||
|
||||
for (Map.Entry<String, List<String>> stringListEntry : _responseHeaders.entrySet())
|
||||
{
|
||||
String name = stringListEntry.getKey();
|
||||
List<String> values = stringListEntry.getValue();
|
||||
|
||||
for (String value : values)
|
||||
{
|
||||
_resp.setHeader(name, value);
|
||||
}
|
||||
}
|
||||
if (responseLength > 0)
|
||||
_resp.setHeader("content-length", "" + responseLength);
|
||||
_resp.setStatus(rCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getRemoteAddress()
|
||||
{
|
||||
return new InetSocketAddress(_req.getRemoteAddr(), _req.getRemotePort());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResponseCode()
|
||||
{
|
||||
return _responseCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getLocalAddress()
|
||||
{
|
||||
return new InetSocketAddress(_req.getLocalAddr(), _req.getLocalPort());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol()
|
||||
{
|
||||
return _req.getProtocol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name)
|
||||
{
|
||||
return _req.getAttribute(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, Object value)
|
||||
{
|
||||
_req.setAttribute(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStreams(InputStream i, OutputStream o)
|
||||
{
|
||||
_is = i;
|
||||
_os = o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpPrincipal getPrincipal()
|
||||
{
|
||||
return _httpPrincipal;
|
||||
}
|
||||
|
||||
public void setPrincipal(HttpPrincipal principal)
|
||||
{
|
||||
this._httpPrincipal = principal;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,262 @@
|
|||
package org.eclipse.jetty.http.spi;
|
||||
|
||||
//========================================================================
|
||||
//Copyright (c) 2004-2009 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.
|
||||
//========================================================================
|
||||
|
||||
import com.sun.net.httpserver.HttpContext;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.nio.SelectChannelConnector;
|
||||
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* Jetty implementation of {@link com.sun.net.httpserver.HttpServer}.
|
||||
*/
|
||||
public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(JettyHttpServer.class);
|
||||
|
||||
|
||||
private Server _server;
|
||||
|
||||
private boolean _serverShared;
|
||||
|
||||
private InetSocketAddress _addr;
|
||||
|
||||
private ThreadPoolExecutor _executor;
|
||||
|
||||
private Map<String, JettyHttpContext> _contexts = new HashMap<String, JettyHttpContext>();
|
||||
|
||||
private Map<String, Connector> _connectors = new HashMap<String, Connector>();
|
||||
|
||||
|
||||
public JettyHttpServer(Server server, boolean shared)
|
||||
{
|
||||
this._server = server;
|
||||
this._serverShared = shared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(InetSocketAddress addr, int backlog) throws IOException
|
||||
{
|
||||
// check if there is already a connector listening
|
||||
Connector[] connectors = _server.getConnectors();
|
||||
if (connectors != null)
|
||||
{
|
||||
for (Connector connector : connectors)
|
||||
{
|
||||
if (connector.getPort() == addr.getPort()) {
|
||||
if (LOG.isDebugEnabled()) LOG.debug("server already bound to port " + addr.getPort() + ", no need to rebind");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_serverShared)
|
||||
throw new IOException("jetty server is not bound to port " + addr.getPort());
|
||||
|
||||
this._addr = addr;
|
||||
|
||||
if (LOG.isDebugEnabled()) LOG.debug("binding server to port " + addr.getPort());
|
||||
SelectChannelConnector connector = new SelectChannelConnector();
|
||||
connector.setAcceptors(1);
|
||||
connector.setPort(addr.getPort());
|
||||
connector.setHost(addr.getHostName());
|
||||
_server.addConnector(connector);
|
||||
|
||||
_connectors.put(addr.getHostName() + addr.getPort(), connector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getAddress()
|
||||
{
|
||||
return _addr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start()
|
||||
{
|
||||
if (_serverShared) return;
|
||||
|
||||
try
|
||||
{
|
||||
_server.start();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExecutor(Executor executor)
|
||||
{
|
||||
if (executor == null)
|
||||
throw new IllegalArgumentException("missing required 'executor' argument");
|
||||
|
||||
if (!(executor instanceof ThreadPoolExecutor))
|
||||
throw new IllegalArgumentException("only java.util.concurrent.ThreadPoolExecutor instances are allowed, got: " + executor.getClass().getName());
|
||||
|
||||
if (LOG.isDebugEnabled()) LOG.debug("using ThreadPoolExecutor for server thread pool");
|
||||
this._executor = (ThreadPoolExecutor) executor;
|
||||
_server.setThreadPool(new ThreadPoolExecutorAdapter(_executor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getExecutor()
|
||||
{
|
||||
return _executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(int delay)
|
||||
{
|
||||
cleanUpContexts();
|
||||
cleanUpConnectors();
|
||||
|
||||
if (_serverShared) return;
|
||||
|
||||
try
|
||||
{
|
||||
_server.stop();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanUpContexts()
|
||||
{
|
||||
for (Map.Entry<String, JettyHttpContext> stringJettyHttpContextEntry : _contexts.entrySet())
|
||||
{
|
||||
JettyHttpContext context = stringJettyHttpContextEntry.getValue();
|
||||
_server.removeBean(context.getJettyContextHandler());
|
||||
}
|
||||
_contexts.clear();
|
||||
}
|
||||
|
||||
private void cleanUpConnectors()
|
||||
{
|
||||
for (Map.Entry<String, Connector> stringConnectorEntry : _connectors.entrySet())
|
||||
{
|
||||
Connector connector = stringConnectorEntry.getValue();
|
||||
try
|
||||
{
|
||||
connector.stop();
|
||||
} catch (Exception ex) {
|
||||
LOG.warn(ex);
|
||||
}
|
||||
_server.removeConnector(connector);
|
||||
}
|
||||
_connectors.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpContext createContext(String path, HttpHandler httpHandler)
|
||||
{
|
||||
checkIfContextIsFree(path);
|
||||
|
||||
JettyHttpContext context = new JettyHttpContext(this, path, httpHandler);
|
||||
HttpSpiContextHandler jettyContextHandler = context.getJettyContextHandler();
|
||||
|
||||
ContextHandlerCollection chc = findContextHandlerCollection(_server.getHandlers());
|
||||
if (chc == null)
|
||||
throw new RuntimeException("could not find ContextHandlerCollection, you must configure one");
|
||||
|
||||
chc.addHandler(jettyContextHandler);
|
||||
_contexts.put(path, context);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
private ContextHandlerCollection findContextHandlerCollection(Handler[] handlers)
|
||||
{
|
||||
if (handlers == null)
|
||||
return null;
|
||||
|
||||
for (Handler handler : handlers)
|
||||
{
|
||||
if (handler instanceof ContextHandlerCollection)
|
||||
{
|
||||
return (ContextHandlerCollection) handler;
|
||||
}
|
||||
|
||||
if (handler instanceof HandlerCollection)
|
||||
{
|
||||
HandlerCollection hc = (HandlerCollection) handler;
|
||||
ContextHandlerCollection chc = findContextHandlerCollection(hc.getHandlers());
|
||||
if (chc != null)
|
||||
return chc;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkIfContextIsFree(String path)
|
||||
{
|
||||
Handler serverHandler = _server.getHandler();
|
||||
if (serverHandler instanceof ContextHandler)
|
||||
{
|
||||
ContextHandler ctx = (ContextHandler) serverHandler;
|
||||
if (ctx.getContextPath().equals(path))
|
||||
throw new RuntimeException("another context already bound to path " + path);
|
||||
}
|
||||
|
||||
Handler[] handlers = _server.getHandlers();
|
||||
if (handlers == null) return;
|
||||
|
||||
for (Handler handler : handlers)
|
||||
{
|
||||
if (handler instanceof ContextHandler) {
|
||||
ContextHandler ctx = (ContextHandler) handler;
|
||||
if (ctx.getContextPath().equals(path))
|
||||
throw new RuntimeException("another context already bound to path " + path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpContext createContext(String path)
|
||||
{
|
||||
return createContext(path, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeContext(String path) throws IllegalArgumentException
|
||||
{
|
||||
JettyHttpContext context = _contexts.remove(path);
|
||||
if (context == null) return;
|
||||
_server.removeBean(context.getJettyContextHandler());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeContext(HttpContext context)
|
||||
{
|
||||
removeContext(context.getPath());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package org.eclipse.jetty.http.spi;
|
||||
|
||||
//========================================================================
|
||||
//Copyright (c) 2004-2009 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.
|
||||
//========================================================================
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import com.sun.net.httpserver.HttpsServer;
|
||||
import com.sun.net.httpserver.spi.HttpServerProvider;
|
||||
|
||||
/**
|
||||
* Jetty implementation of <a href="http://java.sun.com/javase/6/docs/jre/api/net/httpserver/spec/index.html">Java HTTP Server SPI</a>
|
||||
*/
|
||||
public class JettyHttpServerProvider extends HttpServerProvider
|
||||
{
|
||||
|
||||
private static Server _server;
|
||||
|
||||
public static void setServer(Server server)
|
||||
{
|
||||
_server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpServer createHttpServer(InetSocketAddress addr, int backlog)
|
||||
throws IOException
|
||||
{
|
||||
Server server = _server;
|
||||
boolean shared = true;
|
||||
|
||||
if (server == null)
|
||||
{
|
||||
server = new Server();
|
||||
|
||||
HandlerCollection handlerCollection = new HandlerCollection();
|
||||
handlerCollection.setHandlers(new Handler[] {new ContextHandlerCollection(), new DefaultHandler()});
|
||||
server.setHandler(handlerCollection);
|
||||
|
||||
shared = false;
|
||||
}
|
||||
|
||||
JettyHttpServer jettyHttpServer = new JettyHttpServer(server, shared);
|
||||
jettyHttpServer.bind(addr, backlog);
|
||||
return jettyHttpServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpsServer createHttpsServer(InetSocketAddress addr, int backlog) throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
package org.eclipse.jetty.http.spi;
|
||||
|
||||
//========================================================================
|
||||
//Copyright (c) 2004-2009 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.
|
||||
//========================================================================
|
||||
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
import org.eclipse.jetty.util.thread.ThreadPool;
|
||||
|
||||
/**
|
||||
* Jetty {@link ThreadPool} that bridges requests to a {@link ThreadPoolExecutor}.
|
||||
*/
|
||||
public class ThreadPoolExecutorAdapter extends AbstractLifeCycle implements ThreadPool
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(ThreadPoolExecutorAdapter.class);
|
||||
|
||||
|
||||
private ThreadPoolExecutor executor;
|
||||
|
||||
public ThreadPoolExecutorAdapter(ThreadPoolExecutor executor)
|
||||
{
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
public boolean dispatch(Runnable job)
|
||||
{
|
||||
try
|
||||
{
|
||||
executor.execute(job);
|
||||
return true;
|
||||
}
|
||||
catch(RejectedExecutionException e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int getIdleThreads()
|
||||
{
|
||||
return executor.getPoolSize()-executor.getActiveCount();
|
||||
}
|
||||
|
||||
public int getThreads()
|
||||
{
|
||||
return executor.getPoolSize();
|
||||
}
|
||||
|
||||
public boolean isLowOnThreads()
|
||||
{
|
||||
return executor.getActiveCount()>=executor.getMaximumPoolSize();
|
||||
}
|
||||
|
||||
public void join() throws InterruptedException
|
||||
{
|
||||
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isFailed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isRunning()
|
||||
{
|
||||
return !executor.isTerminated() && !executor.isTerminating();
|
||||
}
|
||||
|
||||
public boolean isStarted()
|
||||
{
|
||||
return !executor.isTerminated() && !executor.isTerminating();
|
||||
}
|
||||
|
||||
public boolean isStarting()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isStopped()
|
||||
{
|
||||
return executor.isTerminated();
|
||||
}
|
||||
|
||||
public boolean isStopping()
|
||||
{
|
||||
return executor.isTerminating();
|
||||
}
|
||||
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
if (executor.isTerminated() || executor.isTerminating() || executor.isShutdown())
|
||||
throw new IllegalStateException("Cannot restart");
|
||||
}
|
||||
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
executor.shutdown();
|
||||
if (!executor.awaitTermination(60, TimeUnit.SECONDS))
|
||||
executor.shutdownNow();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.eclipse.jetty.http.spi.JettyHttpServerProvider
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
|
|
|
@ -483,8 +483,13 @@ public abstract class AbstractGenerator implements Generator
|
|||
{
|
||||
if (close)
|
||||
_persistent=false;
|
||||
if (!isCommitted())
|
||||
if (isCommitted())
|
||||
{
|
||||
LOG.debug("sendError on committed: {} {}",code,reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.debug("sendError: {} {}",code,reason);
|
||||
setResponse(code, reason);
|
||||
if (content != null)
|
||||
{
|
||||
|
|
|
@ -4,15 +4,16 @@
|
|||
// 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
|
||||
// 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.
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jetty.io.Buffer;
|
||||
|
@ -67,7 +68,7 @@ public class HttpParser implements Parser
|
|||
private String _multiLineValue;
|
||||
private int _responseStatus; // If >0 then we are parsing a response
|
||||
private boolean _forceContentBuffer;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
protected final View _contentView=new View(); // View of the content in the buffer for {@link Input}
|
||||
protected int _state=STATE_START;
|
||||
|
@ -78,7 +79,7 @@ public class HttpParser implements Parser
|
|||
protected int _chunkLength;
|
||||
protected int _chunkPosition;
|
||||
private boolean _headResponse;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -103,7 +104,7 @@ public class HttpParser implements Parser
|
|||
/* ------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Constructor.
|
||||
* @param buffers the buffers to use
|
||||
* @param buffers the buffers to use
|
||||
* @param endp the endpoint
|
||||
* @param handler the even handler
|
||||
*/
|
||||
|
@ -134,7 +135,7 @@ public class HttpParser implements Parser
|
|||
{
|
||||
_headResponse=head;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public int getState()
|
||||
{
|
||||
|
@ -170,7 +171,7 @@ public class HttpParser implements Parser
|
|||
{
|
||||
return isState(STATE_END);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isMoreInBuffer()
|
||||
throws IOException
|
||||
|
@ -203,11 +204,11 @@ public class HttpParser implements Parser
|
|||
if (parseNext()<0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Parse until END state.
|
||||
* This method will parse any remaining content in the current buffer. It does not care about the
|
||||
* This method will parse any remaining content in the current buffer. It does not care about the
|
||||
* {@link #getState current state} of the parser.
|
||||
* @see #parse
|
||||
* @see #parseNext
|
||||
|
@ -216,7 +217,7 @@ public class HttpParser implements Parser
|
|||
{
|
||||
int progress = parseNext();
|
||||
int total=progress>0?1:0;
|
||||
|
||||
|
||||
// continue parsing
|
||||
while (!isComplete() && _buffer!=null && _buffer.length()>0)
|
||||
{
|
||||
|
@ -237,9 +238,9 @@ public class HttpParser implements Parser
|
|||
{
|
||||
int progress=0;
|
||||
|
||||
if (_state == STATE_END)
|
||||
if (_state == STATE_END)
|
||||
return 0;
|
||||
|
||||
|
||||
if (_buffer==null)
|
||||
{
|
||||
if (_header == null)
|
||||
|
@ -252,24 +253,24 @@ public class HttpParser implements Parser
|
|||
_tok0.setPutIndex(_tok0.getIndex());
|
||||
_tok1.setPutIndex(_tok1.getIndex());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (_state == STATE_CONTENT && _contentPosition == _contentLength)
|
||||
{
|
||||
_state=STATE_END;
|
||||
_handler.messageComplete(_contentPosition);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int length=_buffer.length();
|
||||
|
||||
|
||||
// Fill buffer if we can
|
||||
if (length == 0)
|
||||
{
|
||||
long filled=-1;
|
||||
IOException ex=null;
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
filled=fill();
|
||||
}
|
||||
catch(IOException e)
|
||||
|
@ -277,8 +278,8 @@ public class HttpParser implements Parser
|
|||
LOG.debug(this.toString(),e);
|
||||
ex=e;
|
||||
}
|
||||
|
||||
if (filled < 0 || _endp.isInputShutdown())
|
||||
|
||||
if (filled < 0 || _endp.isInputShutdown())
|
||||
{
|
||||
if (_headResponse && _state>STATE_END)
|
||||
{
|
||||
|
@ -294,21 +295,25 @@ public class HttpParser implements Parser
|
|||
Buffer chunk=_buffer.get(_buffer.length());
|
||||
_contentPosition += chunk.length();
|
||||
_contentView.update(chunk);
|
||||
_handler.content(chunk); // May recurse here
|
||||
_handler.content(chunk); // May recurse here
|
||||
}
|
||||
_state=STATE_END;
|
||||
_handler.messageComplete(_contentPosition);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (ex!=null)
|
||||
throw ex;
|
||||
|
||||
if (!isComplete() && !isIdle())
|
||||
throw new EOFException();
|
||||
|
||||
return -1;
|
||||
}
|
||||
length=_buffer.length();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// EventHandler header
|
||||
byte ch;
|
||||
byte[] array=_buffer.array();
|
||||
|
@ -320,16 +325,16 @@ public class HttpParser implements Parser
|
|||
progress++;
|
||||
last=_state;
|
||||
}
|
||||
|
||||
|
||||
ch=_buffer.get();
|
||||
|
||||
|
||||
if (_eol == HttpTokens.CARRIAGE_RETURN && ch == HttpTokens.LINE_FEED)
|
||||
{
|
||||
_eol=HttpTokens.LINE_FEED;
|
||||
continue;
|
||||
}
|
||||
_eol=0;
|
||||
|
||||
|
||||
switch (_state)
|
||||
{
|
||||
case STATE_START:
|
||||
|
@ -476,22 +481,22 @@ public class HttpParser implements Parser
|
|||
_state=STATE_HEADER_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
// handler last header if any
|
||||
if (_cached!=null || _tok0.length() > 0 || _tok1.length() > 0 || _multiLineValue != null)
|
||||
{
|
||||
|
||||
|
||||
Buffer header=_cached!=null?_cached:HttpHeaders.CACHE.lookup(_tok0);
|
||||
_cached=null;
|
||||
Buffer value=_multiLineValue == null ? _tok1 : new ByteArrayBuffer(_multiLineValue);
|
||||
|
||||
|
||||
int ho=HttpHeaders.CACHE.getOrdinal(header);
|
||||
if (ho >= 0)
|
||||
{
|
||||
int vo;
|
||||
|
||||
int vo;
|
||||
|
||||
switch (ho)
|
||||
{
|
||||
case HttpHeaders.CONTENT_LENGTH_ORDINAL:
|
||||
|
@ -510,7 +515,7 @@ public class HttpParser implements Parser
|
|||
_contentLength=HttpTokens.NO_CONTENT;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case HttpHeaders.TRANSFER_ENCODING_ORDINAL:
|
||||
value=HttpHeaderValues.CACHE.lookup(value);
|
||||
vo=HttpHeaderValues.CACHE.getOrdinal(value);
|
||||
|
@ -521,22 +526,22 @@ public class HttpParser implements Parser
|
|||
String c=value.toString(StringUtil.__ISO_8859_1);
|
||||
if (c.endsWith(HttpHeaderValues.CHUNKED))
|
||||
_contentLength=HttpTokens.CHUNKED_CONTENT;
|
||||
|
||||
|
||||
else if (c.indexOf(HttpHeaderValues.CHUNKED) >= 0)
|
||||
throw new HttpException(400,null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_handler.parsedHeader(header, value);
|
||||
_tok0.setPutIndex(_tok0.getIndex());
|
||||
_tok1.setPutIndex(_tok1.getIndex());
|
||||
_multiLineValue=null;
|
||||
}
|
||||
_buffer.setMarkIndex(-1);
|
||||
|
||||
|
||||
|
||||
|
||||
// now handle ch
|
||||
if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED)
|
||||
{
|
||||
|
@ -556,7 +561,7 @@ public class HttpParser implements Parser
|
|||
_eol=ch;
|
||||
if (_eol==HttpTokens.CARRIAGE_RETURN && _buffer.hasContent() && _buffer.peek()==HttpTokens.LINE_FEED)
|
||||
_eol=_buffer.get();
|
||||
|
||||
|
||||
// We convert _contentLength to an int for this switch statement because
|
||||
// we don't care about the amount of data available just whether there is some.
|
||||
switch (_contentLength > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) _contentLength)
|
||||
|
@ -565,19 +570,19 @@ public class HttpParser implements Parser
|
|||
_state=STATE_EOF_CONTENT;
|
||||
_handler.headerComplete(); // May recurse here !
|
||||
break;
|
||||
|
||||
|
||||
case HttpTokens.CHUNKED_CONTENT:
|
||||
_state=STATE_CHUNKED_CONTENT;
|
||||
_handler.headerComplete(); // May recurse here !
|
||||
break;
|
||||
|
||||
|
||||
case HttpTokens.NO_CONTENT:
|
||||
_state=STATE_END;
|
||||
returnBuffers();
|
||||
_handler.headerComplete();
|
||||
_handler.headerComplete();
|
||||
_handler.messageComplete(_contentPosition);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
_state=STATE_CONTENT;
|
||||
_handler.headerComplete(); // May recurse here !
|
||||
|
@ -591,7 +596,7 @@ public class HttpParser implements Parser
|
|||
_length=1;
|
||||
_buffer.mark();
|
||||
_state=STATE_HEADER_NAME;
|
||||
|
||||
|
||||
// try cached name!
|
||||
if (array!=null)
|
||||
{
|
||||
|
@ -604,10 +609,10 @@ public class HttpParser implements Parser
|
|||
length=_buffer.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case STATE_HEADER_NAME:
|
||||
|
@ -629,16 +634,16 @@ public class HttpParser implements Parser
|
|||
case HttpTokens.SPACE:
|
||||
case HttpTokens.TAB:
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
{
|
||||
_cached=null;
|
||||
if (_length == -1)
|
||||
if (_length == -1)
|
||||
_buffer.mark();
|
||||
_length=_buffer.getIndex() - _buffer.markIndex();
|
||||
_state=STATE_HEADER_IN_NAME;
|
||||
_state=STATE_HEADER_IN_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case STATE_HEADER_IN_NAME:
|
||||
|
@ -694,11 +699,11 @@ public class HttpParser implements Parser
|
|||
break;
|
||||
default:
|
||||
{
|
||||
if (_length == -1)
|
||||
if (_length == -1)
|
||||
_buffer.mark();
|
||||
_length=_buffer.getIndex() - _buffer.markIndex();
|
||||
_state=STATE_HEADER_IN_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -732,9 +737,9 @@ public class HttpParser implements Parser
|
|||
break;
|
||||
}
|
||||
} // end of HEADER states loop
|
||||
|
||||
|
||||
// ==========================
|
||||
|
||||
|
||||
// Handle HEAD response
|
||||
if (_responseStatus>0 && _headResponse)
|
||||
{
|
||||
|
@ -743,10 +748,10 @@ public class HttpParser implements Parser
|
|||
}
|
||||
|
||||
// ==========================
|
||||
|
||||
|
||||
// Handle _content
|
||||
length=_buffer.length();
|
||||
Buffer chunk;
|
||||
Buffer chunk;
|
||||
last=_state;
|
||||
while (_state > STATE_END && length > 0)
|
||||
{
|
||||
|
@ -755,7 +760,7 @@ public class HttpParser implements Parser
|
|||
progress++;
|
||||
last=_state;
|
||||
}
|
||||
|
||||
|
||||
if (_eol == HttpTokens.CARRIAGE_RETURN && _buffer.peek() == HttpTokens.LINE_FEED)
|
||||
{
|
||||
_eol=_buffer.get();
|
||||
|
@ -769,11 +774,11 @@ public class HttpParser implements Parser
|
|||
chunk=_buffer.get(_buffer.length());
|
||||
_contentPosition += chunk.length();
|
||||
_contentView.update(chunk);
|
||||
_handler.content(chunk); // May recurse here
|
||||
_handler.content(chunk); // May recurse here
|
||||
// TODO adjust the _buffer to keep unconsumed content
|
||||
return 1;
|
||||
|
||||
case STATE_CONTENT:
|
||||
case STATE_CONTENT:
|
||||
{
|
||||
long remaining=_contentLength - _contentPosition;
|
||||
if (remaining == 0)
|
||||
|
@ -782,24 +787,24 @@ public class HttpParser implements Parser
|
|||
_handler.messageComplete(_contentPosition);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (length > remaining)
|
||||
|
||||
if (length > remaining)
|
||||
{
|
||||
// We can cast reamining to an int as we know that it is smaller than
|
||||
// or equal to length which is already an int.
|
||||
// or equal to length which is already an int.
|
||||
length=(int)remaining;
|
||||
}
|
||||
|
||||
|
||||
chunk=_buffer.get(length);
|
||||
_contentPosition += chunk.length();
|
||||
_contentView.update(chunk);
|
||||
_handler.content(chunk); // May recurse here
|
||||
|
||||
_handler.content(chunk); // May recurse here
|
||||
|
||||
if(_contentPosition == _contentLength)
|
||||
{
|
||||
_state=STATE_END;
|
||||
_handler.messageComplete(_contentPosition);
|
||||
}
|
||||
}
|
||||
// TODO adjust the _buffer to keep unconsumed content
|
||||
return 1;
|
||||
}
|
||||
|
@ -826,7 +831,7 @@ public class HttpParser implements Parser
|
|||
if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED)
|
||||
{
|
||||
_eol=ch;
|
||||
|
||||
|
||||
if (_chunkLength == 0)
|
||||
{
|
||||
if (_eol==HttpTokens.CARRIAGE_RETURN && _buffer.hasContent() && _buffer.peek()==HttpTokens.LINE_FEED)
|
||||
|
@ -870,8 +875,8 @@ public class HttpParser implements Parser
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case STATE_CHUNK:
|
||||
|
||||
case STATE_CHUNK:
|
||||
{
|
||||
int remaining=_chunkLength - _chunkPosition;
|
||||
if (remaining == 0)
|
||||
|
@ -879,13 +884,13 @@ public class HttpParser implements Parser
|
|||
_state=STATE_CHUNKED_CONTENT;
|
||||
break;
|
||||
}
|
||||
else if (length > remaining)
|
||||
else if (length > remaining)
|
||||
length=remaining;
|
||||
chunk=_buffer.get(length);
|
||||
_contentPosition += chunk.length();
|
||||
_chunkPosition += chunk.length();
|
||||
_contentView.update(chunk);
|
||||
_handler.content(chunk); // May recurse here
|
||||
_handler.content(chunk); // May recurse here
|
||||
// TODO adjust the _buffer to keep unconsumed content
|
||||
return 1;
|
||||
}
|
||||
|
@ -893,13 +898,13 @@ public class HttpParser implements Parser
|
|||
|
||||
length=_buffer.length();
|
||||
}
|
||||
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/** fill the buffers from the endpoint
|
||||
*
|
||||
*
|
||||
*/
|
||||
public long fill() throws IOException
|
||||
{
|
||||
|
@ -910,14 +915,14 @@ public class HttpParser implements Parser
|
|||
_tok0=new View.CaseInsensitive(_buffer);
|
||||
_tok1=new View.CaseInsensitive(_buffer);
|
||||
}
|
||||
|
||||
|
||||
// Is there unconsumed content in body buffer
|
||||
if (_state>STATE_END && _buffer==_header && _header!=null && !_header.hasContent() && _body!=null && _body.hasContent())
|
||||
{
|
||||
_buffer=_body;
|
||||
return _buffer.length();
|
||||
}
|
||||
|
||||
|
||||
// Shall we switch to a body buffer?
|
||||
if (_buffer==_header && _state>STATE_END && _header.length()==0 && (_forceContentBuffer || (_contentLength-_contentPosition)>_header.capacity()) && (_body!=null||_buffers!=null))
|
||||
{
|
||||
|
@ -925,20 +930,20 @@ public class HttpParser implements Parser
|
|||
_body=_buffers.getBuffer();
|
||||
_buffer=_body;
|
||||
}
|
||||
|
||||
|
||||
// Do we have somewhere to fill from?
|
||||
if (_endp != null )
|
||||
{
|
||||
// Shall we compact the body?
|
||||
if (_buffer==_body || _state>STATE_END)
|
||||
if (_buffer==_body || _state>STATE_END)
|
||||
{
|
||||
_buffer.compact();
|
||||
}
|
||||
|
||||
|
||||
// Are we full?
|
||||
if (_buffer.space() == 0)
|
||||
throw new HttpException(HttpStatus.REQUEST_ENTITY_TOO_LARGE_413, "FULL "+(_buffer==_body?"body":"head"));
|
||||
|
||||
if (_buffer.space() == 0)
|
||||
throw new HttpException(HttpStatus.REQUEST_ENTITY_TOO_LARGE_413, "FULL "+(_buffer==_body?"body":"head"));
|
||||
|
||||
try
|
||||
{
|
||||
return _endp.fill(_buffer);
|
||||
|
@ -955,7 +960,7 @@ public class HttpParser implements Parser
|
|||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/** Skip any CRLFs in buffers
|
||||
*
|
||||
*
|
||||
*/
|
||||
public void skipCRLF()
|
||||
{
|
||||
|
@ -983,12 +988,12 @@ public class HttpParser implements Parser
|
|||
else
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public void reset()
|
||||
{
|
||||
{
|
||||
// reset state
|
||||
_contentView.setGetIndex(_contentView.putIndex());
|
||||
_state=STATE_START;
|
||||
|
@ -1038,12 +1043,12 @@ public class HttpParser implements Parser
|
|||
public void returnBuffers()
|
||||
{
|
||||
if (_body!=null && !_body.hasContent() && _body.markIndex()==-1 && _buffers!=null)
|
||||
{
|
||||
{
|
||||
if (_buffer==_body)
|
||||
_buffer=_header;
|
||||
if (_buffers!=null)
|
||||
_buffers.returnBuffer(_body);
|
||||
_body=null;
|
||||
_body=null;
|
||||
}
|
||||
|
||||
if (_header!=null && !_header.hasContent() && _header.markIndex()==-1 && _buffers!=null)
|
||||
|
@ -1054,7 +1059,7 @@ public class HttpParser implements Parser
|
|||
_header=null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public void setState(int state)
|
||||
{
|
||||
|
@ -1067,13 +1072,13 @@ public class HttpParser implements Parser
|
|||
{
|
||||
return "state=" + _state + " length=" + _length + " buf=" + buf.hashCode();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "state=" + _state + " length=" + _length + " len=" + _contentLength;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Buffer getHeaderBuffer()
|
||||
|
@ -1084,7 +1089,7 @@ public class HttpParser implements Parser
|
|||
}
|
||||
return _header;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Buffer getBodyBuffer()
|
||||
{
|
||||
|
@ -1098,20 +1103,20 @@ public class HttpParser implements Parser
|
|||
public void setForceContentBuffer(boolean force)
|
||||
{
|
||||
_forceContentBuffer=force;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Buffer blockForContent(long maxIdleTime) throws IOException
|
||||
{
|
||||
if (_contentView.length()>0)
|
||||
return _contentView;
|
||||
if (getState() <= HttpParser.STATE_END)
|
||||
if (getState() <= HttpParser.STATE_END)
|
||||
return null;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
parseNext();
|
||||
|
||||
|
||||
// parse until some progress is made (or IOException thrown for timeout)
|
||||
while(_contentView.length() == 0 && !isState(HttpParser.STATE_END) && _endp!=null && _endp.isOpen())
|
||||
{
|
||||
|
@ -1135,9 +1140,9 @@ public class HttpParser implements Parser
|
|||
_endp.close();
|
||||
throw e;
|
||||
}
|
||||
|
||||
return _contentView.length()>0?_contentView:null;
|
||||
}
|
||||
|
||||
return _contentView.length()>0?_contentView:null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* (non-Javadoc)
|
||||
|
@ -1155,11 +1160,11 @@ public class HttpParser implements Parser
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
parseNext();
|
||||
return _contentView==null?0:_contentView.length();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1187,7 +1192,7 @@ public class HttpParser implements Parser
|
|||
*/
|
||||
public abstract void startRequest(Buffer method, Buffer url, Buffer version)
|
||||
throws IOException;
|
||||
|
||||
|
||||
/**
|
||||
* This is the method called by parser when the HTTP request line is parsed
|
||||
*/
|
||||
|
@ -1197,5 +1202,5 @@ public class HttpParser implements Parser
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
|
|
|
@ -47,6 +47,7 @@ public interface EndPoint
|
|||
* The buffer may chose to do a compact before filling.
|
||||
* @return an <code>int</code> value indicating the number of bytes
|
||||
* filled or -1 if EOF is reached.
|
||||
* @throws EofException If input is shutdown or the endpoint is closed.
|
||||
*/
|
||||
int fill(Buffer buffer) throws IOException;
|
||||
|
||||
|
@ -59,6 +60,7 @@ public interface EndPoint
|
|||
*
|
||||
* @param buffer The buffer to flush. This buffers getIndex is updated.
|
||||
* @return the number of bytes written
|
||||
* @throws EofException If the endpoint is closed or output is shutdown.
|
||||
*/
|
||||
int flush(Buffer buffer) throws IOException;
|
||||
|
||||
|
@ -157,7 +159,7 @@ public interface EndPoint
|
|||
/* ------------------------------------------------------------ */
|
||||
/** Flush any buffered output.
|
||||
* May fail to write all data if endpoint is non-blocking
|
||||
* @throws IOException
|
||||
* @throws EofException If the endpoint is closed or output is shutdown.
|
||||
*/
|
||||
public void flush() throws IOException;
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
// 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
|
||||
// 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.
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
package org.eclipse.jetty.io.bio;
|
||||
|
@ -17,6 +17,7 @@ import java.io.IOException;
|
|||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -34,13 +35,13 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
final Socket _socket;
|
||||
final InetSocketAddress _local;
|
||||
final InetSocketAddress _remote;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public SocketEndPoint(Socket socket)
|
||||
throws IOException
|
||||
throws IOException
|
||||
{
|
||||
super(socket.getInputStream(),socket.getOutputStream());
|
||||
_socket=socket;
|
||||
|
@ -48,13 +49,13 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
_remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
|
||||
super.setMaxIdleTime(_socket.getSoTimeout());
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
protected SocketEndPoint(Socket socket, int maxIdleTime)
|
||||
throws IOException
|
||||
throws IOException
|
||||
{
|
||||
super(socket.getInputStream(),socket.getOutputStream());
|
||||
_socket=socket;
|
||||
|
@ -63,7 +64,7 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
_socket.setSoTimeout(maxIdleTime>0?maxIdleTime:0);
|
||||
super.setMaxIdleTime(maxIdleTime);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.io.BufferIO#isClosed()
|
||||
|
@ -73,19 +74,19 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
{
|
||||
return super.isOpen() && _socket!=null && !_socket.isClosed();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public boolean isInputShutdown()
|
||||
{
|
||||
return !super.isOpen() || _socket!=null && _socket.isInputShutdown();
|
||||
return !isOpen() || super.isInputShutdown();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public boolean isOutputShutdown()
|
||||
{
|
||||
return !super.isOpen() || _socket!=null && _socket.isOutputShutdown();
|
||||
return !isOpen() || super.isOutputShutdown();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -94,9 +95,13 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
*/
|
||||
@Override
|
||||
public void shutdownOutput() throws IOException
|
||||
{
|
||||
if (!_socket.isClosed() && !_socket.isOutputShutdown())
|
||||
_socket.shutdownOutput();
|
||||
{
|
||||
if (!isOutputShutdown())
|
||||
{
|
||||
super.shutdownOutput();
|
||||
if (!(_socket instanceof SSLSocket))
|
||||
_socket.shutdownOutput();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,11 +111,15 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
*/
|
||||
@Override
|
||||
public void shutdownInput() throws IOException
|
||||
{
|
||||
if (!_socket.isClosed() && !_socket.isInputShutdown())
|
||||
_socket.shutdownInput();
|
||||
{
|
||||
if (!isInputShutdown())
|
||||
{
|
||||
super.shutdownInput();
|
||||
if (!(_socket instanceof SSLSocket))
|
||||
_socket.shutdownInput();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.io.BufferIO#close()
|
||||
|
@ -122,10 +131,10 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
_in=null;
|
||||
_out=null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
/*
|
||||
* @see org.eclipse.io.EndPoint#getLocalAddr()
|
||||
*/
|
||||
@Override
|
||||
|
@ -133,12 +142,12 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
{
|
||||
if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
|
||||
return StringUtil.ALL_INTERFACES;
|
||||
|
||||
|
||||
return _local.getAddress().getHostAddress();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
/*
|
||||
* @see org.eclipse.io.EndPoint#getLocalHost()
|
||||
*/
|
||||
@Override
|
||||
|
@ -146,12 +155,12 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
{
|
||||
if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
|
||||
return StringUtil.ALL_INTERFACES;
|
||||
|
||||
|
||||
return _local.getAddress().getCanonicalHostName();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
/*
|
||||
* @see org.eclipse.io.EndPoint#getLocalPort()
|
||||
*/
|
||||
@Override
|
||||
|
@ -163,7 +172,7 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
/*
|
||||
* @see org.eclipse.io.EndPoint#getRemoteAddr()
|
||||
*/
|
||||
@Override
|
||||
|
@ -176,7 +185,7 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
/*
|
||||
* @see org.eclipse.io.EndPoint#getRemoteHost()
|
||||
*/
|
||||
@Override
|
||||
|
@ -188,7 +197,7 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
/*
|
||||
* @see org.eclipse.io.EndPoint#getRemotePort()
|
||||
*/
|
||||
@Override
|
||||
|
@ -200,7 +209,7 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
/*
|
||||
* @see org.eclipse.io.EndPoint#getConnection()
|
||||
*/
|
||||
@Override
|
||||
|
@ -237,5 +246,5 @@ public class SocketEndPoint extends StreamEndPoint
|
|||
_socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -22,17 +22,13 @@ import java.net.SocketTimeoutException;
|
|||
import org.eclipse.jetty.io.Buffer;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* To change the template for this generated type comment go to
|
||||
* Window - Preferences - Java - Code Generation - Code and Comments
|
||||
*/
|
||||
public class StreamEndPoint implements EndPoint
|
||||
{
|
||||
InputStream _in;
|
||||
OutputStream _out;
|
||||
int _maxIdleTime;
|
||||
boolean _ishut;
|
||||
boolean _oshut;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -75,23 +71,33 @@ public class StreamEndPoint implements EndPoint
|
|||
}
|
||||
|
||||
public void shutdownOutput() throws IOException
|
||||
{
|
||||
{
|
||||
if (_oshut)
|
||||
return;
|
||||
_oshut = true;
|
||||
if (_out!=null)
|
||||
_out.close();
|
||||
}
|
||||
|
||||
|
||||
public boolean isInputShutdown()
|
||||
{
|
||||
return !isOpen();
|
||||
return _ishut;
|
||||
}
|
||||
|
||||
public void shutdownInput() throws IOException
|
||||
{
|
||||
{
|
||||
if (_ishut)
|
||||
return;
|
||||
_ishut = true;
|
||||
if (_in!=null)
|
||||
_in.close();
|
||||
}
|
||||
|
||||
|
||||
public boolean isOutputShutdown()
|
||||
{
|
||||
return !isOpen();
|
||||
return _oshut;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @see org.eclipse.io.BufferIO#close()
|
||||
*/
|
||||
|
@ -107,35 +113,43 @@ public class StreamEndPoint implements EndPoint
|
|||
|
||||
protected void idleExpired() throws IOException
|
||||
{
|
||||
_in.close();
|
||||
if (_in!=null)
|
||||
_in.close();
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.io.BufferIO#fill(org.eclipse.io.Buffer)
|
||||
*/
|
||||
public int fill(Buffer buffer) throws IOException
|
||||
{
|
||||
// TODO handle null array()
|
||||
if (_in==null)
|
||||
return 0;
|
||||
|
||||
int space=buffer.space();
|
||||
if (space<=0)
|
||||
{
|
||||
if (buffer.hasContent())
|
||||
return 0;
|
||||
throw new IOException("FULL");
|
||||
}
|
||||
int space=buffer.space();
|
||||
if (space<=0)
|
||||
{
|
||||
if (buffer.hasContent())
|
||||
return 0;
|
||||
throw new IOException("FULL");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return buffer.readFrom(_in,space);
|
||||
}
|
||||
catch(SocketTimeoutException e)
|
||||
{
|
||||
idleExpired();
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
int read=buffer.readFrom(_in, space);
|
||||
if (read<0 && isOpen())
|
||||
{
|
||||
if (!isInputShutdown())
|
||||
shutdownInput();
|
||||
else if (isOutputShutdown())
|
||||
close();
|
||||
}
|
||||
return read;
|
||||
}
|
||||
catch(SocketTimeoutException e)
|
||||
{
|
||||
idleExpired();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -143,7 +157,6 @@ public class StreamEndPoint implements EndPoint
|
|||
*/
|
||||
public int flush(Buffer buffer) throws IOException
|
||||
{
|
||||
// TODO handle null array()
|
||||
if (_out==null)
|
||||
return -1;
|
||||
int length=buffer.length();
|
||||
|
@ -314,13 +327,13 @@ public class StreamEndPoint implements EndPoint
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public int getMaxIdleTime()
|
||||
{
|
||||
return _maxIdleTime;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setMaxIdleTime(int timeMs) throws IOException
|
||||
{
|
||||
|
|
|
@ -38,21 +38,42 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
|
|||
|
||||
private final SelectorManager.SelectSet _selectSet;
|
||||
private final SelectorManager _manager;
|
||||
private SelectionKey _key;
|
||||
private final Runnable _handler = new Runnable()
|
||||
{
|
||||
public void run() { handle(); }
|
||||
};
|
||||
|
||||
/** The desired value for {@link SelectionKey#interestOps()} */
|
||||
private int _interestOps;
|
||||
|
||||
/**
|
||||
* The connection instance is the handler for any IO activity on the endpoint.
|
||||
* There is a different type of connection for HTTP, AJP, WebSocket and
|
||||
* ProxyConnect. The connection may change for an SCEP as it is upgraded
|
||||
* from HTTP to proxy connect or websocket.
|
||||
*/
|
||||
private volatile Connection _connection;
|
||||
|
||||
/** true if a thread has been dispatched to handle this endpoint */
|
||||
private boolean _dispatched = false;
|
||||
|
||||
/** true if a non IO dispatch (eg async resume) is outstanding */
|
||||
private boolean _redispatched = false;
|
||||
|
||||
/** true if the last write operation succeed and wrote all offered bytes */
|
||||
private volatile boolean _writable = true;
|
||||
|
||||
private SelectionKey _key;
|
||||
private int _interestOps;
|
||||
|
||||
/** True if a thread has is blocked in {@link #blockReadable(long)} */
|
||||
private boolean _readBlocked;
|
||||
|
||||
/** True if a thread has is blocked in {@link #blockWritable(long)} */
|
||||
private boolean _writeBlocked;
|
||||
|
||||
/** true if {@link SelectSet#destroyEndPoint(SelectChannelEndPoint)} has not been called */
|
||||
private boolean _open;
|
||||
|
||||
private volatile long _idleTimestamp;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -242,7 +242,10 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||
if (_closing)
|
||||
{
|
||||
if (outBuf!=null && outBuf.hasContent())
|
||||
throw new IOException("Write while closing");
|
||||
{
|
||||
LOG.debug("Write while closing");
|
||||
outBuf.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -317,7 +320,7 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||
|
||||
// Need more data to be unwrapped so try another call to unwrap
|
||||
progress|=unwrap(inBBuf);
|
||||
if (_closing)
|
||||
if (_closing && inBBuf.hasRemaining())
|
||||
inBBuf.clear();
|
||||
break;
|
||||
}
|
||||
|
@ -338,15 +341,16 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
if (_closing)
|
||||
return;
|
||||
|
||||
_closing=true;
|
||||
LOG.debug("{} close",_session);
|
||||
// For safety we always force a close calling super
|
||||
try
|
||||
{
|
||||
_engine.closeOutbound();
|
||||
process(null,null);
|
||||
if (!_closing)
|
||||
{
|
||||
_closing=true;
|
||||
LOG.debug("{} close",_session);
|
||||
_engine.closeOutbound();
|
||||
process(null,null);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
@ -642,7 +646,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||
catch(SSLException e)
|
||||
{
|
||||
LOG.warn(getRemoteAddr()+":"+getRemotePort()+" ",e);
|
||||
super.close();
|
||||
if (getChannel().isOpen())
|
||||
getChannel().close();
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
|
|
|
@ -14,9 +14,15 @@
|
|||
package org.eclipse.jetty.io;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Reader;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.junit.Test;
|
||||
|
@ -42,4 +48,88 @@ public class IOTest
|
|||
out.toString(),
|
||||
"The quick brown fox jumped over the lazy dog");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHalfCloses() throws Exception
|
||||
{
|
||||
ServerSocket connector = new ServerSocket(0);
|
||||
|
||||
Socket client = new Socket("localhost",connector.getLocalPort());
|
||||
System.err.println(client);
|
||||
Socket server = connector.accept();
|
||||
System.err.println(server);
|
||||
|
||||
// we can write both ways
|
||||
client.getOutputStream().write(1);
|
||||
assertEquals(1,server.getInputStream().read());
|
||||
server.getOutputStream().write(1);
|
||||
assertEquals(1,client.getInputStream().read());
|
||||
|
||||
// shutdown output results in read -1
|
||||
client.shutdownOutput();
|
||||
assertEquals(-1,server.getInputStream().read());
|
||||
|
||||
// Even though EOF has been read, the server input is not seen as shutdown
|
||||
assertFalse(server.isInputShutdown());
|
||||
|
||||
// and we can read -1 again
|
||||
assertEquals(-1,server.getInputStream().read());
|
||||
|
||||
// but cannot write
|
||||
try { client.getOutputStream().write(1); assertTrue(false); } catch (SocketException e) {}
|
||||
|
||||
// but can still write in opposite direction.
|
||||
server.getOutputStream().write(1);
|
||||
assertEquals(1,client.getInputStream().read());
|
||||
|
||||
|
||||
// server can shutdown input to match the shutdown out of client
|
||||
server.shutdownInput();
|
||||
|
||||
// now we EOF instead of reading -1
|
||||
try { server.getInputStream().read(); assertTrue(false); } catch (SocketException e) {}
|
||||
|
||||
|
||||
// but can still write in opposite direction.
|
||||
server.getOutputStream().write(1);
|
||||
assertEquals(1,client.getInputStream().read());
|
||||
|
||||
// client can shutdown input
|
||||
client.shutdownInput();
|
||||
|
||||
// now we EOF instead of reading -1
|
||||
try { client.getInputStream().read(); assertTrue(false); } catch (SocketException e) {}
|
||||
|
||||
// But we can still write at the server (data which will never be read)
|
||||
server.getOutputStream().write(1);
|
||||
|
||||
// and the server output is not shutdown
|
||||
assertFalse( server.isOutputShutdown() );
|
||||
|
||||
// until we explictly shut it down
|
||||
server.shutdownOutput();
|
||||
|
||||
// and now we can't write
|
||||
try { server.getOutputStream().write(1); assertTrue(false); } catch (SocketException e) {}
|
||||
|
||||
// but the sockets are still open
|
||||
assertFalse(client.isClosed());
|
||||
assertFalse(server.isClosed());
|
||||
|
||||
// but if we close one end
|
||||
client.close();
|
||||
|
||||
// it is seen as closed.
|
||||
assertTrue(client.isClosed());
|
||||
|
||||
// but not the other end
|
||||
assertFalse(server.isClosed());
|
||||
|
||||
// which has to be closed explictly
|
||||
server.close();
|
||||
assertTrue(server.isClosed());
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jaspi</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jmx</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jndi</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jsp-2.1</artifactId>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-monitor</artifactId>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jetty-nested</artifactId>
|
||||
<name>Jetty :: Nested</name>
|
||||
|
|
|
@ -4,29 +4,25 @@
|
|||
// 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
|
||||
// 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.
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.nested;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.io.Buffer;
|
||||
import org.eclipse.jetty.io.bio.StreamEndPoint;
|
||||
|
||||
public class NestedEndPoint extends StreamEndPoint
|
||||
{
|
||||
private final HttpServletRequest _outerRequest;
|
||||
|
||||
|
||||
public NestedEndPoint(HttpServletRequest outerRequest, HttpServletResponse outerResponse)
|
||||
throws IOException
|
||||
{
|
||||
|
@ -65,7 +61,6 @@ public class NestedEndPoint extends StreamEndPoint
|
|||
@Override
|
||||
public String getRemoteHost()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return _outerRequest.getRemoteHost();
|
||||
}
|
||||
@Override
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-nosql</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-overlay-deployer</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-plus</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-policy</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-rewrite</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-security</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
|
|
|
@ -27,7 +27,6 @@ public class AsyncHttpConnection extends HttpConnection
|
|||
|
||||
public Connection handle() throws IOException
|
||||
{
|
||||
LOG.debug("handle {}",this);
|
||||
Connection connection = this;
|
||||
boolean some_progress=false;
|
||||
boolean progress=true;
|
||||
|
@ -60,6 +59,11 @@ public class AsyncHttpConnection extends HttpConnection
|
|||
// Flush output from buffering endpoint
|
||||
if (_endp.isBufferingOutput())
|
||||
_endp.flush();
|
||||
|
||||
// Special case close handling.
|
||||
// If we were dispatched and have made no progress, but io is shutdown, then close
|
||||
if (!progress && !some_progress && (_endp.isInputShutdown()||_endp.isOutputShutdown()))
|
||||
_endp.close();
|
||||
}
|
||||
catch (HttpException e)
|
||||
{
|
||||
|
@ -123,13 +127,12 @@ public class AsyncHttpConnection extends HttpConnection
|
|||
{
|
||||
setCurrentConnection(null);
|
||||
_parser.returnBuffers();
|
||||
_generator.returnBuffers();
|
||||
|
||||
// Are we write blocked
|
||||
if (_generator.isCommitted() && !_generator.isComplete() && _endp.isOpen())
|
||||
((AsyncEndPoint)_endp).scheduleWrite();
|
||||
else
|
||||
_generator.returnBuffers();
|
||||
|
||||
// Check if we are write blocked
|
||||
if (_generator.isCommitted() && !_generator.isComplete() && _endp.isOpen() && !_endp.isOutputShutdown())
|
||||
((AsyncEndPoint)_endp).scheduleWrite(); // TODO. This should not be required
|
||||
|
||||
if (!some_progress)
|
||||
{
|
||||
_total_no_progress++;
|
||||
|
@ -137,24 +140,18 @@ public class AsyncHttpConnection extends HttpConnection
|
|||
if (NO_PROGRESS_INFO>0 && _total_no_progress%NO_PROGRESS_INFO==0 && (NO_PROGRESS_CLOSE<=0 || _total_no_progress< NO_PROGRESS_CLOSE))
|
||||
{
|
||||
LOG.info("EndPoint making no progress: "+_total_no_progress+" "+_endp);
|
||||
|
||||
LOG.setDebugEnabled(true);
|
||||
Log.getLogger("org.eclipse.jetty.io.nio").getLogger("ssl").setDebugEnabled(true);
|
||||
Log.getLogger(ChannelEndPoint.class).setDebugEnabled(true);
|
||||
|
||||
}
|
||||
|
||||
if (NO_PROGRESS_CLOSE>0 && _total_no_progress>NO_PROGRESS_CLOSE)
|
||||
if (NO_PROGRESS_CLOSE>0 && _total_no_progress==NO_PROGRESS_CLOSE)
|
||||
{
|
||||
LOG.warn("Closing EndPoint making no progress: "+_total_no_progress+" "+_endp);
|
||||
_endp.close();
|
||||
if (_endp instanceof SelectChannelEndPoint)
|
||||
{
|
||||
System.err.println(((SelectChannelEndPoint)_endp).getSelectManager().dump());
|
||||
((SelectChannelEndPoint)_endp).getChannel().close();
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG.debug("unhandle {}",this);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
|
|
@ -453,29 +453,29 @@ public abstract class HttpConnection extends AbstractConnection
|
|||
catch (EofException e)
|
||||
{
|
||||
LOG.debug(e);
|
||||
_request.setHandled(true);
|
||||
error=true;
|
||||
_request.setHandled(true);
|
||||
}
|
||||
catch (RuntimeIOException e)
|
||||
{
|
||||
LOG.debug(e);
|
||||
_request.setHandled(true);
|
||||
error=true;
|
||||
_request.setHandled(true);
|
||||
}
|
||||
catch (HttpException e)
|
||||
{
|
||||
LOG.debug(e);
|
||||
error=true;
|
||||
_request.setHandled(true);
|
||||
_response.sendError(e.getStatus(), e.getReason());
|
||||
error=true;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (e instanceof ThreadDeath)
|
||||
throw (ThreadDeath)e;
|
||||
|
||||
error=true;
|
||||
LOG.warn(String.valueOf(_uri),e);
|
||||
error=true;
|
||||
_request.setHandled(true);
|
||||
_generator.sendError(info==null?400:500, null, null, true);
|
||||
}
|
||||
|
@ -509,7 +509,12 @@ public abstract class HttpConnection extends AbstractConnection
|
|||
if(_endp.isOpen())
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
_endp.shutdownOutput();
|
||||
_generator.setPersistent(false);
|
||||
if (!_generator.isComplete())
|
||||
_response.complete();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_response.isCommitted() && !_request.isHandled())
|
||||
|
|
|
@ -82,7 +82,7 @@ public class SocketConnector extends AbstractConnector
|
|||
_localPort=_serverSocket.getLocalPort();
|
||||
if (_localPort<=0)
|
||||
throw new IllegalStateException("port not allocated for "+this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -176,7 +176,6 @@ public class SocketConnector extends AbstractConnector
|
|||
/* ------------------------------------------------------------------------------- */
|
||||
protected class ConnectorEndPoint extends SocketEndPoint implements Runnable, ConnectedEndPoint
|
||||
{
|
||||
boolean _dispatched=false;
|
||||
volatile Connection _connection;
|
||||
protected final Socket _socket;
|
||||
|
||||
|
@ -284,7 +283,7 @@ public class SocketConnector extends AbstractConnector
|
|||
if (!_socket.isClosed())
|
||||
{
|
||||
long timestamp=System.currentTimeMillis();
|
||||
int max_idle=getMaxIdleTime();
|
||||
int max_idle=getMaxIdleTime();
|
||||
|
||||
_socket.setSoTimeout(getMaxIdleTime());
|
||||
int c=0;
|
||||
|
|
|
@ -34,13 +34,30 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* Usage:
|
||||
*
|
||||
* <pre>
|
||||
* Server server = new Server(8080);
|
||||
* HandlerList handlers = new HandlerList();
|
||||
* handlers.setHandlers(new Handler[]
|
||||
* { someOtherHandler, new ShutdownHandler(server,"secret password") });
|
||||
* server.setHandler(handlers);
|
||||
* server.start();
|
||||
* </pre>
|
||||
Server server = new Server(8080);
|
||||
HandlerList handlers = new HandlerList();
|
||||
handlers.setHandlers(new Handler[]
|
||||
{ someOtherHandler, new ShutdownHandler(server,"secret password") });
|
||||
server.setHandler(handlers);
|
||||
server.start();
|
||||
</pre>
|
||||
*
|
||||
<pre>
|
||||
public static void attemptShutdown(int port, String shutdownCookie) {
|
||||
try {
|
||||
URL url = new URL("http://localhost:" + port + "/shutdown?cookie=" + shutdownCookie);
|
||||
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.getResponseCode();
|
||||
logger.info("Shutting down " + url + ": " + connection.getResponseMessage());
|
||||
} catch (SocketException e) {
|
||||
logger.debug("Not running");
|
||||
// Okay - the server is not running
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
*/
|
||||
public class ShutdownHandler extends AbstractHandler
|
||||
{
|
||||
|
|
|
@ -4,26 +4,23 @@
|
|||
// 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
|
||||
// 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.
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
package org.eclipse.jetty.server.ssl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
import javax.net.ssl.HandshakeCompletedEvent;
|
||||
import javax.net.ssl.HandshakeCompletedListener;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLException;
|
||||
import javax.net.ssl.SSLServerSocket;
|
||||
import javax.net.ssl.SSLServerSocketFactory;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
|
@ -40,17 +37,17 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* SSL Socket Connector.
|
||||
*
|
||||
*
|
||||
* This specialization of SocketConnector is an abstract listener that can be used as the basis for a
|
||||
* specific JSSE listener.
|
||||
*
|
||||
* The original of this class was heavily based on the work from Court Demas, which in turn is
|
||||
*
|
||||
* The original of this class was heavily based on the work from Court Demas, which in turn is
|
||||
* based on the work from Forge Research. Since JSSE, this class has evolved significantly from
|
||||
* that early work.
|
||||
*
|
||||
*
|
||||
* @org.apache.xbean.XBean element="sslSocketConnector" description="Creates an ssl socket connector"
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class SslSocketConnector extends SocketConnector implements SslConnector
|
||||
{
|
||||
|
@ -87,7 +84,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
/**
|
||||
* Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
|
||||
* a vulnerability in SSL/TLS with re-negotiation. If your JVM
|
||||
* does not have CVE-2009-3555 fixed, then re-negotiation should
|
||||
* does not have CVE-2009-3555 fixed, then re-negotiation should
|
||||
* not be allowed.
|
||||
* @param allowRenegotiate true if re-negotiation is allowed (default false)
|
||||
*/
|
||||
|
@ -100,19 +97,19 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
@Override
|
||||
public void accept(int acceptorID)
|
||||
throws IOException, InterruptedException
|
||||
{
|
||||
{
|
||||
Socket socket = _serverSocket.accept();
|
||||
configure(socket);
|
||||
|
||||
|
||||
ConnectorEndPoint connection=new SslConnectorEndPoint(socket);
|
||||
connection.dispatch();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
protected void configure(Socket socket)
|
||||
throws IOException
|
||||
{
|
||||
{
|
||||
super.configure(socket);
|
||||
}
|
||||
|
||||
|
@ -131,8 +128,8 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
* certificate in the chain is the one set by the client, the next is the one used to
|
||||
* authenticate the first, and so on. </li>
|
||||
* </ul>
|
||||
*
|
||||
* @param endpoint The Socket the request arrived on.
|
||||
*
|
||||
* @param endpoint The Socket the request arrived on.
|
||||
* This should be a {@link SocketEndPoint} wrapping a {@link SSLSocket}.
|
||||
* @param request HttpRequest to be customised.
|
||||
*/
|
||||
|
@ -142,7 +139,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
{
|
||||
super.customize(endpoint, request);
|
||||
request.setScheme(HttpSchemes.HTTPS);
|
||||
|
||||
|
||||
SocketEndPoint socket_end_point = (SocketEndPoint)endpoint;
|
||||
SSLSocket sslSocket = (SSLSocket)socket_end_point.getTransport();
|
||||
SSLSession sslSession = sslSocket.getSession();
|
||||
|
@ -150,7 +147,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
SslCertificates.customize(sslSession,endpoint,request);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
|
||||
* @deprecated
|
||||
|
@ -159,7 +156,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
public String[] getExcludeCipherSuites() {
|
||||
return _sslContextFactory.getExcludeCipherSuites();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.ssl.SslConnector#getIncludeCipherSuites()
|
||||
|
@ -188,7 +185,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public String getKeystoreType()
|
||||
public String getKeystoreType()
|
||||
{
|
||||
return _sslContextFactory.getKeyStoreType();
|
||||
}
|
||||
|
@ -210,7 +207,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public String getProtocol()
|
||||
public String getProtocol()
|
||||
{
|
||||
return _sslContextFactory.getProtocol();
|
||||
}
|
||||
|
@ -231,7 +228,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public String getSecureRandomAlgorithm()
|
||||
public String getSecureRandomAlgorithm()
|
||||
{
|
||||
return _sslContextFactory.getSecureRandomAlgorithm();
|
||||
}
|
||||
|
@ -242,7 +239,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public String getSslKeyManagerFactoryAlgorithm()
|
||||
public String getSslKeyManagerFactoryAlgorithm()
|
||||
{
|
||||
return _sslContextFactory.getSslKeyManagerFactoryAlgorithm();
|
||||
}
|
||||
|
@ -253,7 +250,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public String getSslTrustManagerFactoryAlgorithm()
|
||||
public String getSslTrustManagerFactoryAlgorithm()
|
||||
{
|
||||
return _sslContextFactory.getTrustManagerFactoryAlgorithm();
|
||||
}
|
||||
|
@ -315,7 +312,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
final int confidentialPort = getConfidentialPort();
|
||||
return confidentialPort == 0 || confidentialPort == request.getServerPort();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* By default, we're integral, given we speak SSL. But, if we've been told about an integral
|
||||
|
@ -346,7 +343,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
}
|
||||
super.open();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
|
@ -356,10 +353,10 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
{
|
||||
_sslContextFactory.checkKeyStore();
|
||||
_sslContextFactory.start();
|
||||
|
||||
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.bio.SocketConnector#doStop()
|
||||
|
@ -371,14 +368,14 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param host The host name that this server should listen on
|
||||
* @param port the port that this server should listen on
|
||||
* @param port the port that this server should listen on
|
||||
* @param backlog See {@link ServerSocket#bind(java.net.SocketAddress, int)}
|
||||
* @return A new {@link ServerSocket socket object} bound to the supplied address with all other
|
||||
* settings as per the current configuration of this connector.
|
||||
* settings as per the current configuration of this connector.
|
||||
* @see #setWantClientAuth(boolean)
|
||||
* @see #setNeedClientAuth(boolean)
|
||||
* @exception IOException
|
||||
|
@ -439,7 +436,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public void setKeystoreType(String keystoreType)
|
||||
public void setKeystoreType(String keystoreType)
|
||||
{
|
||||
_sslContextFactory.setKeyStoreType(keystoreType);
|
||||
}
|
||||
|
@ -447,7 +444,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Set the value of the needClientAuth property
|
||||
*
|
||||
*
|
||||
* @param needClientAuth true iff we require client certificate authentication.
|
||||
* @deprecated
|
||||
*/
|
||||
|
@ -456,7 +453,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
{
|
||||
_sslContextFactory.setNeedClientAuth(needClientAuth);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.ssl.SslConnector#setPassword(java.lang.String)
|
||||
|
@ -467,7 +464,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
{
|
||||
_sslContextFactory.setKeyStorePassword(password);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.ssl.SslConnector#setTrustPassword(java.lang.String)
|
||||
|
@ -485,7 +482,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public void setProtocol(String protocol)
|
||||
public void setProtocol(String protocol)
|
||||
{
|
||||
_sslContextFactory.setProtocol(protocol);
|
||||
}
|
||||
|
@ -506,7 +503,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public void setSecureRandomAlgorithm(String algorithm)
|
||||
public void setSecureRandomAlgorithm(String algorithm)
|
||||
{
|
||||
_sslContextFactory.setSecureRandomAlgorithm(algorithm);
|
||||
}
|
||||
|
@ -517,18 +514,18 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public void setSslKeyManagerFactoryAlgorithm(String algorithm)
|
||||
public void setSslKeyManagerFactoryAlgorithm(String algorithm)
|
||||
{
|
||||
_sslContextFactory.setSslKeyManagerFactoryAlgorithm(algorithm);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.ssl.SslConnector#setSslTrustManagerFactoryAlgorithm(java.lang.String)
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public void setSslTrustManagerFactoryAlgorithm(String algorithm)
|
||||
public void setSslTrustManagerFactoryAlgorithm(String algorithm)
|
||||
{
|
||||
_sslContextFactory.setTrustManagerFactoryAlgorithm(algorithm);
|
||||
}
|
||||
|
@ -543,7 +540,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
{
|
||||
_sslContextFactory.setTrustStore(truststore);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.ssl.SslConnector#setTruststoreType(java.lang.String)
|
||||
|
@ -554,7 +551,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
{
|
||||
_sslContextFactory.setTrustStoreType(truststoreType);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
|
||||
|
@ -579,9 +576,9 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Set the value of the _wantClientAuth property. This property is used
|
||||
* Set the value of the _wantClientAuth property. This property is used
|
||||
* internally when opening server sockets.
|
||||
*
|
||||
*
|
||||
* @param wantClientAuth true if we want client certificate authentication.
|
||||
* @see SSLServerSocket#setWantClientAuth
|
||||
* @deprecated
|
||||
|
@ -602,7 +599,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
{
|
||||
_handshakeTimeout = msec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public int getHandshakeTimeout ()
|
||||
|
@ -617,19 +614,19 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
{
|
||||
super(socket);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void shutdownOutput() throws IOException
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void shutdownInput() throws IOException
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
|
@ -637,7 +634,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
{
|
||||
int handshakeTimeout = getHandshakeTimeout();
|
||||
int oldTimeout = _socket.getSoTimeout();
|
||||
if (handshakeTimeout > 0)
|
||||
if (handshakeTimeout > 0)
|
||||
_socket.setSoTimeout(handshakeTimeout);
|
||||
|
||||
final SSLSocket ssl=(SSLSocket)_socket;
|
||||
|
@ -667,7 +664,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
}
|
||||
catch (SSLException e)
|
||||
{
|
||||
LOG.debug(e);
|
||||
LOG.debug(e);
|
||||
try{close();}
|
||||
catch(IOException e2){LOG.ignore(e2);}
|
||||
}
|
||||
|
@ -676,14 +673,14 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
LOG.debug(e);
|
||||
try{close();}
|
||||
catch(IOException e2){LOG.ignore(e2);}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Unsupported.
|
||||
*
|
||||
*
|
||||
* TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
|
||||
* @deprecated
|
||||
*/
|
||||
|
@ -696,7 +693,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Unsupported.
|
||||
*
|
||||
*
|
||||
* TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
|
||||
* @deprecated
|
||||
*/
|
||||
|
|
|
@ -45,7 +45,6 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testMaxIdleWithRequest10() throws Exception
|
||||
{
|
||||
System.err.println("testMaxIdleWithRequest10");
|
||||
configureServer(new HelloWorldHandler());
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
@ -77,7 +76,6 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testMaxIdleWithRequest11() throws Exception
|
||||
{
|
||||
System.err.println("testMaxIdleWithRequest11");
|
||||
configureServer(new EchoHandler());
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
@ -112,7 +110,6 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testMaxIdleNoRequest() throws Exception
|
||||
{
|
||||
System.err.println("testMaxIdleNoRequest");
|
||||
configureServer(new EchoHandler());
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
@ -141,7 +138,6 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testMaxIdleWithSlowRequest() throws Exception
|
||||
{
|
||||
System.err.println("testMaxIdleWithSlowRequest");
|
||||
configureServer(new EchoHandler());
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
@ -182,7 +178,6 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testMaxIdleWithSlowResponse() throws Exception
|
||||
{
|
||||
System.err.println("testMaxIdleWithSlowResponse");
|
||||
configureServer(new SlowResponseHandler());
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
@ -212,7 +207,6 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testMaxIdleWithWait() throws Exception
|
||||
{
|
||||
System.err.println("testMaxIdleWithWait");
|
||||
configureServer(new WaitHandler());
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
|
|
@ -37,8 +37,11 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.StdErrLog;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -106,7 +109,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
* Feed the server the entire request at once.
|
||||
*/
|
||||
@Test
|
||||
public void testRequest1_jetty() throws Exception
|
||||
public void testRequest1() throws Exception
|
||||
{
|
||||
configureServer(new HelloWorldHandler());
|
||||
|
||||
|
@ -164,7 +167,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
* Feed the server fragmentary headers and see how it copes with it.
|
||||
*/
|
||||
@Test
|
||||
public void testRequest1Fragments_jetty() throws Exception, InterruptedException
|
||||
public void testRequest1Fragments() throws Exception, InterruptedException
|
||||
{
|
||||
configureServer(new HelloWorldHandler());
|
||||
|
||||
|
@ -197,7 +200,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRequest2_jetty() throws Exception
|
||||
public void testRequest2() throws Exception
|
||||
{
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
|
@ -226,7 +229,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRequest2Fragments_jetty() throws Exception
|
||||
public void testRequest2Fragments() throws Exception
|
||||
{
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
|
@ -270,7 +273,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRequest2Iterate_jetty() throws Exception
|
||||
public void testRequest2Iterate() throws Exception
|
||||
{
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
|
@ -309,7 +312,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
* After several iterations, I generated some known bad fragment points.
|
||||
*/
|
||||
@Test
|
||||
public void testRequest2KnownBad_jetty() throws Exception
|
||||
public void testRequest2KnownBad() throws Exception
|
||||
{
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
|
@ -914,6 +917,68 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommittedError() throws Exception
|
||||
{
|
||||
CommittedErrorHandler handler =new CommittedErrorHandler();
|
||||
configureServer(handler);
|
||||
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
try
|
||||
{
|
||||
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
|
||||
OutputStream os=client.getOutputStream();
|
||||
InputStream is=client.getInputStream();
|
||||
|
||||
// Send a request
|
||||
os.write((
|
||||
"GET / HTTP/1.1\r\n"+
|
||||
"Host: "+HOST+":"+_connector.getLocalPort()+"\r\n" +
|
||||
"\r\n"
|
||||
).getBytes());
|
||||
os.flush();
|
||||
|
||||
client.setSoTimeout(2000);
|
||||
String in = IO.toString(is);
|
||||
|
||||
assertEquals(-1,is.read()); // Closed by error!
|
||||
|
||||
assertTrue(in.indexOf("HTTP/1.1 200 OK")>=0);
|
||||
assertTrue(in.indexOf("Transfer-Encoding: chunked")>0);
|
||||
assertTrue(in.indexOf("Now is the time for all good men to come to the aid of the party")>0);
|
||||
assertTrue(in.indexOf("\r\n0\r\n")==-1); // chunking is interrupted by error close
|
||||
|
||||
client.close();
|
||||
Thread.sleep(100);
|
||||
assertTrue(!handler._endp.isOpen());
|
||||
}
|
||||
finally
|
||||
{
|
||||
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(false);
|
||||
|
||||
if (!client.isClosed())
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected static class CommittedErrorHandler extends AbstractHandler
|
||||
{
|
||||
public EndPoint _endp;
|
||||
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
_endp=baseRequest.getConnection().getEndPoint();
|
||||
response.setHeader("test","value");
|
||||
response.setStatus(200);
|
||||
response.setContentType("text/plain");
|
||||
response.getWriter().println("Now is the time for all good men to come to the aid of the party");
|
||||
response.getWriter().flush();
|
||||
response.flushBuffer();
|
||||
|
||||
throw new ServletException(new Exception("exception after commit"));
|
||||
}
|
||||
}
|
||||
|
||||
protected static class AvailableHandler extends AbstractHandler
|
||||
{
|
||||
public Exchanger<Object> _ex = new Exchanger<Object>();
|
||||
|
|
|
@ -25,10 +25,12 @@ public class SelectChannelServerTest extends HttpServerTestBase
|
|||
{
|
||||
startServer(new SelectChannelConnector());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void testBigBlocks() throws Exception
|
||||
public void testCommittedError() throws Exception
|
||||
{
|
||||
super.testBigBlocks();
|
||||
super.testCommittedError();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-start</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
|
|
|
@ -13,64 +13,74 @@
|
|||
|
||||
package org.eclipse.jetty.util.log;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.security.AccessControlException;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.eclipse.jetty.util.DateCache;
|
||||
|
||||
/**
|
||||
* StdErr Logging. This implementation of the Logging facade sends all logs to
|
||||
* StdErr with minimal formatting.
|
||||
* StdErr Logging. This implementation of the Logging facade sends all logs to StdErr with minimal formatting.
|
||||
* <p>
|
||||
* If the system property "org.eclipse.jetty.util.log.DEBUG" is set, then debug
|
||||
* logs are printed if stderr is being used. For named debuggers, the system
|
||||
* property name+".DEBUG" is checked. If it is not not set, then
|
||||
* "org.eclipse.jetty.util.log.DEBUG" is used as the default.
|
||||
* If the system property "org.eclipse.jetty.LEVEL" is set to one of the following (ALL, DEBUG, INFO, WARN), then set
|
||||
* the eclipse jetty root level logger level to that specified level. (Default level is INFO)
|
||||
* <p>
|
||||
* If the system property "org.eclipse.jetty.util.log.SOURCE" is set, then the
|
||||
* source method/file of a log is logged. For named debuggers, the system
|
||||
* property name+".SOURCE" is checked. If it is not not set, then
|
||||
* If the system property "org.eclipse.jetty.util.log.SOURCE" is set, then the source method/file of a log is logged.
|
||||
* For named debuggers, the system property name+".SOURCE" is checked. If it is not not set, then
|
||||
* "org.eclipse.jetty.util.log.SOURCE" is used as the default.
|
||||
* <p>
|
||||
* If the system property "org.eclipse.jetty.util.log.LONG" is set, then the
|
||||
* full, unabbreviated name of the logger is used for logging.
|
||||
* For named debuggers, the system property name+".LONG" is checked.
|
||||
* If it is not not set, then "org.eclipse.jetty.util.log.LONG" is used as the default.
|
||||
* If the system property "org.eclipse.jetty.util.log.LONG" is set, then the full, unabbreviated name of the logger is
|
||||
* used for logging. For named debuggers, the system property name+".LONG" is checked. If it is not not set, then
|
||||
* "org.eclipse.jetty.util.log.LONG" is used as the default.
|
||||
*/
|
||||
public class StdErrLog implements Logger
|
||||
{
|
||||
private static DateCache _dateCache;
|
||||
|
||||
private final static boolean __debug = Boolean.parseBoolean(
|
||||
System.getProperty("org.eclipse.jetty.util.log.DEBUG",
|
||||
System.getProperty("org.eclipse.jetty.util.log.stderr.DEBUG", "false")));
|
||||
private final static boolean __source = Boolean.parseBoolean(
|
||||
System.getProperty("org.eclipse.jetty.util.log.SOURCE",
|
||||
System.getProperty("org.eclipse.jetty.util.log.stderr.SOURCE", "false")));
|
||||
private final static boolean __long = Boolean.parseBoolean(
|
||||
System.getProperty("org.eclipse.jetty.util.log.stderr.LONG", "false"));
|
||||
private final static boolean __source = Boolean.parseBoolean(System.getProperty("org.eclipse.jetty.util.log.SOURCE",
|
||||
System.getProperty("org.eclipse.jetty.util.log.stderr.SOURCE","false")));
|
||||
private final static boolean __long = Boolean.parseBoolean(System.getProperty("org.eclipse.jetty.util.log.stderr.LONG","false"));
|
||||
|
||||
private final static ConcurrentMap<String, StdErrLog> __loggers = new ConcurrentHashMap<String, StdErrLog>();
|
||||
|
||||
private final static ConcurrentMap<String,StdErrLog> __loggers = new ConcurrentHashMap<String, StdErrLog>();
|
||||
|
||||
static
|
||||
{
|
||||
String deprecatedProperites[] =
|
||||
{ "DEBUG", "org.eclipse.jetty.util.log.DEBUG", "org.eclipse.jetty.util.log.stderr.DEBUG" };
|
||||
|
||||
// Toss a message to users about deprecated system properties
|
||||
for (String deprecatedProp : deprecatedProperites)
|
||||
{
|
||||
if (System.getProperty(deprecatedProp) != null)
|
||||
{
|
||||
System.err.printf("System Property [%s] has been deprecated! (Use org.eclipse.jetty.LEVEL=DEBUG instead)%n",deprecatedProp);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_dateCache = new DateCache("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
x.printStackTrace();
|
||||
x.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean _debug = __debug;
|
||||
public static final int LEVEL_ALL = 0;
|
||||
public static final int LEVEL_DEBUG = 1;
|
||||
public static final int LEVEL_INFO = 2;
|
||||
public static final int LEVEL_WARN = 3;
|
||||
|
||||
private int _level = LEVEL_INFO;
|
||||
private PrintStream _stderr = System.err;
|
||||
private boolean _source = __source;
|
||||
// Print the long form names, otherwise use abbreviated
|
||||
private boolean _printLongNames = __long;
|
||||
// The full log name, as provided by the system.
|
||||
private final String _name;
|
||||
private final String _name;
|
||||
// The abbreviated log name (used by default, unless _long is specified)
|
||||
private final String _abbrevname;
|
||||
private boolean _hideStacks = false;
|
||||
|
@ -82,31 +92,81 @@ public class StdErrLog implements Logger
|
|||
|
||||
public StdErrLog(String name)
|
||||
{
|
||||
this._name = name == null ? "" : name;
|
||||
this._name = name == null?"":name;
|
||||
this._abbrevname = condensePackageString(this._name);
|
||||
this._level = getLoggingLevel(System.getProperties(),this._name);
|
||||
|
||||
try
|
||||
{
|
||||
_debug = Boolean.parseBoolean(System.getProperty(_name + ".DEBUG", Boolean.toString(_debug)));
|
||||
}
|
||||
catch (AccessControlException ace)
|
||||
{
|
||||
_debug = __debug;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_source = Boolean.parseBoolean(System.getProperty(_name + ".SOURCE", Boolean.toString(_source)));
|
||||
_source = Boolean.parseBoolean(System.getProperty(_name + ".SOURCE",Boolean.toString(_source)));
|
||||
}
|
||||
catch (AccessControlException ace)
|
||||
{
|
||||
_source = __source;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the Logging Level for the provided log name. Using the FQCN first, then each package segment from longest to
|
||||
* shortest.
|
||||
*
|
||||
* @param props
|
||||
* the properties to check
|
||||
* @param name
|
||||
* the name to get log for
|
||||
* @return the logging level
|
||||
*/
|
||||
public static int getLoggingLevel(Properties props, final String name)
|
||||
{
|
||||
// Calculate the level this named logger should operate under.
|
||||
// Checking with FQCN first, then each package segment from longest to shortest.
|
||||
String nameSegment = name;
|
||||
|
||||
while ((nameSegment != null) && (nameSegment.length() > 0))
|
||||
{
|
||||
String levelStr = props.getProperty(nameSegment + ".LEVEL");
|
||||
// System.err.printf("[StdErrLog.CONFIG] Checking for property [%s.LEVEL] = %s%n",nameSegment,levelStr);
|
||||
if (levelStr == null)
|
||||
{
|
||||
// Trim and try again.
|
||||
int idx = nameSegment.lastIndexOf('.');
|
||||
if (idx >= 0)
|
||||
{
|
||||
nameSegment = nameSegment.substring(0,idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
nameSegment = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ("ALL".equalsIgnoreCase(levelStr.trim()))
|
||||
{
|
||||
return LEVEL_ALL;
|
||||
}
|
||||
else if ("DEBUG".equalsIgnoreCase(levelStr.trim()))
|
||||
{
|
||||
return LEVEL_DEBUG;
|
||||
}
|
||||
else if ("INFO".equalsIgnoreCase(levelStr.trim()))
|
||||
{
|
||||
return LEVEL_INFO;
|
||||
}
|
||||
else if ("WARN".equalsIgnoreCase(levelStr.trim()))
|
||||
{
|
||||
return LEVEL_WARN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default Logging Level
|
||||
return LEVEL_INFO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Condenses a classname by stripping down the package name to just the first character of each package name
|
||||
* segment.
|
||||
* segment.Configured
|
||||
* <p>
|
||||
*
|
||||
* <pre>
|
||||
|
@ -139,7 +199,7 @@ public class StdErrLog implements Logger
|
|||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
|
||||
public void setPrintLongNames(boolean printLongNames)
|
||||
{
|
||||
this._printLongNames = printLongNames;
|
||||
|
@ -161,7 +221,9 @@ public class StdErrLog implements Logger
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Is the source of a log, logged
|
||||
/**
|
||||
* Is the source of a log, logged
|
||||
*
|
||||
* @return true if the class, method, file and line number of a log is logged.
|
||||
*/
|
||||
public boolean isSource()
|
||||
|
@ -170,8 +232,11 @@ public class StdErrLog implements Logger
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set if a log source is logged.
|
||||
* @param source true if the class, method, file and line number of a log is logged.
|
||||
/**
|
||||
* Set if a log source is logged.
|
||||
*
|
||||
* @param source
|
||||
* true if the class, method, file and line number of a log is logged.
|
||||
*/
|
||||
public void setSource(boolean source)
|
||||
{
|
||||
|
@ -180,90 +245,143 @@ public class StdErrLog implements Logger
|
|||
|
||||
public void warn(String msg, Object... args)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer, ":WARN:", msg, args);
|
||||
System.err.println(buffer);
|
||||
if (_level <= LEVEL_WARN)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer,":WARN:",msg,args);
|
||||
_stderr.println(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void warn(Throwable thrown)
|
||||
{
|
||||
warn("", thrown);
|
||||
warn("",thrown);
|
||||
}
|
||||
|
||||
public void warn(String msg, Throwable thrown)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer, ":WARN:", msg, thrown);
|
||||
System.err.println(buffer);
|
||||
if (_level <= LEVEL_WARN)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer,":WARN:",msg,thrown);
|
||||
_stderr.println(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void info(String msg, Object... args)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer, ":INFO:", msg, args);
|
||||
System.err.println(buffer);
|
||||
if (_level <= LEVEL_INFO)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer,":INFO:",msg,args);
|
||||
_stderr.println(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void info(Throwable thrown)
|
||||
{
|
||||
info("", thrown);
|
||||
info("",thrown);
|
||||
}
|
||||
|
||||
public void info(String msg, Throwable thrown)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer, ":INFO:", msg, thrown);
|
||||
System.err.println(buffer);
|
||||
if (_level <= LEVEL_INFO)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer,":INFO:",msg,thrown);
|
||||
_stderr.println(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDebugEnabled()
|
||||
{
|
||||
return _debug;
|
||||
return (_level >= LEVEL_DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #setLevel(int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setDebugEnabled(boolean enabled)
|
||||
{
|
||||
_debug = enabled;
|
||||
if (enabled)
|
||||
{
|
||||
_level = LEVEL_DEBUG;
|
||||
}
|
||||
else
|
||||
{
|
||||
_level = LEVEL_INFO;
|
||||
}
|
||||
}
|
||||
|
||||
public int getLevel()
|
||||
{
|
||||
return _level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the level for this logger.
|
||||
* <p>
|
||||
* Available values ({@link StdErrLog#LEVEL_ALL}, {@link StdErrLog#LEVEL_DEBUG}, {@link StdErrLog#LEVEL_INFO},
|
||||
* {@link StdErrLog#LEVEL_WARN})
|
||||
*
|
||||
* @param level
|
||||
* the level to set the logger to
|
||||
*/
|
||||
public void setLevel(int level)
|
||||
{
|
||||
this._level = level;
|
||||
}
|
||||
|
||||
public void setStdErrStream(PrintStream stream)
|
||||
{
|
||||
this._stderr = stream;
|
||||
}
|
||||
|
||||
public void debug(String msg, Object... args)
|
||||
{
|
||||
if (!_debug)
|
||||
return;
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer, ":DBUG:", msg, args);
|
||||
System.err.println(buffer);
|
||||
if (_level <= LEVEL_DEBUG)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer,":DBUG:",msg,args);
|
||||
_stderr.println(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void debug(Throwable thrown)
|
||||
{
|
||||
debug("", thrown);
|
||||
debug("",thrown);
|
||||
}
|
||||
|
||||
public void debug(String msg, Throwable thrown)
|
||||
{
|
||||
if (!_debug)
|
||||
return;
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer, ":DBUG:", msg, thrown);
|
||||
System.err.println(buffer);
|
||||
if (_level <= LEVEL_DEBUG)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer,":DBUG:",msg,thrown);
|
||||
_stderr.println(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private void format(StringBuilder buffer, String level, String msg, Object... args)
|
||||
{
|
||||
String d = _dateCache.now();
|
||||
int ms = _dateCache.lastMs();
|
||||
tag(buffer, d, ms, level);
|
||||
format(buffer, msg, args);
|
||||
tag(buffer,d,ms,level);
|
||||
format(buffer,msg,args);
|
||||
}
|
||||
|
||||
private void format(StringBuilder buffer, String level, String msg, Throwable thrown)
|
||||
{
|
||||
format(buffer, level, msg);
|
||||
format(buffer,level,msg);
|
||||
if (isHideStacks())
|
||||
format(buffer, String.valueOf(thrown));
|
||||
{
|
||||
format(buffer,String.valueOf(thrown));
|
||||
}
|
||||
else
|
||||
format(buffer, thrown);
|
||||
{
|
||||
format(buffer,thrown);
|
||||
}
|
||||
}
|
||||
|
||||
private void tag(StringBuilder buffer, String d, int ms, String tag)
|
||||
|
@ -271,36 +389,52 @@ public class StdErrLog implements Logger
|
|||
buffer.setLength(0);
|
||||
buffer.append(d);
|
||||
if (ms > 99)
|
||||
{
|
||||
buffer.append('.');
|
||||
}
|
||||
else if (ms > 9)
|
||||
{
|
||||
buffer.append(".0");
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.append(".00");
|
||||
}
|
||||
buffer.append(ms).append(tag);
|
||||
if(_printLongNames) {
|
||||
if (_printLongNames)
|
||||
{
|
||||
buffer.append(_name);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.append(_abbrevname);
|
||||
}
|
||||
buffer.append(':');
|
||||
if (_source)
|
||||
{
|
||||
Throwable source = new Throwable();
|
||||
StackTraceElement[] frames = source.getStackTrace();
|
||||
for (int i=0;i<frames.length;i++)
|
||||
StackTraceElement[] frames = source.getStackTrace();
|
||||
for (int i = 0; i < frames.length; i++)
|
||||
{
|
||||
final StackTraceElement frame = frames[i];
|
||||
String clazz = frame.getClassName();
|
||||
if (clazz.equals(StdErrLog.class.getName())|| clazz.equals(Log.class.getName()))
|
||||
if (clazz.equals(StdErrLog.class.getName()) || clazz.equals(Log.class.getName()))
|
||||
{
|
||||
continue;
|
||||
if (!_printLongNames && clazz.startsWith("org.eclipse.jetty.")) {
|
||||
}
|
||||
if (!_printLongNames && clazz.startsWith("org.eclipse.jetty."))
|
||||
{
|
||||
buffer.append(condensePackageString(clazz));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.append(clazz);
|
||||
}
|
||||
buffer.append('#').append(frame.getMethodName());
|
||||
if (frame.getFileName()!=null)
|
||||
if (frame.getFileName() != null)
|
||||
{
|
||||
buffer.append('(').append(frame.getFileName()).append(':').append(frame.getLineNumber()).append(')');
|
||||
}
|
||||
buffer.append(':');
|
||||
break;
|
||||
}
|
||||
|
@ -309,32 +443,34 @@ public class StdErrLog implements Logger
|
|||
|
||||
private void format(StringBuilder builder, String msg, Object... args)
|
||||
{
|
||||
if (msg==null)
|
||||
if (msg == null)
|
||||
{
|
||||
msg="";
|
||||
for (Object o : args)
|
||||
msg+="{} ";
|
||||
msg = "";
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
msg += "{} ";
|
||||
}
|
||||
}
|
||||
String braces = "{}";
|
||||
int start = 0;
|
||||
for (Object arg : args)
|
||||
{
|
||||
int bracesIndex = msg.indexOf(braces, start);
|
||||
int bracesIndex = msg.indexOf(braces,start);
|
||||
if (bracesIndex < 0)
|
||||
{
|
||||
escape(builder, msg.substring(start));
|
||||
escape(builder,msg.substring(start));
|
||||
builder.append(" ");
|
||||
builder.append(arg);
|
||||
start = msg.length();
|
||||
}
|
||||
else
|
||||
{
|
||||
escape(builder, msg.substring(start, bracesIndex));
|
||||
escape(builder,msg.substring(start,bracesIndex));
|
||||
builder.append(String.valueOf(arg));
|
||||
start = bracesIndex + braces.length();
|
||||
}
|
||||
}
|
||||
escape(builder, msg.substring(start));
|
||||
escape(builder,msg.substring(start));
|
||||
}
|
||||
|
||||
private void escape(StringBuilder builder, String string)
|
||||
|
@ -345,14 +481,22 @@ public class StdErrLog implements Logger
|
|||
if (Character.isISOControl(c))
|
||||
{
|
||||
if (c == '\n')
|
||||
{
|
||||
builder.append('|');
|
||||
}
|
||||
else if (c == '\r')
|
||||
{
|
||||
builder.append('<');
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.append('?');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,16 +509,16 @@ public class StdErrLog implements Logger
|
|||
else
|
||||
{
|
||||
buffer.append('\n');
|
||||
format(buffer, thrown.toString());
|
||||
format(buffer,thrown.toString());
|
||||
StackTraceElement[] elements = thrown.getStackTrace();
|
||||
for (int i = 0; elements != null && i < elements.length; i++)
|
||||
{
|
||||
buffer.append("\n\tat ");
|
||||
format(buffer, elements[i].toString());
|
||||
format(buffer,elements[i].toString());
|
||||
}
|
||||
|
||||
|
||||
Throwable cause = thrown.getCause();
|
||||
if (cause!=null && cause!=thrown)
|
||||
if (cause != null && cause != thrown)
|
||||
{
|
||||
buffer.append("\nCaused by: ");
|
||||
format(buffer,cause);
|
||||
|
@ -384,42 +528,66 @@ public class StdErrLog implements Logger
|
|||
|
||||
public Logger getLogger(String name)
|
||||
{
|
||||
String fullname=_name == null || _name.length() == 0?name:_name + "." + name;
|
||||
|
||||
String fullname = _name == null || _name.length() == 0?name:_name + "." + name;
|
||||
|
||||
if ((name == null && this._name == null) || fullname.equals(_name))
|
||||
return this;
|
||||
|
||||
StdErrLog logger = __loggers.get(name);
|
||||
if (logger==null)
|
||||
{
|
||||
StdErrLog sel=new StdErrLog(fullname);
|
||||
return this;
|
||||
}
|
||||
|
||||
StdErrLog logger = __loggers.get(name);
|
||||
if (logger == null)
|
||||
{
|
||||
StdErrLog sel = new StdErrLog(fullname);
|
||||
// Preserve configuration for new loggers configuration
|
||||
sel.setPrintLongNames(_printLongNames);
|
||||
sel.setDebugEnabled(_debug);
|
||||
sel.setLevel(_level);
|
||||
sel.setSource(_source);
|
||||
logger=__loggers.putIfAbsent(fullname,sel);
|
||||
if (logger==null)
|
||||
logger=sel;
|
||||
logger = __loggers.putIfAbsent(fullname,sel);
|
||||
if (logger == null)
|
||||
{
|
||||
logger = sel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "StdErrLog:" + _name + ":DEBUG=" + _debug;
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append("StdErrLog:");
|
||||
s.append(_name);
|
||||
s.append(":LEVEL=");
|
||||
switch (_level)
|
||||
{
|
||||
case LEVEL_ALL:
|
||||
s.append("ALL");
|
||||
break;
|
||||
case LEVEL_DEBUG:
|
||||
s.append("DEBUG");
|
||||
break;
|
||||
case LEVEL_INFO:
|
||||
s.append("INFO");
|
||||
break;
|
||||
case LEVEL_WARN:
|
||||
s.append("WARN");
|
||||
break;
|
||||
default:
|
||||
s.append("?");
|
||||
break;
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public void ignore(Throwable ignored)
|
||||
{
|
||||
if (Log.isIgnored())
|
||||
if (_level <= LEVEL_ALL)
|
||||
{
|
||||
warn(Log.IGNORED, ignored);
|
||||
StringBuilder buffer = new StringBuilder(64);
|
||||
format(buffer,":IGNORED:","",ignored);
|
||||
_stderr.println(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug("Ignored {}",ignored.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,12 +101,13 @@ public class LogTest
|
|||
logContains("INFO:oejul.LogTest:testing");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void testStdErrLogDebug()
|
||||
{
|
||||
StdErrLog log = new StdErrLog("xxx");
|
||||
|
||||
log.setDebugEnabled(true);
|
||||
log.setLevel(StdErrLog.LEVEL_DEBUG);
|
||||
log.debug("testing {} {}","test","debug");
|
||||
logContains("DBUG:xxx:testing test debug");
|
||||
|
||||
|
@ -116,9 +117,18 @@ public class LogTest
|
|||
log.warn("testing {} {}","test","warn");
|
||||
logContains("WARN:xxx:testing test warn");
|
||||
|
||||
log.setDebugEnabled(false);
|
||||
log.setLevel(StdErrLog.LEVEL_INFO);
|
||||
log.debug("YOU SHOULD NOT SEE THIS!",null,null);
|
||||
logNotContains("YOU SHOULD NOT SEE THIS!");
|
||||
|
||||
// Test for backward compat with old (now deprecated) method
|
||||
log.setDebugEnabled(true);
|
||||
log.debug("testing {} {}","test","debug-deprecated");
|
||||
logContains("DBUG:xxx:testing test debug-deprecated");
|
||||
|
||||
log.setDebugEnabled(false);
|
||||
log.debug("testing {} {}","test","debug-deprecated-false");
|
||||
logNotContains("DBUG:xxx:testing test debug-depdeprecated-false");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -134,7 +144,6 @@ public class LogTest
|
|||
|
||||
next.info("testing {} {}","next","info");
|
||||
logContains(":test.next:testing next info");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -164,6 +173,5 @@ public class LogTest
|
|||
logContains("Message with ? escape");
|
||||
log.info(th.toString());
|
||||
logContains("Message with ? escape");
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,70 +13,270 @@
|
|||
|
||||
package org.eclipse.jetty.util.log;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author mgorovoy
|
||||
* */
|
||||
public class StdErrLogTest extends TestCase
|
||||
* Tests for StdErrLog
|
||||
*/
|
||||
public class StdErrLogTest
|
||||
{
|
||||
public void testNullValues()
|
||||
/**
|
||||
* Test to make sure that using a Null parameter on parameterized messages does not result in a NPE
|
||||
*/
|
||||
@Test
|
||||
public void testParameterizedMessage_NullValues() throws NullPointerException
|
||||
{
|
||||
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
|
||||
log.setDebugEnabled(true);
|
||||
log.setLevel(StdErrLog.LEVEL_DEBUG);
|
||||
log.setHideStacks(true);
|
||||
|
||||
try {
|
||||
log.info("Testing info(msg,null,null) - {} {}","arg0","arg1");
|
||||
log.info("Testing info(msg,null,null) - {} {}",null,null);
|
||||
log.info("Testing info(msg,null,null) - {}",null,null);
|
||||
log.info("Testing info(msg,null,null)",null,null);
|
||||
log.info(null,"Testing","info(null,arg0,arg1)");
|
||||
log.info(null,null,null);
|
||||
log.info("Testing info(msg,null,null) - {} {}","arg0","arg1");
|
||||
log.info("Testing info(msg,null,null) - {} {}",null,null);
|
||||
log.info("Testing info(msg,null,null) - {}",null,null);
|
||||
log.info("Testing info(msg,null,null)",null,null);
|
||||
log.info(null,"Testing","info(null,arg0,arg1)");
|
||||
log.info(null,null,null);
|
||||
|
||||
log.debug("Testing debug(msg,null,null) - {} {}","arg0","arg1");
|
||||
log.debug("Testing debug(msg,null,null) - {} {}",null,null);
|
||||
log.debug("Testing debug(msg,null,null) - {}",null,null);
|
||||
log.debug("Testing debug(msg,null,null)",null,null);
|
||||
log.debug(null,"Testing","debug(null,arg0,arg1)");
|
||||
log.debug(null,null,null);
|
||||
log.debug("Testing debug(msg,null,null) - {} {}","arg0","arg1");
|
||||
log.debug("Testing debug(msg,null,null) - {} {}",null,null);
|
||||
log.debug("Testing debug(msg,null,null) - {}",null,null);
|
||||
log.debug("Testing debug(msg,null,null)",null,null);
|
||||
log.debug(null,"Testing","debug(null,arg0,arg1)");
|
||||
log.debug(null,null,null);
|
||||
|
||||
log.debug("Testing debug(msg,null)");
|
||||
log.debug(null,new Throwable("Testing debug(null,thrw)").fillInStackTrace());
|
||||
log.debug("Testing debug(msg,null)");
|
||||
log.debug(null,new Throwable("Testing debug(null,thrw)").fillInStackTrace());
|
||||
|
||||
log.warn("Testing warn(msg,null,null) - {} {}","arg0","arg1");
|
||||
log.warn("Testing warn(msg,null,null) - {} {}",null,null);
|
||||
log.warn("Testing warn(msg,null,null) - {}",null,null);
|
||||
log.warn("Testing warn(msg,null,null)",null,null);
|
||||
log.warn(null,"Testing","warn(msg,arg0,arg1)");
|
||||
log.warn(null,null,null);
|
||||
log.warn("Testing warn(msg,null,null) - {} {}","arg0","arg1");
|
||||
log.warn("Testing warn(msg,null,null) - {} {}",null,null);
|
||||
log.warn("Testing warn(msg,null,null) - {}",null,null);
|
||||
log.warn("Testing warn(msg,null,null)",null,null);
|
||||
log.warn(null,"Testing","warn(msg,arg0,arg1)");
|
||||
log.warn(null,null,null);
|
||||
|
||||
log.warn("Testing warn(msg,null)");
|
||||
log.warn(null,new Throwable("Testing warn(msg,thrw)").fillInStackTrace());
|
||||
}
|
||||
catch (NullPointerException npe)
|
||||
{
|
||||
System.err.println(npe);
|
||||
npe.printStackTrace();
|
||||
assertTrue("NullPointerException in StdErrLog.", false);
|
||||
}
|
||||
log.warn("Testing warn(msg,null)");
|
||||
log.warn(null,new Throwable("Testing warn(msg,thrw)").fillInStackTrace());
|
||||
}
|
||||
|
||||
public void testIgnores()
|
||||
|
||||
@Test
|
||||
public void testGetLoggingLevel_Default()
|
||||
{
|
||||
Properties props = new Properties();
|
||||
|
||||
// Default Levels
|
||||
Assert.assertEquals("Default Logging Level",StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,null));
|
||||
Assert.assertEquals("Default Logging Level",StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,""));
|
||||
Assert.assertEquals("Default Logging Level",StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty"));
|
||||
Assert.assertEquals("Default Logging Level",StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,StdErrLogTest.class.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLoggingLevel_FQCN()
|
||||
{
|
||||
String name = StdErrLogTest.class.getName();
|
||||
Properties props = new Properties();
|
||||
props.setProperty(name + ".LEVEL","ALL");
|
||||
|
||||
// Default Levels
|
||||
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,null));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,""));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty"));
|
||||
|
||||
// Specified Level
|
||||
Assert.assertEquals(StdErrLog.LEVEL_ALL,StdErrLog.getLoggingLevel(props,name));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLoggingLevel_UtilLevel()
|
||||
{
|
||||
Properties props = new Properties();
|
||||
props.setProperty("org.eclipse.jetty.util.LEVEL","DEBUG");
|
||||
|
||||
// Default Levels
|
||||
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,null));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,""));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty"));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.server.BogusObject"));
|
||||
|
||||
// Configured Level
|
||||
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,StdErrLogTest.class.getName()));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util.Bogus"));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util"));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util.resource.FileResource"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLoggingLevel_MixedLevels()
|
||||
{
|
||||
Properties props = new Properties();
|
||||
props.setProperty("org.eclipse.jetty.util.LEVEL","DEBUG");
|
||||
props.setProperty("org.eclipse.jetty.util.ConcurrentHashMap.LEVEL","ALL");
|
||||
|
||||
// Default Levels
|
||||
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,null));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,""));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty"));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_INFO,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.server.ServerObject"));
|
||||
|
||||
// Configured Level
|
||||
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,StdErrLogTest.class.getName()));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util.MagicUtil"));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util"));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_DEBUG,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util.resource.FileResource"));
|
||||
Assert.assertEquals(StdErrLog.LEVEL_ALL,StdErrLog.getLoggingLevel(props,"org.eclipse.jetty.util.ConcurrentHashMap"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests StdErrLog.warn() methods with level filtering.
|
||||
* <p>
|
||||
* Should always see WARN level messages, regardless of set level.
|
||||
*/
|
||||
@Test
|
||||
public void testWarnFiltering() throws UnsupportedEncodingException
|
||||
{
|
||||
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
|
||||
log.setHideStacks(true);
|
||||
|
||||
Log.__ignored=false;
|
||||
log.setDebugEnabled(false);
|
||||
|
||||
ByteArrayOutputStream test = new ByteArrayOutputStream();
|
||||
PrintStream err = new PrintStream(test);
|
||||
log.setStdErrStream(err);
|
||||
|
||||
// Start with default level
|
||||
log.warn("See Me");
|
||||
|
||||
// Set to debug level
|
||||
log.setLevel(StdErrLog.LEVEL_DEBUG);
|
||||
log.warn("Hear Me");
|
||||
|
||||
// Set to warn level
|
||||
log.setLevel(StdErrLog.LEVEL_WARN);
|
||||
log.warn("Cheer Me");
|
||||
|
||||
// Validate Output
|
||||
String output = new String(test.toByteArray(),"UTF-8");
|
||||
System.err.print(output);
|
||||
Assert.assertThat(output,containsString("See Me"));
|
||||
Assert.assertThat(output,containsString("Hear Me"));
|
||||
Assert.assertThat(output,containsString("Cheer Me"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests StdErrLog.info() methods with level filtering.
|
||||
* <p>
|
||||
* Should only see INFO level messages when level is set to {@link StdErrLog#LEVEL_INFO} and below.
|
||||
*/
|
||||
@Test
|
||||
public void testInfoFiltering() throws UnsupportedEncodingException
|
||||
{
|
||||
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
|
||||
log.setHideStacks(true);
|
||||
|
||||
ByteArrayOutputStream test = new ByteArrayOutputStream();
|
||||
PrintStream err = new PrintStream(test);
|
||||
log.setStdErrStream(err);
|
||||
|
||||
// Normal/Default behavior
|
||||
log.info("I will not buy");
|
||||
|
||||
// Level Debug
|
||||
log.setLevel(StdErrLog.LEVEL_DEBUG);
|
||||
log.info("this record");
|
||||
|
||||
// Level All
|
||||
log.setLevel(StdErrLog.LEVEL_ALL);
|
||||
log.info("it is scratched.");
|
||||
|
||||
// Level Warn
|
||||
log.setLevel(StdErrLog.LEVEL_WARN);
|
||||
log.info("sorry?");
|
||||
|
||||
// Validate Output
|
||||
String output = new String(test.toByteArray(),"UTF-8");
|
||||
System.err.print(output);
|
||||
Assert.assertThat(output,containsString("I will not buy"));
|
||||
Assert.assertThat(output,containsString("this record"));
|
||||
Assert.assertThat(output,containsString("it is scratched."));
|
||||
Assert.assertThat(output,not(containsString("sorry?")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests StdErrLog.debug() methods with level filtering.
|
||||
* <p>
|
||||
* Should only see DEBUG level messages when level is set to {@link StdErrLog#LEVEL_DEBUG} and below.
|
||||
*/
|
||||
@Test
|
||||
public void testDebugFiltering() throws UnsupportedEncodingException
|
||||
{
|
||||
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
|
||||
log.setHideStacks(true);
|
||||
|
||||
ByteArrayOutputStream test = new ByteArrayOutputStream();
|
||||
PrintStream err = new PrintStream(test);
|
||||
log.setStdErrStream(err);
|
||||
|
||||
// Normal/Default behavior
|
||||
log.debug("Tobacconist");
|
||||
|
||||
// Level Debug
|
||||
log.setLevel(StdErrLog.LEVEL_DEBUG);
|
||||
log.debug("my hovercraft is");
|
||||
|
||||
// Level All
|
||||
log.setLevel(StdErrLog.LEVEL_ALL);
|
||||
log.debug("full of eels.");
|
||||
|
||||
// Level Warn
|
||||
log.setLevel(StdErrLog.LEVEL_WARN);
|
||||
log.debug("what?");
|
||||
|
||||
// Validate Output
|
||||
String output = new String(test.toByteArray(),"UTF-8");
|
||||
System.err.print(output);
|
||||
Assert.assertThat(output,not(containsString("Tobacconist")));
|
||||
Assert.assertThat(output,containsString("my hovercraft is"));
|
||||
Assert.assertThat(output,containsString("full of eels."));
|
||||
Assert.assertThat(output,not(containsString("what?")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests StdErrLog with {@link Logger#ignore(Throwable)} use.
|
||||
* <p>
|
||||
* Should only see IGNORED level messages when level is set to {@link StdErrLog#LEVEL_ALL}.
|
||||
*/
|
||||
@Test
|
||||
public void testIgnores() throws UnsupportedEncodingException
|
||||
{
|
||||
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
|
||||
log.setHideStacks(true);
|
||||
|
||||
ByteArrayOutputStream test = new ByteArrayOutputStream();
|
||||
PrintStream err = new PrintStream(test);
|
||||
log.setStdErrStream(err);
|
||||
|
||||
// Normal/Default behavior
|
||||
log.ignore(new Throwable("IGNORE ME"));
|
||||
|
||||
Log.__ignored=true;
|
||||
log.setDebugEnabled(false);
|
||||
// Show Ignored
|
||||
log.setLevel(StdErrLog.LEVEL_ALL);
|
||||
log.ignore(new Throwable("Don't ignore me"));
|
||||
|
||||
Log.__ignored=false;
|
||||
log.setDebugEnabled(true);
|
||||
|
||||
// Set to Debug level
|
||||
log.setLevel(StdErrLog.LEVEL_DEBUG);
|
||||
log.ignore(new Throwable("Debug me"));
|
||||
|
||||
// Validate Output
|
||||
String output = new String(test.toByteArray(),"UTF-8");
|
||||
System.err.print(output);
|
||||
Assert.assertThat(output,not(containsString("IGNORE ME")));
|
||||
Assert.assertThat(output,containsString("Don't ignore me"));
|
||||
Assert.assertThat(output,not(containsString("Debug me")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
|
|
|
@ -271,11 +271,11 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
|
|||
}
|
||||
}
|
||||
|
||||
// TODO is this too soon?
|
||||
/* Set the webapp's classpath for Jasper */
|
||||
context.setAttribute("org.apache.catalina.jsp_classpath", context.getClassPath());
|
||||
|
||||
/* Set the system classpath for Jasper */
|
||||
holder.setInitParameter("com.sun.appserv.jsp.classpath", getSystemClassPath(context));
|
||||
holder.setInitParameter("com.sun.appserv.jsp.classpath", getSystemClassPath(context));
|
||||
}
|
||||
|
||||
//Set the servlet-class
|
||||
|
@ -321,6 +321,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
|
|||
{
|
||||
holder.setForcedPath(jsp_file);
|
||||
holder.setClassName(jspServletClass);
|
||||
//set the system classpath explicitly for the holder that will represent the JspServlet instance
|
||||
holder.setInitParameter("com.sun.appserv.jsp.classpath", getSystemClassPath(context));
|
||||
}
|
||||
|
||||
// handle load-on-startup
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-xml</artifactId>
|
||||
|
|
12
pom.xml
12
pom.xml
|
@ -6,7 +6,7 @@
|
|||
<version>19</version>
|
||||
</parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
<name>Jetty :: Project</name>
|
||||
<url>${jetty.url}</url>
|
||||
<packaging>pom</packaging>
|
||||
|
@ -275,16 +275,17 @@
|
|||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
<reporting>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jxr-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.8</version>
|
||||
<configuration>
|
||||
<maxmemory>512m</maxmemory>
|
||||
<docfilessubdirs>true</docfilessubdirs>
|
||||
|
@ -295,6 +296,7 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-pmd-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<targetJdk>1.5</targetJdk>
|
||||
<rulesets>
|
||||
|
@ -305,6 +307,7 @@
|
|||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>findbugs-maven-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
@ -346,6 +349,7 @@
|
|||
<module>jetty-nested</module>
|
||||
<module>jetty-overlay-deployer</module>
|
||||
<module>jetty-nosql</module>
|
||||
<module>jetty-http-spi</module>
|
||||
<module>jetty-distribution</module>
|
||||
<module>test-continuation</module>
|
||||
<module>test-continuation-jetty6</module>
|
||||
|
@ -470,7 +474,7 @@
|
|||
<id>gen-versiontxt</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>gen-version-text</goal>
|
||||
<goal>update-version-text</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<refreshTags>true</refreshTags>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>test-continuation-jetty6</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>test-continuation</artifactId>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>test-jetty-nested</artifactId>
|
||||
<name>Jetty :: Nested Test</name>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>test-jetty-servlet</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
|
@ -95,12 +95,11 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!--
|
||||
<!--
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>jetty-maven-plugin</artifactId>
|
||||
<version>7.1.1-SNAPSHOT</version>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<configuration>
|
||||
<stopPort>8087</stopPort>
|
||||
<stopKey>foo</stopKey>
|
||||
|
|
|
@ -250,6 +250,17 @@
|
|||
<url-pattern>/javadoc-proxy/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
|
||||
|
||||
<servlet>
|
||||
<servlet-name>foo.jsp</servlet-name>
|
||||
<jsp-file>/jsp/foo/foo.jsp</jsp-file>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>foo.jsp</servlet-name>
|
||||
<url-pattern>/jsp/foo/</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<error-page>
|
||||
<error-code>404</error-code>
|
||||
<location>/error404.html</location>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<h1>FOO Example</h1>
|
||||
<hr>
|
||||
<p>A trivial FOO example
|
||||
<hr>
|
||||
<c:forEach var="i" begin="1" end="10" step="1">
|
||||
<c:out value="${i}" />
|
||||
<br />
|
||||
</c:forEach>
|
||||
</body>
|
||||
</html>
|
|
@ -11,6 +11,7 @@
|
|||
<li><a href="tagfile.jsp">JSP 2.0 Tag File demo</a><br/>
|
||||
<li><a href="expr.jsp?A=1">JSP 2.0 Tag Expression</a><br/>
|
||||
<li><a href="jstl.jsp">JSTL Expression</a><br/>
|
||||
<li><a href="foo/">Mapping to <jsp-file></a><br/>
|
||||
</ul>
|
||||
<a href="/">Main Menu</a>
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>tests-parent</artifactId>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>tests-parent</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>test-integration</artifactId>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>tests-parent</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>test-loginservice</artifactId>
|
||||
<name>Jetty Tests :: Login Service</name>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>tests-parent</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>test-sessions-parent</artifactId>
|
||||
<name>Jetty Tests :: Sessions :: Parent</name>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-sessions-parent</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>test-hash-sessions</artifactId>
|
||||
<name>Jetty Tests :: Sessions :: Hash</name>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-sessions-parent</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>test-jdbc-sessions</artifactId>
|
||||
<name>Jetty Tests :: Sessions :: JDBC</name>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-sessions-parent</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>test-sessions-common</artifactId>
|
||||
<name>Jetty Tests :: Sessions :: Common</name>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>tests-parent</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>test-webapps-parent</artifactId>
|
||||
<name>Jetty Tests :: WebApps :: Parent</name>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-webapps-parent</artifactId>
|
||||
<version>7.5.2-SNAPSHOT</version>
|
||||
<version>7.5.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>test-webapp-rfc2616</artifactId>
|
||||
<name>Jetty Tests :: WebApp :: RFC2616</name>
|
||||
|
|
Loading…
Reference in New Issue