Skip to content

Commit

Permalink
Ensure that when sessions are loaded from the Store that the correct
Browse files Browse the repository at this point in the history
class loader is used. In most cases it was already set but some code
paths from early in the processing chain (e.g. the Adaptor) could
trigger the loading of a session without setting the TCCL.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1725696 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
markt-asf committed Jan 20, 2016
1 parent 1d894a1 commit 547ec0c
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 59 deletions.
32 changes: 5 additions & 27 deletions java/org/apache/catalina/session/FileStore.java
Expand Up @@ -16,7 +16,6 @@
*/
package org.apache.catalina.session;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
Expand All @@ -30,9 +29,8 @@
import javax.servlet.ServletContext;

import org.apache.catalina.Context;
import org.apache.catalina.Loader;
import org.apache.catalina.Globals;
import org.apache.catalina.Session;
import org.apache.catalina.util.CustomObjectInputStream;
import org.apache.juli.logging.Log;

/**
Expand Down Expand Up @@ -226,22 +224,10 @@ public Session load(String id) throws ClassNotFoundException, IOException {
contextLog.debug(sm.getString(getStoreName()+".loading", id, file.getAbsolutePath()));
}

ObjectInputStream ois = null;
Loader loader = null;
ClassLoader classLoader = null;
ClassLoader oldThreadContextCL = Thread.currentThread().getContextClassLoader();
ClassLoader oldThreadContextCL = context.bind(Globals.IS_SECURITY_ENABLED, null);

try (FileInputStream fis = new FileInputStream(file.getAbsolutePath());
BufferedInputStream bis = new BufferedInputStream(fis)) {
loader = context.getLoader();
if (loader != null) {
classLoader = loader.getClassLoader();
}
if (classLoader == null) {
classLoader = getClass().getClassLoader();
} else {
Thread.currentThread().setContextClassLoader(classLoader);
}
ois = new CustomObjectInputStream(bis, classLoader);
ObjectInputStream ois = getObjectInputStream(fis)) {

StandardSession session = (StandardSession) manager.createEmptySession();
session.readObjectData(ois);
Expand All @@ -253,15 +239,7 @@ public Session load(String id) throws ClassNotFoundException, IOException {
}
return null;
} finally {
if (ois != null) {
// Close the input stream
try {
ois.close();
} catch (IOException f) {
// Ignore
}
}
Thread.currentThread().setContextClassLoader(oldThreadContextCL);
context.unbind(Globals.IS_SECURITY_ENABLED, oldThreadContextCL);
}
}

Expand Down
44 changes: 12 additions & 32 deletions java/org/apache/catalina/session/JDBCStore.java
Expand Up @@ -39,10 +39,9 @@
import javax.sql.DataSource;

import org.apache.catalina.Container;
import org.apache.catalina.Globals;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Loader;
import org.apache.catalina.Session;
import org.apache.catalina.util.CustomObjectInputStream;
import org.apache.juli.logging.Log;
import org.apache.tomcat.util.ExceptionUtils;

Expand Down Expand Up @@ -592,10 +591,6 @@ public int getSize() throws IOException {
@Override
public Session load(String id) throws ClassNotFoundException, IOException {
StandardSession _session = null;
Loader loader = null;
ClassLoader classLoader = null;
ObjectInputStream ois = null;
BufferedInputStream bis = null;
org.apache.catalina.Context context = getManager().getContext();
Log contextLog = context.getLogger();

Expand All @@ -607,7 +602,8 @@ public Session load(String id) throws ClassNotFoundException, IOException {
return null;
}

ClassLoader oldThreadContextCL = Thread.currentThread().getContextClassLoader();
ClassLoader oldThreadContextCL = context.bind(Globals.IS_SECURITY_ENABLED, null);

try {
if (preparedLoadSql == null) {
String loadSql = "SELECT " + sessionIdCol + ", "
Expand All @@ -621,26 +617,17 @@ public Session load(String id) throws ClassNotFoundException, IOException {
preparedLoadSql.setString(2, getName());
try (ResultSet rst = preparedLoadSql.executeQuery()) {
if (rst.next()) {
bis = new BufferedInputStream(rst.getBinaryStream(2));
loader = context.getLoader();
if (loader != null) {
classLoader = loader.getClassLoader();
}
if (classLoader == null) {
classLoader = getClass().getClassLoader();
} else {
Thread.currentThread().setContextClassLoader(classLoader);
}
ois = new CustomObjectInputStream(bis, classLoader);
try (ObjectInputStream ois =
getObjectInputStream(rst.getBinaryStream(2))) {
if (contextLog.isDebugEnabled()) {
contextLog.debug(sm.getString(
getStoreName() + ".loading", id, sessionTable));
}

if (contextLog.isDebugEnabled()) {
contextLog.debug(
sm.getString(getStoreName() + ".loading", id, sessionTable));
_session = (StandardSession) manager.createEmptySession();
_session.readObjectData(ois);
_session.setManager(manager);
}

_session = (StandardSession) manager.createEmptySession();
_session.readObjectData(ois);
_session.setManager(manager);
} else if (context.getLogger().isDebugEnabled()) {
contextLog.debug(getStoreName() + ": No persisted data object found");
}
Expand All @@ -652,13 +639,6 @@ public Session load(String id) throws ClassNotFoundException, IOException {
if (dbConnection != null)
close(dbConnection);
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
// Ignore
}
}
Thread.currentThread().setContextClassLoader(oldThreadContextCL);
release(_conn);
}
Expand Down
24 changes: 24 additions & 0 deletions java/org/apache/catalina/session/StoreBase.java
Expand Up @@ -19,12 +19,16 @@

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleState;
import org.apache.catalina.Manager;
import org.apache.catalina.Store;
import org.apache.catalina.util.CustomObjectInputStream;
import org.apache.catalina.util.LifecycleBase;
import org.apache.tomcat.util.res.StringManager;

Expand Down Expand Up @@ -193,8 +197,28 @@ public void processExpires() {
}
}


// --------------------------------------------------------- Protected Methods

/**
* Create the object input stream to use to read a session from the store.
* Sub-classes <b>must</b> have set the thread context class loader before
* calling this method.
*
* @param is The input stream provided by the sub-class that will provide
* the data for a session
*
* @return An appropriately configured ObjectInputStream from which the
* session can be read.
*
* @throws IOException if a problem occurs creating the ObjectInputStream
*/
protected ObjectInputStream getObjectInputStream(InputStream is) throws IOException {
BufferedInputStream bis = new BufferedInputStream(is);
return new CustomObjectInputStream(bis, Thread.currentThread().getContextClassLoader());
}


@Override
protected void initInternal() {
// NOOP
Expand Down

0 comments on commit 547ec0c

Please sign in to comment.