From 949975e46a19f9bf8326752e154b41061bf1fdb0 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Mon, 19 Sep 2011 08:09:20 +1000
Subject: [PATCH 034/134] 358035 servlet streams access max idle time from endp
---
.../eclipse/jetty/server/HttpConnection.java | 15 ++++++++---
.../org/eclipse/jetty/server/HttpInput.java | 12 ++++-----
.../org/eclipse/jetty/server/HttpOutput.java | 23 ++++++++++-------
.../eclipse/jetty/server/HttpWriterTest.java | 25 +++++++++++++++++--
4 files changed, 55 insertions(+), 20 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java
index c77f76af97a..8ee1938d1c6 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java
@@ -327,7 +327,7 @@ public abstract class HttpConnection extends AbstractConnection
}
if (_in == null)
- _in = new HttpInput(((HttpParser)_parser),_connector.getMaxIdleTime());
+ _in = new HttpInput(HttpConnection.this);
return _in;
}
@@ -671,6 +671,16 @@ public abstract class HttpConnection extends AbstractConnection
return _expect102Processing;
}
+ /* ------------------------------------------------------------ */
+ public int getMaxIdleTime()
+ {
+ if (_endp.getMaxIdleTime()>0)
+ return _endp.getMaxIdleTime();
+ if (_connector.isLowResources())
+ return _connector.getLowResourceMaxIdleTime();
+ return _connector.getMaxIdleTime();
+ }
+
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
@@ -960,8 +970,7 @@ public abstract class HttpConnection extends AbstractConnection
{
Output()
{
- super((AbstractGenerator)HttpConnection.this._generator,
- _connector.isLowResources()?_connector.getLowResourceMaxIdleTime():_connector.getMaxIdleTime());
+ super(HttpConnection.this);
}
/* ------------------------------------------------------------ */
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
index f0bbc9aec8b..670fa95c81a 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
@@ -22,14 +22,14 @@ import org.eclipse.jetty.io.Buffer;
public class HttpInput extends ServletInputStream
{
+ protected final HttpConnection _connection;
protected final HttpParser _parser;
- protected final long _maxIdleTime;
/* ------------------------------------------------------------ */
- public HttpInput(HttpParser parser, long maxIdleTime)
+ public HttpInput(HttpConnection connection)
{
- _parser=parser;
- _maxIdleTime=maxIdleTime;
+ _connection=connection;
+ _parser=(HttpParser)connection.getParser();
}
/* ------------------------------------------------------------ */
@@ -40,7 +40,7 @@ public class HttpInput extends ServletInputStream
public int read() throws IOException
{
int c=-1;
- Buffer content=_parser.blockForContent(_maxIdleTime);
+ Buffer content=_parser.blockForContent(_connection.getMaxIdleTime());
if (content!=null)
c= 0xff & content.get();
return c;
@@ -54,7 +54,7 @@ public class HttpInput extends ServletInputStream
public int read(byte[] b, int off, int len) throws IOException
{
int l=-1;
- Buffer content=_parser.blockForContent(_maxIdleTime);
+ Buffer content=_parser.blockForContent(_connection.getMaxIdleTime());
if (content!=null)
l= content.get(b, off, len);
return l;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
index 5fd7d91c522..6d595877851 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
@@ -36,8 +36,8 @@ import org.eclipse.jetty.util.ByteArrayOutputStream2;
*/
public class HttpOutput extends ServletOutputStream
{
+ protected final HttpConnection _connection;
protected final AbstractGenerator _generator;
- protected final long _maxIdleTime;
private boolean _closed;
// These are held here for reuse by Writer
@@ -45,15 +45,20 @@ public class HttpOutput extends ServletOutputStream
Writer _converter;
char[] _chars;
ByteArrayOutputStream2 _bytes;
-
/* ------------------------------------------------------------ */
- public HttpOutput(AbstractGenerator generator, long maxIdleTime)
+ public HttpOutput(HttpConnection connection)
{
- _generator=generator;
- _maxIdleTime=maxIdleTime;
+ _connection=connection;
+ _generator=(AbstractGenerator)connection.getGenerator();
}
+ /* ------------------------------------------------------------ */
+ public int getMaxIdleTime()
+ {
+ return _connection.getMaxIdleTime();
+ }
+
/* ------------------------------------------------------------ */
public boolean isWritten()
{
@@ -86,7 +91,7 @@ public class HttpOutput extends ServletOutputStream
@Override
public void flush() throws IOException
{
- _generator.flush(_maxIdleTime);
+ _generator.flush(getMaxIdleTime());
}
/* ------------------------------------------------------------ */
@@ -121,7 +126,7 @@ public class HttpOutput extends ServletOutputStream
// Block until we can add _content.
while (_generator.isBufferFull())
{
- _generator.blockForOutput(_maxIdleTime);
+ _generator.blockForOutput(getMaxIdleTime());
if (_closed)
throw new IOException("Closed");
if (!_generator.isOpen())
@@ -151,7 +156,7 @@ public class HttpOutput extends ServletOutputStream
// Block until we can add _content.
while (_generator.isBufferFull())
{
- _generator.blockForOutput(_maxIdleTime);
+ _generator.blockForOutput(getMaxIdleTime());
if (_closed)
throw new IOException("Closed");
if (!_generator.isOpen())
@@ -174,7 +179,7 @@ public class HttpOutput extends ServletOutputStream
// Block until our buffer is free
while (buffer.length() > 0 && _generator.isOpen())
{
- _generator.blockForOutput(_maxIdleTime);
+ _generator.blockForOutput(getMaxIdleTime());
}
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java
index fa86c3dcba0..73828e81bf1 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java
@@ -12,6 +12,7 @@ import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.ByteArrayEndPoint;
+import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.SimpleBuffers;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
@@ -75,7 +76,17 @@ public class HttpWriterTest
};
- HttpOutput httpOut = new HttpOutput(generator,60000);
+ HttpConnection connection = new HttpConnection(null,endp,new Server(),null,generator,null)
+ {
+ @Override
+ public Connection handle() throws IOException
+ {
+ return null;
+ }
+ };
+ endp.setMaxIdleTime(60000);
+
+ HttpOutput httpOut = new HttpOutput(connection);
_writer = new HttpWriter(httpOut);
}
@@ -158,7 +169,17 @@ public class HttpWriterTest
hb.setResponse(200,"OK");
- HttpOutput output = new HttpOutput(hb,10000);
+ HttpConnection connection = new HttpConnection(null,endp,new Server(),null,hb,null)
+ {
+ @Override
+ public Connection handle() throws IOException
+ {
+ return null;
+ }
+ };
+ endp.setMaxIdleTime(10000);
+ hb.setSendServerVersion(false);
+ HttpOutput output = new HttpOutput(connection);
HttpWriter writer = new HttpWriter(output);
writer.setCharacterEncoding(StringUtil.__UTF8);
From 8e765f12c64b3ee55a716598185deaf824dd38b0 Mon Sep 17 00:00:00 2001
From: Jan Bartel
Date: Mon, 19 Sep 2011 10:32:43 +1000
Subject: [PATCH 035/134] JETTY-1431
---
.../main/java/org/eclipse/jetty/server/handler/GzipHandler.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java
index 7aead3c0c3a..29a9a833932 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java
@@ -159,7 +159,7 @@ public class GzipHandler extends HandlerWrapper
*
* @return the buffer size
*/
- public int setBufferSize()
+ public int getBufferSize()
{
return _bufferSize;
}
From c984d2587106555d72cd6f94413d6f5fcf67169b Mon Sep 17 00:00:00 2001
From: Jan Bartel
Date: Mon, 19 Sep 2011 17:57:48 +1000
Subject: [PATCH 036/134] 358027 NullPointerException in ResourceHandler with
jetty-stylesheet.css
---
.../eclipse/jetty/server/handler/ResourceHandler.java | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
index 87be3d7b3fd..5d618165ed7 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
@@ -45,7 +45,7 @@ import org.eclipse.jetty.util.resource.Resource;
*
* This handle will serve static content and handle If-Modified-Since headers.
* No caching is done.
- * Requests that cannot be handled are let pass (Eg no 404's)
+ * Requests for resources that do not exist are let pass (Eg no 404's).
*
*
* @org.apache.xbean.XBean
@@ -205,7 +205,7 @@ public class ResourceHandler extends AbstractHandler
{
try
{
- _defaultStylesheet = Resource.newResource(this.getClass().getResource("/jetty-default.css"));
+ _defaultStylesheet = Resource.newResource(this.getClass().getResource("/jetty-dir.css"));
}
catch(IOException e)
{
@@ -326,7 +326,7 @@ public class ResourceHandler extends AbstractHandler
/* ------------------------------------------------------------ */
/*
- * @see org.eclipse.jetty.server.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
+ * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
*/
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
@@ -344,7 +344,7 @@ public class ResourceHandler extends AbstractHandler
Resource resource = getResource(request);
if (resource==null || !resource.exists())
{
- if (target.endsWith("/jetty-stylesheet.css"))
+ if (target.endsWith("/jetty-dir.css"))
{
response.setContentType("text/css");
resource = getStylesheet();
@@ -359,7 +359,7 @@ public class ResourceHandler extends AbstractHandler
return;
}
- // We are going to server something
+ // We are going to serve something
baseRequest.setHandled(true);
if (resource.isDirectory())
From 479d9606ec83acd4033a2b6b101781d227906ecd Mon Sep 17 00:00:00 2001
From: Jan Bartel
Date: Mon, 19 Sep 2011 19:05:49 +1000
Subject: [PATCH 037/134] 353267 Request._parameters initialization bug
---
.../org/eclipse/jetty/server/Request.java | 147 ++++++++++--------
.../org/eclipse/jetty/server/RequestTest.java | 42 +++++
2 files changed, 120 insertions(+), 69 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
index 3a239ff6011..38f3b460d23 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
@@ -186,79 +186,36 @@ public class Request implements HttpServletRequest
/* ------------------------------------------------------------ */
/**
- * Extract Paramters from query string and/or form _content.
+ * Extract Parameters from query string and/or form _content.
*/
public void extractParameters()
{
if (_baseParameters == null)
_baseParameters = new MultiMap(16);
-
+
if (_paramsExtracted)
{
if (_parameters==null)
_parameters=_baseParameters;
return;
}
-
+
_paramsExtracted = true;
- // Handle query string
- if (_uri!=null && _uri.hasQuery())
+ try
{
- if (_queryEncoding==null)
- _uri.decodeQueryTo(_baseParameters);
- else
+ // Handle query string
+ if (_uri!=null && _uri.hasQuery())
{
- try
- {
- _uri.decodeQueryTo(_baseParameters,_queryEncoding);
- }
- catch (UnsupportedEncodingException e)
- {
- if (LOG.isDebugEnabled())
- LOG.warn(e);
- else
- LOG.warn(e.toString());
- }
- }
- }
-
- // handle any _content.
- String encoding = getCharacterEncoding();
- String content_type = getContentType();
- if (content_type != null && content_type.length() > 0)
- {
- content_type = HttpFields.valueParameters(content_type, null);
-
- if (MimeTypes.FORM_ENCODED.equalsIgnoreCase(content_type) && _inputState==__NONE &&
- (HttpMethods.POST.equals(getMethod()) || HttpMethods.PUT.equals(getMethod())))
- {
- int content_length = getContentLength();
- if (content_length != 0)
+ if (_queryEncoding==null)
+ _uri.decodeQueryTo(_baseParameters);
+ else
{
try
{
- int maxFormContentSize=-1;
-
- if (_context!=null)
- maxFormContentSize=_context.getContextHandler().getMaxFormContentSize();
- else
- {
- Integer size = (Integer)_connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormContentSize");
- if (size!=null)
- maxFormContentSize =size.intValue();
- }
-
- if (content_length>maxFormContentSize && maxFormContentSize > 0)
- {
- throw new IllegalStateException("Form too large"+content_length+">"+maxFormContentSize);
- }
- InputStream in = getInputStream();
-
- // Add form params to query params
- UrlEncoded.decodeTo(in, _baseParameters, encoding,content_length<0?maxFormContentSize:-1);
+ _uri.decodeQueryTo(_baseParameters,_queryEncoding);
}
- catch (IOException e)
+ catch (UnsupportedEncodingException e)
{
if (LOG.isDebugEnabled())
LOG.warn(e);
@@ -267,23 +224,75 @@ public class Request implements HttpServletRequest
}
}
}
- }
-
- if (_parameters==null)
- _parameters=_baseParameters;
- else if (_parameters!=_baseParameters)
- {
- // Merge parameters (needed if parameters extracted after a forward).
- Iterator iter = _baseParameters.entrySet().iterator();
- while (iter.hasNext())
+
+ // handle any _content.
+ String encoding = getCharacterEncoding();
+ String content_type = getContentType();
+ if (content_type != null && content_type.length() > 0)
{
- Map.Entry entry = (Map.Entry)iter.next();
- String name=(String)entry.getKey();
- Object values=entry.getValue();
- for (int i=0;imaxFormContentSize && maxFormContentSize > 0)
+ {
+ throw new IllegalStateException("Form too large"+content_length+">"+maxFormContentSize);
+ }
+ InputStream in = getInputStream();
+
+ // Add form params to query params
+ UrlEncoded.decodeTo(in, _baseParameters, encoding,content_length<0?maxFormContentSize:-1);
+ }
+ catch (IOException e)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.warn(e);
+ else
+ LOG.warn(e.toString());
+ }
+ }
+ }
}
- }
+
+ if (_parameters==null)
+ _parameters=_baseParameters;
+ else if (_parameters!=_baseParameters)
+ {
+ // Merge parameters (needed if parameters extracted after a forward).
+ Iterator iter = _baseParameters.entrySet().iterator();
+ while (iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry)iter.next();
+ String name=(String)entry.getKey();
+ Object values=entry.getValue();
+ for (int i=0;i
Date: Mon, 19 Sep 2011 19:09:55 +1000
Subject: [PATCH 038/134] 353267 Request._parameters initialization bug
Add some extra tests.
---
.../src/test/java/org/eclipse/jetty/server/RequestTest.java | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java
index 50bcd110c6e..bc938bc0b67 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java
@@ -24,6 +24,7 @@ import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Enumeration;
import java.util.Map;
import javax.servlet.ServletException;
@@ -93,6 +94,10 @@ public class RequestTest
map = request.getParameterMap();
assertFalse(map == null);
assertTrue(map.isEmpty());
+
+ Enumeration names = request.getParameterNames();
+ assertFalse(names.hasMoreElements());
+
}
return true;
From 0949443fab7d9104277a72b6b79bf3cfb5b3acbe Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 20 Sep 2011 12:59:22 +1000
Subject: [PATCH 039/134] 358164 Dispatch from servlet to handler
---
.../org/eclipse/jetty/server/Dispatcher.java | 5 ++++
.../jetty/server/handler/ContextHandler.java | 2 +-
.../jetty/server/handler/ResourceHandler.java | 27 ++++++++++++++++---
.../eclipse/jetty/servlet/ServletHandler.java | 5 +++-
4 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
index 355fc46adaa..5422cb2662c 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
@@ -222,6 +222,7 @@ public class Dispatcher implements RequestDispatcher
if (!(response instanceof HttpServletResponse))
response = new ServletResponseHttpWrapper(response);
+ final boolean old_handled=baseRequest.isHandled();
final String old_uri=baseRequest.getRequestURI();
final String old_context_path=baseRequest.getContextPath();
final String old_servlet_path=baseRequest.getServletPath();
@@ -233,6 +234,7 @@ public class Dispatcher implements RequestDispatcher
try
{
+ baseRequest.setHandled(false);
baseRequest.setDispatcherType(dispatch);
if (_named!=null)
@@ -279,6 +281,8 @@ public class Dispatcher implements RequestDispatcher
baseRequest.setRequestURI(_uri);
baseRequest.setContextPath(_contextHandler.getContextPath());
+ baseRequest.setServletPath(null);
+ baseRequest.setPathInfo(_uri);
baseRequest.setAttributes(attr);
_contextHandler.handle(_path,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response);
@@ -303,6 +307,7 @@ public class Dispatcher implements RequestDispatcher
}
finally
{
+ baseRequest.setHandled(old_handled);
baseRequest.setRequestURI(old_uri);
baseRequest.setContextPath(old_context_path);
baseRequest.setServletPath(old_servlet_path);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
index 42feb615a0c..46554a844bc 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
@@ -801,7 +801,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
String old_path_info = null;
ClassLoader old_classloader = null;
Thread current_thread = null;
- String pathInfo = null;
+ String pathInfo = target;
DispatcherType dispatch = baseRequest.getDispatcherType();
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
index 5d618165ed7..1d3f196c127 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
@@ -29,6 +29,7 @@ import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.WriterOutputStream;
+import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
@@ -292,10 +293,28 @@ public class ResourceHandler extends AbstractHandler
/* ------------------------------------------------------------ */
protected Resource getResource(HttpServletRequest request) throws MalformedURLException
{
- String path_info=request.getPathInfo();
- if (path_info==null)
- return null;
- return getResource(path_info);
+ String servletPath;
+ String pathInfo;
+ Boolean included =request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI)!=null;
+ if (included!=null && included.booleanValue())
+ {
+ servletPath=(String)request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH);
+ pathInfo=(String)request.getAttribute(Dispatcher.INCLUDE_PATH_INFO);
+ if (servletPath==null)
+ {
+ servletPath=request.getServletPath();
+ pathInfo=request.getPathInfo();
+ }
+ }
+ else
+ {
+ included = Boolean.FALSE;
+ servletPath = request.getServletPath();
+ pathInfo = request.getPathInfo();
+ }
+
+ String pathInContext=URIUtil.addPaths(servletPath,pathInfo);
+ return getResource(pathInContext);
}
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
index 45df833bf51..72de75cf444 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
@@ -474,7 +474,6 @@ public class ServletHandler extends ScopedHandler
res = ((ServletResponseHttpWrapper)res).getResponse();
// Do the filter/handling thang
- baseRequest.setHandled(true);
if (chain!=null)
chain.doFilter(req, res);
else
@@ -583,6 +582,10 @@ public class ServletHandler extends ScopedHandler
else
LOG.debug("Response already committed for handling ",e);
}
+ finally
+ {
+ baseRequest.setHandled(true);
+ }
}
/* ------------------------------------------------------------ */
From 978f06242b7dd5d8da8a99abfe9cbfc9f168b063 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 20 Sep 2011 14:50:53 +1000
Subject: [PATCH 040/134] 357240 extra debug
---
.../java/org/eclipse/jetty/server/AsyncHttpConnection.java | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java
index 52310ebf65d..adc3dc18e0b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java
@@ -139,6 +139,10 @@ public class AsyncHttpConnection extends HttpConnection
{
LOG.warn("Closing EndPoint making no progress: "+_total_no_progress+" "+_endp);
_endp.close();
+ if (_endp instanceof SelectChannelEndPoint)
+ {
+ System.err.println(((SelectChannelEndPoint)_endp).getSelectManager().dump());
+ }
}
}
}
From 94d43e42297489aff4a9a5ab88215574385e24a7 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 20 Sep 2011 15:19:19 +1000
Subject: [PATCH 041/134] 356274 Start SSL socket factory in call to open()
---
.../eclipse/jetty/embedded/LikeJettyXml.java | 27 +++++++++++++++++++
.../jetty/server/ssl/SslSocketConnector.java | 22 +++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
index ce7329c2245..0caec484893 100644
--- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
+++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
@@ -33,6 +33,7 @@ import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.server.handler.StatisticsHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
+import org.eclipse.jetty.server.ssl.SslSocketConnector;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
@@ -89,7 +90,33 @@ public class LikeJettyXml
});
ssl_connector.setStatsOn(true);
server.addConnector(ssl_connector);
+ ssl_connector.open();
+
+ SslSocketConnector ssls_connector = new SslSocketConnector();
+ ssls_connector.setPort(8444);
+ cf = ssls_connector.getSslContextFactory();
+ cf.setKeyStore(jetty_home + "/etc/keystore");
+ cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
+ cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
+ cf.setTrustStore(jetty_home + "/etc/keystore");
+ cf.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
+ cf.setExcludeCipherSuites(
+ new String[] {
+ "SSL_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+ "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+ "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"
+ });
+ ssls_connector.setStatsOn(true);
+ server.addConnector(ssls_connector);
+ ssls_connector.open();
+
+
+
Ajp13SocketConnector ajp = new Ajp13SocketConnector();
ajp.setPort(8009);
server.addConnector(ajp);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java
index 1783f9aba0e..85c50bb4a94 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java
@@ -30,6 +30,7 @@ import javax.net.ssl.SSLSocket;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.http.ssl.SslContextFactory;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.io.bio.SocketEndPoint;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.bio.SocketConnector;
@@ -67,6 +68,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
this(new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH));
}
+ /* ------------------------------------------------------------ */
public SslSocketConnector(SslContextFactory sslContextFactory)
{
_sslContextFactory = sslContextFactory;
@@ -329,6 +331,26 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
return integralPort == 0 || integralPort == request.getServerPort();
}
+ /* ------------------------------------------------------------ */
+ @Override
+ public void open() throws IOException
+ {
+ if (!_sslContextFactory.checkConfig())
+ {
+ throw new IllegalStateException("SSL context is not configured correctly.");
+ }
+
+ try
+ {
+ _sslContextFactory.start();
+ }
+ catch(Exception e)
+ {
+ throw new RuntimeIOException(e);
+ }
+ super.open();
+ }
+
/* ------------------------------------------------------------ */
/**
* {@inheritDoc}
From dacb8962f00cf3668b14e0a65a055f3f16593e71 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 20 Sep 2011 15:23:25 +1000
Subject: [PATCH 042/134] 356144 Allow SelectorManager thread priority to be
set
---
.../eclipse/jetty/server/nio/SelectChannelConnector.java | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
index c8cff99341c..9a4f8f03bcf 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
@@ -133,6 +133,12 @@ public class SelectChannelConnector extends AbstractNIOConnector
super.persist(endpoint);
}
+ /* ------------------------------------------------------------ */
+ public SelectorManager getSelectorManager()
+ {
+ return _manager;
+ }
+
/* ------------------------------------------------------------ */
public Object getConnection()
{
From 57bd9f3bced17a05b837d1285dcef20eb671ee94 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 20 Sep 2011 17:04:01 +1000
Subject: [PATCH 043/134] 336443 Check nonce count is increasing
---
.../jetty/embedded/SecuredHelloHandler.java | 5 +-
.../authentication/DigestAuthenticator.java | 164 +++++++++---------
2 files changed, 83 insertions(+), 86 deletions(-)
diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java
index 7224824cb3e..5d2547e3f1b 100644
--- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java
+++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java
@@ -23,13 +23,14 @@ import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
+import org.eclipse.jetty.security.authentication.DigestAuthenticator;
import org.eclipse.jetty.server.Server;
public class SecuredHelloHandler
{
public static void main(String[] args) throws Exception
{
- Server server = new Server(0);
+ Server server = new Server(8080);
LoginService loginService = new HashLoginService("MyRealm","src/test/resources/realm.properties");
server.addBean(loginService);
@@ -51,7 +52,7 @@ public class SecuredHelloHandler
knownRoles.add("admin");
security.setConstraintMappings(Collections.singletonList(mapping), knownRoles);
- security.setAuthenticator(new BasicAuthenticator());
+ security.setAuthenticator(new DigestAuthenticator());
security.setLoginService(loginService);
security.setStrict(false);
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java
index 7fa563a8502..ee9f5625aeb 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java
@@ -15,6 +15,12 @@ package org.eclipse.jetty.security.authentication;
import java.io.IOException;
import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -42,17 +48,29 @@ import org.eclipse.jetty.util.log.Logger;
/**
* @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
*
- * The nonce max age can be set with the {@link SecurityHandler#setInitParameter(String, String)}
+ * The nonce max age in ms can be set with the {@link SecurityHandler#setInitParameter(String, String)}
* using the name "maxNonceAge"
*/
public class DigestAuthenticator extends LoginAuthenticator
{
private static final Logger LOG = Log.getLogger(DigestAuthenticator.class);
+ SecureRandom _random = new SecureRandom();
+ private long _maxNonceAgeMs = 60*1000;
+ private ConcurrentMap _nonceCount = new ConcurrentHashMap();
+ private Queue _nonceQueue = new ConcurrentLinkedQueue();
+ private static class Nonce
+ {
+ final String _nonce;
+ final long _ts;
+ AtomicInteger _nc=new AtomicInteger();
+ public Nonce(String nonce, long ts)
+ {
+ _nonce=nonce;
+ _ts=ts;
+ }
+ }
- protected long _maxNonceAge = 0;
- protected long _nonceSecret = this.hashCode() ^ System.currentTimeMillis();
- protected boolean _useStale = false;
-
+ /* ------------------------------------------------------------ */
public DigestAuthenticator()
{
super();
@@ -69,19 +87,22 @@ public class DigestAuthenticator extends LoginAuthenticator
String mna=configuration.getInitParameter("maxNonceAge");
if (mna!=null)
- _maxNonceAge=Long.valueOf(mna);
+ _maxNonceAgeMs=Long.valueOf(mna);
}
+ /* ------------------------------------------------------------ */
public String getAuthMethod()
{
return Constraint.__DIGEST_AUTH;
}
-
+
+ /* ------------------------------------------------------------ */
public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException
{
return true;
}
+ /* ------------------------------------------------------------ */
public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException
{
if (!mandatory)
@@ -144,7 +165,7 @@ public class DigestAuthenticator extends LoginAuthenticator
}
}
- int n = checkNonce(digest.nonce, (Request)request);
+ int n = checkNonce(digest,(Request)request);
if (n > 0)
{
@@ -171,7 +192,7 @@ public class DigestAuthenticator extends LoginAuthenticator
+ "\", nonce=\""
+ newNonce((Request)request)
+ "\", algorithm=MD5, qop=\"auth\""
- + (_useStale ? (" stale=" + stale) : ""));
+ + " stale=" + stale);
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return Authentication.SEND_CONTINUE;
@@ -186,87 +207,59 @@ public class DigestAuthenticator extends LoginAuthenticator
}
+ /* ------------------------------------------------------------ */
public String newNonce(Request request)
{
- long ts=request.getTimeStamp();
- long sk = _nonceSecret;
-
- byte[] nounce = new byte[24];
- for (int i = 0; i < 8; i++)
+ Nonce nonce;
+
+ do
{
- nounce[i] = (byte) (ts & 0xff);
- ts = ts >> 8;
- nounce[8 + i] = (byte) (sk & 0xff);
- sk = sk >> 8;
- }
+ byte[] nounce = new byte[24];
+ _random.nextBytes(nounce);
- byte[] hash = null;
- try
- {
- MessageDigest md = MessageDigest.getInstance("MD5");
- md.reset();
- md.update(nounce, 0, 16);
- hash = md.digest();
+ nonce = new Nonce(new String(B64Code.encode(nounce)),request.getTimeStamp());
}
- catch (Exception e)
- {
- LOG.warn(e);
- }
-
- for (int i = 0; i < hash.length; i++)
- {
- nounce[8 + i] = hash[i];
- if (i == 23) break;
- }
-
- return new String(B64Code.encode(nounce));
+ while (_nonceCount.putIfAbsent(nonce._nonce,nonce)!=null);
+ _nonceQueue.add(nonce);
+
+ return nonce._nonce;
}
/**
- * @param nonce nonce to check
+ * @param nstring nonce to check
* @param request
* @return -1 for a bad nonce, 0 for a stale none, 1 for a good nonce
*/
/* ------------------------------------------------------------ */
- private int checkNonce(String nonce, Request request)
+ private int checkNonce(Digest digest, Request request)
{
+ // firstly let's expire old nonces
+ long expired = request.getTimeStamp()-_maxNonceAgeMs;
+
+ Nonce nonce=_nonceQueue.peek();
+ while (nonce!=null && nonce._ts> 8;
- ts = (ts << 8) + (0xff & (long) n[7 - i]);
- }
-
- long age = request.getTimeStamp() - ts;
- if (LOG.isDebugEnabled()) LOG.debug("age=" + age);
-
- byte[] hash = null;
- try
- {
- MessageDigest md = MessageDigest.getInstance("MD5");
- md.reset();
- md.update(n2, 0, 16);
- hash = md.digest();
- }
- catch (Exception e)
- {
- LOG.warn(e);
- }
-
- for (int i = 0; i < 16; i++)
- if (n[i + 8] != hash[i]) return -1;
-
- if (_maxNonceAge > 0 && (age < 0 || age > _maxNonceAge)) return 0; // stale
-
+ nonce = _nonceCount.get(digest.nonce);
+ if (nonce==null)
+ return 0;
+
+ long count = Long.parseLong(digest.nc,16);
+ if (count>Integer.MAX_VALUE)
+ return 0;
+ int old=nonce._nc.get();
+ while (!nonce._nc.compareAndSet(old,(int)count))
+ old=nonce._nc.get();
+ if (count<=old)
+ return -1;
+
return 1;
}
catch (Exception e)
@@ -276,18 +269,21 @@ public class DigestAuthenticator extends LoginAuthenticator
return -1;
}
+ /* ------------------------------------------------------------ */
+ /* ------------------------------------------------------------ */
+ /* ------------------------------------------------------------ */
private static class Digest extends Credential
{
private static final long serialVersionUID = -2484639019549527724L;
- String method = null;
- String username = null;
- String realm = null;
- String nonce = null;
- String nc = null;
- String cnonce = null;
- String qop = null;
- String uri = null;
- String response = null;
+ String method = "";
+ String username = "";
+ String realm = "";
+ String nonce = "";
+ String nc = "";
+ String cnonce = "";
+ String qop = "";
+ String uri = "";
+ String response = "";
/* ------------------------------------------------------------ */
Digest(String m)
From b7b567d86d0f297b3e38a166ac738f1fd84df474 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 20 Sep 2011 17:16:58 +1000
Subject: [PATCH 044/134] 353627 Basic Auth checks that Basic method has been
send
---
.../jetty/embedded/SecuredHelloHandler.java | 3 +-
.../authentication/BasicAuthenticator.java | 32 ++++++++++++-------
.../authentication/DigestAuthenticator.java | 2 +-
.../jetty/security/ConstraintTest.java | 30 ++++++++---------
4 files changed, 37 insertions(+), 30 deletions(-)
diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java
index 5d2547e3f1b..33c00e7a69b 100644
--- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java
+++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java
@@ -23,7 +23,6 @@ import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
-import org.eclipse.jetty.security.authentication.DigestAuthenticator;
import org.eclipse.jetty.server.Server;
public class SecuredHelloHandler
@@ -52,7 +51,7 @@ public class SecuredHelloHandler
knownRoles.add("admin");
security.setConstraintMappings(Collections.singletonList(mapping), knownRoles);
- security.setAuthenticator(new DigestAuthenticator());
+ security.setAuthenticator(new BasicAuthenticator());
security.setLoginService(loginService);
security.setStrict(false);
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java
index e680644609f..372f9b63ea0 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java
@@ -65,20 +65,28 @@ public class BasicAuthenticator extends LoginAuthenticator
return _deferred;
if (credentials != null)
- {
- credentials = credentials.substring(credentials.indexOf(' ')+1);
- credentials = B64Code.decode(credentials,StringUtil.__ISO_8859_1);
- int i = credentials.indexOf(':');
- if (i>0)
+ {
+ int space=credentials.indexOf(' ');
+ if (space>0)
{
- String username = credentials.substring(0,i);
- String password = credentials.substring(i+1);
-
- UserIdentity user = _loginService.login(username,password);
- if (user!=null)
+ String method=credentials.substring(0,space);
+ if ("basic".equalsIgnoreCase(method))
{
- renewSessionOnAuthentication(request,response);
- return new UserAuthentication(getAuthMethod(),user);
+ credentials = credentials.substring(space+1);
+ credentials = B64Code.decode(credentials,StringUtil.__ISO_8859_1);
+ int i = credentials.indexOf(':');
+ if (i>0)
+ {
+ String username = credentials.substring(0,i);
+ String password = credentials.substring(i+1);
+
+ UserIdentity user = _loginService.login(username,password);
+ if (user!=null)
+ {
+ renewSessionOnAuthentication(request,response);
+ return new UserAuthentication(getAuthMethod(),user);
+ }
+ }
}
}
}
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java
index ee9f5625aeb..ac4ebe2ea30 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java
@@ -275,7 +275,7 @@ public class DigestAuthenticator extends LoginAuthenticator
private static class Digest extends Credential
{
private static final long serialVersionUID = -2484639019549527724L;
- String method = "";
+ final String method;
String username = "";
String realm = "";
String nonce = "";
diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java
index 9a40357de9e..19eb3099011 100644
--- a/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java
+++ b/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java
@@ -201,13 +201,13 @@ public class ConstraintTest
assertTrue(response.indexOf("WWW-Authenticate: basic realm=\"TestRealm\"") > 0);
response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("user:wrong") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("user:wrong") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 401 Unauthorized"));
assertTrue(response.indexOf("WWW-Authenticate: basic realm=\"TestRealm\"") > 0);
response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("user:password") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("user:password") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
@@ -218,20 +218,20 @@ public class ConstraintTest
assertTrue(response.indexOf("WWW-Authenticate: basic realm=\"TestRealm\"") > 0);
response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("admin:wrong") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("admin:wrong") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 401 Unauthorized"));
assertTrue(response.indexOf("WWW-Authenticate: basic realm=\"TestRealm\"") > 0);
response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("user:password") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("user:password") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 403 "));
assertTrue(response.indexOf("!role") > 0);
response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("admin:password") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("admin:password") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
@@ -490,18 +490,18 @@ public class ConstraintTest
assertTrue(response.indexOf("WWW-Authenticate: basic realm=\"TestRealm\"") > 0);
response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("user:wrong") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("user:wrong") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 401 Unauthorized"));
assertTrue(response.indexOf("WWW-Authenticate: basic realm=\"TestRealm\"") > 0);
response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("user:password") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("user:password") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 403"));
response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("user2:password") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("user2:password") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
@@ -512,20 +512,20 @@ public class ConstraintTest
assertTrue(response.indexOf("WWW-Authenticate: basic realm=\"TestRealm\"") > 0);
response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("admin:wrong") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("admin:wrong") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 401 Unauthorized"));
assertTrue(response.indexOf("WWW-Authenticate: basic realm=\"TestRealm\"") > 0);
response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("user:password") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("user:password") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 403 "));
assertTrue(response.indexOf("!role") > 0);
response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("admin:password") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("admin:password") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
@@ -776,7 +776,7 @@ public class ConstraintTest
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("user2:password") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("user2:password") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 500 "));
@@ -789,7 +789,7 @@ public class ConstraintTest
_server.start();
response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" +
- "Authorization: " + B64Code.encode("user2:password") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("user2:password") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
}
@@ -809,13 +809,13 @@ public class ConstraintTest
assertTrue(response.indexOf("user=null") > 0);
response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n"+
- "Authorization: " + B64Code.encode("admin:wrong") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("admin:wrong") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
assertTrue(response.indexOf("user=null") > 0);
response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n"+
- "Authorization: " + B64Code.encode("admin:password") + "\r\n" +
+ "Authorization: Basic " + B64Code.encode("admin:password") + "\r\n" +
"\r\n");
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
assertTrue(response.indexOf("user=admin") > 0);
From 26c8cc851452b7a2f1abf21db55535b21aad6917 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 20 Sep 2011 18:00:24 +1000
Subject: [PATCH 045/134] 346419 testing HttpClient FDs
---
.../org/eclipse/jetty/client/HttpClient.java | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
index 85b16242c91..99b4a07dfa1 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
@@ -182,6 +182,15 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
*/
public ThreadPool getThreadPool()
{
+ if (_threadPool==null)
+ {
+ QueuedThreadPool pool = new QueuedThreadPool();
+ pool.setMaxThreads(16);
+ pool.setDaemon(true);
+ pool.setName("HttpClient");
+ _threadPool = pool;
+ }
+
return _threadPool;
}
@@ -420,13 +429,7 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
_idleTimeoutQ.setNow();
if (_threadPool == null)
- {
- QueuedThreadPool pool = new QueuedThreadPool();
- pool.setMaxThreads(16);
- pool.setDaemon(true);
- pool.setName("HttpClient");
- _threadPool = pool;
- }
+ getThreadPool();
if (_threadPool instanceof LifeCycle)
{
From 1e30a58419ef1b1f156be6f6d0158e7bd1622149 Mon Sep 17 00:00:00 2001
From: Thomas Becker
Date: Fri, 26 Aug 2011 19:34:37 +0200
Subject: [PATCH 046/134] HashLoginService code format
---
.../jetty/security/HashLoginService.java | 62 +++++++++----------
1 file changed, 30 insertions(+), 32 deletions(-)
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
index 5e5a8445863..0d6a7e45b7b 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
@@ -36,22 +36,18 @@ import org.eclipse.jetty.util.resource.Resource;
/**
* Properties User Realm.
*
- * An implementation of UserRealm that stores users and roles in-memory in
- * HashMaps.
+ * An implementation of UserRealm that stores users and roles in-memory in HashMaps.
*
- * Typically these maps are populated by calling the load() method or passing a
- * properties resource to the constructor. The format of the properties file is:
+ * Typically these maps are populated by calling the load() method or passing a properties resource to the constructor. The format of the properties file is:
*
*
* username: password [,rolename ...]
*
*
- * Passwords may be clear text, obfuscated or checksummed. The class
- * com.eclipse.Util.Password should be used to generate obfuscated passwords or
- * password checksums.
+ * Passwords may be clear text, obfuscated or checksummed. The class com.eclipse.Util.Password should be used to generate obfuscated passwords or password
+ * checksums.
*
- * If DIGEST Authentication is used, the password must be in a recoverable
- * format, either plain text or OBF:.
+ * If DIGEST Authentication is used, the password must be in a recoverable format, either plain text or OBF:.
*/
public class HashLoginService extends MappedLoginService
{
@@ -72,14 +68,14 @@ public class HashLoginService extends MappedLoginService
{
setName(name);
}
-
+
/* ------------------------------------------------------------ */
public HashLoginService(String name, String config)
{
setName(name);
setConfig(config);
}
-
+
/* ------------------------------------------------------------ */
public String getConfig()
{
@@ -89,7 +85,7 @@ public class HashLoginService extends MappedLoginService
/* ------------------------------------------------------------ */
public void getConfig(String config)
{
- _config=config;
+ _config = config;
}
/* ------------------------------------------------------------ */
@@ -100,11 +96,10 @@ public class HashLoginService extends MappedLoginService
/* ------------------------------------------------------------ */
/**
- * Load realm users from properties file. The property file maps usernames
- * to password specs followed by an optional comma separated list of role
- * names.
+ * Load realm users from properties file. The property file maps usernames to password specs followed by an optional comma separated list of role names.
*
- * @param config Filename or url of user properties file.
+ * @param config
+ * Filename or url of user properties file.
*/
public void setConfig(String config)
{
@@ -129,30 +124,31 @@ public class HashLoginService extends MappedLoginService
{
return null;
}
-
+
/* ------------------------------------------------------------ */
@Override
public void loadUsers() throws IOException
{
- if (_config==null)
+ if (_config == null)
return;
_configResource = Resource.newResource(_config);
if (LOG.isDebugEnabled()) LOG.debug("Load " + this + " from " + _config);
+
Properties properties = new Properties();
properties.load(_configResource.getInputStream());
Set known = new HashSet();
for (Map.Entry entry : properties.entrySet())
{
- String username = ((String) entry.getKey()).trim();
- String credentials = ((String) entry.getValue()).trim();
+ String username = ((String)entry.getKey()).trim();
+ String credentials = ((String)entry.getValue()).trim();
String roles = null;
int c = credentials.indexOf(',');
if (c > 0)
{
roles = credentials.substring(c + 1).trim();
- credentials = credentials.substring(0, c).trim();
+ credentials = credentials.substring(0,c).trim();
}
if (username != null && username.length() > 0 && credentials != null && credentials.length() > 0)
@@ -164,17 +160,16 @@ public class HashLoginService extends MappedLoginService
putUser(username,Credential.getCredential(credentials),roleArray);
}
}
-
+
Iterator users = _users.keySet().iterator();
- while(users.hasNext())
+ while (users.hasNext())
{
- String user=users.next();
+ String user = users.next();
if (!known.contains(user))
users.remove();
}
}
-
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
@@ -182,7 +177,7 @@ public class HashLoginService extends MappedLoginService
protected void doStart() throws Exception
{
super.doStart();
-
+
if (getRefreshInterval() > 0)
{
_scanner = new Scanner();
@@ -194,10 +189,11 @@ public class HashLoginService extends MappedLoginService
{
public boolean accept(File dir, String name)
{
- File f = new File(dir, name);
+ File f = new File(dir,name);
try
{
- if (f.compareTo(_configResource.getFile()) == 0) return true;
+ if (f.compareTo(_configResource.getFile()) == 0)
+ return true;
}
catch (IOException e)
{
@@ -212,8 +208,10 @@ public class HashLoginService extends MappedLoginService
{
public void filesChanged(List filenames) throws Exception
{
- if (filenames == null) return;
- if (filenames.isEmpty()) return;
+ if (filenames == null)
+ return;
+ if (filenames.isEmpty())
+ return;
if (filenames.size() == 1)
{
Resource r = Resource.newResource(filenames.get(0));
@@ -241,9 +239,9 @@ public class HashLoginService extends MappedLoginService
protected void doStop() throws Exception
{
super.doStop();
- if (_scanner != null) _scanner.stop();
+ if (_scanner != null)
+ _scanner.stop();
_scanner = null;
}
-
}
From 95ee2157bddc7fe60a43591a160d49383078d64e Mon Sep 17 00:00:00 2001
From: Thomas Becker
Date: Fri, 26 Aug 2011 19:35:51 +0200
Subject: [PATCH 047/134] JETTY-1414 applied to PropertyUserStore
---
.../org/eclipse/jetty/security/PropertyUserStore.java | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java
index 5e463165103..7f49893030d 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java
@@ -201,15 +201,17 @@ public class PropertyUserStore extends AbstractLifeCycle
_scanner.addListener(new BulkListener()
{
- public void filesChanged(List filenames) throws Exception
+ public void filesChanged(List filenames) throws Exception
{
if (filenames == null)
return;
if (filenames.isEmpty())
return;
- if (filenames.size() == 1 && filenames.get(0).equals(getConfigResource().getFile().getAbsolutePath()))
+ if (filenames.size() == 1)
{
- loadUsers();
+ Resource r = Resource.newResource(filenames.get(0));
+ if (r.getFile().equals(_configResource.getFile()))
+ loadUsers();
}
}
From 129a66f57918b972df7674c94180a687977f7b26 Mon Sep 17 00:00:00 2001
From: Thomas Becker
Date: Fri, 26 Aug 2011 19:58:15 +0200
Subject: [PATCH 048/134] 323311: HashLoginService uses PropertyUserStore now
---
.../jetty/security/HashLoginService.java | 128 ++++--------------
1 file changed, 27 insertions(+), 101 deletions(-)
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
index 0d6a7e45b7b..ab73707e1ce 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
@@ -13,21 +13,12 @@
package org.eclipse.jetty.security;
-import java.io.File;
-import java.io.FilenameFilter;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
import org.eclipse.jetty.http.security.Credential;
+import org.eclipse.jetty.security.PropertyUserStore.UserListener;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.Scanner;
-import org.eclipse.jetty.util.Scanner.BulkListener;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
@@ -49,10 +40,11 @@ import org.eclipse.jetty.util.resource.Resource;
*
* If DIGEST Authentication is used, the password must be in a recoverable format, either plain text or OBF:.
*/
-public class HashLoginService extends MappedLoginService
+public class HashLoginService extends MappedLoginService implements UserListener
{
private static final Logger LOG = Log.getLogger(HashLoginService.class);
+ private PropertyUserStore _propertyUserStore;
private String _config;
private Resource _configResource;
private Scanner _scanner;
@@ -129,45 +121,7 @@ public class HashLoginService extends MappedLoginService
@Override
public void loadUsers() throws IOException
{
- if (_config == null)
- return;
- _configResource = Resource.newResource(_config);
-
- if (LOG.isDebugEnabled()) LOG.debug("Load " + this + " from " + _config);
-
- Properties properties = new Properties();
- properties.load(_configResource.getInputStream());
- Set known = new HashSet();
-
- for (Map.Entry entry : properties.entrySet())
- {
- String username = ((String)entry.getKey()).trim();
- String credentials = ((String)entry.getValue()).trim();
- String roles = null;
- int c = credentials.indexOf(',');
- if (c > 0)
- {
- roles = credentials.substring(c + 1).trim();
- credentials = credentials.substring(0,c).trim();
- }
-
- if (username != null && username.length() > 0 && credentials != null && credentials.length() > 0)
- {
- String[] roleArray = IdentityService.NO_ROLES;
- if (roles != null && roles.length() > 0)
- roleArray = roles.split(",");
- known.add(username);
- putUser(username,Credential.getCredential(credentials),roleArray);
- }
- }
-
- Iterator users = _users.keySet().iterator();
- while (users.hasNext())
- {
- String user = users.next();
- if (!known.contains(user))
- users.remove();
- }
+ // TODO: Consider refactoring MappedLoginService to not have to override with unused methods
}
/* ------------------------------------------------------------ */
@@ -177,58 +131,15 @@ public class HashLoginService extends MappedLoginService
protected void doStart() throws Exception
{
super.doStart();
-
- if (getRefreshInterval() > 0)
+ if (_propertyUserStore == null)
{
- _scanner = new Scanner();
- _scanner.setScanInterval(getRefreshInterval());
- List dirList = new ArrayList(1);
- dirList.add(_configResource.getFile());
- _scanner.setScanDirs(dirList);
- _scanner.setFilenameFilter(new FilenameFilter()
- {
- public boolean accept(File dir, String name)
- {
- File f = new File(dir,name);
- try
- {
- if (f.compareTo(_configResource.getFile()) == 0)
- return true;
- }
- catch (IOException e)
- {
- return false;
- }
-
- return false;
- }
-
- });
- _scanner.addListener(new BulkListener()
- {
- public void filesChanged(List filenames) throws Exception
- {
- if (filenames == null)
- return;
- if (filenames.isEmpty())
- return;
- if (filenames.size() == 1)
- {
- Resource r = Resource.newResource(filenames.get(0));
- if (r.getFile().equals(_configResource.getFile()))
- loadUsers();
- }
- }
-
- public String toString()
- {
- return "HashLoginService$Scanner";
- }
-
- });
- _scanner.setReportExistingFilesOnStartup(false);
- _scanner.setRecursive(false);
- _scanner.start();
+ if(Log.isDebugEnabled())
+ Log.debug("doStart: Starting new PropertyUserStore. PropertiesFile: " + _config + " refreshInterval: " + _refreshInterval);
+ _propertyUserStore = new PropertyUserStore();
+ _propertyUserStore.setRefreshInterval(_refreshInterval);
+ _propertyUserStore.setConfig(_config);
+ _propertyUserStore.registerUserListener(this);
+ _propertyUserStore.start();
}
}
@@ -243,5 +154,20 @@ public class HashLoginService extends MappedLoginService
_scanner.stop();
_scanner = null;
}
+
+ /* ------------------------------------------------------------ */
+ public void update(String userName, Credential credential, String[] roleArray)
+ {
+ if (Log.isDebugEnabled())
+ Log.debug("update: " + userName + " Roles: " + roleArray.length);
+ putUser(userName,credential,roleArray);
+ }
+ /* ------------------------------------------------------------ */
+ public void remove(String userName)
+ {
+ if (Log.isDebugEnabled())
+ Log.debug("remove: " + userName);
+ removeUser(userName);
+ }
}
From df0aab1f49b395fe4bb903fcef2c3d214a79dc9e Mon Sep 17 00:00:00 2001
From: Thomas Becker
Date: Fri, 26 Aug 2011 20:00:02 +0200
Subject: [PATCH 049/134] PropertyUserStore: Code Format
---
.../jaas/spi/PropertyFileLoginModule.java | 98 +++++++++----------
1 file changed, 47 insertions(+), 51 deletions(-)
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java
index 67a207042ff..b10342e303d 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java
@@ -31,108 +31,104 @@ import org.eclipse.jetty.util.log.Logger;
/**
* PropertyFileLoginModule
- *
- *
+ *
+ *
*/
public class PropertyFileLoginModule extends AbstractLoginModule
{
private static final Logger LOG = Log.getLogger(PropertyFileLoginModule.class);
public static final String DEFAULT_FILENAME = "realm.properties";
- public static final Map> fileMap = new HashMap>();
-
- private String propertyFileName;
-
-
+ public static final Map> fileMap = new HashMap>();
- /**
+ private String propertyFileName;
+
+ /**
* Read contents of the configured property file.
*
- * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
+ * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map,
+ * java.util.Map)
* @param subject
* @param callbackHandler
* @param sharedState
* @param options
*/
- public void initialize(Subject subject, CallbackHandler callbackHandler,
- Map sharedState, Map options)
+ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
{
- super.initialize(subject, callbackHandler, sharedState, options);
+ super.initialize(subject,callbackHandler,sharedState,options);
loadProperties((String)options.get("file"));
}
-
-
-
- public void loadProperties (String filename)
+
+ public void loadProperties(String filename)
{
File propsFile;
-
+
if (filename == null)
{
- propsFile = new File(System.getProperty("user.dir"), DEFAULT_FILENAME);
- //look for a file called realm.properties in the current directory
- //if that fails, look for a file called realm.properties in $jetty.home/etc
+ propsFile = new File(System.getProperty("user.dir"),DEFAULT_FILENAME);
+ // look for a file called realm.properties in the current directory
+ // if that fails, look for a file called realm.properties in $jetty.home/etc
if (!propsFile.exists())
- propsFile = new File(System.getProperty("jetty.home"), DEFAULT_FILENAME);
+ propsFile = new File(System.getProperty("jetty.home"),DEFAULT_FILENAME);
}
else
{
propsFile = new File(filename);
}
-
- //give up, can't find a property file to load
+
+ // give up, can't find a property file to load
if (!propsFile.exists())
{
LOG.warn("No property file found");
throw new IllegalStateException ("No property file specified in login module configuration file");
}
-
-
-
+
try
{
this.propertyFileName = propsFile.getCanonicalPath();
if (fileMap.get(propertyFileName) != null)
{
- if (LOG.isDebugEnabled()) {LOG.debug("Properties file "+propertyFileName+" already in cache, skipping load");}
+ if (Log.isDebugEnabled())
+ {
+ Log.debug("Properties file " + propertyFileName + " already in cache, skipping load");
+ }
return;
}
-
+
Map userInfoMap = new HashMap();
Properties props = new Properties();
props.load(new FileInputStream(propsFile));
- Iterator> iter = props.entrySet().iterator();
- while(iter.hasNext())
+ Iterator> iter = props.entrySet().iterator();
+ while (iter.hasNext())
{
-
- Map.Entry entry = iter.next();
- String username=entry.getKey().toString().trim();
- String credentials=entry.getValue().toString().trim();
- String roles=null;
- int c=credentials.indexOf(',');
- if (c>0)
+
+ Map.Entry entry = iter.next();
+ String username = entry.getKey().toString().trim();
+ String credentials = entry.getValue().toString().trim();
+ String roles = null;
+ int c = credentials.indexOf(',');
+ if (c > 0)
{
- roles=credentials.substring(c+1).trim();
- credentials=credentials.substring(0,c).trim();
+ roles = credentials.substring(c + 1).trim();
+ credentials = credentials.substring(0,c).trim();
}
- if (username!=null && username.length()>0 &&
- credentials!=null && credentials.length()>0)
+ if (username != null && username.length() > 0 && credentials != null && credentials.length() > 0)
{
ArrayList roleList = new ArrayList();
- if(roles!=null && roles.length()>0)
+ if (roles != null && roles.length() > 0)
{
StringTokenizer tok = new StringTokenizer(roles,", ");
-
+
while (tok.hasMoreTokens())
roleList.add(tok.nextToken());
}
-
- userInfoMap.put(username, (new UserInfo(username, Credential.getCredential(credentials.toString()), roleList)));
+
+ userInfoMap.put(username,(new UserInfo(username,Credential.getCredential(credentials.toString()),roleList)));
}
}
-
- fileMap.put(propertyFileName, userInfoMap);
+
+ fileMap.put(propertyFileName,userInfoMap);
}
catch (Exception e)
{
@@ -141,13 +137,13 @@ public class PropertyFileLoginModule extends AbstractLoginModule
}
}
- /**
- * Don't implement this as we want to pre-fetch all of the
- * users.
+ /**
+ * Don't implement this as we want to pre-fetch all of the users.
+ *
* @param username
* @throws Exception
*/
- public UserInfo getUserInfo (String username) throws Exception
+ public UserInfo getUserInfo(String username) throws Exception
{
Map, ?> userInfoMap = (Map, ?>)fileMap.get(propertyFileName);
if (userInfoMap == null)
From c17552ee50090a02dc11328dd31d4a5cd662d9cf Mon Sep 17 00:00:00 2001
From: Jesse McConnell
Date: Tue, 13 Sep 2011 15:44:37 -0500
Subject: [PATCH 050/134] [323311] apply 5th patch of thomas, also removed
extra method on IdentityService since it appears not needed, moved behavior
to loadUsers() method instead.
---
.../jaas/spi/PropertyFileLoginModule.java | 133 +++++++-----------
.../security/DefaultIdentityService.java | 3 +
.../jetty/security/HashLoginService.java | 15 +-
.../jetty/security/IdentityService.java | 2 +-
.../jetty/security/PropertyUserStore.java | 38 ++++-
.../jetty/security/PropertyUserStoreTest.java | 7 +
6 files changed, 105 insertions(+), 93 deletions(-)
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java
index b10342e303d..d3e69878cc1 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java
@@ -13,19 +13,18 @@
package org.eclipse.jetty.plus.jaas.spi;
-import java.io.File;
-import java.io.FileInputStream;
-import java.util.ArrayList;
+import java.security.Principal;
+import java.util.Arrays;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
-import java.util.Properties;
-import java.util.StringTokenizer;
+import java.util.Set;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import org.eclipse.jetty.http.security.Credential;
+import org.eclipse.jetty.security.PropertyUserStore;
+import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -36,12 +35,14 @@ import org.eclipse.jetty.util.log.Logger;
*/
public class PropertyFileLoginModule extends AbstractLoginModule
{
+ public static final String DEFAULT_FILENAME = "realm.properties";
+
private static final Logger LOG = Log.getLogger(PropertyFileLoginModule.class);
- public static final String DEFAULT_FILENAME = "realm.properties";
- public static final Map> fileMap = new HashMap>();
+ private static Map _propertyUserStores = new HashMap();
- private String propertyFileName;
+ private int _refreshInterval = 0;
+ private String _filename = DEFAULT_FILENAME;
/**
* Read contents of the configured property file.
@@ -56,99 +57,61 @@ public class PropertyFileLoginModule extends AbstractLoginModule
public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
{
super.initialize(subject,callbackHandler,sharedState,options);
- loadProperties((String)options.get("file"));
+ setupPropertyUserStore(options);
}
- public void loadProperties(String filename)
+ private void setupPropertyUserStore(Map options)
{
- File propsFile;
+ if (_propertyUserStores.get(_filename) == null)
+ {
+ parseConfig(options);
- if (filename == null)
- {
- propsFile = new File(System.getProperty("user.dir"),DEFAULT_FILENAME);
- // look for a file called realm.properties in the current directory
- // if that fails, look for a file called realm.properties in $jetty.home/etc
- if (!propsFile.exists())
- propsFile = new File(System.getProperty("jetty.home"),DEFAULT_FILENAME);
- }
- else
- {
- propsFile = new File(filename);
- }
+ PropertyUserStore _propertyUserStore = new PropertyUserStore();
+ _propertyUserStore.setConfig(_filename);
+ _propertyUserStore.setRefreshInterval(_refreshInterval);
+ LOG.debug("setupPropertyUserStore: Starting new PropertyUserStore. PropertiesFile: " + _filename + " refreshInterval: " + _refreshInterval);
- // give up, can't find a property file to load
- if (!propsFile.exists())
- {
- LOG.warn("No property file found");
- throw new IllegalStateException ("No property file specified in login module configuration file");
- }
-
- try
- {
- this.propertyFileName = propsFile.getCanonicalPath();
- if (fileMap.get(propertyFileName) != null)
+ try
{
- if (Log.isDebugEnabled())
- {
- Log.debug("Properties file " + propertyFileName + " already in cache, skipping load");
- }
- return;
+ _propertyUserStore.start();
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Exception while starting propertyUserStore: ",e);
}
- Map userInfoMap = new HashMap();
- Properties props = new Properties();
- props.load(new FileInputStream(propsFile));
- Iterator> iter = props.entrySet().iterator();
- while (iter.hasNext())
- {
-
- Map.Entry entry = iter.next();
- String username = entry.getKey().toString().trim();
- String credentials = entry.getValue().toString().trim();
- String roles = null;
- int c = credentials.indexOf(',');
- if (c > 0)
- {
- roles = credentials.substring(c + 1).trim();
- credentials = credentials.substring(0,c).trim();
- }
-
- if (username != null && username.length() > 0 && credentials != null && credentials.length() > 0)
- {
- ArrayList roleList = new ArrayList();
- if (roles != null && roles.length() > 0)
- {
- StringTokenizer tok = new StringTokenizer(roles,", ");
-
- while (tok.hasMoreTokens())
- roleList.add(tok.nextToken());
- }
-
- userInfoMap.put(username,(new UserInfo(username,Credential.getCredential(credentials.toString()),roleList)));
- }
- }
-
- fileMap.put(propertyFileName,userInfoMap);
- }
- catch (Exception e)
- {
- LOG.warn("Error loading properties from file", e);
- throw new RuntimeException(e);
+ _propertyUserStores.put(_filename,_propertyUserStore);
}
}
+ private void parseConfig(Map options)
+ {
+ _filename = (String)options.get("file") != null?(String)options.get("file"):DEFAULT_FILENAME;
+ String refreshIntervalString = (String)options.get("refreshInterval");
+ _refreshInterval = refreshIntervalString == null?_refreshInterval:Integer.parseInt(refreshIntervalString);
+ }
+
/**
* Don't implement this as we want to pre-fetch all of the users.
*
- * @param username
+ * @param userName
* @throws Exception
*/
- public UserInfo getUserInfo(String username) throws Exception
+ public UserInfo getUserInfo(String userName) throws Exception
{
- Map, ?> userInfoMap = (Map, ?>)fileMap.get(propertyFileName);
- if (userInfoMap == null)
+ PropertyUserStore propertyUserStore = _propertyUserStores.get(_filename);
+ if (propertyUserStore == null)
+ throw new IllegalStateException("PropertyUserStore should never be null here!");
+
+ UserIdentity userIdentity = propertyUserStore.getUserIdentity(userName);
+ if(userIdentity==null)
return null;
- return (UserInfo)userInfoMap.get(username);
+
+ Set principals = userIdentity.getSubject().getPrincipals();
+ String[] roles = principals.toArray(new String[principals.size()]);
+ Credential credential = (Credential)userIdentity.getSubject().getPrivateCredentials().iterator().next();
+ LOG.debug("Found: " + userName + " in PropertyUserStore");
+ return new UserInfo(userName, credential,Arrays.asList(roles));
}
-}
+}
\ No newline at end of file
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java
index 2b2b7462761..472da9c6654 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java
@@ -17,6 +17,9 @@ import java.security.Principal;
import javax.security.auth.Subject;
+import org.eclipse.jetty.http.security.Credential;
+import org.eclipse.jetty.security.MappedLoginService.KnownUser;
+import org.eclipse.jetty.security.MappedLoginService.RolePrincipal;
import org.eclipse.jetty.server.UserIdentity;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
index ab73707e1ce..12b51f51502 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
@@ -131,10 +131,13 @@ public class HashLoginService extends MappedLoginService implements UserListener
protected void doStart() throws Exception
{
super.doStart();
+
if (_propertyUserStore == null)
{
- if(Log.isDebugEnabled())
- Log.debug("doStart: Starting new PropertyUserStore. PropertiesFile: " + _config + " refreshInterval: " + _refreshInterval);
+ if(LOG.isDebugEnabled())
+ {
+ LOG.debug("doStart: Starting new PropertyUserStore. PropertiesFile: " + _config + " refreshInterval: " + _refreshInterval);
+ }
_propertyUserStore = new PropertyUserStore();
_propertyUserStore.setRefreshInterval(_refreshInterval);
_propertyUserStore.setConfig(_config);
@@ -158,16 +161,16 @@ public class HashLoginService extends MappedLoginService implements UserListener
/* ------------------------------------------------------------ */
public void update(String userName, Credential credential, String[] roleArray)
{
- if (Log.isDebugEnabled())
- Log.debug("update: " + userName + " Roles: " + roleArray.length);
+ if (LOG.isDebugEnabled())
+ LOG.debug("update: " + userName + " Roles: " + roleArray.length);
putUser(userName,credential,roleArray);
}
/* ------------------------------------------------------------ */
public void remove(String userName)
{
- if (Log.isDebugEnabled())
- Log.debug("remove: " + userName);
+ if (LOG.isDebugEnabled())
+ LOG.debug("remove: " + userName);
removeUser(userName);
}
}
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java
index e05a000b2e0..216ae818d9b 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java
@@ -14,9 +14,9 @@
package org.eclipse.jetty.security;
import java.security.Principal;
-
import javax.security.auth.Subject;
+import org.eclipse.jetty.http.security.Credential;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.UserIdentity;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java
index 7f49893030d..b7e64ac123b 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java
@@ -3,7 +3,9 @@ package org.eclipse.jetty.security;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.security.Principal;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -11,7 +13,12 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import javax.security.auth.Subject;
+
import org.eclipse.jetty.http.security.Credential;
+import org.eclipse.jetty.security.MappedLoginService.KnownUser;
+import org.eclipse.jetty.security.MappedLoginService.RolePrincipal;
+import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.Scanner.BulkListener;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
@@ -42,8 +49,10 @@ public class PropertyUserStore extends AbstractLifeCycle
private Scanner _scanner;
private int _refreshInterval = 0;// default is not to reload
+ private IdentityService _identityService = new DefaultIdentityService();
private boolean _firstLoad = true; // true if first load, false from that point on
private final List _knownUsers = new ArrayList();
+ private final Map _knownUserIdentities = new HashMap();
private List _listeners;
/* ------------------------------------------------------------ */
@@ -57,6 +66,12 @@ public class PropertyUserStore extends AbstractLifeCycle
{
_config = config;
}
+
+ /* ------------------------------------------------------------ */
+ public UserIdentity getUserIdentity(String userName)
+ {
+ return _knownUserIdentities.get(userName);
+ }
/* ------------------------------------------------------------ */
/**
@@ -119,9 +134,29 @@ public class PropertyUserStore extends AbstractLifeCycle
{
String[] roleArray = IdentityService.NO_ROLES;
if (roles != null && roles.length() > 0)
+ {
roleArray = roles.split(",");
+ }
known.add(username);
- notifyUpdate(username,Credential.getCredential(credentials),roleArray);
+ Credential credential = Credential.getCredential(credentials);
+
+ Principal userPrincipal = new KnownUser(username,credential);
+ Subject subject = new Subject();
+ subject.getPrincipals().add(userPrincipal);
+ subject.getPrivateCredentials().add(credential);
+
+ if (roles != null)
+ {
+ for (String role : roleArray)
+ {
+ subject.getPrincipals().add(new RolePrincipal(role));
+ }
+ }
+
+ subject.setReadOnly();
+
+ _knownUserIdentities.put(username,_identityService.newUserIdentity(subject,userPrincipal,roleArray));
+ notifyUpdate(username,credential,roleArray);
}
}
@@ -138,6 +173,7 @@ public class PropertyUserStore extends AbstractLifeCycle
String user = users.next();
if (!known.contains(user))
{
+ _knownUserIdentities.remove(user);
notifyRemove(user);
}
}
diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java
index dde1df50bc1..68220b8dbca 100644
--- a/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java
+++ b/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java
@@ -78,6 +78,9 @@ public class PropertyUserStoreTest
store.start();
+ Assert.assertNotNull("Failed to retrieve UserIdentity directly from PropertyUserStore", store.getUserIdentity("tom"));
+ Assert.assertNotNull("Failed to retrieve UserIdentity directly from PropertyUserStore", store.getUserIdentity("dick"));
+ Assert.assertNotNull("Failed to retrieve UserIdentity directly from PropertyUserStore", store.getUserIdentity("harry"));
Assert.assertEquals(3,userCount.get());
}
@@ -117,7 +120,11 @@ public class PropertyUserStoreTest
long start = System.currentTimeMillis();
while (userCount.get() < 4 && (System.currentTimeMillis() - start) < 10000)
+ {
Thread.sleep(10);
+ }
+
+ Assert.assertNotNull("Failed to retrieve UserIdentity from PropertyUserStore directly", store.getUserIdentity("skip"));
Assert.assertEquals(4,userCount.get());
Assert.assertTrue(users.contains("skip"));
From 2ef624e9fa4c125b60b785bf358b111a07f20eab Mon Sep 17 00:00:00 2001
From: Jesse McConnell
Date: Tue, 20 Sep 2011 10:11:08 -0500
Subject: [PATCH 051/134] add resource dir for tests
---
jetty-servlet/src/test/resources/dispatchTest/dispatch.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 jetty-servlet/src/test/resources/dispatchTest/dispatch.txt
diff --git a/jetty-servlet/src/test/resources/dispatchTest/dispatch.txt b/jetty-servlet/src/test/resources/dispatchTest/dispatch.txt
new file mode 100644
index 00000000000..f3a34851d44
--- /dev/null
+++ b/jetty-servlet/src/test/resources/dispatchTest/dispatch.txt
@@ -0,0 +1 @@
+text
\ No newline at end of file
From 3091739b70b9cca0e612fbb8d3cac6ab7b70851b Mon Sep 17 00:00:00 2001
From: Jesse McConnell
Date: Tue, 20 Sep 2011 11:47:17 -0500
Subject: [PATCH 052/134] remove plugin versions we get from parent and remove
groupId
---
pom.xml | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/pom.xml b/pom.xml
index fcb8e146e5c..4b45232f305 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,6 @@
jetty-parent19-SNAPSHOT
- org.eclipse.jettyjetty-project7.5.2-SNAPSHOTJetty :: Project
@@ -245,7 +244,6 @@
org.codehaus.mojofindbugs-maven-plugin
- 2.3.2truetrue
@@ -260,12 +258,10 @@
org.apache.maven.pluginsmaven-jxr-plugin
- 2.2org.apache.maven.pluginsmaven-javadoc-plugin
- 2.8truetrue
@@ -275,7 +271,6 @@
org.apache.maven.pluginsmaven-pmd-plugin
- 2.5
@@ -286,12 +281,10 @@
org.apache.maven.pluginsmaven-jxr-plugin
- 2.2org.apache.maven.pluginsmaven-javadoc-plugin
- 2.8512mtrue
@@ -302,7 +295,6 @@
org.apache.maven.pluginsmaven-pmd-plugin
- 2.51.5
@@ -313,7 +305,6 @@
org.codehaus.mojofindbugs-maven-plugin
- 2.3.2
From bc86f5d154f0482eb2b1316c7b6a0e0061b33a92 Mon Sep 17 00:00:00 2001
From: Jesse McConnell
Date: Tue, 20 Sep 2011 14:08:30 -0500
Subject: [PATCH 053/134] update parent version
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 4b45232f305..9bbf848c240 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
org.eclipse.jettyjetty-parent
- 19-SNAPSHOT
+ 19jetty-project7.5.2-SNAPSHOT
From f6d26c20078fbf9df043c4a02fe1bf4b728a2c6f Mon Sep 17 00:00:00 2001
From: Jesse McConnell
Date: Tue, 20 Sep 2011 14:09:26 -0500
Subject: [PATCH 054/134] [Bug 358263] add method for osgi users to register a
driver as Class.forName does not work for them
---
.../server/session/JDBCSessionIdManager.java | 21 ++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
index 8e73f3af1d0..ad5b244d761 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
@@ -18,6 +18,7 @@ import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
+import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -56,6 +57,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
protected final HashSet _sessionIds = new HashSet();
protected Server _server;
+ protected Driver _driver;
protected String _driverClassName;
protected String _connectionUrl;
protected DataSource _datasource;
@@ -184,6 +186,19 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
_connectionUrl=connectionUrl;
}
+ /**
+ * Configure jdbc connection information via a jdbc Driver
+ *
+ * @param driverClass
+ * @param connectionUrl
+ */
+ public void setDriverInfo (Driver driverClass, String connectionUrl)
+ {
+ _driver=driverClass;
+ _connectionUrl=connectionUrl;
+ }
+
+
public String getDriverClassName()
{
return _driverClassName;
@@ -461,7 +476,11 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
InitialContext ic = new InitialContext();
_datasource = (DataSource)ic.lookup(_jndiName);
}
- else if (_driverClassName!=null && _connectionUrl!=null)
+ else if ( _driver != null && _connectionUrl != null )
+ {
+ DriverManager.registerDriver(_driver);
+ }
+ else if (_driverClassName != null && _connectionUrl != null)
{
Class.forName(_driverClassName);
}
From f0fe55165b6ff36c9440d3ba4272f64ebd232b10 Mon Sep 17 00:00:00 2001
From: Thomas Becker
Date: Tue, 20 Sep 2011 10:19:23 +0200
Subject: [PATCH 055/134] SelectConnector.java code format
---
.../java/org/eclipse/jetty/client/SelectConnector.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
index 333c4166ba4..f070951407e 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
@@ -103,12 +103,12 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector
}
else
{
- channel.configureBlocking( false );
+ channel.configureBlocking(false);
channel.connect(address.toSocketAddress());
- _selectorManager.register( channel, destination );
- ConnectTimeout connectTimeout = new ConnectTimeout(channel, destination);
+ _selectorManager.register(channel,destination);
+ ConnectTimeout connectTimeout = new ConnectTimeout(channel,destination);
_httpClient.schedule(connectTimeout,_httpClient.getConnectTimeout());
- _connectingChannels.put(channel, connectTimeout);
+ _connectingChannels.put(channel,connectTimeout);
}
}
From 4b7f8d79dd9465b561599e1635bb86f08d99d14b Mon Sep 17 00:00:00 2001
From: Thomas Becker
Date: Tue, 20 Sep 2011 10:20:24 +0200
Subject: [PATCH 056/134] 358147: SelectConnector catch
UnresolvedAddressException to avoid socket leak
---
.../org/eclipse/jetty/client/SelectConnector.java | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
index f070951407e..caadb23c274 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
@@ -17,8 +17,10 @@ import java.io.IOException;
import java.net.SocketTimeoutException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
+import java.nio.channels.UnresolvedAddressException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSession;
@@ -104,7 +106,15 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector
else
{
channel.configureBlocking(false);
- channel.connect(address.toSocketAddress());
+ try
+ {
+ channel.connect(address.toSocketAddress());
+ }
+ catch (UnresolvedAddressException ex)
+ {
+ channel.close();
+ throw ex;
+ }
_selectorManager.register(channel,destination);
ConnectTimeout connectTimeout = new ConnectTimeout(channel,destination);
_httpClient.schedule(connectTimeout,_httpClient.getConnectTimeout());
From 21ddd768f0edf75becbb65ca494ff3f4be1d9b3d Mon Sep 17 00:00:00 2001
From: Jesse McConnell
Date: Tue, 20 Sep 2011 14:26:17 -0500
Subject: [PATCH 057/134] [Bug 358147] Add catch for UnknownHostException to
fix leaky file descriptor in client
---
.../org/eclipse/jetty/client/SelectConnector.java | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
index caadb23c274..c2274ef5eda 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
@@ -15,6 +15,7 @@ package org.eclipse.jetty.client;
import java.io.IOException;
import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.channels.UnresolvedAddressException;
@@ -110,11 +111,17 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector
{
channel.connect(address.toSocketAddress());
}
- catch (UnresolvedAddressException ex)
+ catch (UnresolvedAddressException uae)
{
channel.close();
- throw ex;
+ throw uae;
}
+ catch ( UnknownHostException uhe )
+ {
+ channel.close();
+ throw uhe;
+ }
+
_selectorManager.register(channel,destination);
ConnectTimeout connectTimeout = new ConnectTimeout(channel,destination);
_httpClient.schedule(connectTimeout,_httpClient.getConnectTimeout());
From f8b8a2e77083c76b326c050e78c3937aa7b28b01 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 21 Sep 2011 11:30:40 +1000
Subject: [PATCH 058/134] JETTY-1277 Fixed sendRedirect encoding of relative
locations
---
.../org/eclipse/jetty/server/Response.java | 2 +-
.../eclipse/jetty/server/ResponseTest.java | 62 ++++++++++++-------
2 files changed, 39 insertions(+), 25 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
index b5c9563b5b7..fb6196a2087 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
@@ -430,7 +430,7 @@ public class Response implements HttpServletResponse
if (!canonical.equals(path))
{
buf = _connection.getRequest().getRootURL();
- buf.append(canonical);
+ buf.append(URIUtil.encodePath(canonical));
if (uri.getQuery()!=null)
{
buf.append('?');
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
index 29ab7d91e03..ecc45ee835e 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
@@ -381,31 +381,45 @@ public class ResponseTest
public void testSendRedirect()
throws Exception
{
- ByteArrayEndPoint out=new ByteArrayEndPoint(new byte[]{},4096);
- HttpConnection connection=new TestHttpConnection(connector,out, connector.getServer());
- Response response = new Response(connection);
- Request request = connection.getRequest();
- request.setServerName("myhost");
- request.setServerPort(8888);
- request.setUri(new HttpURI("/path/info;param;jsessionid=12345?query=0&more=1#target"));
- request.setContextPath("/path");
- request.setRequestedSessionId("12345");
- request.setRequestedSessionIdFromCookie(false);
- AbstractSessionManager manager=new HashSessionManager();
- manager.setSessionIdManager(new HashSessionIdManager());
- request.setSessionManager(manager);
- request.setSession(new TestSession(manager,"12345"));
- manager.setCheckingRemoteSessionIdEncoding(false);
+ String[][] tests={
+ {"/other/location?name=value","http://myhost:8888/other/location;jsessionid=12345?name=value"},
+ {"/other/location","http://myhost:8888/other/location"},
+ {"/other/l%20cation","http://myhost:8888/other/l%20cation"},
+ {"location","http://myhost:8888/path/location"},
+ {"./location","http://myhost:8888/path/location"},
+ {"../location","http://myhost:8888/location"},
+ {"/other/l%20cation","http://myhost:8888/other/l%20cation"},
+ {"l%20cation","http://myhost:8888/path/l%20cation"},
+ {"./l%20cation","http://myhost:8888/path/l%20cation"},
+ {"../l%20cation","http://myhost:8888/l%20cation"},
+ };
+
+ for (int i=1;i0);
+ AbstractSessionManager manager=new HashSessionManager();
+ manager.setSessionIdManager(new HashSessionIdManager());
+ request.setSessionManager(manager);
+ request.setSession(new TestSession(manager,"12345"));
+ manager.setCheckingRemoteSessionIdEncoding(false);
- response.sendRedirect("/other/location");
-
- String location = out.getOut().toString();
- int l=location.indexOf("Location: ");
- int e=location.indexOf('\n',l);
- location=location.substring(l+10,e).trim();
-
- assertEquals("http://myhost:8888/other/location;jsessionid=12345",location);
-
+ response.sendRedirect(tests[i][0]);
+
+ String location = out.getOut().toString();
+ int l=location.indexOf("Location: ");
+ int e=location.indexOf('\n',l);
+ location=location.substring(l+10,e).trim();
+ assertEquals(tests[i][0],tests[i][1],location);
+ }
}
@Test
From 790f6be8a6e09929feeb487716c92b1bda17bf3c Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 21 Sep 2011 11:41:43 +1000
Subject: [PATCH 059/134] JETTY-1130 Access Sessions from HashSessionIdManager
---
.../server/session/HashSessionIdManager.java | 30 +++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
index 5e0aea6b457..7624afcf87a 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
@@ -14,7 +14,9 @@
package org.eclipse.jetty.server.session;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -46,6 +48,34 @@ public class HashSessionIdManager extends AbstractSessionIdManager
super(random);
}
+ /* ------------------------------------------------------------ */
+ /**
+ * @return Collection of String session IDs
+ */
+ public Collection getSessions()
+ {
+ return Collections.unmodifiableCollection(_sessions.keySet());
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return Collection of Sessions for the passed session ID
+ */
+ public Collection getSession(String id)
+ {
+ ArrayList sessions = new ArrayList();
+ Set> refs =_sessions.get(id);
+ if (refs!=null)
+ {
+ for (WeakReference ref: refs)
+ {
+ HttpSession session = ref.get();
+ if (session!=null)
+ sessions.add(session);
+ }
+ }
+ return sessions;
+ }
/* ------------------------------------------------------------ */
/** Get the session ID with any worker ID.
*
From ff29a1cc51325ebf4f95feaa4bed847023a7e3fc Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 21 Sep 2011 13:46:48 +1000
Subject: [PATCH 060/134] JETTY-1322 idle sweeper checks for closed endp
---
.../java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
index 161cf194735..d682584c096 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
@@ -251,7 +251,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
public void checkIdleTimestamp(long now)
{
long idleTimestamp=_idleTimestamp;
- if (idleTimestamp!=0 && _maxIdleTime>0 && now>(idleTimestamp+_maxIdleTime))
+ if (!getChannel().isOpen() || idleTimestamp!=0 && _maxIdleTime!=0 && now>(idleTimestamp+_maxIdleTime))
idleExpired();
}
From e15e9ddc99b4961361d2b59c96a7ef90dcb7c1d9 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 21 Sep 2011 16:17:35 +1000
Subject: [PATCH 061/134] JETTY-1377 extra logging for busy selector
---
.../eclipse/jetty/io/nio/SelectorManager.java | 184 ++++--------------
.../org/eclipse/jetty/server/StressTest.java | 6 +-
2 files changed, 45 insertions(+), 145 deletions(-)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
index 2a01ba3d2a4..32a76910e9e 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
@@ -55,12 +55,9 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio");
- // TODO Tune these by approx system speed.
- private static final int __JVMBUG_THRESHHOLD=Integer.getInteger("org.eclipse.jetty.io.nio.JVMBUG_THRESHHOLD",0).intValue();
private static final int __MONITOR_PERIOD=Integer.getInteger("org.eclipse.jetty.io.nio.MONITOR_PERIOD",1000).intValue();
- private static final int __MAX_SELECTS=Integer.getInteger("org.eclipse.jetty.io.nio.MAX_SELECTS",25000).intValue();
+ private static final int __MAX_SELECTS=Integer.getInteger("org.eclipse.jetty.io.nio.MAX_SELECTS",3).intValue();
private static final int __BUSY_PAUSE=Integer.getInteger("org.eclipse.jetty.io.nio.BUSY_PAUSE",50).intValue();
- private static final int __BUSY_KEY=Integer.getInteger("org.eclipse.jetty.io.nio.BUSY_KEY",-1).intValue();
private static final int __IDLE_TICK=Integer.getInteger("org.eclipse.jetty.io.nio.IDLE_TICK",400).intValue();
private int _maxIdleTime;
@@ -389,18 +386,10 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
private volatile Selector _selector;
private volatile Thread _selecting;
- private int _jvmBug;
- private int _selects;
- private long _monitorStart;
+ private int _busySelects;
private long _monitorNext;
private boolean _pausing;
- private SelectionKey _busyKey;
- private int _busyKeyCount;
- private long _log;
- private int _paused;
- private int _jvmFix0;
- private int _jvmFix1;
- private int _jvmFix2;
+ private boolean _paused;
private volatile long _idleTick;
private ConcurrentMap _endPoints = new ConcurrentHashMap();
@@ -415,9 +404,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
// create a selector;
_selector = Selector.open();
- _monitorStart=System.currentTimeMillis();
- _monitorNext=_monitorStart+__MONITOR_PERIOD;
- _log=_monitorStart+60000;
+ _monitorNext=System.currentTimeMillis()+__MONITOR_PERIOD;
}
/* ------------------------------------------------------------ */
@@ -539,7 +526,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
// Do and instant select to see if any connections can be handled.
int selected=selector.selectNow();
- _selects++;
long now=System.currentTimeMillis();
@@ -573,12 +559,36 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
long before=now;
selected=selector.select(wait);
- _selects++;
now = System.currentTimeMillis();
_timeout.setNow(now);
- if (__JVMBUG_THRESHHOLD>0)
- checkJvmBugs(before, now, wait, selected);
+ // If we are monitoring for busy selector
+ // and this select did not wait more than 1ms
+ if (__MONITOR_PERIOD>0 && now-before <=1)
+ {
+ // count this as a busy select and if there have been too many this monitor cycle
+ if (++_busySelects>__MAX_SELECTS)
+ {
+ // Start injecting pauses
+ _pausing=true;
+
+ // if this is the first pause
+ if (!_paused)
+ {
+ // Log and dump some status
+ _paused=true;
+ LOG.warn("Selector {} is too busy, pausing!",this);
+ final SelectSet set = this;
+ SelectorManager.this.dispatch(
+ new Runnable(){
+ public void run()
+ {
+ System.err.println(set+":\n"+set.dump());
+ }
+ });
+ }
+ }
+ }
}
}
@@ -705,6 +715,16 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
}
}
});
+
+ }
+
+ // Reset busy select monitor counts
+ if (__MONITOR_PERIOD>0 && now>_monitorNext)
+ {
+ _busySelects=0;
+ _pausing=false;
+ _monitorNext=now+__MONITOR_PERIOD;
+
}
}
catch (ClosedSelectorException e)
@@ -724,126 +744,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
}
}
- /* ------------------------------------------------------------ */
- private void checkJvmBugs(long before, long now, long wait, int selected)
- throws IOException
- {
- Selector selector = _selector;
- if (selector==null)
- return;
-
- // Look for JVM bugs over a monitor period.
- // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6403933
- // http://bugs.sun.com/view_bug.do?bug_id=6693490
- if (now>_monitorNext)
- {
- _selects=(int)(_selects*__MONITOR_PERIOD/(now-_monitorStart));
- _pausing=_selects>__MAX_SELECTS;
- if (_pausing)
- _paused++;
-
- _selects=0;
- _jvmBug=0;
- _monitorStart=now;
- _monitorNext=now+__MONITOR_PERIOD;
- }
-
- if (now>_log)
- {
- if (_paused>0)
- LOG.debug(this+" Busy selector - injecting delay "+_paused+" times");
-
- if (_jvmFix2>0)
- LOG.debug(this+" JVM BUG(s) - injecting delay"+_jvmFix2+" times");
-
- if (_jvmFix1>0)
- LOG.debug(this+" JVM BUG(s) - recreating selector "+_jvmFix1+" times, cancelled keys "+_jvmFix0+" times");
-
- else if(LOG.isDebugEnabled() && _jvmFix0>0)
- LOG.debug(this+" JVM BUG(s) - cancelled keys "+_jvmFix0+" times");
- _paused=0;
- _jvmFix2=0;
- _jvmFix1=0;
- _jvmFix0=0;
- _log=now+60000;
- }
-
- // If we see signature of possible JVM bug, increment count.
- if (selected==0 && wait>10 && (now-before)<(wait/2))
- {
- // Increment bug count and try a work around
- _jvmBug++;
- if (_jvmBug>(__JVMBUG_THRESHHOLD))
- {
- try
- {
- if (_jvmBug==__JVMBUG_THRESHHOLD+1)
- _jvmFix2++;
-
- Thread.sleep(__BUSY_PAUSE); // pause to avoid busy loop
- }
- catch(InterruptedException e)
- {
- LOG.ignore(e);
- }
- }
- else if (_jvmBug==__JVMBUG_THRESHHOLD)
- {
- renewSelector();
- }
- else if (_jvmBug%32==31) // heuristic attempt to cancel key 31,63,95,... loops
- {
- // Cancel keys with 0 interested ops
- int cancelled=0;
- for (SelectionKey k: selector.keys())
- {
- if (k.isValid()&&k.interestOps()==0)
- {
- k.cancel();
- cancelled++;
- }
- }
- if (cancelled>0)
- _jvmFix0++;
-
- return;
- }
- }
- else if (__BUSY_KEY>0 && selected==1 && _selects>__MAX_SELECTS)
- {
- // Look for busy key
- SelectionKey busy = selector.selectedKeys().iterator().next();
- if (busy==_busyKey)
- {
- if (++_busyKeyCount>__BUSY_KEY && !(busy.channel() instanceof ServerSocketChannel))
- {
- final SelectChannelEndPoint endpoint = (SelectChannelEndPoint)busy.attachment();
- LOG.warn("Busy Key "+busy.channel()+" "+endpoint);
- busy.cancel();
- if (endpoint!=null)
- {
- dispatch(new Runnable()
- {
- public void run()
- {
- try
- {
- endpoint.close();
- }
- catch (IOException e)
- {
- LOG.ignore(e);
- }
- }
- });
- }
- }
- }
- else
- _busyKeyCount=0;
- _busyKey=busy;
- }
- }
/* ------------------------------------------------------------ */
private void renewSelector()
@@ -1044,7 +944,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
final CountDownLatch latch = new CountDownLatch(1);
- addChange(new Runnable(){
+ addChange(new ChangeTask(){
public void run()
{
dumpKeyState(dump);
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java
index ccf1dcf1ac5..0c46f2a3615 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java
@@ -91,7 +91,7 @@ public class StressTest
_server.setThreadPool(_threads);
_connector = new SelectChannelConnector();
- _connector.setAcceptors(Math.max(1, Runtime.getRuntime().availableProcessors() / 2));
+ _connector.setAcceptors(1);
_connector.setAcceptQueueSize(5000);
_connector.setMaxIdleTime(30000);
_server.addConnector(_connector);
@@ -123,7 +123,7 @@ public class StressTest
// TODO needs to be further investigated
assumeTrue(!OS.IS_OSX || Stress.isEnabled());
- doThreads(10,100,false);
+ doThreads(10,10,false);
if (Stress.isEnabled())
{
Thread.sleep(1000);
@@ -139,7 +139,7 @@ public class StressTest
// TODO needs to be further investigated
assumeTrue(!OS.IS_OSX || Stress.isEnabled());
- doThreads(20,100,true);
+ doThreads(20,10,true);
if (Stress.isEnabled())
{
Thread.sleep(1000);
From 6bebdceb3a3bec1b15032f19b1c35965f09c9468 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 21 Sep 2011 16:45:32 +1000
Subject: [PATCH 062/134] JETTY-1377 extra logging for busy selector
---
.../main/java/org/eclipse/jetty/io/nio/SelectorManager.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
index 32a76910e9e..dfb8141d61c 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
@@ -48,15 +48,13 @@ import org.eclipse.jetty.util.thread.Timeout.Task;
* The Selector Manager manages and number of SelectSets to allow
* NIO scheduling to scale to large numbers of connections.
*