Merge branch 'master' into jetty-8

This commit is contained in:
Jesse McConnell 2012-02-15 13:49:23 -06:00
commit 098428dd37
47 changed files with 587 additions and 375 deletions

View File

@ -1,8 +1,6 @@
==============================================================
Jetty Web Container
Copyright 1995-2009 Mort Bay Consulting Pty Ltd
2009-2012 Webtide LLC
2011-2012 Intalio Inc
Copyright 1995-2012 Mort Bay Consulting Pty Ltd.
==============================================================
The Jetty Web Container is Copyright Mort Bay Consulting Pty Ltd

View File

@ -37,7 +37,7 @@
<configuration>
<classifier>sources</classifier>
<includes>**/*</includes>
<excludes>META-INF/**</excludes>
<excludes>META-INF/**,**/Servlet3Continuation*,**/Jetty6Continuation*</excludes>
<includeGroupIds>org.eclipse.jetty</includeGroupIds>
<excludeArtifactIds>javax</excludeArtifactIds>
<excludeGroupIds>javax,org.eclipse.jetty.orbit</excludeGroupIds>
@ -170,5 +170,11 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -31,14 +31,6 @@
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<verbose>false</verbose>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>

View File

@ -30,7 +30,6 @@ public class TestSPIServer
new HttpHandler()
{
@Override
public void handle(HttpExchange exchange) throws IOException
{
Headers responseHeaders = exchange.getResponseHeaders();

View File

@ -105,7 +105,7 @@ public class HttpGenerator extends AbstractGenerator
}
// data
private boolean _bypass = false; // True if _content buffer can be written directly to endp and bypass the content buffer
protected boolean _bypass = false; // True if _content buffer can be written directly to endp and bypass the content buffer
private boolean _needCRLF = false;
private boolean _needEOC = false;
private boolean _bufferChunked = false;

View File

@ -13,6 +13,7 @@
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<!-- Jetty 7 is JDK5 +
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
@ -21,6 +22,7 @@
<verbose>false</verbose>
</configuration>
</plugin>
-->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>

View File

@ -16,6 +16,8 @@ import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.server.session.AbstractSession;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -33,9 +35,9 @@ public class NoSqlSession extends AbstractSession
private long _lastSync;
/* ------------------------------------------------------------ */
public NoSqlSession(NoSqlSessionManager manager, long created, long accessed, String clusterId)
public NoSqlSession(NoSqlSessionManager manager, HttpServletRequest request)
{
super(manager, created,accessed,clusterId);
super(manager, request);
_manager=manager;
save(true);
_active.incrementAndGet();

View File

@ -117,8 +117,7 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme
protected AbstractSession newSession(HttpServletRequest request)
{
long created=System.currentTimeMillis();
String clusterId=getSessionIdManager().newSessionId(request,created);
return new NoSqlSession(this,created,created,clusterId);
return new NoSqlSession(this,request);
}
/* ------------------------------------------------------------ */

View File

@ -61,7 +61,9 @@ public class MongoSessionIdManager extends AbstractSessionIdManager
final static DBObject __version_1 = new BasicDBObject(MongoSessionManager.__VERSION,1);
final static DBObject __valid_false = new BasicDBObject(MongoSessionManager.__VALID,false);
final static DBObject __valid_true = new BasicDBObject(MongoSessionManager.__VALID,true);
final DBCollection _sessions;
protected Server _server;
private Timer _scavengeTimer;
@ -429,16 +431,15 @@ public class MongoSessionIdManager extends AbstractSessionIdManager
/**
* is the session id known to mongo, and is it valid
*/
@Override
public boolean idInUse(String sessionId)
{
/*
* optimize this query to only return the valid variable
*/
DBObject o = _sessions.findOne(new BasicDBObject("id",sessionId), __valid_false);
DBObject o = _sessions.findOne(new BasicDBObject("id",sessionId), __valid_true);
if ( o != null )
{
{
Boolean valid = (Boolean)o.get(MongoSessionManager.__VALID);
if ( valid == null )
@ -453,7 +454,6 @@ public class MongoSessionIdManager extends AbstractSessionIdManager
}
/* ------------------------------------------------------------ */
@Override
public void addSession(HttpSession session)
{
if (session == null)
@ -475,7 +475,6 @@ public class MongoSessionIdManager extends AbstractSessionIdManager
}
/* ------------------------------------------------------------ */
@Override
public void removeSession(HttpSession session)
{
if (session == null)
@ -490,7 +489,6 @@ public class MongoSessionIdManager extends AbstractSessionIdManager
}
/* ------------------------------------------------------------ */
@Override
public void invalidateAll(String sessionId)
{
synchronized (_sessionsIds)
@ -519,7 +517,6 @@ public class MongoSessionIdManager extends AbstractSessionIdManager
/* ------------------------------------------------------------ */
// TODO not sure if this is correct
@Override
public String getClusterId(String nodeId)
{
int dot=nodeId.lastIndexOf('.');
@ -528,7 +525,6 @@ public class MongoSessionIdManager extends AbstractSessionIdManager
/* ------------------------------------------------------------ */
// TODO not sure if this is correct
@Override
public String getNodeId(String clusterId, HttpServletRequest request)
{
if (_workerName!=null)

View File

@ -118,7 +118,6 @@ public class MongoSessionManager extends NoSqlSessionManager
// Form query for upsert
BasicDBObject key = new BasicDBObject(__ID,session.getClusterId());
key.put(__VALID,true);
// Form updates
BasicDBObject update = new BasicDBObject();
@ -133,6 +132,7 @@ public class MongoSessionManager extends NoSqlSessionManager
upsert = true;
version = new Long(1);
sets.put(__CREATED,session.getCreationTime());
sets.put(__VALID,true);
sets.put(getContextKey(__VERSION),version);
}
else

View File

@ -503,15 +503,18 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti
previousIdentity = deferred.getPreviousAssociation();
deferred.setIdentityService(null);
}
Authentication auth=baseRequest.getAuthentication();
if (auth instanceof Authentication.User)
if (authenticator!=null)
{
Authentication.User userAuth = (Authentication.User)auth;
authenticator.secureResponse(request, response, isAuthMandatory, userAuth);
Authentication auth=baseRequest.getAuthentication();
if (auth instanceof Authentication.User)
{
Authentication.User userAuth = (Authentication.User)auth;
authenticator.secureResponse(request, response, isAuthMandatory, userAuth);
}
else
authenticator.secureResponse(request, response, isAuthMandatory, null);
}
else
authenticator.secureResponse(request, response, isAuthMandatory, null);
}
else
{

View File

@ -18,6 +18,7 @@ import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.atomic.AtomicLong;
import javax.servlet.ServletRequest;
import org.eclipse.jetty.http.HttpBuffers;
@ -30,7 +31,6 @@ import org.eclipse.jetty.io.Buffers.Type;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.AggregateLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
@ -49,8 +49,6 @@ import org.eclipse.jetty.util.thread.ThreadPool;
* <li>Base acceptor thread</li>
* <li>Optional reverse proxy headers checking</li>
* </ul>
*
*
*/
public abstract class AbstractConnector extends AggregateLifeCycle implements HttpBuffers, Connector, Dumpable
{
@ -130,7 +128,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht
/** Set the ThreadPool.
* The threadpool passed is added via {@link #addBean(Object)} so that
* it's lifecycle may be managed as a {@link AggregateLifeCycle}.
* @param threadPool the threadPool to set
* @param pool the threadPool to set
*/
public void setThreadPool(ThreadPool pool)
{
@ -225,6 +223,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht
* @return Returns the maxIdleTime when resources are low.
* @deprecated
*/
@Deprecated
public final int getLowResourceMaxIdleTime()
{
return getLowResourcesMaxIdleTime();
@ -236,6 +235,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht
* The maxIdleTime to set when resources are low.
* @deprecated
*/
@Deprecated
public final void setLowResourceMaxIdleTime(int maxIdleTime)
{
setLowResourcesMaxIdleTime(maxIdleTime);
@ -639,10 +639,10 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht
*
* @param check
* true if this connector is checking the x-forwarded-for/host/server headers
* @set {@link #setForwardedForHeader(String)}
* @set {@link #setForwardedHostHeader(String)}
* @set {@link #setForwardedProtoHeader(String)}
* @set {@link #setForwardedServerHeader(String)}
* @see #setForwardedForHeader(String)
* @see #setForwardedHostHeader(String)
* @see #setForwardedProtoHeader(String)
* @see #setForwardedServerHeader(String)
*/
public void setForwarded(boolean check)
{

View File

@ -118,6 +118,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
private int _version = UNKNOWN;
private String _charset;
private boolean _expect = false;
private boolean _expect100Continue = false;
private boolean _expect102Processing = false;
@ -138,9 +139,6 @@ public abstract class AbstractHttpConnection extends AbstractConnection
}
/* ------------------------------------------------------------ */
/** Constructor
*
*/
public AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server)
{
super(endpoint);
@ -152,7 +150,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
_responseFields = new HttpFields(server.getMaxCookieVersion());
_request = new Request(this);
_response = new Response(this);
_generator = new HttpGenerator(ab.getResponseBuffers(), _endp);
_generator = newHttpGenerator(ab.getResponseBuffers(), endpoint);
_generator.setSendServerVersion(server.getSendServerVersion());
_server = server;
}
@ -180,6 +178,11 @@ public abstract class AbstractHttpConnection extends AbstractConnection
return new HttpParser(requestBuffers, endpoint, requestHandler);
}
protected HttpGenerator newHttpGenerator(Buffers responseBuffers, EndPoint endPoint)
{
return new HttpGenerator(responseBuffers, endPoint);
}
/* ------------------------------------------------------------ */
/**
* @return the parser used by this connection
@ -251,28 +254,26 @@ public abstract class AbstractHttpConnection extends AbstractConnection
/* ------------------------------------------------------------ */
/**
* @return The result of calling {@link #getConnector}.{@link Connector#isConfidential(Request) isCondidential}(request), or false
* if there is no connector.
* Find out if the request supports CONFIDENTIAL security.
* @param request the incoming HTTP request
* @return the result of calling {@link Connector#isConfidential(Request)}, or false
* if there is no connector
*/
public boolean isConfidential(Request request)
{
if (_connector!=null)
return _connector.isConfidential(request);
return false;
return _connector != null && _connector.isConfidential(request);
}
/* ------------------------------------------------------------ */
/**
* Find out if the request is INTEGRAL security.
* @param request
* @return <code>true</code> if there is a {@link #getConnector() connector} and it considers <code>request</code>
* to be {@link Connector#isIntegral(Request) integral}
* Find out if the request supports INTEGRAL security.
* @param request the incoming HTTP request
* @return the result of calling {@link Connector#isIntegral(Request)}, or false
* if there is no connector
*/
public boolean isIntegral(Request request)
{
if (_connector!=null)
return _connector.isIntegral(request);
return false;
return _connector != null && _connector.isIntegral(request);
}
/* ------------------------------------------------------------ */
@ -312,6 +313,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
*
* @return The input stream for this connection.
* The stream will be created if it does not already exist.
* @throws IOException if the input stream cannot be retrieved
*/
public ServletInputStream getInputStream() throws IOException
{
@ -347,6 +349,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
/* ------------------------------------------------------------ */
/**
* @param encoding the PrintWriter encoding
* @return A {@link PrintWriter} wrapping the {@link #getOutputStream output stream}. The writer is created if it
* does not already exist.
*/
@ -562,10 +565,6 @@ public abstract class AbstractHttpConnection extends AbstractConnection
_generator.setPersistent(false);
_generator.completeHeader(_responseFields, last);
}
catch(IOException io)
{
throw io;
}
catch(RuntimeException e)
{
LOG.warn("header full: " + e);
@ -593,10 +592,6 @@ public abstract class AbstractHttpConnection extends AbstractConnection
{
_generator.completeHeader(_responseFields, Generator.LAST);
}
catch(IOException io)
{
throw io;
}
catch(RuntimeException e)
{
LOG.warn("header full: "+e);
@ -707,13 +702,219 @@ public abstract class AbstractHttpConnection extends AbstractConnection
_requests);
}
protected void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
{
uri=uri.asImmutableBuffer();
_host = false;
_expect = false;
_expect100Continue=false;
_expect102Processing=false;
_delayedHandling=false;
_charset=null;
if(_request.getTimeStamp()==0)
_request.setTimeStamp(System.currentTimeMillis());
_request.setMethod(method.toString());
try
{
_head=false;
switch (HttpMethods.CACHE.getOrdinal(method))
{
case HttpMethods.CONNECT_ORDINAL:
_uri.parseConnect(uri.array(), uri.getIndex(), uri.length());
break;
case HttpMethods.HEAD_ORDINAL:
_head=true;
_uri.parse(uri.array(), uri.getIndex(), uri.length());
break;
default:
_uri.parse(uri.array(), uri.getIndex(), uri.length());
}
_request.setUri(_uri);
if (version==null)
{
_request.setProtocol(HttpVersions.HTTP_0_9);
_version=HttpVersions.HTTP_0_9_ORDINAL;
}
else
{
version= HttpVersions.CACHE.get(version);
if (version==null)
throw new HttpException(HttpStatus.BAD_REQUEST_400,null);
_version = HttpVersions.CACHE.getOrdinal(version);
if (_version <= 0) _version = HttpVersions.HTTP_1_0_ORDINAL;
_request.setProtocol(version.toString());
}
}
catch (Exception e)
{
LOG.debug(e);
if (e instanceof HttpException)
throw (HttpException)e;
throw new HttpException(HttpStatus.BAD_REQUEST_400,null,e);
}
}
protected void parsedHeader(Buffer name, Buffer value) throws IOException
{
int ho = HttpHeaders.CACHE.getOrdinal(name);
switch (ho)
{
case HttpHeaders.HOST_ORDINAL:
// TODO check if host matched a host in the URI.
_host = true;
break;
case HttpHeaders.EXPECT_ORDINAL:
value = HttpHeaderValues.CACHE.lookup(value);
switch(HttpHeaderValues.CACHE.getOrdinal(value))
{
case HttpHeaderValues.CONTINUE_ORDINAL:
_expect100Continue=_generator instanceof HttpGenerator;
break;
case HttpHeaderValues.PROCESSING_ORDINAL:
_expect102Processing=_generator instanceof HttpGenerator;
break;
default:
String[] values = value.toString().split(",");
for (int i=0;values!=null && i<values.length;i++)
{
CachedBuffer cb=HttpHeaderValues.CACHE.get(values[i].trim());
if (cb==null)
_expect=true;
else
{
switch(cb.getOrdinal())
{
case HttpHeaderValues.CONTINUE_ORDINAL:
_expect100Continue=_generator instanceof HttpGenerator;
break;
case HttpHeaderValues.PROCESSING_ORDINAL:
_expect102Processing=_generator instanceof HttpGenerator;
break;
default:
_expect=true;
}
}
}
}
break;
case HttpHeaders.ACCEPT_ENCODING_ORDINAL:
case HttpHeaders.USER_AGENT_ORDINAL:
value = HttpHeaderValues.CACHE.lookup(value);
break;
case HttpHeaders.CONTENT_TYPE_ORDINAL:
value = MimeTypes.CACHE.lookup(value);
_charset=MimeTypes.getCharsetFromContentType(value);
break;
}
_requestFields.add(name, value);
}
protected void headerComplete() throws IOException
{
_requests++;
_generator.setVersion(_version);
switch (_version)
{
case HttpVersions.HTTP_0_9_ORDINAL:
break;
case HttpVersions.HTTP_1_0_ORDINAL:
_generator.setHead(_head);
if (_parser.isPersistent())
{
_responseFields.add(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.KEEP_ALIVE_BUFFER);
_generator.setPersistent(true);
}
else if (HttpMethods.CONNECT.equals(_request.getMethod()))
{
_generator.setPersistent(true);
_parser.setPersistent(true);
}
if (_server.getSendDateHeader())
_generator.setDate(_request.getTimeStampBuffer());
break;
case HttpVersions.HTTP_1_1_ORDINAL:
_generator.setHead(_head);
if (!_parser.isPersistent())
{
_responseFields.add(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER);
_generator.setPersistent(false);
}
if (_server.getSendDateHeader())
_generator.setDate(_request.getTimeStampBuffer());
if (!_host)
{
LOG.debug("!host {}",this);
_generator.setResponse(HttpStatus.BAD_REQUEST_400, null);
_responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
_generator.completeHeader(_responseFields, true);
_generator.complete();
return;
}
if (_expect)
{
LOG.debug("!expectation {}",this);
_generator.setResponse(HttpStatus.EXPECTATION_FAILED_417, null);
_responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
_generator.completeHeader(_responseFields, true);
_generator.complete();
return;
}
break;
default:
}
if(_charset!=null)
_request.setCharacterEncodingUnchecked(_charset);
// Either handle now or wait for first content
if ((((HttpParser)_parser).getContentLength()<=0 && !((HttpParser)_parser).isChunking())||_expect100Continue)
handleRequest();
else
_delayedHandling=true;
}
protected void content(Buffer buffer) throws IOException
{
if (_delayedHandling)
{
_delayedHandling=false;
handleRequest();
}
}
public void messageComplete(long contentLength) throws IOException
{
if (_delayedHandling)
{
_delayedHandling=false;
handleRequest();
}
}
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
private class RequestHandler extends HttpParser.EventHandler
{
private String _charset;
/*
*
* @see org.eclipse.jetty.server.server.HttpParser.EventHandler#startRequest(org.eclipse.io.Buffer,
@ -722,126 +923,16 @@ public abstract class AbstractHttpConnection extends AbstractConnection
@Override
public void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
{
uri=uri.asImmutableBuffer();
_host = false;
_expect = false;
_expect100Continue=false;
_expect102Processing=false;
_delayedHandling=false;
_charset=null;
if(_request.getTimeStamp()==0)
_request.setTimeStamp(System.currentTimeMillis());
_request.setMethod(method.toString());
try
{
_head=false;
switch (HttpMethods.CACHE.getOrdinal(method))
{
case HttpMethods.CONNECT_ORDINAL:
_uri.parseConnect(uri.array(), uri.getIndex(), uri.length());
break;
case HttpMethods.HEAD_ORDINAL:
_head=true;
_uri.parse(uri.array(), uri.getIndex(), uri.length());
break;
default:
_uri.parse(uri.array(), uri.getIndex(), uri.length());
}
_request.setUri(_uri);
if (version==null)
{
_request.setProtocol(HttpVersions.HTTP_0_9);
_version=HttpVersions.HTTP_0_9_ORDINAL;
}
else
{
version= HttpVersions.CACHE.get(version);
if (version==null)
throw new HttpException(HttpStatus.BAD_REQUEST_400,null);
_version = HttpVersions.CACHE.getOrdinal(version);
if (_version <= 0) _version = HttpVersions.HTTP_1_0_ORDINAL;
_request.setProtocol(version.toString());
}
}
catch (Exception e)
{
LOG.debug(e);
if (e instanceof HttpException)
throw (HttpException)e;
throw new HttpException(HttpStatus.BAD_REQUEST_400,null,e);
}
AbstractHttpConnection.this.startRequest(method, uri, version);
}
/*
* @see org.eclipse.jetty.server.server.HttpParser.EventHandler#parsedHeaderValue(org.eclipse.io.Buffer)
*/
@Override
public void parsedHeader(Buffer name, Buffer value)
public void parsedHeader(Buffer name, Buffer value) throws IOException
{
int ho = HttpHeaders.CACHE.getOrdinal(name);
switch (ho)
{
case HttpHeaders.HOST_ORDINAL:
// TODO check if host matched a host in the URI.
_host = true;
break;
case HttpHeaders.EXPECT_ORDINAL:
value = HttpHeaderValues.CACHE.lookup(value);
switch(HttpHeaderValues.CACHE.getOrdinal(value))
{
case HttpHeaderValues.CONTINUE_ORDINAL:
_expect100Continue=_generator instanceof HttpGenerator;
break;
case HttpHeaderValues.PROCESSING_ORDINAL:
_expect102Processing=_generator instanceof HttpGenerator;
break;
default:
String[] values = value.toString().split(",");
for (int i=0;values!=null && i<values.length;i++)
{
CachedBuffer cb=HttpHeaderValues.CACHE.get(values[i].trim());
if (cb==null)
_expect=true;
else
{
switch(cb.getOrdinal())
{
case HttpHeaderValues.CONTINUE_ORDINAL:
_expect100Continue=_generator instanceof HttpGenerator;
break;
case HttpHeaderValues.PROCESSING_ORDINAL:
_expect102Processing=_generator instanceof HttpGenerator;
break;
default:
_expect=true;
}
}
}
}
break;
case HttpHeaders.ACCEPT_ENCODING_ORDINAL:
case HttpHeaders.USER_AGENT_ORDINAL:
value = HttpHeaderValues.CACHE.lookup(value);
break;
case HttpHeaders.CONTENT_TYPE_ORDINAL:
value = MimeTypes.CACHE.lookup(value);
_charset=MimeTypes.getCharsetFromContentType(value);
break;
}
_requestFields.add(name, value);
AbstractHttpConnection.this.parsedHeader(name, value);
}
/*
@ -850,72 +941,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
@Override
public void headerComplete() throws IOException
{
_requests++;
_generator.setVersion(_version);
switch (_version)
{
case HttpVersions.HTTP_0_9_ORDINAL:
break;
case HttpVersions.HTTP_1_0_ORDINAL:
_generator.setHead(_head);
if (_parser.isPersistent())
{
_responseFields.add(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.KEEP_ALIVE_BUFFER);
_generator.setPersistent(true);
}
else if (HttpMethods.CONNECT.equals(_request.getMethod()))
{
_generator.setPersistent(true);
_parser.setPersistent(true);
}
if (_server.getSendDateHeader())
_generator.setDate(_request.getTimeStampBuffer());
break;
case HttpVersions.HTTP_1_1_ORDINAL:
_generator.setHead(_head);
if (!_parser.isPersistent())
{
_responseFields.add(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER);
_generator.setPersistent(false);
}
if (_server.getSendDateHeader())
_generator.setDate(_request.getTimeStampBuffer());
if (!_host)
{
LOG.debug("!host {}",this);
_generator.setResponse(HttpStatus.BAD_REQUEST_400, null);
_responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
_generator.completeHeader(_responseFields, true);
_generator.complete();
return;
}
if (_expect)
{
LOG.debug("!expectation {}",this);
_generator.setResponse(HttpStatus.EXPECTATION_FAILED_417, null);
_responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
_generator.completeHeader(_responseFields, true);
_generator.complete();
return;
}
break;
default:
}
if(_charset!=null)
_request.setCharacterEncodingUnchecked(_charset);
// Either handle now or wait for first content
if ((((HttpParser)_parser).getContentLength()<=0 && !((HttpParser)_parser).isChunking())||_expect100Continue)
handleRequest();
else
_delayedHandling=true;
AbstractHttpConnection.this.headerComplete();
}
/* ------------------------------------------------------------ */
@ -925,11 +951,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
@Override
public void content(Buffer ref) throws IOException
{
if (_delayedHandling)
{
_delayedHandling=false;
handleRequest();
}
AbstractHttpConnection.this.content(ref);
}
/* ------------------------------------------------------------ */
@ -941,11 +963,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
@Override
public void messageComplete(long contentLength) throws IOException
{
if (_delayedHandling)
{
_delayedHandling=false;
handleRequest();
}
AbstractHttpConnection.this.messageComplete(contentLength);
}
/* ------------------------------------------------------------ */
@ -961,10 +979,8 @@ public abstract class AbstractHttpConnection extends AbstractConnection
if (LOG.isDebugEnabled())
LOG.debug("Bad request!: "+version+" "+status+" "+reason);
}
}
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */

View File

@ -25,6 +25,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.http.HttpContent;
import org.eclipse.jetty.http.HttpContent.ResourceAsHttpContent;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.Buffer;
@ -172,7 +173,7 @@ public class ResourceCache
* @param pathInContext The key into the cache
* @return The entry matching <code>pathInContext</code>, or a new entry
* if no matching entry was found. If the content exists but is not cachable,
* then a {@link HttpContent.ResourceAsHttpContent} instance is return. If
* then a {@link ResourceAsHttpContent} instance is return. If
* the resource does not exist, then null is returned.
* @throws IOException Problem loading the resource
*/
@ -337,6 +338,7 @@ public class ResourceCache
}
/* ------------------------------------------------------------ */
@Override
public String toString()
{
return "ResourceCache["+_parent+","+_factory+"]@"+hashCode();

View File

@ -61,6 +61,10 @@ public class HashSessionManager extends AbstractSessionManager
File _storeDir;
private boolean _lazyLoad=false;
private volatile boolean _sessionsLoaded=false;
private boolean _deleteUnrestorableSessions=false;
/* ------------------------------------------------------------ */
public HashSessionManager()
@ -434,6 +438,18 @@ public class HashSessionManager extends AbstractSessionManager
{
return _lazyLoad;
}
/* ------------------------------------------------------------ */
public boolean isDeleteUnrestorableSessions()
{
return _deleteUnrestorableSessions;
}
/* ------------------------------------------------------------ */
public void setDeleteUnrestorableSessions(boolean deleteUnrestorableSessions)
{
_deleteUnrestorableSessions = deleteUnrestorableSessions;
}
/* ------------------------------------------------------------ */
public void restoreSessions () throws Exception
@ -461,9 +477,9 @@ public class HashSessionManager extends AbstractSessionManager
/* ------------------------------------------------------------ */
protected synchronized HashedSession restoreSession(String idInCuster)
{
File file = new File(_storeDir,idInCuster);
try
{
File file = new File(_storeDir,idInCuster);
if (file.exists())
{
FileInputStream in = new FileInputStream(file);
@ -477,7 +493,18 @@ public class HashSessionManager extends AbstractSessionManager
}
catch (Exception e)
{
__log.warn("Problem restoring session "+idInCuster, e);
if (isDeleteUnrestorableSessions())
{
if (file.exists())
{
file.delete();
__log.warn("Deleting file for unrestorable session "+idInCuster, e);
}
}
else
__log.warn("Problem restoring session "+idInCuster, e);
}
return null;
}

View File

@ -358,7 +358,6 @@ public class UrlEncoded extends MultiMap implements Cloneable
/** Decoded parameters to Map.
* @param in InputSteam to read
* @param map MultiMap to add parameters to
* @param maxLength maximum length of content to read or -1 for no limit
* @param maxLength maximum number of keys to read or -1 for no limit
*/
public static void decode88591To(InputStream in, MultiMap map, int maxLength, int maxKeys)
@ -444,7 +443,6 @@ public class UrlEncoded extends MultiMap implements Cloneable
/** Decoded parameters to Map.
* @param in InputSteam to read
* @param map MultiMap to add parameters to
* @param maxLength maximum length of content to read or -1 for no limit
* @param maxLength maximum number of keys to read or -1 for no limit
*/
public static void decodeUtf8To(InputStream in, MultiMap map, int maxLength, int maxKeys)

View File

@ -15,13 +15,13 @@ import org.eclipse.jetty.util.log.Logger;
* An AggregateLifeCycle is an {@link LifeCycle} implementation for a collection of contained beans.
* <p>
* Beans can be added the AggregateLifeCycle either as managed beans or as unmanaged beans. A managed bean is started, stopped and destroyed with the aggregate.
* An umanaged bean is associated with the aggregate for the purposes of {@link #dump()}, but it's lifecycle must be managed externally.
* An unmanaged bean is associated with the aggregate for the purposes of {@link #dump()}, but it's lifecycle must be managed externally.
* <p>
* When a bean is added, if it is a {@link LifeCycle} and it is already started, then it is assumed to be an unmanaged bean.
* Otherwise the methods {@link #addBean(LifeCycle, boolean)}, {@link #manage(LifeCycle)} and {@link #unmanage(LifeCycle)} can be used to
* Otherwise the methods {@link #addBean(Object, boolean)}, {@link #manage(Object)} and {@link #unmanage(Object)} can be used to
* explicitly control the life cycle relationship.
* <p>
* If adding a bean that is shared between multiple {@link AggregateLifeCycle} instances, then it should be started before being added, so it is unmanged, or
* If adding a bean that is shared between multiple {@link AggregateLifeCycle} instances, then it should be started before being added, so it is unmanaged, or
* the API must be used to explicitly set it as unmanaged.
* <p>
*/
@ -154,7 +154,7 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
/** Add an associated lifecycle.
* @param o The lifecycle to add
* @param managed True if the LifeCycle is to be joined, otherwise it will be disjoint.
* @return
* @return true if bean was added, false if already present.
*/
public boolean addBean(Object o, boolean managed)
{

View File

@ -35,7 +35,7 @@ import java.security.cert.X509CertSelector;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.net.ssl.CertPathTrustManagerParameters;
@ -86,7 +86,7 @@ public class SslContextFactory extends AbstractLifeCycle
{
}
}};
private static final Logger LOG = Log.getLogger(SslContextFactory.class);
public static final String DEFAULT_KEYMANAGERFACTORY_ALGORITHM =
@ -107,13 +107,12 @@ public class SslContextFactory extends AbstractLifeCycle
public static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password";
/** Excluded protocols. */
private final Set<String> _excludeProtocols = new HashSet<String>();
// private final Set<String> _excludeProtocols = new HashSet<String>(Collections.singleton("SSLv2Hello"));
private final Set<String> _excludeProtocols = new LinkedHashSet<String>();
/** Included protocols. */
private Set<String> _includeProtocols = null;
/** Excluded cipher suites. */
private final Set<String> _excludeCipherSuites = new HashSet<String>();
private final Set<String> _excludeCipherSuites = new LinkedHashSet<String>();
/** Included cipher suites. */
private Set<String> _includeCipherSuites = null;
@ -210,6 +209,8 @@ public class SslContextFactory extends AbstractLifeCycle
/**
* Construct an instance of SslContextFactory
* Default constructor for use in XmlConfiguration files
* @param trustAll whether to blindly trust all certificates
* @see #setTrustAll(boolean)
*/
public SslContextFactory(boolean trustAll)
{
@ -313,7 +314,7 @@ public class SslContextFactory extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
* @param Protocols
* @param protocols
* The array of protocol names to exclude from
* {@link SSLEngine#setEnabledProtocols(String[])}
*/
@ -347,7 +348,7 @@ public class SslContextFactory extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
* @param Protocols
* @param protocols
* The array of protocol names to include in
* {@link SSLEngine#setEnabledProtocols(String[])}
*/
@ -355,7 +356,7 @@ public class SslContextFactory extends AbstractLifeCycle
{
checkNotStarted();
_includeProtocols = new HashSet<String>(Arrays.asList(protocols));
_includeProtocols = new LinkedHashSet<String>(Arrays.asList(protocols));
}
/* ------------------------------------------------------------ */
@ -411,7 +412,7 @@ public class SslContextFactory extends AbstractLifeCycle
{
checkNotStarted();
_includeCipherSuites = new HashSet<String>(Arrays.asList(cipherSuites));
_includeCipherSuites = new LinkedHashSet<String>(Arrays.asList(cipherSuites));
}
/* ------------------------------------------------------------ */
@ -444,7 +445,7 @@ public class SslContextFactory extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
* @param keyStorePath
* @param keyStorePath the file system path or URL of the keystore
* @deprecated Use {@link #setKeyStorePath(String)}
*/
@Deprecated
@ -1003,7 +1004,7 @@ public class SslContextFactory extends AbstractLifeCycle
* Override this method to provide alternate way to load a keystore.
*
* @return the key store instance
* @throws Exception
* @throws Exception if the keystore cannot be loaded
*/
protected KeyStore loadKeyStore() throws Exception
{
@ -1017,7 +1018,7 @@ public class SslContextFactory extends AbstractLifeCycle
* Override this method to provide alternate way to load a truststore.
*
* @return the key store instance
* @throws Exception
* @throws Exception if the truststore cannot be loaded
*/
protected KeyStore loadTrustStore() throws Exception
{
@ -1040,7 +1041,7 @@ public class SslContextFactory extends AbstractLifeCycle
* @param storeProvider keystore provider
* @param storePassword keystore password
* @return created keystore
* @throws Exception
* @throws Exception if the keystore cannot be obtained
*
* @deprecated
*/
@ -1059,7 +1060,7 @@ public class SslContextFactory extends AbstractLifeCycle
*
* @param crlPath path of certificate revocation list file
* @return Collection of CRL's
* @throws Exception
* @throws Exception if the certificate revocation list cannot be loaded
*/
protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception
{
@ -1199,16 +1200,16 @@ public class SslContextFactory extends AbstractLifeCycle
/* ------------------------------------------------------------ */
/**
* Select cipher suites to be used by the connector
* Select protocols to be used by the connector
* based on configured inclusion and exclusion lists
* as well as enabled and supported cipher suite lists.
* @param enabledCipherSuites Array of enabled cipher suites
* @param supportedCipherSuites Array of supported cipher suites
* @return Array of cipher suites to enable
* as well as enabled and supported protocols.
* @param enabledProtocols Array of enabled protocols
* @param supportedProtocols Array of supported protocols
* @return Array of protocols to enable
*/
public String[] selectProtocols(String[] enabledProtocols, String[] supportedProtocols)
{
Set<String> selected_protocols = new HashSet<String>();
Set<String> selected_protocols = new LinkedHashSet<String>();
// Set the starting protocols - either from the included or enabled list
if (_includeProtocols!=null)
@ -1240,7 +1241,7 @@ public class SslContextFactory extends AbstractLifeCycle
*/
public String[] selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites)
{
Set<String> selected_ciphers = new HashSet<String>();
Set<String> selected_ciphers = new LinkedHashSet<String>();
// Set the starting ciphers - either from the included or enabled list
if (_includeCipherSuites!=null)

View File

@ -38,7 +38,7 @@ public interface Ordering
/**
* AbsoluteOrdering
*
* An <absolute-order> element in web.xml
* An &lt;absolute-order&gt; element in web.xml
*/
public static class AbsoluteOrdering implements Ordering
{
@ -123,7 +123,7 @@ public interface Ordering
/**
* RelativeOrdering
*
* A set of <order> elements in web-fragment.xmls.
* A set of &lt;order&gt; elements in web-fragment.xmls.
*/
public static class RelativeOrdering implements Ordering
{
@ -347,7 +347,7 @@ public interface Ordering
* @param list
* @param fragNameA
* @param fragNameB
* @return true if frament name A is before fragment name B
* @return true if fragment name A is before fragment name B
*/
protected boolean isBefore (List<Resource> list, String fragNameA, String fragNameB)
{

View File

@ -27,7 +27,7 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* @TODO Implement proposed deflate frame draft
* TODO Implement proposed deflate frame draft
*/
public class DeflateFrameExtension extends AbstractExtension
{

View File

@ -129,6 +129,7 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
int filled=_endp.fill(_hixieBytes);
if (filled<0)
{
_endp.flush();
_endp.close();
break;
}

View File

@ -15,6 +15,8 @@
*******************************************************************************/
package org.eclipse.jetty.websocket;
import static org.hamcrest.Matchers.*;
import java.net.URI;
import java.util.concurrent.TimeUnit;
@ -31,9 +33,6 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
public class SafariWebsocketDraft0Test
{
private Server server;
@ -45,7 +44,7 @@ public class SafariWebsocketDraft0Test
{
// Configure Logging
// System.setProperty("org.eclipse.jetty.util.log.class",StdErrLog.class.getName());
// System.setProperty("org.eclipse.jetty.LEVEL","DEBUG");
System.setProperty("org.eclipse.jetty.websocket.helper.LEVEL","DEBUG");
}
@Before

View File

@ -15,6 +15,8 @@
*******************************************************************************/
package org.eclipse.jetty.websocket.helper;
import static org.hamcrest.Matchers.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@ -28,12 +30,14 @@ import java.net.URI;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.log.StdErrLog;
import org.junit.Assert;
import static org.hamcrest.Matchers.is;
public class SafariD00
{
private static final Logger LOG = Log.getLogger(SafariD00.class);
private URI uri;
private SocketAddress endpoint;
private Socket socket;
@ -42,19 +46,25 @@ public class SafariD00
public SafariD00(URI uri)
{
if (LOG instanceof StdErrLog)
{
((StdErrLog)LOG).setLevel(StdErrLog.LEVEL_DEBUG);
}
this.uri = uri;
this.endpoint = new InetSocketAddress(uri.getHost(),uri.getPort());
}
/**
* Open the Socket to the destination endpoint and
*
*
* @return the open java Socket.
* @throws IOException
*/
public Socket connect() throws IOException
{
LOG.info("Connecting to endpoint: " + endpoint);
socket = new Socket();
socket.setTcpNoDelay(true);
socket.connect(endpoint,1000);
out = socket.getOutputStream();
@ -64,12 +74,13 @@ public class SafariD00
}
/**
* Issue an Http websocket (Draft-0) upgrade request using the Safari particulars.
*
* Issue an Http websocket (Draft-0) upgrade request (using an example request captured from OSX/Safari)
*
* @throws UnsupportedEncodingException
*/
public void issueHandshake() throws IOException
{
LOG.debug("Issuing Handshake");
StringBuilder req = new StringBuilder();
req.append("GET ").append(uri.getPath()).append(" HTTP/1.1\r\n");
req.append("Upgrade: WebSocket\r\n");
@ -80,7 +91,7 @@ public class SafariD00
req.append("Sec-WebSocket-Key2: 3? C;7~0 8 \" 3 2105 6 `_ {\r\n");
req.append("\r\n");
// System.out.printf("--- Request ---%n%s",req);
LOG.debug("Request:" + req);
byte reqBytes[] = req.toString().getBytes("UTF-8");
byte hixieBytes[] = TypeUtil.fromHexString("e739617916c9daf3");
@ -96,8 +107,9 @@ public class SafariD00
InputStreamReader reader = new InputStreamReader(in);
BufferedReader br = new BufferedReader(reader);
socket.setSoTimeout(5000);
socket.setSoTimeout(10000);
LOG.debug("Reading http header");
boolean foundEnd = false;
String line;
while (!foundEnd)
@ -113,9 +125,19 @@ public class SafariD00
// Read expected handshake hixie bytes
byte hixieHandshakeExpected[] = TypeUtil.fromHexString("c7438d956cf611a6af70603e6fa54809");
byte hixieHandshake[] = new byte[hixieHandshakeExpected.length];
Assert.assertThat("Hixie handshake buffer size",hixieHandshake.length,is(16));
int readLen = in.read(hixieHandshake,0,hixieHandshake.length);
Assert.assertThat("Read hixie handshake bytes",readLen,is(hixieHandshake.length));
LOG.debug("Reading hixie handshake bytes");
int bytesRead = 0;
while (bytesRead < hixieHandshake.length)
{
int val = in.read();
if (val >= 0)
{
hixieHandshake[bytesRead++] = (byte)val;
}
}
Assert.assertThat("Read hixie handshake bytes",bytesRead,is(hixieHandshake.length));
}
public void sendMessage(String... msgs) throws IOException
@ -123,6 +145,7 @@ public class SafariD00
int len = 0;
for (String msg : msgs)
{
LOG.debug("sending message: " + msg);
len += (msg.length() + 2);
}
@ -141,6 +164,7 @@ public class SafariD00
public void disconnect() throws IOException
{
LOG.debug("disconnect");
socket.close();
}
}

15
pom.xml
View File

@ -281,9 +281,20 @@
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<docfilessubdirs>true</docfilessubdirs>
<detectLinks>true</detectLinks>
<detectLinks>false</detectLinks>
<detectJavaApiLink>true</detectJavaApiLink>
</configuration>
<excludePackageNames>org.slf4j.*;org.mortbay.*</excludePackageNames>
<links>
<link>http://download.eclipse.org/jetty/stable-7/apidocs/</link>
</links>
<tags>
<tag>
<name>org.apache.xbean.XBean</name>
<placement>a</placement>
<head>Apache XBean:</head>
</tag>
</tags>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@ -32,5 +32,6 @@
<module>test-sessions-common</module>
<module>test-hash-sessions</module>
<module>test-jdbc-sessions</module>
<module>test-mongodb-sessions</module>
</modules>
</project>

View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
// ========================================================================
// Copyright (c) Webtide LLC
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-sessions-parent</artifactId>
<version>7.6.1-SNAPSHOT</version>
</parent>
<artifactId>test-mongodb-sessions</artifactId>
<name>Jetty Tests :: Sessions :: Mongo</name>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<!-- DO NOT DEPLOY (or Release) -->
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-test-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-policy</artifactId>
<version>${jetty-test-policy-version}</version>
<type>jar</type>
<overWrite>true</overWrite>
<includes>**/*.keystore,**/*.pem</includes>
<outputDirectory>${jetty.test.policy.loc}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-sessions-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-nosql</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jmx</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>mongodb</id>
<activation>
<property>
<name>mongodb.enabled</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>false</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -26,7 +26,6 @@ public class ClientCrossContextSessionTest extends AbstractClientCrossContextSes
}
@Test
@Ignore ("requires mongodb server")
public void testCrossContextDispatch() throws Exception
{
super.testCrossContextDispatch();

View File

@ -26,7 +26,6 @@ public class LastAccessTimeTest extends AbstractLastAccessTimeTest
}
@Test
@Ignore ("requires mongodb server")
public void testLastAccessTime() throws Exception
{
super.testLastAccessTime();

View File

@ -30,7 +30,6 @@ public class LightLoadTest extends AbstractLightLoadTest
}
@Test
@Ignore ("requires mongodb server")
public void testLightLoad() throws Exception
{
super.testLightLoad();

View File

@ -30,8 +30,7 @@ import org.eclipse.jetty.server.session.SessionHandler;
*/
public class MongoTestServer extends AbstractTestServer
{
static MongoSessionIdManager _idManager;
static int __workers=0;
private boolean _saveAllAttributes = false; // false save dirty, true save all
public MongoTestServer(int port)
@ -54,45 +53,19 @@ public class MongoTestServer extends AbstractTestServer
public SessionIdManager newSessionIdManager(String config)
{
if ( _idManager != null )
{
try
{
_idManager.stop();
}
catch (Exception e)
{
e.printStackTrace();
}
_idManager.setScavengeDelay(_scavengePeriod + 1000);
_idManager.setScavengePeriod(_maxInactivePeriod);
try
{
_idManager.start();
}
catch (Exception e)
{
e.printStackTrace();
}
return _idManager;
}
try
{
System.err.println("MongoTestServer:SessionIdManager:" + _maxInactivePeriod + "/" + _scavengePeriod);
_idManager = new MongoSessionIdManager(_server);
_idManager.setScavengeDelay((int)TimeUnit.SECONDS.toMillis(_scavengePeriod));
_idManager.setScavengePeriod(_maxInactivePeriod);
return _idManager;
MongoSessionIdManager idManager = new MongoSessionIdManager(_server);
idManager.setWorkerName("w"+(__workers++));
idManager.setScavengeDelay((int)TimeUnit.SECONDS.toMillis(_scavengePeriod));
idManager.setScavengePeriod(_maxInactivePeriod);
return idManager;
}
catch (Exception e)
{
throw new IllegalStateException();
throw new RuntimeException(e);
}
}

View File

@ -30,7 +30,6 @@ public class NewSessionTest extends AbstractNewSessionTest
}
@Test
@Ignore ("requires mongodb server")
public void testNewSession() throws Exception
{
super.testNewSession();

View File

@ -29,7 +29,6 @@ public class OrphanedSessionTest extends AbstractOrphanedSessionTest
}
@Test
@Ignore ("requires mongodb server")
public void testOrphanedSession() throws Exception
{
super.testOrphanedSession();

View File

@ -29,7 +29,6 @@ public class ReentrantRequestSessionTest extends AbstractReentrantRequestSession
}
@Test
@Ignore ("requires mongodb server")
public void testReentrantRequestSession() throws Exception
{
super.testReentrantRequestSession();

View File

@ -26,7 +26,6 @@ public class RemoveSessionTest extends AbstractRemoveSessionTest
}
@Test
@Ignore ("requires mongodb server")
public void testRemoveSession() throws Exception
{
super.testRemoveSession();

View File

@ -26,7 +26,6 @@ public class ServerCrossContextSessionTest extends AbstractServerCrossContextSes
}
@Test
@Ignore ("requires mongodb server")
public void testCrossContextDispatch() throws Exception
{
super.testCrossContextDispatch();

View File

@ -0,0 +1,22 @@
#
# This file defines users passwords and roles for a HashUserRealm
#
# The format is
# <username>: <password>[,<rolename> ...]
#
# Passwords may be clear text, obfuscated or checksummed. The class
# org.eclipse.util.Password should be used to generate obfuscated
# passwords or password checksums
#
# If DIGEST Authentication is used, the password must be in a recoverable
# format, either plain text or OBF:.
#
# if using digest authentication, do not MD5-hash the password
jetty: jetty,user
admin: CRYPT:ad1ks..kc.1Ug,server-administrator,content-administrator,admin,user
other: OBF:1xmk1w261u9r1w1c1xmq,user
plain: plain,user
user: password,user
# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password
digest: MD5:6e120743ad67abfbc385bc2bb754e297,user

View File

@ -26,6 +26,7 @@ import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@ -46,10 +47,14 @@ public abstract class AbstractClientCrossContextSessionTest
String contextB = "/contextB";
String servletMapping = "/server";
AbstractTestServer server = createServer(0);
TestServletA servletA = new TestServletA();
ServletHolder holderA = new ServletHolder(servletA);
ServletContextHandler ctxA = server.addContext(contextA);
ctxA.addServlet(TestServletA.class, servletMapping);
ctxA.addServlet(holderA, servletMapping);
ServletContextHandler ctxB = server.addContext(contextB);
ctxB.addServlet(TestServletB.class, servletMapping);
TestServletB servletB = new TestServletB();
ServletHolder holderB = new ServletHolder(servletB);
ctxB.addServlet(holderB, servletMapping);
server.start();
int port = server.getPort();
@ -76,10 +81,12 @@ public abstract class AbstractClientCrossContextSessionTest
ContentExchange exchangeB = new ContentExchange(true);
exchangeB.setMethod(HttpMethods.GET);
exchangeB.setURL("http://localhost:" + port + contextB + servletMapping);
exchangeB.getRequestFields().add("Cookie", sessionCookie);
System.err.println("Cookie = "+sessionCookie);
exchangeB.getRequestFields().add("Cookie", sessionCookie);
client.send(exchangeB);
exchangeB.waitForDone();
assertEquals(HttpServletResponse.SC_OK,exchangeB.getResponseStatus());
assertEquals(servletA.sessionId, servletB.sessionId);
}
finally
{
@ -94,11 +101,17 @@ public abstract class AbstractClientCrossContextSessionTest
public static class TestServletA extends HttpServlet
{
public String sessionId;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
HttpSession session = request.getSession(false);
if (session == null) session = request.getSession(true);
if (session == null)
{
session = request.getSession(true);
sessionId = session.getId();
}
// Add something to the session
session.setAttribute("A", "A");
@ -106,17 +119,22 @@ public abstract class AbstractClientCrossContextSessionTest
// Check that we don't see things put in session by contextB
Object objectB = session.getAttribute("B");
assertTrue(objectB == null);
System.out.println("A: session.getAttributeNames() = " + Collections.list(session.getAttributeNames()));
}
}
public static class TestServletB extends HttpServlet
{
public String sessionId;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException
{
HttpSession session = request.getSession(false);
if (session == null) session = request.getSession(true);
if (session == null)
{
session = request.getSession(true);
sessionId = session.getId();
}
// Add something to the session
session.setAttribute("B", "B");
@ -124,7 +142,6 @@ public abstract class AbstractClientCrossContextSessionTest
// Check that we don't see things put in session by contextA
Object objectA = session.getAttribute("A");
assertTrue(objectA == null);
System.out.println("B: session.getAttributeNames() = " + Collections.list(session.getAttributeNames()));
}
}
}

View File

@ -44,6 +44,7 @@ public abstract class AbstractImmortalSessionTest
String contextPath = "";
String servletMapping = "/server";
int scavengePeriod = 2;
//turn off session expiry by setting maxInactiveInterval to -1
AbstractTestServer server = createServer(0, -1, scavengePeriod);
server.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
server.start();

View File

@ -98,13 +98,11 @@ public abstract class AbstractLastAccessTimeTest
Thread.sleep(requestInterval);
}
System.out.println("Waiting for scavenging on node1...");
// At this point, session1 should be eligible for expiration.
// Let's wait for the scavenger to run, waiting 2.5 times the scavenger period
Thread.sleep(scavengePeriod * 2500L);
// Access again server1, and be sure we can
// Access again server1, and ensure that we can still access the session
exchange1 = new ContentExchange(true);
exchange1.setMethod(HttpMethods.GET);
exchange1.setURL("http://localhost:" + port1 + contextPath + servletMapping);
@ -112,6 +110,8 @@ public abstract class AbstractLastAccessTimeTest
client.send(exchange1);
exchange1.waitForDone();
assertEquals(HttpServletResponse.SC_OK, exchange1.getResponseStatus());
//test that the session was kept alive by server 2 and still contains what server1 put in it
assertEquals("test", exchange1.getResponseContent());
}
finally

View File

@ -20,6 +20,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.eclipse.jetty.client.ContentExchange;
import org.eclipse.jetty.client.HttpClient;
@ -109,7 +110,8 @@ public abstract class AbstractNewSessionTest
String action = request.getParameter("action");
if ("create".equals(action))
{
request.getSession(true);
HttpSession session = request.getSession(true);
assertTrue(session.isNew());
}
else if ("old-create".equals(action))
{

View File

@ -84,19 +84,7 @@ public abstract class AbstractOrphanedSessionTest
// must be removed by scavenging done in the other node.
Thread.sleep(TimeUnit.SECONDS.toMillis(inactivePeriod + 2L * scavengePeriod));
System.err.println("FINISHED waiting for session to expire");
// Perform one request to server2 to be sure that the session has been expired
//
// force invalidate to test
// ContentExchange exchange3 = new ContentExchange(true);
// exchange3.setMethod(HttpMethods.GET);
// exchange3.setURL("http://localhost:" + port2 + contextPath + servletMapping + "?action=remove");
// exchange3.getRequestFields().add("Cookie", sessionCookie);
// client.send(exchange3);
// exchange3.waitForDone();
System.err.println("CHECKING NODE2");
ContentExchange exchange2 = new ContentExchange(true);
exchange2.setMethod(HttpMethods.GET);
exchange2.setURL("http://localhost:" + port2 + contextPath + servletMapping + "?action=check");

View File

@ -92,7 +92,7 @@ public abstract class AbstractReentrantRequestSessionTest
int port = Integer.parseInt(request.getParameter("port"));
String path = request.getParameter("path");
// We want to make another request with a different session
// We want to make another request
// while this request is still pending, to see if the locking is
// fine grained (per session at least).
try