Merge branch 'master' into jetty-9.4.x-Feature
This commit is contained in:
commit
4e286266c0
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
alpn-boot
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
alpn-boot
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
alpn-boot
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
alpn-boot
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
alpn-boot
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.2.v20141202|lib/alpn/alpn-boot-8.1.2.v20141202.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
alpn-boot
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.3.v20150130|lib/alpn/alpn-boot-8.1.3.v20150130.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.3.v20150130/alpn-boot-8.1.3.v20150130.jar|lib/alpn/alpn-boot-8.1.3.v20150130.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.3.v20150130/alpn-boot-8.1.3.v20150130.jar|lib/alpn/alpn-boot-8.1.3.v20150130.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.4.v20150727/alpn-boot-8.1.4.v20150727.jar|lib/alpn/alpn-boot-8.1.4.v20150727.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.5.v20150921/alpn-boot-8.1.5.v20150921.jar|lib/alpn/alpn-boot-8.1.5.v20150921.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.6.v20151105/alpn-boot-8.1.6.v20151105.jar|lib/alpn/alpn-boot-8.1.6.v20151105.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.6.v20151105/alpn-boot-8.1.6.v20151105.jar|lib/alpn/alpn-boot-8.1.6.v20151105.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
[name]
|
||||
protonego-boot
|
||||
|
||||
[files]
|
||||
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.8.v20160420/alpn-boot-8.1.8.v20160420.jar|lib/alpn/alpn-boot-8.1.8.v20160420.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.8.v20160420.jar
|
|
@ -15,9 +15,6 @@ specific version of Java.
|
|||
# All versions of alpn-boot can be found at
|
||||
# http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/
|
||||
|
||||
[name]
|
||||
alpn
|
||||
|
||||
[depend]
|
||||
ssl
|
||||
alpn-impl/alpn-${java.version}
|
||||
|
|
|
@ -466,8 +466,6 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
|||
if (initializers != null && initializers.size()>0)
|
||||
{
|
||||
Map<String, Set<String>> map = ( Map<String, Set<String>>) context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
|
||||
if (map == null)
|
||||
LOG.warn ("ServletContainerInitializers: detected. Class hierarchy: empty");
|
||||
for (ContainerInitializer i : initializers)
|
||||
i.resolveClasses(context,map);
|
||||
}
|
||||
|
|
|
@ -218,6 +218,7 @@ public class Servlet3Continuation implements Continuation, AsyncListener
|
|||
{
|
||||
if (isSuspended())
|
||||
{
|
||||
_initial=false;
|
||||
if (ContinuationFilter.__debug)
|
||||
throw new ContinuationThrowable();
|
||||
throw __exception;
|
||||
|
@ -244,14 +245,12 @@ public class Servlet3Continuation implements Continuation, AsyncListener
|
|||
@Override
|
||||
public void onStartAsync(AsyncEvent event) throws IOException
|
||||
{
|
||||
_initial=false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public void onTimeout(AsyncEvent event) throws IOException
|
||||
{
|
||||
_initial=false;
|
||||
_expired=true;
|
||||
for (ContinuationListener listener:_listeners)
|
||||
listener.onTimeout(this);
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<!-- ============================================================================================== -->
|
||||
<!-- GCloud configuration when running in the cloud -->
|
||||
<!-- ============================================================================================== -->
|
||||
<New id="gconf" class="org.eclipse.jetty.gcloud.session.GCloudConfiguration">
|
||||
<!-- All configuration information is provided by the cloud environment -->
|
||||
</New>
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<!-- ============================================================================================== -->
|
||||
<!-- GCloud configuration for interacting with a local dev gcloud server for testing -->
|
||||
<!-- ============================================================================================== -->
|
||||
<New id="gconf" class="org.eclipse.jetty.gcloud.session.GCloudConfiguration">
|
||||
<Set name="projectId"><Property name="jetty.gcloudSession.projectId"><Default><Env name="DATASTORE_DATASET"/></Default></Property></Set>
|
||||
<!-- ensure DATASTORE_HOST System property/environment variable to the url of the dev server -->
|
||||
</New>
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<!-- ============================================================================================== -->
|
||||
<!-- GCloud configuration. -->
|
||||
<!-- Note: passwords can use jetty obfuscation. See -->
|
||||
<!-- https://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html -->
|
||||
<!-- See your start.ini or gcloud-session-store.ini file for more configuration information. -->
|
||||
<!-- ============================================================================================== -->
|
||||
<New id="gconf" class="org.eclipse.jetty.gcloud.session.GCloudConfiguration">
|
||||
<Set name="projectId"><Property name="jetty.gcloudSession.projectId"><Default><Env name="DATASTORE_DATASET"/></Default></Property></Set>
|
||||
<Set name="p12File"><Property name="jetty.gcloudSession.p12File"/></Set>
|
||||
<Set name="serviceAccount"><Property name="jetty.gcloudSession.serviceAccount"/></Set>
|
||||
<Set name="password"><Property name="jetty.gcloudSession.password"/></Set>
|
||||
</New>
|
||||
|
||||
</Configure>
|
|
@ -3,11 +3,17 @@
|
|||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Configure a GCloudSessionIdManager -->
|
||||
<!-- Configure a factory for GCloudSessionStores -->
|
||||
<!-- ===================================================================== -->
|
||||
<Get name="sessionIdManager">
|
||||
<Set name="workerName"><Property name="jetty.sessionIdManager.workerName"><Default>node<Env name="GAE_MODULE_INSTANCE" default="0"/></Default></Property></Set>
|
||||
</Get>
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.session.GCloudSessionStoreFactory">
|
||||
<Set name="gcloudConfiguration"><Ref id="gconf"/></Set>
|
||||
<Set name="gracePeriod"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1,9 @@
|
|||
[description]
|
||||
Enables session storage when running inside the cloud.
|
||||
|
||||
[name]
|
||||
gcloud-embedded
|
||||
|
||||
|
||||
[xml]
|
||||
etc/jetty-gcloud-embedded.xml
|
|
@ -0,0 +1,9 @@
|
|||
[description]
|
||||
Enables session storage on a local GCloudDataStore dev server.
|
||||
|
||||
[name]
|
||||
gcloud-local
|
||||
|
||||
|
||||
[xml]
|
||||
etc/jetty-gcloud-local.xml
|
|
@ -0,0 +1,15 @@
|
|||
[description]
|
||||
Enables session storage on a remote GCloudDataStore service.
|
||||
|
||||
[name]
|
||||
gcloud-remote
|
||||
|
||||
|
||||
[xml]
|
||||
etc/jetty-gcloud-remote.xml
|
||||
|
||||
[ini-template]
|
||||
#jetty.gcloudSession.projectId=
|
||||
#jetty.gcloudSession.p12File=
|
||||
#jetty.gcloudSession.serviceAccount=
|
||||
#jetty.gcloudSession.password=
|
|
@ -1,12 +1,16 @@
|
|||
[description]
|
||||
Enables GCloudDatastore session management.
|
||||
|
||||
[name]
|
||||
gcloud-session-store
|
||||
|
||||
[depend]
|
||||
annotations
|
||||
webapp
|
||||
sessions
|
||||
gcloud-${type}
|
||||
|
||||
[files]
|
||||
|
||||
maven://com.google.gcloud/gcloud-java-datastore/0.0.7|lib/gcloud/gcloud-java-datastore-0.0.7.jar
|
||||
maven://com.google.gcloud/gcloud-java-core/0.0.7|lib/gcloud/gcloud-java-core-0.0.7.jar
|
||||
maven://com.google.auth/google-auth-library-credentials/0.1.0|lib/gcloud/google-auth-library-credentials-0.1.0.jar
|
||||
|
@ -49,28 +53,16 @@ GCloudDatastore is an open source project hosted on Github and released under th
|
|||
https://github.com/GoogleCloudPlatform/gcloud-java
|
||||
http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
[xml]
|
||||
etc/jetty-gcloud-sessions.xml
|
||||
|
||||
[ini]
|
||||
type=remote
|
||||
|
||||
[ini-template]
|
||||
#type=local
|
||||
#type=embedded
|
||||
|
||||
|
||||
## GCloudDatastore Session config
|
||||
## If running inside Google cloud all configuration is provided by
|
||||
## environment variables and you do not need to set anything in this file.
|
||||
##
|
||||
## If running externally to Google:
|
||||
## To contact the remote gcloud datastore:
|
||||
## 1. set the DATASTORE_DATASET System property/environment variable to the name of your project
|
||||
## or alternatively set the jetty.gcloudSession.projectId property below.
|
||||
## 2. set the jetty.gcloudSession.p12File, jetty.gcloudSession.serviceAccount and
|
||||
## jetty.gcloudSession.password (supports obfuscation) below.
|
||||
##
|
||||
## To contact a local dev gcloud datastore server:
|
||||
## 1. set the DATASTORE_DATASET System property/environment variable to the name of your project.
|
||||
## 2. set the DATASTORE_HOST System property/environment variable to the url of the dev server
|
||||
## as described at https://cloud.google.com/datastore/docs/tools/devserver#setting_environment_variables
|
||||
|
||||
## The gcloud projectId
|
||||
## Set this property to connect to remote gcloud datastore.
|
||||
|
@ -78,13 +70,13 @@ etc/jetty-gcloud-sessions.xml
|
|||
#jetty.gcloudSession.projectId=
|
||||
|
||||
## The p12 file associated with the project.
|
||||
## Set this property to connect to remote gcloud datastore
|
||||
## Set this property only when connecting to remote gcloud datastore
|
||||
#jetty.gcloudSession.p12File=
|
||||
|
||||
## The serviceAccount for the Datastore.
|
||||
## Set this property to connect to to remote gcloud datastore
|
||||
## Set this property only when connecting to remote gcloud datastore
|
||||
#jetty.gcloudSession.serviceAccount=
|
||||
|
||||
## The password (can be obfuscated).
|
||||
## Set this property to connect to remote gcloud datastore
|
||||
## Set this property only when connecting to remote gcloud datastore
|
||||
#jetty.gcloudSession.password=
|
|
@ -1,42 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
|
||||
<!-- ============================================================================================== -->
|
||||
<!-- GCloud configuration. -->
|
||||
<!-- Note: passwords can use jetty obfuscation. See -->
|
||||
<!-- https://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html -->
|
||||
<!-- See your start.ini or gcloud-sessions.ini file for more configuration information. -->
|
||||
<!-- ============================================================================================== -->
|
||||
<New id="gconf" class="org.eclipse.jetty.gcloud.session.GCloudConfiguration">
|
||||
<!-- Either set jetty.gcloudSession.projectId or use system property/env var DATASTORE_DATASET-->
|
||||
<Set name="projectId"><Property name="jetty.gcloudSession.projectId"/></Set>
|
||||
<!-- To contact remote gclouddatastore set the following properties in start.ini -->
|
||||
<Set name="p12File"><Property name="jetty.gcloudSession.p12File"/></Set>
|
||||
<Set name="serviceAccount"><Property name="jetty.gcloudSession.serviceAccount"/></Set>
|
||||
<Set name="password"><Property name="jetty.gcloudSession.password"/></Set>
|
||||
</New>
|
||||
|
||||
|
||||
|
||||
<Get name="sessionHandler">
|
||||
<Set name="sessionManager">
|
||||
<New class="org.eclipse.jetty.gcloud.session.GCloudSessionManager">
|
||||
<Set name="maxInactiveInterval">seconds</Set>
|
||||
<Get name="sessionDataStore">
|
||||
<Set name="gcloudConfiguration">
|
||||
<Ref id="gconf"/>
|
||||
</Set>
|
||||
<Set name="maxResults">integer</Set>
|
||||
</Get>
|
||||
<Get name="sessionStore">
|
||||
<Set name="idlePassivationTimeoutSec">seconds</Set>
|
||||
<Set name="expiryTimeoutSec">seconds</Set>
|
||||
</Get>
|
||||
</New>
|
||||
</Set>
|
||||
</Get>
|
||||
|
||||
</Configure>
|
|
@ -1,87 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.gcloud.session;
|
||||
|
||||
import org.eclipse.jetty.server.session.AbstractSessionStore;
|
||||
import org.eclipse.jetty.server.session.MemorySessionStore;
|
||||
import org.eclipse.jetty.server.session.SessionManager;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* GCloudSessionManager
|
||||
*
|
||||
* Convenience class to link up a MemorySessionStore with the GCloudSessionDataStore.
|
||||
*
|
||||
*/
|
||||
public class GCloudSessionManager extends SessionManager
|
||||
{
|
||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
|
||||
private GCloudSessionDataStore _sessionDataStore = null;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public GCloudSessionManager()
|
||||
{
|
||||
_sessionDataStore = new GCloudSessionDataStore();
|
||||
setSessionStore(new MemorySessionStore(this));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public GCloudSessionDataStore getSessionDataStore()
|
||||
{
|
||||
return _sessionDataStore;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Start the session manager.
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.SessionManager#doStart()
|
||||
*/
|
||||
@Override
|
||||
public void doStart() throws Exception
|
||||
{
|
||||
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop the session manager.
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.SessionManager#doStop()
|
||||
*/
|
||||
@Override
|
||||
public void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.server.session.AbstractSessionDataStore;
|
||||
import org.eclipse.jetty.server.session.AbstractSessionStore;
|
||||
import org.eclipse.jetty.server.session.SessionContext;
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
|
||||
|
@ -51,11 +51,11 @@ import org.eclipse.jetty.util.log.Log;
|
|||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/**
|
||||
* GCloudSessionDataStore
|
||||
* GCloudSessionStore
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class GCloudSessionDataStore extends AbstractSessionDataStore
|
||||
public class GCloudSessionStore extends AbstractSessionStore
|
||||
{
|
||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
|
@ -85,7 +85,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStart()
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStart()
|
||||
*/
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
|
@ -138,7 +138,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#load(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public SessionData load(String id) throws Exception
|
||||
|
@ -159,7 +159,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean delete(String id) throws Exception
|
||||
|
@ -170,7 +170,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(Set)
|
||||
*/
|
||||
@Override
|
||||
public Set<String> doGetExpired(Set<String> candidates)
|
||||
|
@ -264,7 +264,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean exists(String id) throws Exception
|
||||
|
@ -290,7 +290,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
|
||||
*/
|
||||
@Override
|
||||
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
|
||||
|
@ -431,7 +431,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#isPassivating()
|
||||
*/
|
||||
@Override
|
||||
public boolean isPassivating()
|
|
@ -25,6 +25,7 @@ import org.eclipse.jetty.security.HashLoginService;
|
|||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.AllowSymLinkAliasChecker;
|
||||
import org.eclipse.jetty.server.session.DefaultSessionIdManager;
|
||||
import org.eclipse.jetty.server.session.DefaultSessionCache;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
||||
|
@ -58,10 +59,12 @@ public class GCloudSessionTester
|
|||
webapp.setContextPath("/");
|
||||
webapp.setWar("../../jetty-distribution/target/distribution/demo-base/webapps/test.war");
|
||||
webapp.addAliasCheck(new AllowSymLinkAliasChecker());
|
||||
GCloudSessionManager mgr = new GCloudSessionManager();
|
||||
mgr.getSessionDataStore().setGCloudConfiguration(config);
|
||||
mgr.setSessionIdManager(idmgr);
|
||||
webapp.setSessionHandler(new SessionHandler(mgr));
|
||||
GCloudSessionStore ds = new GCloudSessionStore();
|
||||
ds.setGCloudConfiguration(config);
|
||||
DefaultSessionCache ss = new DefaultSessionCache(webapp.getSessionHandler());
|
||||
webapp.getSessionHandler().setSessionStore(ss);
|
||||
ss.setSessionStore(ds);
|
||||
webapp.getSessionHandler().setSessionIdManager(idmgr);
|
||||
|
||||
// A WebAppContext is a ContextHandler as well so it needs to be set to
|
||||
// the server so it is aware of where to send the appropriate requests.
|
||||
|
|
|
@ -18,9 +18,12 @@
|
|||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import static java.lang.Integer.MIN_VALUE;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
@ -41,12 +44,41 @@ public class QuotedQualityCSV implements Iterable<String>
|
|||
private final List<String> _values = new ArrayList<>();
|
||||
private final List<Double> _quality = new ArrayList<>();
|
||||
private boolean _sorted = false;
|
||||
private final Function<String, Integer> secondaryOrderingFunction;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public QuotedQualityCSV(String... values)
|
||||
|
||||
/**
|
||||
* Sorts values with equal quality according to the length of the value String.
|
||||
*/
|
||||
public QuotedQualityCSV()
|
||||
{
|
||||
for (String v:values)
|
||||
addValue(v);
|
||||
this((s) -> s.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts values with equal quality according to given order.
|
||||
*/
|
||||
public QuotedQualityCSV(String[] serverPreferredValueOrder)
|
||||
{
|
||||
this((s) -> {
|
||||
for (int i=0;i<serverPreferredValueOrder.length;++i)
|
||||
if (serverPreferredValueOrder[i].equals(s))
|
||||
return serverPreferredValueOrder.length-i;
|
||||
|
||||
if ("*".equals(s))
|
||||
return serverPreferredValueOrder.length;
|
||||
|
||||
return MIN_VALUE;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Orders values with equal quality with the given function.
|
||||
*/
|
||||
public QuotedQualityCSV(Function<String, Integer> secondaryOrderingFunction)
|
||||
{
|
||||
this.secondaryOrderingFunction = secondaryOrderingFunction;
|
||||
}
|
||||
|
||||
|
||||
|
@ -224,7 +256,7 @@ public class QuotedQualityCSV implements Iterable<String>
|
|||
_sorted=true;
|
||||
|
||||
Double last = ZERO;
|
||||
int len = Integer.MIN_VALUE;
|
||||
int lastOrderIndex = Integer.MIN_VALUE;
|
||||
|
||||
for (int i = _values.size(); i-- > 0;)
|
||||
{
|
||||
|
@ -232,20 +264,20 @@ public class QuotedQualityCSV implements Iterable<String>
|
|||
Double q = _quality.get(i);
|
||||
|
||||
int compare=last.compareTo(q);
|
||||
if (compare > 0 || (compare==0 && v.length()<len))
|
||||
if (compare>0 || (compare==0 && secondaryOrderingFunction.apply(v)<lastOrderIndex))
|
||||
{
|
||||
_values.set(i, _values.get(i + 1));
|
||||
_values.set(i + 1, v);
|
||||
_quality.set(i, _quality.get(i + 1));
|
||||
_quality.set(i + 1, q);
|
||||
last = ZERO;
|
||||
len=0;
|
||||
lastOrderIndex=0;
|
||||
i = _values.size();
|
||||
continue;
|
||||
}
|
||||
|
||||
last=q;
|
||||
len=v.length();
|
||||
lastOrderIndex=secondaryOrderingFunction.apply(v);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -143,4 +146,74 @@ public class QuotedQualityCSVTest
|
|||
"value1.0",
|
||||
"value0.5;p=v"));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
private static final String[] preferBrotli = {"br","gzip"};
|
||||
private static final String[] preferGzip = {"gzip","br"};
|
||||
private static final String[] noFormats = {};
|
||||
|
||||
@Test
|
||||
public void testFirefoxContentEncodingWithBrotliPreference()
|
||||
{
|
||||
QuotedQualityCSV values = new QuotedQualityCSV(preferBrotli);
|
||||
values.addValue("gzip, deflate, br");
|
||||
assertThat(values, contains("br", "gzip", "deflate"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFirefoxContentEncodingWithGzipPreference()
|
||||
{
|
||||
QuotedQualityCSV values = new QuotedQualityCSV(preferGzip);
|
||||
values.addValue("gzip, deflate, br");
|
||||
assertThat(values, contains("gzip", "br", "deflate"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFirefoxContentEncodingWithNoPreference()
|
||||
{
|
||||
QuotedQualityCSV values = new QuotedQualityCSV(noFormats);
|
||||
values.addValue("gzip, deflate, br");
|
||||
assertThat(values, contains("gzip", "deflate", "br"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChromeContentEncodingWithBrotliPreference()
|
||||
{
|
||||
QuotedQualityCSV values = new QuotedQualityCSV(preferBrotli);
|
||||
values.addValue("gzip, deflate, sdch, br");
|
||||
assertThat(values, contains("br", "gzip", "deflate", "sdch"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComplexEncodingWithGzipPreference()
|
||||
{
|
||||
QuotedQualityCSV values = new QuotedQualityCSV(preferGzip);
|
||||
values.addValue("gzip;q=0.9, identity;q=0.1, *;q=0.01, deflate;q=0.9, sdch;q=0.7, br;q=0.9");
|
||||
assertThat(values, contains("gzip", "br", "deflate", "sdch", "identity", "*"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComplexEncodingWithBrotliPreference()
|
||||
{
|
||||
QuotedQualityCSV values = new QuotedQualityCSV(preferBrotli);
|
||||
values.addValue("gzip;q=0.9, identity;q=0.1, *;q=0, deflate;q=0.9, sdch;q=0.7, br;q=0.99");
|
||||
assertThat(values, contains("br", "gzip", "deflate", "sdch", "identity"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStarEncodingWithGzipPreference()
|
||||
{
|
||||
QuotedQualityCSV values = new QuotedQualityCSV(preferGzip);
|
||||
values.addValue("br, *");
|
||||
assertThat(values, contains("*", "br"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStarEncodingWithBrotliPreference()
|
||||
{
|
||||
QuotedQualityCSV values = new QuotedQualityCSV(preferBrotli);
|
||||
values.addValue("gzip, *");
|
||||
assertThat(values, contains("*", "gzip"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,11 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
|||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.util.thread.ExecutionStrategy;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.eclipse.jetty.util.thread.strategy.ProduceConsume;
|
||||
|
||||
/**
|
||||
* <p>{@link HTTP2Client} provides an asynchronous, non-blocking implementation
|
||||
|
@ -127,6 +129,7 @@ public class HTTP2Client extends ContainerLifeCycle
|
|||
private int initialSessionRecvWindow = FlowControlStrategy.DEFAULT_WINDOW_SIZE;
|
||||
private int initialStreamRecvWindow = FlowControlStrategy.DEFAULT_WINDOW_SIZE;
|
||||
private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F);
|
||||
private ExecutionStrategy.Factory executionStrategyFactory = new ProduceConsume.Factory();
|
||||
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
|
@ -225,6 +228,16 @@ public class HTTP2Client extends ContainerLifeCycle
|
|||
this.flowControlStrategyFactory = flowControlStrategyFactory;
|
||||
}
|
||||
|
||||
public ExecutionStrategy.Factory getExecutionStrategyFactory()
|
||||
{
|
||||
return executionStrategyFactory;
|
||||
}
|
||||
|
||||
public void setExecutionStrategyFactory(ExecutionStrategy.Factory executionStrategyFactory)
|
||||
{
|
||||
this.executionStrategyFactory = executionStrategyFactory;
|
||||
}
|
||||
|
||||
@ManagedAttribute("The number of selectors")
|
||||
public int getSelectors()
|
||||
{
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.eclipse.jetty.io.EndPoint;
|
|||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.thread.ExecutionStrategy;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
|
||||
public class HTTP2ClientConnectionFactory implements ClientConnectionFactory
|
||||
|
@ -67,7 +68,8 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory
|
|||
FlowControlStrategy flowControl = client.getFlowControlStrategyFactory().newFlowControlStrategy();
|
||||
HTTP2ClientSession session = new HTTP2ClientSession(scheduler, endPoint, generator, listener, flowControl);
|
||||
Parser parser = new Parser(byteBufferPool, session, 4096, 8192);
|
||||
HTTP2ClientConnection connection = new HTTP2ClientConnection(client, byteBufferPool, executor, endPoint, parser, session, client.getInputBufferSize(), promise, listener);
|
||||
HTTP2ClientConnection connection = new HTTP2ClientConnection(client, byteBufferPool, executor, endPoint,
|
||||
parser, session, client.getInputBufferSize(), client.getExecutionStrategyFactory(), promise, listener);
|
||||
connection.addListener(connectionListener);
|
||||
return connection;
|
||||
}
|
||||
|
@ -78,9 +80,9 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory
|
|||
private final Promise<Session> promise;
|
||||
private final Session.Listener listener;
|
||||
|
||||
public HTTP2ClientConnection(HTTP2Client client, ByteBufferPool byteBufferPool, Executor executor, EndPoint endpoint, Parser parser, ISession session, int bufferSize, Promise<Session> promise, Session.Listener listener)
|
||||
private HTTP2ClientConnection(HTTP2Client client, ByteBufferPool byteBufferPool, Executor executor, EndPoint endpoint, Parser parser, ISession session, int bufferSize, ExecutionStrategy.Factory executionFactory, Promise<Session> promise, Session.Listener listener)
|
||||
{
|
||||
super(byteBufferPool, executor, endpoint, parser, session, bufferSize);
|
||||
super(byteBufferPool, executor, endpoint, parser, session, bufferSize, executionFactory);
|
||||
this.client = client;
|
||||
this.promise = promise;
|
||||
this.listener = listener;
|
||||
|
|
|
@ -46,14 +46,14 @@ public class HTTP2Connection extends AbstractConnection
|
|||
private final HTTP2Producer producer = new HTTP2Producer();
|
||||
private final ExecutionStrategy executionStrategy;
|
||||
|
||||
public HTTP2Connection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, Parser parser, ISession session, int bufferSize)
|
||||
public HTTP2Connection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, Parser parser, ISession session, int bufferSize, ExecutionStrategy.Factory executionFactory)
|
||||
{
|
||||
super(endPoint, executor);
|
||||
this.byteBufferPool = byteBufferPool;
|
||||
this.parser = parser;
|
||||
this.session = session;
|
||||
this.bufferSize = bufferSize;
|
||||
this.executionStrategy = ExecutionStrategy.Factory.instanceFor(producer, executor);
|
||||
this.executionStrategy = executionFactory.newExecutionStrategy(producer, executor);
|
||||
}
|
||||
|
||||
public ISession getSession()
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
|||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.annotation.Name;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.thread.ExecutionStrategy;
|
||||
|
||||
@ManagedObject
|
||||
public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConnectionFactory
|
||||
|
@ -46,6 +47,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
|||
private int maxConcurrentStreams = -1;
|
||||
private int maxHeaderBlockFragment = 0;
|
||||
private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F);
|
||||
private ExecutionStrategy.Factory executionStrategyFactory = ExecutionStrategy.Factory.getDefault();
|
||||
|
||||
public AbstractHTTP2ServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration)
|
||||
{
|
||||
|
@ -112,6 +114,16 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
|||
this.flowControlStrategyFactory = flowControlStrategyFactory;
|
||||
}
|
||||
|
||||
public ExecutionStrategy.Factory getExecutionStrategyFactory()
|
||||
{
|
||||
return executionStrategyFactory;
|
||||
}
|
||||
|
||||
public void setExecutionStrategyFactory(ExecutionStrategy.Factory executionStrategyFactory)
|
||||
{
|
||||
this.executionStrategyFactory = executionStrategyFactory;
|
||||
}
|
||||
|
||||
public HttpConfiguration getHttpConfiguration()
|
||||
{
|
||||
return httpConfiguration;
|
||||
|
@ -135,7 +147,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
|||
|
||||
ServerParser parser = newServerParser(connector, session);
|
||||
HTTP2Connection connection = new HTTP2ServerConnection(connector.getByteBufferPool(), connector.getExecutor(),
|
||||
endPoint, httpConfiguration, parser, session, getInputBufferSize(), listener);
|
||||
endPoint, httpConfiguration, parser, session, getInputBufferSize(), getExecutionStrategyFactory(), listener);
|
||||
connection.addListener(connectionListener);
|
||||
return configure(connection, connector, endPoint);
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.eclipse.jetty.util.BufferUtil;
|
|||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.ConcurrentArrayQueue;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.thread.ExecutionStrategy;
|
||||
|
||||
public class HTTP2ServerConnection extends HTTP2Connection implements Connection.UpgradeTo
|
||||
{
|
||||
|
@ -59,9 +60,9 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection
|
|||
private final HttpConfiguration httpConfig;
|
||||
private final List<Frame> upgradeFrames = new ArrayList<>();
|
||||
|
||||
public HTTP2ServerConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, HttpConfiguration httpConfig, ServerParser parser, ISession session, int inputBufferSize, ServerSessionListener listener)
|
||||
public HTTP2ServerConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, HttpConfiguration httpConfig, ServerParser parser, ISession session, int inputBufferSize, ExecutionStrategy.Factory executionFactory, ServerSessionListener listener)
|
||||
{
|
||||
super(byteBufferPool, executor, endPoint, parser, session, inputBufferSize);
|
||||
super(byteBufferPool, executor, endPoint, parser, session, inputBufferSize, executionFactory);
|
||||
this.listener = listener;
|
||||
this.httpConfig = httpConfig;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Get a reference to the default local cache. -->
|
||||
<!-- ===================================================================== -->
|
||||
<New id="local" class="org.infinispan.manager.DefaultCacheManager">
|
||||
<Get id="cache" name="cache"></Get>
|
||||
</New>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Configure a factory for InfinispanSessionStore using the -->
|
||||
<!-- Infinispan DefaultCache -->
|
||||
<!-- ===================================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.session.InfinispanSessionStoreFactory">
|
||||
<Set name="cache"><Ref id="cache"/></Set>
|
||||
<Set name="infinispanIdleTimeoutSec"><Property name="jetty.session.infinispanIdleTimeout.seconds" default="0" /></Set>
|
||||
<Set name="gracePeriod"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Configure>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Get a reference to the remote cache. -->
|
||||
<!-- ===================================================================== -->
|
||||
<New id="hotrodMgr" class="org.infinispan.client.hotrod.RemoteCacheManager">
|
||||
<Call id="remoteCache" name="getCache">
|
||||
<Arg><Property name="jetty.session.remoteInfinispanCache.name" default="sessions"/></Arg>
|
||||
</Call>
|
||||
</New>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Configure a factory for InfinispanSessionStore using the -->
|
||||
<!-- Infinispan DefaultCache -->
|
||||
<!-- ===================================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.session.InfinispanSessionStoreFactory">
|
||||
<Set name="cache"><Ref id="remoteCache"/></Set>
|
||||
<Set name="infinispanIdleTimeoutSec"><Property name="jetty.session.infinispanIdleTimeout.seconds" default="0" /></Set>
|
||||
<Set name="gracePeriod"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Configure>
|
|
@ -0,0 +1,10 @@
|
|||
[description]
|
||||
Enable use of DefaultCache for session data storage
|
||||
|
||||
[name]
|
||||
infinispan-session-default
|
||||
|
||||
|
||||
[xml]
|
||||
etc/jetty-default-infinispan-session-store.xml
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[description]
|
||||
Enable use of HotRod remote cache for session data storage
|
||||
|
||||
[name]
|
||||
infinispan-session-remote
|
||||
|
||||
[files]
|
||||
https://raw.githubusercontent.com/eclipse/jetty.project/master/jetty-infinispan/src/main/infinispan-resources/hotrod-client.properties?id=${jetty.tag.version}|resources/hotrod-client.properties
|
||||
|
||||
[xml]
|
||||
etc/jetty-remote-infinispan-session-store.xml
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
#
|
||||
# Jetty Infinispan module
|
||||
#
|
||||
[description]
|
||||
Enables session data store in a remote Infinispan cache
|
||||
|
||||
[name]
|
||||
infinispan-session-store
|
||||
|
||||
[depend]
|
||||
annotations
|
||||
webapp
|
||||
session
|
||||
infinispan-session-${cache-type}
|
||||
|
||||
[files]
|
||||
maven://org.infinispan/infinispan-core/7.1.1.Final|lib/infinispan/infinispan-core-7.1.1.Final.jar
|
||||
|
@ -17,17 +19,18 @@ maven://org.jboss.logging/jboss-logging/3.1.2.GA|lib/infinispan/jboss-logging-3.
|
|||
lib/jetty-infinispan-${jetty.version}.jar
|
||||
lib/infinispan/*.jar
|
||||
|
||||
[xml]
|
||||
etc/jetty-infinispan.xml
|
||||
|
||||
[license]
|
||||
Infinispan is an open source project hosted on Github and released under the Apache 2.0 license.
|
||||
http://infinispan.org/
|
||||
http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
|
||||
[ini]
|
||||
cache-type=default
|
||||
|
||||
[ini-template]
|
||||
## Infinispan Session config
|
||||
|
||||
## Unique identifier for this node in the cluster
|
||||
# jetty.infinispanSession.workerName=node1
|
||||
|
||||
#cache-type=remote
|
||||
#jetty.session.remoteInfinispanCache.name=sessions
|
||||
#jetty.session.infinispanIdleTimeout.seconds=0
|
||||
#jetty.session.gracePeriod.seconds=3600
|
|
@ -1,25 +0,0 @@
|
|||
[description]
|
||||
Enables an Infinispan Session Manager for session
|
||||
persistance and/or clustering
|
||||
|
||||
[depend]
|
||||
annotations
|
||||
webapp
|
||||
|
||||
[files]
|
||||
maven://org.infinispan/infinispan-core/7.1.1.Final|lib/infinispan/infinispan-core-7.1.1.Final.jar
|
||||
maven://org.infinispan/infinispan-commons/7.1.1.Final|lib/infinispan/infinispan-commons-7.1.1.Final.jar
|
||||
maven://org.jgroups/jgroups/3.6.1.Final|lib/infinispan/jgroups-3.6.1.Final.jar
|
||||
maven://org.jboss.marshalling/jboss-marshalling-osgi/1.4.4.Final|lib/infinispan/jboss-marshalling-osgi-1.4.4.Final.jar
|
||||
maven://org.jboss.logging/jboss-logging/3.1.2.GA|lib/infinispan/jboss-logging-3.1.2.GA.jar
|
||||
|
||||
[lib]
|
||||
lib/jetty-infinispan-${jetty.version}.jar
|
||||
lib/infinispan/*.jar
|
||||
|
||||
|
||||
[license]
|
||||
Infinispan is an open source project hosted on Github and released under the Apache 2.0 license.
|
||||
http://infinispan.org/
|
||||
http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Get a reference to the default local cache. -->
|
||||
<!-- ===================================================================== -->
|
||||
<New id="local" class="org.infinispan.manager.DefaultCacheManager">
|
||||
<Get id="cache" name="cache"></Get>
|
||||
</New>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Get a reference to a hotrod client for a remote cache. -->
|
||||
<!-- Change the name of the cache to match your setup. -->
|
||||
<!-- ===================================================================== -->
|
||||
<!--
|
||||
<New id="hotrodMgr" class="org.infinispan.client.hotrod.RemoteCacheManager">
|
||||
<Call id="cache" name="getCache">
|
||||
<Arg>sessions</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
-->
|
||||
|
||||
|
||||
<Get name="sessionHandler">
|
||||
<Set name="sessionManager">
|
||||
<New class="org.eclipse.jetty.server.session.infinispan.InfinispanSessionManager">
|
||||
<Set name="maxInactiveInterval">seconds</Set>
|
||||
<Get name="sessionDataStore">
|
||||
<Set name="cache">
|
||||
<Ref id="cache"/>
|
||||
</Set>
|
||||
</Get>
|
||||
<Get name="sessionStore">
|
||||
<Set name="idlePassivationTimeoutSec">seconds</Set>
|
||||
<Set name="expiryTimeoutSec">seconds</Set>
|
||||
</Get>
|
||||
</New>
|
||||
</Set>
|
||||
</Get>
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1 @@
|
|||
infinispan.client.hotrod.marshaller=org.eclipse.jetty.session.infinispan.WebAppMarshaller
|
|
@ -1,88 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.session.infinispan;
|
||||
|
||||
import org.eclipse.jetty.server.session.AbstractSessionStore;
|
||||
import org.eclipse.jetty.server.session.MemorySessionStore;
|
||||
import org.eclipse.jetty.server.session.SessionManager;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* InfinispanSessionManager
|
||||
*
|
||||
* Convenience class to create a MemorySessionStore and an InfinispanSessionDataStore.
|
||||
*
|
||||
*/
|
||||
public class InfinispanSessionManager extends SessionManager
|
||||
{
|
||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
|
||||
protected InfinispanSessionDataStore _sessionDataStore;
|
||||
|
||||
|
||||
public InfinispanSessionManager()
|
||||
{
|
||||
setSessionStore(new MemorySessionStore(this));
|
||||
_sessionDataStore = new InfinispanSessionDataStore();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Start the session manager.
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.SessionManager#doStart()
|
||||
*/
|
||||
@Override
|
||||
public void doStart() throws Exception
|
||||
{
|
||||
if (_sessionIdManager == null)
|
||||
throw new IllegalStateException("No session id manager defined");
|
||||
|
||||
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
|
||||
_sessionDataStore.setSessionIdManager(_sessionIdManager);
|
||||
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop the session manager.
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.SessionManager#doStop()
|
||||
*/
|
||||
@Override
|
||||
public void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public InfinispanSessionDataStore getSessionDataStore()
|
||||
{
|
||||
return _sessionDataStore;
|
||||
}
|
||||
|
||||
}
|
|
@ -25,18 +25,18 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.server.SessionIdManager;
|
||||
import org.eclipse.jetty.server.session.AbstractSessionDataStore;
|
||||
import org.eclipse.jetty.server.session.AbstractSessionStore;
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.infinispan.commons.api.BasicCache;
|
||||
|
||||
/**
|
||||
* InfinispanSessionDataStore
|
||||
* InfinispanSessionStore
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
||||
public class InfinispanSessionStore extends AbstractSessionStore
|
||||
{
|
||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
|
@ -47,7 +47,6 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
*/
|
||||
private BasicCache<String, Object> _cache;
|
||||
|
||||
private SessionIdManager _idMgr = null;
|
||||
|
||||
private int _infinispanIdleTimeoutSec;
|
||||
|
||||
|
@ -74,14 +73,10 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
this._cache = cache;
|
||||
}
|
||||
|
||||
public void setSessionIdManager (SessionIdManager idMgr)
|
||||
{
|
||||
_idMgr = idMgr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#load(String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#load(String)
|
||||
*/
|
||||
@Override
|
||||
public SessionData load(String id) throws Exception
|
||||
|
@ -119,7 +114,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#delete(String)
|
||||
*/
|
||||
@Override
|
||||
public boolean delete(String id) throws Exception
|
||||
|
@ -130,7 +125,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(Set)
|
||||
*/
|
||||
@Override
|
||||
public Set<String> doGetExpired(Set<String> candidates)
|
||||
|
@ -201,7 +196,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(String, SessionData, long)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStore(String, SessionData, long)
|
||||
*/
|
||||
@Override
|
||||
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
|
||||
|
@ -229,7 +224,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#isPassivating()
|
||||
*/
|
||||
@Override
|
||||
public boolean isPassivating()
|
||||
|
@ -253,7 +248,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean exists(String id) throws Exception
|
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.session.infinispan;
|
||||
|
||||
import org.eclipse.jetty.server.session.AbstractSessionStoreFactory;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.server.session.SessionStore;
|
||||
import org.infinispan.commons.api.BasicCache;
|
||||
|
||||
/**
|
||||
* InfinispanSessionStoreFactory
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class InfinispanSessionStoreFactory extends AbstractSessionStoreFactory
|
||||
{
|
||||
int _infinispanIdleTimeoutSec;
|
||||
BasicCache<String, Object> _cache;
|
||||
|
||||
|
||||
/**
|
||||
* @return the infinispanIdleTimeoutSec
|
||||
*/
|
||||
public int getInfinispanIdleTimeoutSec()
|
||||
{
|
||||
return _infinispanIdleTimeoutSec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param infinispanIdleTimeoutSec the infinispanIdleTimeoutSec to set
|
||||
*/
|
||||
public void setInfinispanIdleTimeoutSec(int infinispanIdleTimeoutSec)
|
||||
{
|
||||
_infinispanIdleTimeoutSec = infinispanIdleTimeoutSec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionStoreFactory#getSessionStore(org.eclipse.jetty.server.session.SessionHandler)
|
||||
*/
|
||||
@Override
|
||||
public SessionStore getSessionStore (SessionHandler handler) throws Exception
|
||||
{
|
||||
InfinispanSessionStore store = new InfinispanSessionStore();
|
||||
store.setGracePeriodSec(getGracePeriodSec());
|
||||
store.setInfinispanIdleTimeoutSec(getInfinispanIdleTimeoutSec());
|
||||
store.setCache(getCache());
|
||||
return store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the clustered cache instance.
|
||||
*
|
||||
* @return the cache
|
||||
*/
|
||||
public BasicCache<String, Object> getCache()
|
||||
{
|
||||
return _cache;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the clustered cache instance.
|
||||
*
|
||||
* @param cache the cache
|
||||
*/
|
||||
public void setCache (BasicCache<String, Object> cache)
|
||||
{
|
||||
this._cache = cache;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -66,10 +66,15 @@ public class ManagedSelector extends AbstractLifeCycle implements Runnable, Dump
|
|||
private Selector _selector;
|
||||
|
||||
public ManagedSelector(SelectorManager selectorManager, int id)
|
||||
{
|
||||
this(selectorManager, id, ExecutionStrategy.Factory.getDefault());
|
||||
}
|
||||
|
||||
public ManagedSelector(SelectorManager selectorManager, int id, ExecutionStrategy.Factory executionFactory)
|
||||
{
|
||||
_selectorManager = selectorManager;
|
||||
_id = id;
|
||||
_strategy = ExecutionStrategy.Factory.instanceFor(new SelectorProducer(), selectorManager.getExecutor());
|
||||
_strategy = executionFactory.newExecutionStrategy(new SelectorProducer(), selectorManager.getExecutor());
|
||||
setStopTimeout(5000);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Configure a factory for MongoSessionStores -->
|
||||
<!-- ===================================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.session.MongoSessionStoreFactory">
|
||||
<Set name="dbName"><Property name="jetty.session.dbName" default="HttpSessions" /></Set>
|
||||
<Set name="collectionName"><Property name="jetty.session.collectionName" default="jettySessions" /></Set>
|
||||
<Set name="gracePeriod"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
</Configure>
|
|
@ -1,8 +1,11 @@
|
|||
[description]
|
||||
Enables NoSql session management with a MongoDB driver.
|
||||
|
||||
[name]
|
||||
mongo-session-store
|
||||
|
||||
[depend]
|
||||
webapp
|
||||
sessions
|
||||
|
||||
[files]
|
||||
maven://org.mongodb/mongo-java-driver/2.6.1|lib/nosql/mongo-java-driver-2.6.1.jar
|
||||
|
@ -17,3 +20,12 @@ The java driver for the MongoDB document-based database system is hosted on GitH
|
|||
http://www.mongodb.org/
|
||||
http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
|
||||
[xml]
|
||||
etc/jetty-mongo-session-store.xml
|
||||
|
||||
|
||||
[ini]
|
||||
#jetty.session.dbName=HttpSessions
|
||||
#jetty.session.collectionName=jettySessions
|
||||
#jetty.session.gracePeriod.seconds=3600
|
|
@ -1,37 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Get a reference to the session collection -->
|
||||
<!-- ===================================================================== -->
|
||||
<New class="com.mongodb.Mongo">
|
||||
<Call id="sessiondb" name="getDB">
|
||||
<Arg>HttpSessions</Arg>
|
||||
<Call id="sessioncollection" name="getCollection">
|
||||
<Arg>sessions</Arg>
|
||||
</Call>
|
||||
</Call>
|
||||
</New>
|
||||
|
||||
|
||||
<Get name="sessionHandler">
|
||||
<Set name="sessionManager">
|
||||
<New class="org.eclipse.jetty.nosql.mongodb.MongoSessionManager">
|
||||
<Set name="maxInactiveInterval">seconds</Set>
|
||||
<Get name="sessionDataStore">
|
||||
<Set name="dBCollection">
|
||||
<Ref id="sessioncollection"/>
|
||||
</Set>
|
||||
</Get>
|
||||
<Get name="sessionStore">
|
||||
<Set name="idlePassivationTimeoutSec">seconds</Set>
|
||||
<Set name="expiryTimeoutSec">seconds</Set>
|
||||
</Get>
|
||||
</New>
|
||||
</Set>
|
||||
</Get>
|
||||
|
||||
</Configure>
|
|
@ -22,16 +22,16 @@ package org.eclipse.jetty.nosql;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.server.session.AbstractSessionDataStore;
|
||||
import org.eclipse.jetty.server.session.AbstractSessionStore;
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
|
||||
|
||||
/**
|
||||
* NoSqlSessionDataStore
|
||||
* NoSqlSessionStore
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class NoSqlSessionDataStore extends AbstractSessionDataStore
|
||||
public abstract class NoSqlSessionStore extends AbstractSessionStore
|
||||
{
|
||||
|
||||
public class NoSqlSessionData extends SessionData
|
|
@ -1,138 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.nosql.mongodb;
|
||||
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.MongoException;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.eclipse.jetty.server.SessionIdManager;
|
||||
import org.eclipse.jetty.server.session.AbstractSessionStore;
|
||||
import org.eclipse.jetty.server.session.MemorySessionStore;
|
||||
import org.eclipse.jetty.server.session.SessionManager;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* MongoSessionManager
|
||||
* <p>
|
||||
* Clustered session manager using MongoDB as the shared DB instance.
|
||||
* The document model is an outer object that contains the elements:
|
||||
* <ul>
|
||||
* <li>"id" : session_id </li>
|
||||
* <li>"created" : create_time </li>
|
||||
* <li>"accessed": last_access_time </li>
|
||||
* <li>"maxIdle" : max_idle_time setting as session was created </li>
|
||||
* <li>"expiry" : time at which session should expire </li>
|
||||
* <li>"valid" : session_valid </li>
|
||||
* <li>"context" : a nested object containing 1 nested object per context for which the session id is in use
|
||||
* </ul>
|
||||
* Each of the nested objects inside the "context" element contains:
|
||||
* <ul>
|
||||
* <li>unique_context_name : nested object containing name:value pairs of the session attributes for that context</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* One of the name:value attribute pairs will always be the special attribute "__metadata__". The value
|
||||
* is an object representing a version counter which is incremented every time the attributes change.
|
||||
* </p>
|
||||
* <p>
|
||||
* For example:
|
||||
* <pre>
|
||||
* { "_id" : ObjectId("52845534a40b66410f228f23"),
|
||||
* "accessed" : NumberLong("1384818548903"),
|
||||
* "maxIdle" : 1,
|
||||
* "context" : { "::/contextA" : { "A" : "A",
|
||||
* "__metadata__" : { "version" : NumberLong(2) }
|
||||
* },
|
||||
* "::/contextB" : { "B" : "B",
|
||||
* "__metadata__" : { "version" : NumberLong(1) }
|
||||
* }
|
||||
* },
|
||||
* "created" : NumberLong("1384818548903"),
|
||||
* "expiry" : NumberLong("1384818549903"),
|
||||
* "id" : "w01ijx2vnalgv1sqrpjwuirprp7",
|
||||
* "valid" : true
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* In MongoDB, the nesting level is indicated by "." separators for the key name. Thus to
|
||||
* interact with a session attribute, the key is composed of:
|
||||
* <code>"context".unique_context_name.attribute_name</code>
|
||||
* Eg <code>"context"."::/contextA"."A"</code>
|
||||
*/
|
||||
@ManagedObject("Mongo Session Manager")
|
||||
public class MongoSessionManager extends SessionManager
|
||||
{
|
||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Access to MongoDB
|
||||
*/
|
||||
private DBCollection _dbSessions;
|
||||
|
||||
|
||||
private MongoSessionDataStore _sessionDataStore;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public MongoSessionManager() throws UnknownHostException, MongoException
|
||||
{
|
||||
setSessionStore(new MemorySessionStore(this));
|
||||
_sessionDataStore = new MongoSessionDataStore();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------ */
|
||||
@Override
|
||||
public void doStart() throws Exception
|
||||
{
|
||||
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public MongoSessionDataStore getSessionDataStore()
|
||||
{
|
||||
return _sessionDataStore;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------ */
|
||||
/**
|
||||
* returns the total number of session objects in the session store
|
||||
*
|
||||
* the count() operation itself is optimized to perform on the server side
|
||||
* and avoid loading to client side.
|
||||
* @return the session store count
|
||||
*/
|
||||
@ManagedAttribute("total number of known sessions in the store")
|
||||
public long getSessionStoreCount()
|
||||
{
|
||||
return _dbSessions.find().count();
|
||||
}
|
||||
|
||||
}
|
|
@ -36,14 +36,14 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.nosql.NoSqlSessionDataStore;
|
||||
import org.eclipse.jetty.nosql.NoSqlSessionStore;
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/**
|
||||
* MongoSessionDataStore
|
||||
* MongoSessionStore
|
||||
*
|
||||
* The document model is an outer object that contains the elements:
|
||||
* <ul>
|
||||
|
@ -88,7 +88,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* <code>"context".unique_context_name.attribute_name</code>
|
||||
* Eg <code>"context"."::/contextA"."A"</code>
|
||||
*/
|
||||
public class MongoSessionDataStore extends NoSqlSessionDataStore
|
||||
public class MongoSessionStore extends NoSqlSessionStore
|
||||
{
|
||||
|
||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
@ -166,7 +166,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#load(String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#load(String)
|
||||
*/
|
||||
@Override
|
||||
public SessionData load(String id) throws Exception
|
||||
|
@ -258,7 +258,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#delete(String)
|
||||
*/
|
||||
@Override
|
||||
public boolean delete(String id) throws Exception
|
||||
|
@ -318,7 +318,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean exists(String id) throws Exception
|
||||
|
@ -345,7 +345,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(Set)
|
||||
*/
|
||||
@Override
|
||||
public Set<String> doGetExpired(Set<String> candidates)
|
||||
|
@ -409,7 +409,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(String, SessionData, long)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStore(String, SessionData, long)
|
||||
*/
|
||||
@Override
|
||||
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
|
||||
|
@ -648,7 +648,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#isPassivating()
|
||||
*/
|
||||
@Override
|
||||
public boolean isPassivating()
|
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.nosql.mongodb;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.eclipse.jetty.server.session.AbstractSessionStoreFactory;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.server.session.SessionStore;
|
||||
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
|
||||
/**
|
||||
* MongoSessionStoreFactory
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class MongoSessionStoreFactory extends AbstractSessionStoreFactory
|
||||
{
|
||||
String _dbName;
|
||||
String _collectionName;
|
||||
|
||||
|
||||
/**
|
||||
* @return the dbName
|
||||
*/
|
||||
public String getDbName()
|
||||
{
|
||||
return _dbName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dbName the dbName to set
|
||||
*/
|
||||
public void setDbName(String dbName)
|
||||
{
|
||||
_dbName = dbName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the collectionName
|
||||
*/
|
||||
public String getCollectionName()
|
||||
{
|
||||
return _collectionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param collectionName the collectionName to set
|
||||
*/
|
||||
public void setCollectionName(String collectionName)
|
||||
{
|
||||
_collectionName = collectionName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws MongoException
|
||||
* @throws UnknownHostException
|
||||
* @see org.eclipse.jetty.server.session.SessionStoreFactory#getSessionStore(org.eclipse.jetty.server.session.SessionHandler)
|
||||
*/
|
||||
@Override
|
||||
public SessionStore getSessionStore(SessionHandler handler) throws Exception
|
||||
{
|
||||
MongoSessionStore store = new MongoSessionStore();
|
||||
store.setGracePeriodSec(getGracePeriodSec());
|
||||
store.setDBCollection(new Mongo().getDB(getDbName()).getCollection(getCollectionName()));
|
||||
return store;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.nosql.mongodb.jmx;
|
||||
|
||||
import org.eclipse.jetty.nosql.mongodb.MongoSessionManager;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.server.session.jmx.SessionManagerMBean;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
|
||||
@ManagedObject("Mongo Session Manager MBean")
|
||||
public class MongoSessionManagerMBean extends SessionManagerMBean
|
||||
{
|
||||
|
||||
public MongoSessionManagerMBean(Object managedObject)
|
||||
{
|
||||
super(managedObject);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String getObjectContextBasis()
|
||||
{
|
||||
if (_managed != null && _managed instanceof MongoSessionManager)
|
||||
{
|
||||
MongoSessionManager manager = (MongoSessionManager)_managed;
|
||||
|
||||
String basis = null;
|
||||
SessionHandler handler = manager.getSessionHandler();
|
||||
if (handler != null)
|
||||
{
|
||||
ContextHandler context =
|
||||
AbstractHandlerContainer.findContainerOf(handler.getServer(),
|
||||
ContextHandler.class,
|
||||
handler);
|
||||
if (context != null)
|
||||
basis = getContextName(context);
|
||||
}
|
||||
|
||||
if (basis != null)
|
||||
return basis;
|
||||
}
|
||||
return super.getObjectContextBasis();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
/**
|
||||
* Jetty NoSql : MongoDB Sessions JMX Integration
|
||||
*/
|
||||
package org.eclipse.jetty.nosql.mongodb.jmx;
|
||||
|
|
@ -26,6 +26,7 @@ import org.osgi.framework.FrameworkUtil;
|
|||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.service.event.Event;
|
||||
import org.osgi.service.event.EventAdmin;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
/**
|
||||
* Utility class for emiting OSGi EventAdmin events
|
||||
|
@ -41,14 +42,13 @@ public class EventSender
|
|||
|
||||
private static final EventSender __instance = new EventSender();
|
||||
private Bundle _myBundle;
|
||||
private EventAdmin _eventAdmin;
|
||||
private ServiceTracker _serviceTracker;
|
||||
|
||||
private EventSender ()
|
||||
{
|
||||
_myBundle = FrameworkUtil.getBundle(EventSender.class);
|
||||
ServiceReference ref = _myBundle.getBundleContext().getServiceReference(EventAdmin.class.getName());
|
||||
if (ref != null)
|
||||
_eventAdmin = (EventAdmin)_myBundle.getBundleContext().getService(ref);
|
||||
_serviceTracker = new ServiceTracker(_myBundle.getBundleContext(),EventAdmin.class.getName(),null);
|
||||
_serviceTracker.open();
|
||||
}
|
||||
|
||||
public static EventSender getInstance()
|
||||
|
@ -66,24 +66,24 @@ public class EventSender
|
|||
|
||||
public void send (String topic, Bundle wab, String contextPath, Exception ex)
|
||||
{
|
||||
if (_eventAdmin == null)
|
||||
return;
|
||||
EventAdmin service = (EventAdmin)_serviceTracker.getService();
|
||||
if (service != null) {
|
||||
Dictionary<String,Object> props = new Hashtable<String,Object>();
|
||||
props.put("bundle.symbolicName", wab.getSymbolicName());
|
||||
props.put("bundle.id", wab.getBundleId());
|
||||
props.put("bundle", wab);
|
||||
props.put("bundle.version", wab.getVersion());
|
||||
props.put("context.path", contextPath);
|
||||
props.put("timestamp", System.currentTimeMillis());
|
||||
props.put("extender.bundle", _myBundle);
|
||||
props.put("extender.bundle.symbolicName", _myBundle.getSymbolicName());
|
||||
props.put("extender.bundle.id", _myBundle.getBundleId());
|
||||
props.put("extender.bundle.version", _myBundle.getVersion());
|
||||
|
||||
Dictionary<String,Object> props = new Hashtable<String,Object>();
|
||||
props.put("bundle.symbolicName", wab.getSymbolicName());
|
||||
props.put("bundle.id", wab.getBundleId());
|
||||
props.put("bundle", wab);
|
||||
props.put("bundle.version", wab.getVersion());
|
||||
props.put("context.path", contextPath);
|
||||
props.put("timestamp", System.currentTimeMillis());
|
||||
props.put("extender.bundle", _myBundle);
|
||||
props.put("extender.bundle.symbolicName", _myBundle.getSymbolicName());
|
||||
props.put("extender.bundle.id", _myBundle.getBundleId());
|
||||
props.put("extender.bundle.version", _myBundle.getVersion());
|
||||
if (FAILED_EVENT.equalsIgnoreCase(topic) && ex != null)
|
||||
props.put("exception", ex);
|
||||
|
||||
if (FAILED_EVENT.equalsIgnoreCase(topic) && ex != null)
|
||||
props.put("exception", ex);
|
||||
|
||||
_eventAdmin.sendEvent(new Event(topic, props));
|
||||
service.sendEvent(new Event(topic, props));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ public class OSGiClassLoader extends URLClassLoader
|
|||
|
||||
private Bundle _bundle;
|
||||
private ClassLoader _osgiBundleClassLoader;
|
||||
private boolean _lookInOsgiFirst = true;
|
||||
private ClassLoader _parent;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -69,14 +68,6 @@ public class OSGiClassLoader extends URLClassLoader
|
|||
boolean tried_parent= false;
|
||||
|
||||
|
||||
if (_parent!=null && !_lookInOsgiFirst)
|
||||
{
|
||||
tried_parent= true;
|
||||
|
||||
if (_parent!=null)
|
||||
url= _parent.getResource(name);
|
||||
}
|
||||
|
||||
if (url == null)
|
||||
{
|
||||
url = _osgiBundleClassLoader.getResource(name);
|
||||
|
@ -118,21 +109,6 @@ public class OSGiClassLoader extends URLClassLoader
|
|||
ClassNotFoundException ex= null;
|
||||
boolean tried_parent= false;
|
||||
|
||||
if (c == null && _parent!=null && !_lookInOsgiFirst)
|
||||
{
|
||||
tried_parent= true;
|
||||
try
|
||||
{
|
||||
c= _parent.loadClass(name);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("loaded " + c);
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
ex= e;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == null)
|
||||
{
|
||||
try
|
||||
|
@ -166,14 +142,7 @@ public class OSGiClassLoader extends URLClassLoader
|
|||
{
|
||||
Enumeration<URL> osgiUrls = _osgiBundleClassLoader.getResources(name);
|
||||
Enumeration<URL> urls = super.getResources(name);
|
||||
if (_lookInOsgiFirst)
|
||||
{
|
||||
return Collections.enumeration(toList(osgiUrls, urls));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Collections.enumeration(toList(urls, osgiUrls));
|
||||
}
|
||||
return Collections.enumeration(toList(osgiUrls, urls));
|
||||
}
|
||||
|
||||
|
||||
|
@ -181,21 +150,7 @@ public class OSGiClassLoader extends URLClassLoader
|
|||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException
|
||||
{
|
||||
try
|
||||
{
|
||||
return _lookInOsgiFirst ? _osgiBundleClassLoader.loadClass(name) : super.findClass(name);
|
||||
}
|
||||
catch (ClassNotFoundException cne)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _lookInOsgiFirst ? super.findClass(name) : _osgiBundleClassLoader.loadClass(name);
|
||||
}
|
||||
catch (ClassNotFoundException cne2)
|
||||
{
|
||||
throw cne;
|
||||
}
|
||||
}
|
||||
return _osgiBundleClassLoader.loadClass(name);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -316,15 +316,15 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration impl
|
|||
}
|
||||
|
||||
//session-config
|
||||
if (context.getSessionHandler().getSessionManager() != null)
|
||||
if (context.getSessionHandler() != null)
|
||||
{
|
||||
out.openTag("session-config");
|
||||
int maxInactiveSec = context.getSessionHandler().getSessionManager().getMaxInactiveInterval();
|
||||
int maxInactiveSec = context.getSessionHandler().getMaxInactiveInterval();
|
||||
out.tag("session-timeout", (maxInactiveSec==0?"0":Integer.toString(maxInactiveSec/60)));
|
||||
|
||||
|
||||
//cookie-config
|
||||
SessionCookieConfig cookieConfig = context.getSessionHandler().getSessionManager().getSessionCookieConfig();
|
||||
SessionCookieConfig cookieConfig = context.getSessionHandler().getSessionCookieConfig();
|
||||
if (cookieConfig != null)
|
||||
{
|
||||
out.openTag("cookie-config");
|
||||
|
@ -347,7 +347,7 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration impl
|
|||
}
|
||||
|
||||
// tracking-modes
|
||||
Set<SessionTrackingMode> modes =context. getSessionHandler().getSessionManager().getEffectiveSessionTrackingModes();
|
||||
Set<SessionTrackingMode> modes =context. getSessionHandler().getEffectiveSessionTrackingModes();
|
||||
if (modes != null)
|
||||
{
|
||||
for (SessionTrackingMode mode:modes)
|
||||
|
|
|
@ -118,7 +118,7 @@ public abstract class LoginAuthenticator implements Authenticator
|
|||
s.renewId(request);
|
||||
s.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
|
||||
if (s.isIdChanged() && response != null && (response instanceof Response))
|
||||
((Response)response).addCookie(s.getSessionManager().getSessionCookie(s, request.getContextPath(), request.isSecure()));
|
||||
((Response)response).addCookie(s.getSessionHandler().getSessionCookie(s, request.getContextPath(), request.isSecure()));
|
||||
LOG.debug("renew {}->{}",oldId,s.getId());
|
||||
}
|
||||
else
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Configure a factory for in-memory Session objects -->
|
||||
<!-- ===================================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.session.DefaultSessionCacheFactory">
|
||||
<Set name="idlePassivationTimeoutSec"><Property name="jetty.session.idlePassivationTimeout.seconds" default="0" /></Set>
|
||||
<Set name="passivateOnComplete"><Property name="jetty.session.passivateOnComplete" default="false" /></Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Configure a factory for FileSessionStores -->
|
||||
<!-- ===================================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.session.FileSessionStoreFactory">
|
||||
<Set name="deleteUnrestorableFiles"><Property name="jetty.session.deleteUnrestorableFiles" default="false" /></Set>
|
||||
<Set name="storeDir"><Property name="jetty.session.storeDir"/></Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Configure>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
|
||||
<New id="databaseAdaptor" class="org.eclipse.jetty.server.session.DatabaseAdaptor">
|
||||
<Set name="DatasourceName"><Property name="jetty.session.datasourceName" default="/jdbc/sessions" /></Set>
|
||||
</New>
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<New id="databaseAdaptor" class="org.eclipse.jetty.server.session.DatabaseAdaptor">
|
||||
<Call name="setDriverInfo">
|
||||
<Arg><Property name="jetty.session.driverClass"/></Arg>
|
||||
<Arg><Property name="jetty.session.driverUrl"/></Arg>
|
||||
</Call>
|
||||
</New>
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Configure a factory for JDBCSessionStores -->
|
||||
<!-- ===================================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.session.JDBCSessionStoreFactory">
|
||||
<Set name="gracePeriod"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
|
||||
<Set name="databaseAdaptor">
|
||||
<Ref id="databaseAdaptor"/>
|
||||
</Set>
|
||||
<Set name="sessionTableSchema">
|
||||
<New
|
||||
class="org.eclipse.jetty.server.session.JDBCSessionStore.SessionTableSchema">
|
||||
<Set name="accessTimeColumn">
|
||||
<Property name="jetty.sessionTableSchema.accessTimeColumn" default="accessTime" />
|
||||
</Set>
|
||||
<Set name="contextPathColumn">
|
||||
<Property name="jetty.sessionTableSchema.contextPathColumn" default="contextPath" />
|
||||
</Set>
|
||||
<Set name="cookieTimeColumn">
|
||||
<Property name="jetty.sessionTableSchema.cookieTimeColumn" default="cookieTime" />
|
||||
</Set>
|
||||
<Set name="createTimeColumn">
|
||||
<Property name="jetty.sessionTableSchema.createTimeColumn" default="createTime" />
|
||||
</Set>
|
||||
<Set name="expiryTimeColumn">
|
||||
<Property name="jetty.sessionTableSchema.expiryTimeColumn" default="expiryTime" />
|
||||
</Set>
|
||||
<Set name="lastAccessTimeColumn">
|
||||
<Property name="jetty.sessionTableSchema.lastAccessTimeColumn" default="lastAccessTime" />
|
||||
</Set>
|
||||
<Set name="lastSavedTimeColumn">
|
||||
<Property name="jetty.sessionTableSchema.lastSavedTimeColumn" default="lastSavedTime" />
|
||||
</Set>
|
||||
<Set name="idColumn">
|
||||
<Property name="jetty.sessionTableSchema.idColumn" default="sessionId" />
|
||||
</Set>
|
||||
<Set name="lastNodeColumn">
|
||||
<Property name="jetty.sessionTableSchema.lastNodeColumn" default="lastNode" />
|
||||
</Set>
|
||||
<Set name="virtualHostColumn">
|
||||
<Property name="jetty.sessionTableSchema.virtualHostColumn" default="virtualHost" />
|
||||
</Set>
|
||||
<Set name="maxIntervalColumn">
|
||||
<Property name="jetty.sessionTableSchema.maxIntervalColumn" default="maxInterval" />
|
||||
</Set>
|
||||
<Set name="mapColumn">
|
||||
<Property name="jetty.sessionTableSchema.mapColumn" default="map" />
|
||||
</Set>
|
||||
<Set name="tableName">
|
||||
<Property name="jetty.sessionTableSchema.table" default="JettySessions" />
|
||||
</Set>
|
||||
</New>
|
||||
</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
</Configure>
|
|
@ -12,14 +12,14 @@
|
|||
<Arg>
|
||||
<Ref refid="Server"/>
|
||||
</Arg>
|
||||
<Set name="workerName"><Property name="jetty.sessionIdManager.workerName" default="node1"/></Set>
|
||||
<Set name="workerName"><Property name="jetty.sessionIdManager.workerName"><Default>node<Env name="JETTY_WORKER_INSTANCE" default="0"/></Default></Property></Set>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Configure a session inspector to help with scavenging -->
|
||||
<!-- Configure a session housekeeper to help with scavenging -->
|
||||
<!-- ===================================================================== -->
|
||||
<Set name="sessionInspector">
|
||||
<New id="idMgr" class="org.eclipse.jetty.server.session.PeriodicSessionInspector">
|
||||
<Set name="intervalSec"><Property name="jetty.sessionInspectionInterval.seconds" default="60"/></Set>
|
||||
<Set name="sessionHouseKeeper">
|
||||
<New class="org.eclipse.jetty.server.session.HouseKeeper">
|
||||
<Set name="intervalSec"><Property name="jetty.sessionScavengeInterval.seconds" default="600"/></Set>
|
||||
</New>
|
||||
</Set>
|
||||
</New>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
[description]
|
||||
Always in memory session objects.
|
||||
|
||||
|
||||
[name]
|
||||
default-session-cache
|
||||
|
||||
|
||||
|
||||
[xml]
|
||||
etc/jetty-default-session-cache.xml
|
||||
|
||||
|
||||
[ini-template]
|
||||
#jetty.session.idlePassivationTimeout.seconds=0
|
||||
#jetty.session.passivateOnComplete=false
|
|
@ -0,0 +1,21 @@
|
|||
[description]
|
||||
Enables session storage in files.
|
||||
|
||||
|
||||
[name]
|
||||
file-session-store
|
||||
|
||||
|
||||
|
||||
[xml]
|
||||
etc/jetty-file-session-store.xml
|
||||
|
||||
|
||||
[depend]
|
||||
sessions
|
||||
|
||||
[ini-template]
|
||||
#jetty.session.storeDir=
|
||||
#jetty.session.deleteUnrestorableFiles=false
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
[description]
|
||||
Enables JDBC session storage.
|
||||
|
||||
|
||||
[name]
|
||||
jdbc-session-store
|
||||
|
||||
|
||||
|
||||
[xml]
|
||||
etc/jetty-jdbc-session-store.xml
|
||||
|
||||
|
||||
[depend]
|
||||
sessions
|
||||
sessions/jdbc/${db-connection-type}
|
||||
|
||||
|
||||
|
||||
[ini]
|
||||
db-connection-type=datasource
|
||||
|
||||
|
||||
|
||||
##
|
||||
##JDBC Session properties
|
||||
##
|
||||
|
||||
#jetty.session.gracePeriod.seconds=3600
|
||||
|
||||
## Connection type:driver
|
||||
#db-connection-type=driver
|
||||
#jetty.session.driverClass=
|
||||
#jetty.session.driverUrl=
|
||||
|
||||
## Connection type:Datasource
|
||||
#db-connection-type=datasource
|
||||
#jetty.session.datasourceName=/jdbc/sessions
|
||||
|
||||
## Session table schema
|
||||
#jetty.sessionTableSchema.accessTimeColumn=accessTime
|
||||
#jetty.sessionTableSchema.contextPathColumn=contextPath
|
||||
#jetty.sessionTableSchema.cookieTimeColumn=cookieTime
|
||||
#jetty.sessionTableSchema.createTimeColumn=createTime
|
||||
#jetty.sessionTableSchema.expiryTimeColumn=expiryTime
|
||||
#jetty.sessionTableSchema.lastAccessTimeColumn=lastAccessTime
|
||||
#jetty.sessionTableSchema.lastSavedTimeColumn=lastSavedTime
|
||||
#jetty.sessionTableSchema.idColumn="sessionId
|
||||
#jetty.sessionTableSchema.lastNodeColumn=lastNode
|
||||
#jetty.sessionTableSchema.virtualHostColumn=virtualHost
|
||||
#jetty.sessionTableSchema.maxIntervalColumn=maxInterval
|
||||
#jetty.sessionTableSchema.mapColumn=map
|
||||
#jetty.sessionTableSchema.table=JettySessions
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,13 +1,20 @@
|
|||
[description]
|
||||
Enables basic sessions.
|
||||
Enables session id management and scavenging.
|
||||
|
||||
|
||||
[name]
|
||||
sessions
|
||||
|
||||
|
||||
|
||||
[xml]
|
||||
etc/jetty-sessions.xml
|
||||
|
||||
|
||||
[ini-template]
|
||||
|
||||
## The name to uniquely identify this server instance
|
||||
#jetty.sssionIdManager.workerName=node1
|
||||
#jetty.sessionIdManager.workerName=node1
|
||||
|
||||
## How frequently sessions are inspected
|
||||
#jetty.sessionInspectionInterval.seconds=60
|
||||
## Period between runs of the session scavenger (in seconds)
|
||||
#jetty.sessionScavengeInterval.seconds=60
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
[description]
|
||||
JDBC Datasource connections for session storage
|
||||
|
||||
[name]
|
||||
datasource
|
||||
|
||||
|
||||
[xml]
|
||||
etc/jetty-jdbc-session-store-datasource.xml
|
|
@ -0,0 +1,9 @@
|
|||
[description]
|
||||
JDBC Driver connections for session storage
|
||||
|
||||
[name]
|
||||
driver
|
||||
|
||||
|
||||
[xml]
|
||||
etc/jetty-jdbc-session-store-driver.xml
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
|
||||
<Get name="sessionHandler">
|
||||
<Set name="sessionManager">
|
||||
<New class="org.eclipse.jetty.server.session.FileSessionManager">
|
||||
<Set name="maxInactiveInterval">seconds</Set>
|
||||
<Get name="sessionDataStore">
|
||||
<Set name="storeDir">filename</Set>
|
||||
<Set name="deleteUnrestorableFiles">boolean</Set>
|
||||
</Get>
|
||||
<Get name="sessionStore">
|
||||
<Set name="idlePassivationTimeoutSec">seconds</Set>
|
||||
<Set name="expiryTimeoutSec">seconds</Set>
|
||||
</Get>
|
||||
</New>
|
||||
</Set>
|
||||
</Get>
|
||||
|
||||
</Configure>
|
|
@ -1,50 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
|
||||
|
||||
<Get name="sessionHandler">
|
||||
<Set name="sessionManager">
|
||||
<New class="org.eclipse.jetty.server.session.JDBCSessionManager">
|
||||
<Set name="maxInactiveInterval">seconds</Set>
|
||||
<Get name="sessionDataStore">
|
||||
<Set name="gracePeriod">seconds</Set>
|
||||
<Set name="loadAttempts">integer</Set>
|
||||
<Set name="deleteUnloadableSessions">boolean</Set>
|
||||
<Set name="databaseAdaptor">
|
||||
<New class="org.eclipse.jetty.server.session.DatabaseAdaptor">
|
||||
<!-- or alternative -->
|
||||
<Call name="setDriverInfo">
|
||||
<Arg>driver class</Arg>
|
||||
<Arg>URL</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Set>
|
||||
<Set name="sessionTableSchema">
|
||||
<New class="org.eclipse.jetty.server.session.JDBCSessionDataStore.SessionTableSchema">
|
||||
<Set name="tableName">JettySessions</Set>
|
||||
<Set name="idColumn">sessionId</Set>
|
||||
<Set name="accessTimeColumn">accessTime</Set>
|
||||
<Set name="contextPathColumn">contextPath</Set>
|
||||
<Set nmae="cookieTimeColumn">cookieTime</Set>
|
||||
<Set name="createTimeColumn">createTime</Set>
|
||||
<Set name="expiryTimeColumn">expiryTime</Set>
|
||||
<Set name="lastAccessTimeColumn">lastAccessTime</Set>
|
||||
<Set name="lastNodeColumn">lastNode</Set>
|
||||
<Set name="lastSavedTimeColumn">lastSavedTime</Set>
|
||||
<Set name="mapColumn">map</Set>
|
||||
<Set name="maxIntervalColumn">maxInterval</Set>
|
||||
<Set name="virtualHostColumn">virtualHost</Set>
|
||||
</New>
|
||||
</Get>
|
||||
<Get name="sessionStore">
|
||||
<Set name="idlePassivationTimeoutSec">seconds</Set>
|
||||
<Set name="expiryTimeoutSec">seconds</Set>
|
||||
</Get>
|
||||
</New>
|
||||
</Set>
|
||||
</Get>
|
||||
|
||||
</Configure>
|
|
@ -78,7 +78,7 @@ import org.eclipse.jetty.http.MimeTypes;
|
|||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
||||
import org.eclipse.jetty.server.session.Session;
|
||||
import org.eclipse.jetty.server.session.SessionManager;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
import org.eclipse.jetty.util.AttributesMap;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
|
@ -194,7 +194,7 @@ public class Request implements HttpServletRequest
|
|||
private Map<Object, HttpSession> _savedNewSessions;
|
||||
private UserIdentity.Scope _scope;
|
||||
private HttpSession _session;
|
||||
private SessionManager _sessionManager;
|
||||
private SessionHandler _sessionHandler;
|
||||
private long _timeStamp;
|
||||
private MultiPartInputStreamParser _multiPartInputStream; //if the request is a multi-part mime
|
||||
private AsyncContextState _async;
|
||||
|
@ -1478,7 +1478,7 @@ public class Request implements HttpServletRequest
|
|||
if (getRemoteUser() != null)
|
||||
s.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
|
||||
if (s.isIdChanged())
|
||||
_channel.getResponse().addCookie(_sessionManager.getSessionCookie(s, getContextPath(), isSecure()));
|
||||
_channel.getResponse().addCookie(_sessionHandler.getSessionCookie(s, getContextPath(), isSecure()));
|
||||
}
|
||||
|
||||
return session.getId();
|
||||
|
@ -1503,7 +1503,7 @@ public class Request implements HttpServletRequest
|
|||
{
|
||||
if (_session != null)
|
||||
{
|
||||
if (_sessionManager != null && !_sessionManager.isValid(_session))
|
||||
if (_sessionHandler != null && !_sessionHandler.isValid(_session))
|
||||
_session = null;
|
||||
else
|
||||
return _session;
|
||||
|
@ -1515,11 +1515,11 @@ public class Request implements HttpServletRequest
|
|||
if (getResponse().isCommitted())
|
||||
throw new IllegalStateException("Response is committed");
|
||||
|
||||
if (_sessionManager == null)
|
||||
if (_sessionHandler == null)
|
||||
throw new IllegalStateException("No SessionManager");
|
||||
|
||||
_session = _sessionManager.newHttpSession(this);
|
||||
HttpCookie cookie = _sessionManager.getSessionCookie(_session,getContextPath(),isSecure());
|
||||
_session = _sessionHandler.newHttpSession(this);
|
||||
HttpCookie cookie = _sessionHandler.getSessionCookie(_session,getContextPath(),isSecure());
|
||||
if (cookie != null)
|
||||
_channel.getResponse().addCookie(cookie);
|
||||
|
||||
|
@ -1530,9 +1530,9 @@ public class Request implements HttpServletRequest
|
|||
/**
|
||||
* @return Returns the sessionManager.
|
||||
*/
|
||||
public SessionManager getSessionManager()
|
||||
public SessionHandler getSessionHandler()
|
||||
{
|
||||
return _sessionManager;
|
||||
return _sessionHandler;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1682,7 +1682,7 @@ public class Request implements HttpServletRequest
|
|||
return false;
|
||||
|
||||
HttpSession session = getSession(false);
|
||||
return (session != null && _sessionManager.getSessionIdManager().getId(_requestedSessionId).equals(_sessionManager.getId(session)));
|
||||
return (session != null && _sessionHandler.getSessionIdManager().getId(_requestedSessionId).equals(_sessionHandler.getId(session)));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1831,7 +1831,7 @@ public class Request implements HttpServletRequest
|
|||
_requestedSessionIdFromCookie = false;
|
||||
_secure=false;
|
||||
_session = null;
|
||||
_sessionManager = null;
|
||||
_sessionHandler = null;
|
||||
_scope = null;
|
||||
_servletPath = null;
|
||||
_timeStamp = 0;
|
||||
|
@ -2185,9 +2185,9 @@ public class Request implements HttpServletRequest
|
|||
* @param sessionManager
|
||||
* The sessionManager to set.
|
||||
*/
|
||||
public void setSessionManager(SessionManager sessionManager)
|
||||
public void setSessionHandler(SessionHandler sessionHandler)
|
||||
{
|
||||
_sessionManager = sessionManager;
|
||||
_sessionHandler = sessionHandler;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.eclipse.jetty.http.CompressedContentFormat.BR;
|
||||
import static org.eclipse.jetty.http.CompressedContentFormat.GZIP;
|
||||
import static org.eclipse.jetty.http.HttpFields.qualityList;
|
||||
import static org.eclipse.jetty.http.HttpHeaderValue.IDENTITY;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -32,6 +33,7 @@ import java.util.Collection;
|
|||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.RequestDispatcher;
|
||||
|
@ -48,6 +50,7 @@ import org.eclipse.jetty.http.HttpHeader;
|
|||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.PreEncodedHttpField;
|
||||
import org.eclipse.jetty.http.QuotedCSV;
|
||||
import org.eclipse.jetty.http.QuotedQualityCSV;
|
||||
import org.eclipse.jetty.io.WriterOutputStream;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
@ -73,6 +76,9 @@ public abstract class ResourceService
|
|||
private boolean _dirAllowed=true;
|
||||
private boolean _redirectWelcome=false;
|
||||
private CompressedContentFormat[] _precompressedFormats=new CompressedContentFormat[0];
|
||||
private String[] _preferredEncodingOrder =new String[0];
|
||||
private final Map<String, List<String>> _preferredEncodingOrderCache = new ConcurrentHashMap<>();
|
||||
private int _encodingCacheSize=100;
|
||||
private boolean _pathInfoOnly=false;
|
||||
private boolean _etags=false;
|
||||
private HttpField _cacheControl;
|
||||
|
@ -126,6 +132,17 @@ public abstract class ResourceService
|
|||
public void setPrecompressedFormats(CompressedContentFormat[] precompressedFormats)
|
||||
{
|
||||
_precompressedFormats = precompressedFormats;
|
||||
_preferredEncodingOrder = stream(_precompressedFormats).map(f->f._encoding).toArray(String[]::new);
|
||||
}
|
||||
|
||||
public void setEncodingCacheSize(int encodingCacheSize)
|
||||
{
|
||||
_encodingCacheSize = encodingCacheSize;
|
||||
}
|
||||
|
||||
public int getEncodingCacheSize()
|
||||
{
|
||||
return _encodingCacheSize;
|
||||
}
|
||||
|
||||
public boolean isPathInfoOnly()
|
||||
|
@ -249,7 +266,7 @@ public abstract class ResourceService
|
|||
// Tell caches that response may vary by accept-encoding
|
||||
response.addHeader(HttpHeader.VARY.asString(),HttpHeader.ACCEPT_ENCODING.asString());
|
||||
|
||||
List<String> preferredEncodings = HttpFields.qualityList(request.getHeaders(HttpHeader.ACCEPT_ENCODING.asString()));
|
||||
List<String> preferredEncodings = getPreferredEncodingOrder(request);
|
||||
CompressedContentFormat precompressedContentEncoding = getBestPrecompressedContent(preferredEncodings, precompressedContents.keySet());
|
||||
if (precompressedContentEncoding!=null)
|
||||
{
|
||||
|
@ -285,6 +302,40 @@ public abstract class ResourceService
|
|||
}
|
||||
}
|
||||
|
||||
private List<String> getPreferredEncodingOrder(HttpServletRequest request)
|
||||
{
|
||||
Enumeration<String> headers = request.getHeaders(HttpHeader.ACCEPT_ENCODING.asString());
|
||||
if (!headers.hasMoreElements())
|
||||
return emptyList();
|
||||
|
||||
String key = headers.nextElement();
|
||||
if (headers.hasMoreElements())
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(key.length()*2);
|
||||
do
|
||||
{
|
||||
sb.append(',').append(headers.nextElement());
|
||||
} while (headers.hasMoreElements());
|
||||
key = sb.toString();
|
||||
}
|
||||
|
||||
List<String> values=_preferredEncodingOrderCache.get(key);
|
||||
if (values==null)
|
||||
{
|
||||
QuotedQualityCSV encodingQualityCSV = new QuotedQualityCSV(_preferredEncodingOrder);
|
||||
encodingQualityCSV.addValue(key);
|
||||
values=encodingQualityCSV.getValues();
|
||||
|
||||
// keep cache size in check even if we get strange/malicious input
|
||||
if (_preferredEncodingOrderCache.size()>_encodingCacheSize)
|
||||
_preferredEncodingOrderCache.clear();
|
||||
|
||||
_preferredEncodingOrderCache.put(key,values);
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
private CompressedContentFormat getBestPrecompressedContent(List<String> preferredEncodings, Collection<CompressedContentFormat> availableFormats)
|
||||
{
|
||||
if (availableFormats.isEmpty())
|
||||
|
|
|
@ -53,7 +53,7 @@ import org.eclipse.jetty.http.PreEncodedHttpField;
|
|||
import org.eclipse.jetty.io.RuntimeIOException;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ErrorHandler;
|
||||
import org.eclipse.jetty.server.session.SessionManager;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
|
@ -391,7 +391,8 @@ public class Response implements HttpServletResponse
|
|||
public String encodeURL(String url)
|
||||
{
|
||||
final Request request = _channel.getRequest();
|
||||
SessionManager sessionManager = request.getSessionManager();
|
||||
SessionHandler sessionManager = request.getSessionHandler();
|
||||
|
||||
if (sessionManager == null)
|
||||
return url;
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import java.util.Set;
|
|||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.eclipse.jetty.server.session.SessionManager;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
|
||||
/**
|
||||
|
@ -109,8 +109,8 @@ public interface SessionIdManager extends LifeCycle
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Get the set of all session managers for this node
|
||||
* @return the set of session managers
|
||||
* Get the set of all session handlers for this node
|
||||
* @return the set of session handlers
|
||||
*/
|
||||
public Set<SessionManager> getSessionManagers();
|
||||
public Set<SessionHandler> getSessionHandlers();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,639 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.thread.Locker.Lock;
|
||||
|
||||
/**
|
||||
* AbstractSessionCache
|
||||
*
|
||||
* Basic behaviour for maintaining an in-memory store of Session objects and
|
||||
* making sure that any backing SessionDataStore is kept in sync.
|
||||
*/
|
||||
public abstract class AbstractSessionCache extends AbstractLifeCycle implements SessionCache
|
||||
{
|
||||
final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
protected SessionStore _sessionStore;
|
||||
protected final SessionHandler _handler;
|
||||
protected SessionContext _context;
|
||||
protected int _idlePassivationTimeoutSec;
|
||||
private boolean _passivateOnComplete;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Session object from pre-existing session data
|
||||
* @param data the session data
|
||||
* @return a new Session object
|
||||
*/
|
||||
public abstract Session newSession (SessionData data);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Session for a request.
|
||||
*
|
||||
* @param request the request
|
||||
* @param data the session data
|
||||
* @return the new session
|
||||
*/
|
||||
public abstract Session newSession (HttpServletRequest request, SessionData data);
|
||||
|
||||
|
||||
/**
|
||||
* Get the session matching the key
|
||||
* @param id session id
|
||||
* @return the Session object matching the id
|
||||
*/
|
||||
public abstract Session doGet(String id);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Put the session into the map if it wasn't already there
|
||||
*
|
||||
* @param id the identity of the session
|
||||
* @param session the session object
|
||||
* @return null if the session wasn't already in the map, or the existing entry otherwise
|
||||
*/
|
||||
public abstract Session doPutIfAbsent (String id, Session session);
|
||||
|
||||
|
||||
/**
|
||||
* Replace the mapping from id to oldValue with newValue
|
||||
* @param id the id
|
||||
* @param oldValue the old value
|
||||
* @param newValue the new value
|
||||
* @return true if replacement was done
|
||||
*/
|
||||
public abstract boolean doReplace (String id, Session oldValue, Session newValue);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Remove the session with this identity from the store
|
||||
* @param id the id
|
||||
* @return true if removed false otherwise
|
||||
*/
|
||||
public abstract Session doDelete (String id);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* PlaceHolder
|
||||
*/
|
||||
protected class PlaceHolderSession extends Session
|
||||
{
|
||||
|
||||
/**
|
||||
* @param data the session data
|
||||
*/
|
||||
public PlaceHolderSession(SessionData data)
|
||||
{
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public AbstractSessionCache (SessionHandler manager)
|
||||
{
|
||||
_handler = manager;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the SessionManger
|
||||
*/
|
||||
public SessionHandler getSessionHandler()
|
||||
{
|
||||
return _handler;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionCache#initialize(org.eclipse.jetty.server.session.SessionContext)
|
||||
*/
|
||||
public void initialize (SessionContext context)
|
||||
{
|
||||
if (isStarted())
|
||||
throw new IllegalStateException("Context set after session store started");
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
|
||||
*/
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
if (_sessionStore == null)
|
||||
throw new IllegalStateException ("No session data store configured");
|
||||
|
||||
if (_handler == null)
|
||||
throw new IllegalStateException ("No session manager");
|
||||
|
||||
if (_context == null)
|
||||
throw new IllegalStateException ("No ContextId");
|
||||
|
||||
_sessionStore.initialize(_context);
|
||||
_sessionStore.start();
|
||||
|
||||
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
|
||||
*/
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
_sessionStore.stop();
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the SessionStore or null if there isn't one
|
||||
*/
|
||||
public SessionStore getSessionStore()
|
||||
{
|
||||
return _sessionStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionCache#setSessionStore(org.eclipse.jetty.server.session.SessionStore)
|
||||
*/
|
||||
public void setSessionStore(SessionStore sessionStore)
|
||||
{
|
||||
_sessionStore = sessionStore;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionCache#getIdlePassivationTimeoutSec()
|
||||
*/
|
||||
public int getIdlePassivationTimeoutSec()
|
||||
{
|
||||
return _idlePassivationTimeoutSec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionCache#setIdlePassivationTimeoutSec(int)
|
||||
*/
|
||||
public void setIdlePassivationTimeoutSec(int idleTimeoutSec)
|
||||
{
|
||||
_idlePassivationTimeoutSec = idleTimeoutSec;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a session object.
|
||||
*
|
||||
* If the session object is not in this session store, try getting
|
||||
* the data for it from a SessionDataStore associated with the
|
||||
* session manager.
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.SessionCache#get(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Session get(String id) throws Exception
|
||||
{
|
||||
Session session = null;
|
||||
Exception ex = null;
|
||||
|
||||
while (true)
|
||||
{
|
||||
session = doGet(id);
|
||||
|
||||
if (_sessionStore == null)
|
||||
break; //can't load any session data so just return null or the session object
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Session not found locally, attempting to load");
|
||||
|
||||
//didn't get a session, try and create one and put in a placeholder for it
|
||||
PlaceHolderSession phs = new PlaceHolderSession (new SessionData(id, null, null,0,0,0,0));
|
||||
Lock phsLock = phs.lock();
|
||||
Session s = doPutIfAbsent(id, phs);
|
||||
if (s == null)
|
||||
{
|
||||
//My placeholder won, go ahead and load the full session data
|
||||
try
|
||||
{
|
||||
session = loadSession(id);
|
||||
if (session == null)
|
||||
{
|
||||
//session does not exist, remove the placeholder
|
||||
doDelete(id);
|
||||
phsLock.close();
|
||||
break;
|
||||
}
|
||||
|
||||
try (Lock lock = session.lock())
|
||||
{
|
||||
//swap it in instead of the placeholder
|
||||
boolean success = doReplace(id, phs, session);
|
||||
if (!success)
|
||||
{
|
||||
//something has gone wrong, it should have been our placeholder
|
||||
doDelete(id);
|
||||
session = null;
|
||||
LOG.warn("Replacement of placeholder for session {} failed", id);
|
||||
phsLock.close();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//successfully swapped in the session
|
||||
session.setTimeout (); //TODO start the session timer
|
||||
phsLock.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ex = e; //remember a problem happened loading the session
|
||||
doDelete(id); //remove the placeholder
|
||||
phsLock.close();
|
||||
session = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//my placeholder didn't win, check the session returned
|
||||
phsLock.close();
|
||||
try (Lock lock = s.lock())
|
||||
{
|
||||
//is it a placeholder? or is it passivated? In both cases, chuck it away and start again
|
||||
if (s.isPassivated() || s instanceof PlaceHolderSession)
|
||||
{
|
||||
session = null;
|
||||
continue;
|
||||
}
|
||||
session = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//check the session returned
|
||||
try (Lock lock = session.lock())
|
||||
{
|
||||
//is it a placeholder? or is it passivated? In both cases, chuck it away and start again
|
||||
if (session.isPassivated() || session instanceof PlaceHolderSession)
|
||||
{
|
||||
session = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
//got the session
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ex != null)
|
||||
throw ex;
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the info for the session from the session data store
|
||||
*
|
||||
* @param id the id
|
||||
* @return a Session object filled with data or null if the session doesn't exist
|
||||
* @throws Exception
|
||||
*/
|
||||
private Session loadSession (String id)
|
||||
throws Exception
|
||||
{
|
||||
SessionData data = null;
|
||||
Session session = null;
|
||||
|
||||
if (_sessionStore == null)
|
||||
return null; //can't load it
|
||||
|
||||
try
|
||||
{
|
||||
data =_sessionStore.load(id);
|
||||
|
||||
if (data == null) //session doesn't exist
|
||||
return null;
|
||||
|
||||
session = newSession(data);
|
||||
session.setSessionHandler(_handler);
|
||||
return session;
|
||||
}
|
||||
catch (UnreadableSessionDataException e)
|
||||
{
|
||||
//can't load the session, delete it
|
||||
_sessionStore.delete(id);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the Session object back into the session store.
|
||||
*
|
||||
* This should be called by Session.complete when a request exists the session.
|
||||
*
|
||||
* If the session manager supports a session data store, write the
|
||||
* session data through to the session data store.
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.SessionCache#put(java.lang.String, org.eclipse.jetty.server.session.Session)
|
||||
*/
|
||||
@Override
|
||||
public void put(String id, Session session) throws Exception
|
||||
{
|
||||
if (id == null || session == null)
|
||||
throw new IllegalArgumentException ("Put key="+id+" session="+(session==null?"null":session.getId()));
|
||||
|
||||
|
||||
|
||||
//if the session is new or data has changed write it to any backing store
|
||||
try (Lock lock = session.lock())
|
||||
{
|
||||
session.setSessionHandler(_handler);
|
||||
|
||||
if (session.isPassivated())
|
||||
throw new IllegalStateException ("Session "+id+" is passivated and cannot be saved");
|
||||
|
||||
if (!session.isValid())
|
||||
return;
|
||||
|
||||
if (_sessionStore == null)
|
||||
{
|
||||
doPutIfAbsent(id, session); //ensure it is in our map
|
||||
return;
|
||||
}
|
||||
|
||||
if ((session.getRequests() <= 0))
|
||||
{
|
||||
//only save if all requests have finished
|
||||
if (!_sessionStore.isPassivating())
|
||||
{
|
||||
//if our backing datastore isn't the passivating kind, just save the session
|
||||
_sessionStore.store(id, session.getSessionData());
|
||||
}
|
||||
else
|
||||
{
|
||||
//backing store supports passivation
|
||||
session.willPassivate();
|
||||
_sessionStore.store(id, session.getSessionData());
|
||||
session.setPassivated();
|
||||
if (isPassivateOnComplete())
|
||||
{
|
||||
//throw out the passivated session object from the map
|
||||
doDelete(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
//reactivate the session
|
||||
session.setActive();
|
||||
session.didActivate();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doPutIfAbsent(id,session); //ensure it is in our map
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a session corresponding to the id exists.
|
||||
*
|
||||
* This method will first check with the object store. If it
|
||||
* doesn't exist in the object store (might be passivated etc),
|
||||
* it will check with the data store.
|
||||
* @throws Exception
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.SessionCache#exists(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean exists(String id) throws Exception
|
||||
{
|
||||
//try the object store first
|
||||
Session s = doGet(id);
|
||||
if (s != null)
|
||||
{
|
||||
try (Lock lock = s.lock())
|
||||
{
|
||||
//wait for the lock and check the validity of the session
|
||||
return s.isValid();
|
||||
}
|
||||
}
|
||||
|
||||
//not there, so find out if session data exists for it
|
||||
return _sessionStore.exists (id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a session object from this store and from any backing store.
|
||||
*
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.SessionCache#delete(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Session delete(String id) throws Exception
|
||||
{
|
||||
//get the session, if its not in memory, this will load it
|
||||
Session session = get(id);
|
||||
|
||||
//Always delete it from the backing data store
|
||||
if (_sessionStore != null)
|
||||
{
|
||||
boolean dsdel = _sessionStore.delete(id);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Session {} deleted in db {}",id, dsdel);
|
||||
}
|
||||
|
||||
//delete it from the session object store
|
||||
if (session != null)
|
||||
session.stopTimeout();
|
||||
|
||||
return doDelete(id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionCache#checkExpiration(Set)
|
||||
*/
|
||||
@Override
|
||||
public Set<String> checkExpiration(Set<String> candidates)
|
||||
{
|
||||
if (!isStarted())
|
||||
return Collections.emptySet();
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("SessionStore checking expiration on {}", candidates);
|
||||
return _sessionStore.getExpired(candidates);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* If the SessionDataStore supports passivation,
|
||||
* write the session to the backing data store.
|
||||
*
|
||||
* @param id identity of session to passivate
|
||||
*/
|
||||
@Override
|
||||
public void passivateIdleSession(String id)
|
||||
{
|
||||
if (!isStarted())
|
||||
return;
|
||||
|
||||
if (_sessionStore == null || !_sessionStore.isPassivating())
|
||||
return; //no data store to passivate or it doesn't passivate
|
||||
|
||||
//get the session locally
|
||||
Session s = doGet(id);
|
||||
|
||||
if (s == null)
|
||||
{
|
||||
LOG.warn("Session {} not in this session store", s);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//lock the session during passivation
|
||||
try (Lock lock = s.lock())
|
||||
{
|
||||
//check the session is still idle and that it doesn't have requests using it
|
||||
if (s.isValid() && s.isIdleLongerThan(_idlePassivationTimeoutSec) && s.isActive() && (s.getRequests() <= 0))
|
||||
{
|
||||
//TODO - do we need to check that the session exists in the session data store
|
||||
//before we passivate it? If it doesn't exist, we can assume another node
|
||||
//invalidated it. If the session was new, it shouldn't have been idle passivated.
|
||||
try
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Passivating idle session {}", id);
|
||||
s.willPassivate();
|
||||
_sessionStore.store(id, s.getSessionData());
|
||||
s.setPassivated();
|
||||
s.stopTimeout();
|
||||
doDelete(id); //Take the session object of this session store
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("Passivation of idle session {} failed", id, e);
|
||||
s.setPassivated(); //set it as passivated so it can't be used
|
||||
doDelete(id); //detach it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionCache#renewSessionId(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public Session renewSessionId (String oldId, String newId)
|
||||
throws Exception
|
||||
{
|
||||
if (StringUtil.isBlank(oldId))
|
||||
throw new IllegalArgumentException ("Old session id is null");
|
||||
if (StringUtil.isBlank(newId))
|
||||
throw new IllegalArgumentException ("New session id is null");
|
||||
|
||||
Session session = get(oldId);
|
||||
if (session == null)
|
||||
return null;
|
||||
|
||||
try (Lock lock = session.lock())
|
||||
{
|
||||
session.checkValidForWrite(); //can't change id on invalid session
|
||||
session.getSessionData().setId(newId);
|
||||
session.getSessionData().setLastSaved(0); //pretend that the session has never been saved before to get a full save
|
||||
session.getSessionData().setDirty(true); //ensure we will try to write the session out
|
||||
doPutIfAbsent(newId, session); //put the new id into our map
|
||||
doDelete (oldId); //take old out of map
|
||||
if (_sessionStore != null)
|
||||
{
|
||||
_sessionStore.delete(oldId); //delete the session data with the old id
|
||||
_sessionStore.store(newId, session.getSessionData()); //save the session data with the new id
|
||||
}
|
||||
LOG.info("Session id {} swapped for new id {}", oldId, newId);
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setPassivateOnComplete (boolean passivateOnComplete)
|
||||
{
|
||||
_passivateOnComplete = passivateOnComplete;
|
||||
}
|
||||
|
||||
|
||||
public boolean isPassivateOnComplete ()
|
||||
{
|
||||
return _passivateOnComplete;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionCache#newSession(javax.servlet.http.HttpServletRequest, java.lang.String, long, long)
|
||||
*/
|
||||
@Override
|
||||
public Session newSession(HttpServletRequest request, String id, long time, long maxInactiveMs)
|
||||
{
|
||||
Session session = newSession(request, _sessionStore.newSessionData(id, time, time, time, maxInactiveMs));
|
||||
session.setSessionHandler(_handler);
|
||||
return session;
|
||||
}
|
||||
}
|
|
@ -1,149 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
|
||||
/**
|
||||
* AbstractSessionDataStore
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSessionDataStore extends AbstractLifeCycle implements SessionDataStore
|
||||
{
|
||||
protected SessionContext _context; //context associated with this session data store
|
||||
protected int _gracePeriodSec = 60 * 60; //default of 1hr
|
||||
protected long _lastExpiryCheckTime = 0; //last time in ms that getExpired was called
|
||||
|
||||
|
||||
/**
|
||||
* Store the session data persistently.
|
||||
*
|
||||
* @param id identity of session to store
|
||||
* @param data info of the session
|
||||
* @param lastSaveTime time of previous save or 0 if never saved
|
||||
* @throws Exception if unable to store data
|
||||
*/
|
||||
public abstract void doStore(String id, SessionData data, long lastSaveTime) throws Exception;
|
||||
|
||||
|
||||
/**
|
||||
* Implemented by subclasses to resolve which sessions this node
|
||||
* should attempt to expire.
|
||||
*
|
||||
* @param candidates the ids of sessions the SessionStore thinks has expired
|
||||
* @return the reconciled set of session ids that this node should attempt to expire
|
||||
*/
|
||||
public abstract Set<String> doGetExpired (Set<String> candidates);
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#initialize(org.eclipse.jetty.server.session.SessionContext)
|
||||
*/
|
||||
public void initialize (SessionContext context)
|
||||
{
|
||||
if (isStarted())
|
||||
throw new IllegalStateException("Context set after SessionDataStore started");
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#store(java.lang.String, org.eclipse.jetty.server.session.SessionData)
|
||||
*/
|
||||
@Override
|
||||
public void store(String id, SessionData data) throws Exception
|
||||
{
|
||||
long lastSave = data.getLastSaved();
|
||||
|
||||
//set the last saved time to now
|
||||
data.setLastSaved(System.currentTimeMillis());
|
||||
try
|
||||
{
|
||||
//call the specific store method, passing in previous save time
|
||||
doStore(id, data, lastSave);
|
||||
data.setDirty(false); //only undo the dirty setting if we saved it
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//reset last save time if save failed
|
||||
data.setLastSaved(lastSave);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(java.util.Set)
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getExpired(Set<String> candidates)
|
||||
{
|
||||
try
|
||||
{
|
||||
return doGetExpired (candidates);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_lastExpiryCheckTime = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#newSessionData(java.lang.String, long, long, long, long)
|
||||
*/
|
||||
@Override
|
||||
public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||
{
|
||||
return new SessionData(id, _context.getCanonicalContextPath(), _context.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
|
||||
}
|
||||
|
||||
protected void checkStarted () throws IllegalStateException
|
||||
{
|
||||
if (isStarted())
|
||||
throw new IllegalStateException("Already started");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
if (_context == null)
|
||||
throw new IllegalStateException ("No SessionContext");
|
||||
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
public int getGracePeriodSec()
|
||||
{
|
||||
return _gracePeriodSec;
|
||||
}
|
||||
|
||||
public void setGracePeriodSec(int sec)
|
||||
{
|
||||
_gracePeriodSec = sec;
|
||||
}
|
||||
|
||||
}
|
|
@ -19,126 +19,42 @@
|
|||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.thread.Locker.Lock;
|
||||
|
||||
/**
|
||||
* AbstractSessionStore
|
||||
*
|
||||
* Basic behaviour for maintaining an in-memory store of Session objects and
|
||||
* making sure that any backing SessionDataStore is kept in sync.
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSessionStore extends AbstractLifeCycle implements SessionStore
|
||||
{
|
||||
final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
protected SessionDataStore _sessionDataStore;
|
||||
protected final SessionManager _manager;
|
||||
protected SessionContext _context;
|
||||
protected int _idlePassivationTimeoutSec;
|
||||
private boolean _passivateOnComplete;
|
||||
protected SessionContext _context; //context associated with this session data store
|
||||
protected int _gracePeriodSec = 60 * 60; //default of 1hr
|
||||
protected long _lastExpiryCheckTime = 0; //last time in ms that getExpired was called
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Session object from pre-existing session data
|
||||
* @param data the session data
|
||||
* @return a new Session object
|
||||
*/
|
||||
public abstract Session newSession (SessionData data);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Session for a request.
|
||||
* Store the session data persistently.
|
||||
*
|
||||
* @param request the request
|
||||
* @param data the session data
|
||||
* @return the new session
|
||||
* @param id identity of session to store
|
||||
* @param data info of the session
|
||||
* @param lastSaveTime time of previous save or 0 if never saved
|
||||
* @throws Exception if unable to store data
|
||||
*/
|
||||
public abstract Session newSession (HttpServletRequest request, SessionData data);
|
||||
public abstract void doStore(String id, SessionData data, long lastSaveTime) throws Exception;
|
||||
|
||||
|
||||
/**
|
||||
* Get the session matching the key
|
||||
* @param id session id
|
||||
* @return the Session object matching the id
|
||||
*/
|
||||
public abstract Session doGet(String id);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Put the session into the map if it wasn't already there
|
||||
* Implemented by subclasses to resolve which sessions this node
|
||||
* should attempt to expire.
|
||||
*
|
||||
* @param id the identity of the session
|
||||
* @param session the session object
|
||||
* @return null if the session wasn't already in the map, or the existing entry otherwise
|
||||
* @param candidates the ids of sessions the SessionStore thinks has expired
|
||||
* @return the reconciled set of session ids that this node should attempt to expire
|
||||
*/
|
||||
public abstract Session doPutIfAbsent (String id, Session session);
|
||||
|
||||
|
||||
/**
|
||||
* Replace the mapping from id to oldValue with newValue
|
||||
* @param id the id
|
||||
* @param oldValue the old value
|
||||
* @param newValue the new value
|
||||
* @return true if replacement was done
|
||||
*/
|
||||
public abstract boolean doReplace (String id, Session oldValue, Session newValue);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Remove the session with this identity from the store
|
||||
* @param id the id
|
||||
* @return true if removed false otherwise
|
||||
*/
|
||||
public abstract Session doDelete (String id);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* PlaceHolder
|
||||
*/
|
||||
protected class PlaceHolderSession extends Session
|
||||
{
|
||||
|
||||
/**
|
||||
* @param data the session data
|
||||
*/
|
||||
public PlaceHolderSession(SessionData data)
|
||||
{
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public AbstractSessionStore (SessionManager manager)
|
||||
{
|
||||
_manager = manager;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the SessionManger
|
||||
*/
|
||||
public SessionManager getSessionManager()
|
||||
{
|
||||
return _manager;
|
||||
}
|
||||
public abstract Set<String> doGetExpired (Set<String> candidates);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -147,493 +63,87 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
|||
public void initialize (SessionContext context)
|
||||
{
|
||||
if (isStarted())
|
||||
throw new IllegalStateException("Context set after session store started");
|
||||
throw new IllegalStateException("Context set after SessionDataStore started");
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#store(java.lang.String, org.eclipse.jetty.server.session.SessionData)
|
||||
*/
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
public void store(String id, SessionData data) throws Exception
|
||||
{
|
||||
if (_sessionDataStore == null)
|
||||
throw new IllegalStateException ("No session data store configured");
|
||||
|
||||
if (_manager == null)
|
||||
throw new IllegalStateException ("No session manager");
|
||||
|
||||
if (_context == null)
|
||||
throw new IllegalStateException ("No ContextId");
|
||||
|
||||
_sessionDataStore.initialize(_context);
|
||||
_sessionDataStore.start();
|
||||
|
||||
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
|
||||
*/
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
_sessionDataStore.stop();
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the SessionDataStore or null if there isn't one
|
||||
*/
|
||||
public SessionDataStore getSessionDataStore()
|
||||
{
|
||||
return _sessionDataStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sessionDataStore the session datastore
|
||||
*/
|
||||
public void setSessionDataStore(SessionDataStore sessionDataStore)
|
||||
{
|
||||
_sessionDataStore = sessionDataStore;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#getIdlePassivationTimeoutSec()
|
||||
*/
|
||||
public int getIdlePassivationTimeoutSec()
|
||||
{
|
||||
return _idlePassivationTimeoutSec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#setIdlePassivationTimeoutSec(int)
|
||||
*/
|
||||
public void setIdlePassivationTimeoutSec(int idleTimeoutSec)
|
||||
{
|
||||
_idlePassivationTimeoutSec = idleTimeoutSec;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a session object.
|
||||
*
|
||||
* If the session object is not in this session store, try getting
|
||||
* the data for it from a SessionDataStore associated with the
|
||||
* session manager.
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#get(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Session get(String id) throws Exception
|
||||
{
|
||||
Session session = null;
|
||||
Exception ex = null;
|
||||
|
||||
while (true)
|
||||
{
|
||||
session = doGet(id);
|
||||
|
||||
if (_sessionDataStore == null)
|
||||
break; //can't load any session data so just return null or the session object
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Session not found locally, attempting to load");
|
||||
|
||||
//didn't get a session, try and create one and put in a placeholder for it
|
||||
PlaceHolderSession phs = new PlaceHolderSession (new SessionData(id, null, null,0,0,0,0));
|
||||
Lock phsLock = phs.lock();
|
||||
Session s = doPutIfAbsent(id, phs);
|
||||
if (s == null)
|
||||
{
|
||||
//My placeholder won, go ahead and load the full session data
|
||||
try
|
||||
{
|
||||
session = loadSession(id);
|
||||
if (session == null)
|
||||
{
|
||||
//session does not exist, remove the placeholder
|
||||
doDelete(id);
|
||||
phsLock.close();
|
||||
break;
|
||||
}
|
||||
|
||||
try (Lock lock = session.lock())
|
||||
{
|
||||
//swap it in instead of the placeholder
|
||||
boolean success = doReplace(id, phs, session);
|
||||
if (!success)
|
||||
{
|
||||
//something has gone wrong, it should have been our placeholder
|
||||
doDelete(id);
|
||||
session = null;
|
||||
LOG.warn("Replacement of placeholder for session {} failed", id);
|
||||
phsLock.close();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//successfully swapped in the session
|
||||
session.setTimeout (); //TODO start the session timer
|
||||
phsLock.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ex = e; //remember a problem happened loading the session
|
||||
doDelete(id); //remove the placeholder
|
||||
phsLock.close();
|
||||
session = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//my placeholder didn't win, check the session returned
|
||||
phsLock.close();
|
||||
try (Lock lock = s.lock())
|
||||
{
|
||||
//is it a placeholder? or is it passivated? In both cases, chuck it away and start again
|
||||
if (s.isPassivated() || s instanceof PlaceHolderSession)
|
||||
{
|
||||
session = null;
|
||||
continue;
|
||||
}
|
||||
session = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//check the session returned
|
||||
try (Lock lock = session.lock())
|
||||
{
|
||||
//is it a placeholder? or is it passivated? In both cases, chuck it away and start again
|
||||
if (session.isPassivated() || session instanceof PlaceHolderSession)
|
||||
{
|
||||
session = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
//got the session
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ex != null)
|
||||
throw ex;
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the info for the session from the session data store
|
||||
*
|
||||
* @param id the id
|
||||
* @return a Session object filled with data or null if the session doesn't exist
|
||||
* @throws Exception
|
||||
*/
|
||||
private Session loadSession (String id)
|
||||
throws Exception
|
||||
{
|
||||
SessionData data = null;
|
||||
Session session = null;
|
||||
|
||||
if (_sessionDataStore == null)
|
||||
return null; //can't load it
|
||||
long lastSave = data.getLastSaved();
|
||||
|
||||
//set the last saved time to now
|
||||
data.setLastSaved(System.currentTimeMillis());
|
||||
try
|
||||
{
|
||||
data =_sessionDataStore.load(id);
|
||||
|
||||
if (data == null) //session doesn't exist
|
||||
return null;
|
||||
|
||||
session = newSession(data);
|
||||
session.setSessionManager(_manager);
|
||||
return session;
|
||||
//call the specific store method, passing in previous save time
|
||||
doStore(id, data, lastSave);
|
||||
data.setDirty(false); //only undo the dirty setting if we saved it
|
||||
}
|
||||
catch (UnreadableSessionDataException e)
|
||||
catch (Exception e)
|
||||
{
|
||||
//can't load the session, delete it
|
||||
_sessionDataStore.delete(id);
|
||||
//reset last save time if save failed
|
||||
data.setLastSaved(lastSave);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Put the Session object back into the session store.
|
||||
*
|
||||
* This should be called by Session.complete when a request exists the session.
|
||||
*
|
||||
* If the session manager supports a session data store, write the
|
||||
* session data through to the session data store.
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#put(java.lang.String, org.eclipse.jetty.server.session.Session)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(java.util.Set)
|
||||
*/
|
||||
@Override
|
||||
public void put(String id, Session session) throws Exception
|
||||
public Set<String> getExpired(Set<String> candidates)
|
||||
{
|
||||
if (id == null || session == null)
|
||||
throw new IllegalArgumentException ("Put key="+id+" session="+(session==null?"null":session.getId()));
|
||||
|
||||
|
||||
|
||||
//if the session is new or data has changed write it to any backing store
|
||||
try (Lock lock = session.lock())
|
||||
try
|
||||
{
|
||||
session.setSessionManager(_manager);
|
||||
|
||||
if (session.isPassivated())
|
||||
throw new IllegalStateException ("Session "+id+" is passivated and cannot be saved");
|
||||
|
||||
if (!session.isValid())
|
||||
return;
|
||||
|
||||
if (_sessionDataStore == null)
|
||||
{
|
||||
doPutIfAbsent(id, session); //ensure it is in our map
|
||||
return;
|
||||
}
|
||||
|
||||
if ((session.getRequests() <= 0))
|
||||
{
|
||||
//only save if all requests have finished
|
||||
if (!_sessionDataStore.isPassivating())
|
||||
{
|
||||
//if our backing datastore isn't the passivating kind, just save the session
|
||||
_sessionDataStore.store(id, session.getSessionData());
|
||||
}
|
||||
else
|
||||
{
|
||||
//backing store supports passivation
|
||||
session.willPassivate();
|
||||
_sessionDataStore.store(id, session.getSessionData());
|
||||
session.setPassivated();
|
||||
if (isPassivateOnComplete())
|
||||
{
|
||||
//throw out the passivated session object from the map
|
||||
doDelete(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
//reactivate the session
|
||||
session.setActive();
|
||||
session.didActivate();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doPutIfAbsent(id,session); //ensure it is in our map
|
||||
return doGetExpired (candidates);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a session corresponding to the id exists.
|
||||
*
|
||||
* This method will first check with the object store. If it
|
||||
* doesn't exist in the object store (might be passivated etc),
|
||||
* it will check with the data store.
|
||||
* @throws Exception
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean exists(String id) throws Exception
|
||||
{
|
||||
//try the object store first
|
||||
Session s = doGet(id);
|
||||
if (s != null)
|
||||
finally
|
||||
{
|
||||
try (Lock lock = s.lock())
|
||||
{
|
||||
//wait for the lock and check the validity of the session
|
||||
return s.isValid();
|
||||
}
|
||||
}
|
||||
|
||||
//not there, so find out if session data exists for it
|
||||
return _sessionDataStore.exists (id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a session object from this store and from any backing store.
|
||||
*
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Session delete(String id) throws Exception
|
||||
{
|
||||
//get the session, if its not in memory, this will load it
|
||||
Session session = get(id);
|
||||
|
||||
//Always delete it from the backing data store
|
||||
if (_sessionDataStore != null)
|
||||
{
|
||||
boolean dsdel = _sessionDataStore.delete(id);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Session {} deleted in db {}",id, dsdel);
|
||||
}
|
||||
|
||||
//delete it from the session object store
|
||||
if (session != null)
|
||||
session.stopTimeout();
|
||||
|
||||
return doDelete(id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#checkExpiration(Set)
|
||||
*/
|
||||
@Override
|
||||
public Set<String> checkExpiration(Set<String> candidates)
|
||||
{
|
||||
if (!isStarted())
|
||||
return Collections.emptySet();
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("SessionStore checking expiration on {}", candidates);
|
||||
return _sessionDataStore.getExpired(candidates);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* If the SessionDataStore supports passivation,
|
||||
* write the session to the backing data store.
|
||||
*
|
||||
* @param id identity of session to passivate
|
||||
*/
|
||||
@Override
|
||||
public void passivateIdleSession(String id)
|
||||
{
|
||||
if (!isStarted())
|
||||
return;
|
||||
|
||||
if (_sessionDataStore == null || !_sessionDataStore.isPassivating())
|
||||
return; //no data store to passivate or it doesn't passivate
|
||||
|
||||
//get the session locally
|
||||
Session s = doGet(id);
|
||||
|
||||
if (s == null)
|
||||
{
|
||||
LOG.warn("Session {} not in this session store", s);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//lock the session during passivation
|
||||
try (Lock lock = s.lock())
|
||||
{
|
||||
//check the session is still idle and that it doesn't have requests using it
|
||||
if (s.isValid() && s.isIdleLongerThan(_idlePassivationTimeoutSec) && s.isActive() && (s.getRequests() <= 0))
|
||||
{
|
||||
//TODO - do we need to check that the session exists in the session data store
|
||||
//before we passivate it? If it doesn't exist, we can assume another node
|
||||
//invalidated it. If the session was new, it shouldn't have been idle passivated.
|
||||
try
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Passivating idle session {}", id);
|
||||
s.willPassivate();
|
||||
_sessionDataStore.store(id, s.getSessionData());
|
||||
s.setPassivated();
|
||||
s.stopTimeout();
|
||||
doDelete(id); //Take the session object of this session store
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("Passivation of idle session {} failed", id, e);
|
||||
s.setPassivated(); //set it as passivated so it can't be used
|
||||
doDelete(id); //detach it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#renewSessionId(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public Session renewSessionId (String oldId, String newId)
|
||||
throws Exception
|
||||
{
|
||||
if (StringUtil.isBlank(oldId))
|
||||
throw new IllegalArgumentException ("Old session id is null");
|
||||
if (StringUtil.isBlank(newId))
|
||||
throw new IllegalArgumentException ("New session id is null");
|
||||
|
||||
Session session = get(oldId);
|
||||
if (session == null)
|
||||
return null;
|
||||
|
||||
try (Lock lock = session.lock())
|
||||
{
|
||||
session.checkValidForWrite(); //can't change id on invalid session
|
||||
session.getSessionData().setId(newId);
|
||||
session.getSessionData().setLastSaved(0); //pretend that the session has never been saved before to get a full save
|
||||
session.getSessionData().setDirty(true); //ensure we will try to write the session out
|
||||
doPutIfAbsent(newId, session); //put the new id into our map
|
||||
doDelete (oldId); //take old out of map
|
||||
if (_sessionDataStore != null)
|
||||
{
|
||||
_sessionDataStore.delete(oldId); //delete the session data with the old id
|
||||
_sessionDataStore.store(newId, session.getSessionData()); //save the session data with the new id
|
||||
}
|
||||
LOG.info("Session id {} swapped for new id {}", oldId, newId);
|
||||
return session;
|
||||
_lastExpiryCheckTime = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setPassivateOnComplete (boolean passivateOnComplete)
|
||||
{
|
||||
_passivateOnComplete = passivateOnComplete;
|
||||
}
|
||||
|
||||
|
||||
public boolean isPassivateOnComplete ()
|
||||
{
|
||||
return _passivateOnComplete;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#newSession(javax.servlet.http.HttpServletRequest, java.lang.String, long, long)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#newSessionData(java.lang.String, long, long, long, long)
|
||||
*/
|
||||
@Override
|
||||
public Session newSession(HttpServletRequest request, String id, long time, long maxInactiveMs)
|
||||
public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||
{
|
||||
Session session = newSession(request, _sessionDataStore.newSessionData(id, time, time, time, maxInactiveMs));
|
||||
session.setSessionManager(_manager);
|
||||
return session;
|
||||
return new SessionData(id, _context.getCanonicalContextPath(), _context.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
|
||||
}
|
||||
|
||||
protected void checkStarted () throws IllegalStateException
|
||||
{
|
||||
if (isStarted())
|
||||
throw new IllegalStateException("Already started");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
if (_context == null)
|
||||
throw new IllegalStateException ("No SessionContext");
|
||||
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
public int getGracePeriodSec()
|
||||
{
|
||||
return _gracePeriodSec;
|
||||
}
|
||||
|
||||
public void setGracePeriodSec(int sec)
|
||||
{
|
||||
_gracePeriodSec = sec;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,20 +20,33 @@
|
|||
package org.eclipse.jetty.server.session;
|
||||
|
||||
/**
|
||||
* AlwaysStale
|
||||
* AbstractSessionStoreFactory
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class AlwaysStaleStrategy implements StalenessStrategy
|
||||
public abstract class AbstractSessionStoreFactory implements SessionStoreFactory
|
||||
{
|
||||
|
||||
int _gracePeriodSec;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.StalenessStrategy#isStale(org.eclipse.jetty.server.session.Session)
|
||||
* @return the gracePeriodSec
|
||||
*/
|
||||
@Override
|
||||
public boolean isStale(Session session)
|
||||
public int getGracePeriodSec()
|
||||
{
|
||||
return true;
|
||||
return _gracePeriodSec;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param gracePeriodSec the gracePeriodSec to set
|
||||
*/
|
||||
public void setGracePeriodSec(int gracePeriodSec)
|
||||
{
|
||||
_gracePeriodSec = gracePeriodSec;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -32,7 +32,7 @@ import java.util.Set;
|
|||
* can increase performance. The cache implementation can either be a local cache,
|
||||
* a remote cache, or a clustered cache.
|
||||
*/
|
||||
public class CachingSessionDataStore extends AbstractSessionDataStore
|
||||
public class CachingSessionDataStore extends AbstractSessionStore
|
||||
{
|
||||
|
||||
public interface SessionDataCache
|
||||
|
@ -45,17 +45,17 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
|
||||
protected SessionDataStore _delegateDataStore;
|
||||
protected SessionStore _delegateDataStore;
|
||||
protected SessionDataCache _cache;
|
||||
|
||||
|
||||
public void setSessionDataStore (SessionDataStore store)
|
||||
public void setSessionDataStore (SessionStore store)
|
||||
{
|
||||
checkStarted();
|
||||
_delegateDataStore = store;
|
||||
}
|
||||
|
||||
public SessionDataStore getSessionDataStore()
|
||||
public SessionStore getSessionDataStore()
|
||||
{
|
||||
return _delegateDataStore;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#load(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public SessionData load(String id) throws Exception
|
||||
|
@ -103,7 +103,7 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean delete(String id) throws Exception
|
||||
|
@ -116,7 +116,7 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(Set)
|
||||
*/
|
||||
@Override
|
||||
public Set<String> doGetExpired(Set<String> candidates)
|
||||
|
@ -127,14 +127,14 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
|
||||
*/
|
||||
@Override
|
||||
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
|
||||
{
|
||||
//write to the SessionDataStore first
|
||||
if (_delegateDataStore instanceof AbstractSessionDataStore)
|
||||
((AbstractSessionDataStore)_delegateDataStore).doStore(id, data, lastSaveTime);
|
||||
if (_delegateDataStore instanceof AbstractSessionStore)
|
||||
((AbstractSessionStore)_delegateDataStore).doStore(id, data, lastSaveTime);
|
||||
|
||||
//else??????
|
||||
|
||||
|
@ -159,7 +159,7 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#isPassivating()
|
||||
*/
|
||||
@Override
|
||||
public boolean isPassivating()
|
||||
|
@ -168,7 +168,7 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean exists(String id) throws Exception
|
||||
|
|
|
@ -19,10 +19,7 @@
|
|||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
@ -31,11 +28,11 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
import org.eclipse.jetty.util.statistic.CounterStatistic;
|
||||
|
||||
/**
|
||||
* MemorySessionStore
|
||||
* DefaultSessionCache
|
||||
*
|
||||
* A session store that keeps its sessions in memory in a hashmap
|
||||
*/
|
||||
public class MemorySessionStore extends AbstractSessionStore
|
||||
public class DefaultSessionCache extends AbstractSessionCache
|
||||
{
|
||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
|
@ -73,7 +70,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
|
||||
|
||||
|
||||
public MemorySessionStore (SessionManager manager)
|
||||
public DefaultSessionCache (SessionHandler manager)
|
||||
{
|
||||
super (manager);
|
||||
}
|
||||
|
@ -103,7 +100,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doGet(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionCache#doGet(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Session doGet(String id)
|
||||
|
@ -118,7 +115,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doPutIfAbsent(java.lang.String, org.eclipse.jetty.server.session.Session)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionCache#doPutIfAbsent(java.lang.String, org.eclipse.jetty.server.session.Session)
|
||||
*/
|
||||
@Override
|
||||
public Session doPutIfAbsent(String id, Session session)
|
||||
|
@ -132,7 +129,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doDelete(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionCache#doDelete(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Session doDelete(String id)
|
||||
|
@ -158,14 +155,14 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
for (Session session: _sessions.values())
|
||||
{
|
||||
//if we have a backing store and the session is dirty make sure it is written out
|
||||
if (_sessionDataStore != null)
|
||||
if (_sessionStore != null)
|
||||
{
|
||||
if (session.getSessionData().isDirty())
|
||||
{
|
||||
session.willPassivate();
|
||||
try
|
||||
{
|
||||
_sessionDataStore.store(session.getId(), session.getSessionData());
|
||||
_sessionStore.store(session.getId(), session.getSessionData());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -193,7 +190,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#newSession(javax.servlet.http.HttpServletRequest, org.eclipse.jetty.server.session.SessionData)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionCache#newSession(javax.servlet.http.HttpServletRequest, org.eclipse.jetty.server.session.SessionData)
|
||||
*/
|
||||
@Override
|
||||
public Session newSession(HttpServletRequest request, SessionData data)
|
||||
|
@ -206,7 +203,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#newSession(org.eclipse.jetty.server.session.SessionData)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionCache#newSession(org.eclipse.jetty.server.session.SessionData)
|
||||
*/
|
||||
@Override
|
||||
public Session newSession(SessionData data)
|
||||
|
@ -219,7 +216,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doReplace(java.lang.String, org.eclipse.jetty.server.session.Session, org.eclipse.jetty.server.session.Session)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionCache#doReplace(java.lang.String, org.eclipse.jetty.server.session.Session, org.eclipse.jetty.server.session.Session)
|
||||
*/
|
||||
@Override
|
||||
public boolean doReplace(String id, Session oldValue, Session newValue)
|
|
@ -0,0 +1,80 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
/**
|
||||
* MemorySessionStoreFactory
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class DefaultSessionCacheFactory implements SessionCacheFactory
|
||||
{
|
||||
int _idlePassivationTimeoutSec;
|
||||
boolean _passivateOnComplete;
|
||||
|
||||
|
||||
/**
|
||||
* @return the passivateOnComplete
|
||||
*/
|
||||
public boolean isPassivateOnComplete()
|
||||
{
|
||||
return _passivateOnComplete;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param passivateOnComplete the passivateOnComplete to set
|
||||
*/
|
||||
public void setPassivateOnComplete(boolean passivateOnComplete)
|
||||
{
|
||||
_passivateOnComplete = passivateOnComplete;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the idlePassivationTimeoutSec
|
||||
*/
|
||||
public int getIdlePassivationTimeoutSec()
|
||||
{
|
||||
return _idlePassivationTimeoutSec;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param idlePassivationTimeoutSec the idlePassivationTimeoutSec to set
|
||||
*/
|
||||
public void setIdlePassivationTimeoutSec(int idlePassivationTimeoutSec)
|
||||
{
|
||||
_idlePassivationTimeoutSec = idlePassivationTimeoutSec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionCacheFactory#getSessionStore(org.eclipse.jetty.server.session.SessionHandler)
|
||||
*/
|
||||
@Override
|
||||
public SessionCache getSessionCache (SessionHandler handler)
|
||||
{
|
||||
DefaultSessionCache cache = new DefaultSessionCache(handler);
|
||||
cache.setIdlePassivationTimeoutSec(_idlePassivationTimeoutSec);
|
||||
cache.setPassivateOnComplete(_passivateOnComplete);
|
||||
return cache;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -58,7 +58,7 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
|
|||
protected String _workerAttr;
|
||||
protected long _reseed=100000L;
|
||||
protected Server _server;
|
||||
protected HouseKeeper _inspector;
|
||||
protected HouseKeeper _houseKeeper;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -106,10 +106,10 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
|
|||
/**
|
||||
* @param inspector inspector of sessions
|
||||
*/
|
||||
public void setSessionInspector (HouseKeeper inspector)
|
||||
public void setSessionHouseKeeper (HouseKeeper houseKeeper)
|
||||
{
|
||||
_inspector = inspector;
|
||||
_inspector.setSessionIdManager(this);
|
||||
_houseKeeper = houseKeeper;
|
||||
_houseKeeper.setSessionIdManager(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -291,7 +291,7 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
|
|||
|
||||
try
|
||||
{
|
||||
for (SessionManager manager:getSessionManagers())
|
||||
for (SessionHandler manager:getSessionHandlers())
|
||||
{
|
||||
if (manager.isIdInUse(id))
|
||||
{
|
||||
|
@ -327,14 +327,14 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
|
|||
initRandom();
|
||||
_workerAttr=(_workerName!=null && _workerName.startsWith("$"))?_workerName.substring(1):null;
|
||||
|
||||
if (_inspector == null)
|
||||
if (_houseKeeper == null)
|
||||
{
|
||||
LOG.warn("No SessionScavenger set, using defaults");
|
||||
_inspector = new HouseKeeper();
|
||||
_inspector.setSessionIdManager(this);
|
||||
_houseKeeper = new HouseKeeper();
|
||||
_houseKeeper.setSessionIdManager(this);
|
||||
}
|
||||
|
||||
_inspector.start();
|
||||
_houseKeeper.start();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -344,7 +344,7 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
|
|||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
_inspector.stop();
|
||||
_houseKeeper.stop();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -424,7 +424,7 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Expiring {}",id);
|
||||
|
||||
for (SessionManager manager:getSessionManagers())
|
||||
for (SessionHandler manager:getSessionHandlers())
|
||||
{
|
||||
manager.invalidate(id);
|
||||
}
|
||||
|
@ -435,7 +435,7 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
|
|||
{
|
||||
//tell all contexts that may have a session object with this id to
|
||||
//get rid of them
|
||||
for (SessionManager manager:getSessionManagers())
|
||||
for (SessionHandler manager:getSessionHandlers())
|
||||
{
|
||||
manager.invalidate(id);
|
||||
}
|
||||
|
@ -457,7 +457,7 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
|
|||
//TODO how to handle request for old id whilst id change is happening?
|
||||
|
||||
//tell all contexts to update the id
|
||||
for (SessionManager manager:getSessionManagers())
|
||||
for (SessionHandler manager:getSessionHandlers())
|
||||
{
|
||||
manager.renewSessionId(oldClusterId, oldNodeId, newClusterId, getExtendedId(newClusterId, request));
|
||||
}
|
||||
|
@ -470,9 +470,9 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
|
|||
*
|
||||
* @return all session managers
|
||||
*/
|
||||
public Set<SessionManager> getSessionManagers()
|
||||
public Set<SessionHandler> getSessionHandlers()
|
||||
{
|
||||
Set<SessionManager> managers = new HashSet<>();
|
||||
Set<SessionHandler> handlers = new HashSet<>();
|
||||
|
||||
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
||||
for (int i=0; contexts!=null && i<contexts.length; i++)
|
||||
|
@ -480,12 +480,9 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
|
|||
SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
|
||||
if (sessionHandler != null)
|
||||
{
|
||||
SessionManager manager = (SessionManager)sessionHandler.getSessionManager();
|
||||
|
||||
if (manager != null)
|
||||
managers.add(manager);
|
||||
handlers.add(sessionHandler);
|
||||
}
|
||||
}
|
||||
return managers;
|
||||
return handlers;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
*
|
||||
* A file-based store of session data.
|
||||
*/
|
||||
public class FileSessionDataStore extends AbstractSessionDataStore
|
||||
public class FileSessionDataStore extends AbstractSessionStore
|
||||
{
|
||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
private File _storeDir;
|
||||
|
@ -92,7 +92,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean delete(String id) throws Exception
|
||||
|
@ -112,7 +112,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(Set)
|
||||
*/
|
||||
@Override
|
||||
public Set<String> doGetExpired(final Set<String> candidates)
|
||||
|
@ -166,7 +166,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#load(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public SessionData load(String id) throws Exception
|
||||
|
@ -220,7 +220,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
|
||||
*/
|
||||
@Override
|
||||
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
|
||||
|
@ -262,7 +262,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#isPassivating()
|
||||
*/
|
||||
@Override
|
||||
public boolean isPassivating()
|
||||
|
@ -274,7 +274,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean exists(String id) throws Exception
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
/**
|
||||
* FileHashSessionManager
|
||||
*
|
||||
* Session manager that stores its sessions in files on disk
|
||||
*
|
||||
*/
|
||||
public class FileSessionManager extends SessionManager
|
||||
{
|
||||
protected FileSessionDataStore _sessionDataStore;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public FileSessionManager ()
|
||||
{
|
||||
setSessionStore(new MemorySessionStore(this));
|
||||
_sessionDataStore = new FileSessionDataStore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doStart() throws Exception
|
||||
{
|
||||
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
|
||||
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SessionDataStore to configure it
|
||||
* @return the session datastore
|
||||
*/
|
||||
public FileSessionDataStore getSessionDataStore()
|
||||
{
|
||||
return _sessionDataStore;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* FileSessionStoreFactory
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class FileSessionStoreFactory extends AbstractSessionStoreFactory
|
||||
{
|
||||
boolean _deleteUnrestorableFiles;
|
||||
File _storeDir;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the deleteUnrestorableFiles
|
||||
*/
|
||||
public boolean isDeleteUnrestorableFiles()
|
||||
{
|
||||
return _deleteUnrestorableFiles;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param deleteUnrestorableFiles the deleteUnrestorableFiles to set
|
||||
*/
|
||||
public void setDeleteUnrestorableFiles(boolean deleteUnrestorableFiles)
|
||||
{
|
||||
_deleteUnrestorableFiles = deleteUnrestorableFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the storeDir
|
||||
*/
|
||||
public File getStoreDir()
|
||||
{
|
||||
return _storeDir;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param storeDir the storeDir to set
|
||||
*/
|
||||
public void setStoreDir(File storeDir)
|
||||
{
|
||||
_storeDir = storeDir;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler)
|
||||
*/
|
||||
@Override
|
||||
public SessionStore getSessionStore(SessionHandler handler)
|
||||
{
|
||||
FileSessionDataStore fsds = new FileSessionDataStore();
|
||||
fsds.setDeleteUnrestorableFiles(isDeleteUnrestorableFiles());
|
||||
fsds.setStoreDir(getStoreDir());
|
||||
fsds.setGracePeriodSec(getGracePeriodSec());
|
||||
return fsds;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
/**
|
||||
* HashSessionManager
|
||||
*
|
||||
* In memory-only session manager.
|
||||
*
|
||||
*/
|
||||
public class HashSessionManager extends SessionManager
|
||||
{
|
||||
protected NullSessionDataStore _sessionDataStore = new NullSessionDataStore();
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public HashSessionManager ()
|
||||
{
|
||||
setSessionStore(new MemorySessionStore(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doStart() throws Exception
|
||||
{
|
||||
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
|
||||
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
}
|
|
@ -155,7 +155,7 @@ public class HouseKeeper extends AbstractLifeCycle
|
|||
_intervalMs += tenPercent;
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Inspecting every "+_intervalMs+" ms");
|
||||
LOG.debug("Scavenging every "+_intervalMs+" ms");
|
||||
|
||||
synchronized (this)
|
||||
{
|
||||
|
@ -173,7 +173,7 @@ public class HouseKeeper extends AbstractLifeCycle
|
|||
|
||||
|
||||
/**
|
||||
* Get the period between inspection cycles.
|
||||
* Get the period between scavenge cycles.
|
||||
*
|
||||
* @return the interval (in seconds)
|
||||
*/
|
||||
|
@ -194,10 +194,10 @@ public class HouseKeeper extends AbstractLifeCycle
|
|||
return;
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Inspecting sessions");
|
||||
LOG.debug("Scavenging sessions");
|
||||
|
||||
//find the session managers
|
||||
for (SessionManager manager:_sessionIdManager.getSessionManagers())
|
||||
for (SessionHandler manager:_sessionIdManager.getSessionHandlers())
|
||||
{
|
||||
if (manager != null)
|
||||
{
|
||||
|
|
|
@ -46,7 +46,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
*
|
||||
* Session data stored in database
|
||||
*/
|
||||
public class JDBCSessionDataStore extends AbstractSessionDataStore
|
||||
public class JDBCSessionDataStore extends AbstractSessionStore
|
||||
{
|
||||
final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
|
@ -662,7 +662,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#load(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public SessionData load(String id) throws Exception
|
||||
|
@ -758,7 +758,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean delete(String id) throws Exception
|
||||
|
@ -779,7 +779,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(String, SessionData, long)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStore(String, SessionData, long)
|
||||
*/
|
||||
@Override
|
||||
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
|
||||
|
@ -884,7 +884,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(Set)
|
||||
*/
|
||||
@Override
|
||||
public Set<String> doGetExpired(Set<String> candidates)
|
||||
|
@ -1083,7 +1083,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#isPassivating()
|
||||
*/
|
||||
@Override
|
||||
public boolean isPassivating()
|
||||
|
@ -1096,7 +1096,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean exists(String id)
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
/**
|
||||
* JDBCSessionManager
|
||||
*
|
||||
*/
|
||||
public class JDBCSessionManager extends SessionManager
|
||||
{
|
||||
|
||||
protected JDBCSessionDataStore _sessionDataStore;
|
||||
|
||||
|
||||
public JDBCSessionManager()
|
||||
{
|
||||
setSessionStore(new MemorySessionStore(this));
|
||||
_sessionDataStore = new JDBCSessionDataStore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doStart() throws Exception
|
||||
{
|
||||
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
|
||||
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the SessionDataStore to configure it
|
||||
* @return the session data store
|
||||
*/
|
||||
public JDBCSessionDataStore getSessionDataStore ()
|
||||
{
|
||||
return _sessionDataStore;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
/**
|
||||
* JDBCSessionStoreFactory
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class JDBCSessionStoreFactory extends AbstractSessionStoreFactory
|
||||
{
|
||||
|
||||
DatabaseAdaptor _adaptor;
|
||||
JDBCSessionDataStore.SessionTableSchema _schema;
|
||||
boolean _deleteUnloadableSessions;
|
||||
int _loadAttempts;
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler)
|
||||
*/
|
||||
@Override
|
||||
public SessionStore getSessionStore(SessionHandler handler)
|
||||
{
|
||||
JDBCSessionDataStore ds = new JDBCSessionDataStore();
|
||||
ds.setDatabaseAdaptor(_adaptor);
|
||||
ds.setSessionTableSchema(_schema);
|
||||
ds.setDeleteUnloadableSessions(_deleteUnloadableSessions);
|
||||
ds.setGracePeriodSec(_gracePeriodSec);
|
||||
ds.setLoadAttempts(_loadAttempts);
|
||||
return ds;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param adaptor
|
||||
*/
|
||||
public void setDatabaseAdaptor (DatabaseAdaptor adaptor)
|
||||
{
|
||||
_adaptor = adaptor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param schema
|
||||
*/
|
||||
public void setSessionTableSchema (JDBCSessionDataStore.SessionTableSchema schema)
|
||||
{
|
||||
_schema = schema;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue