Fixes to Hash Sessions for 'Stream Closed' errors

This commit is contained in:
Greg Wilkins 2014-07-17 09:45:12 +10:00
parent ce63ab2290
commit ec310dca90
3 changed files with 34 additions and 46 deletions

View File

@ -19,7 +19,6 @@
package org.eclipse.jetty.server.session;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@ -36,7 +35,6 @@ import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.util.thread.Scheduler;
@ -568,18 +566,22 @@ public class HashSessionManager extends AbstractSessionManager
{
File file = new File(_storeDir,idInCuster);
FileInputStream in = null;
Exception error = null;
try
if (!file.exists())
{
if (file.exists())
if (LOG.isDebugEnabled())
{
in = new FileInputStream(file);
HashedSession session = restoreSession(in, null);
addSession(session, false);
session.didActivate();
return session;
LOG.debug("Not loading: {}",file);
}
return null;
}
try (FileInputStream in = new FileInputStream(file))
{
HashedSession session = restoreSession(in,null);
addSession(session,false);
session.didActivate();
return session;
}
catch (Exception e)
{
@ -587,8 +589,6 @@ public class HashSessionManager extends AbstractSessionManager
}
finally
{
if (in != null) IO.close(in);
if (error != null)
{
if (isDeleteUnrestorableSessions() && file.exists() && file.getParentFile().equals(_storeDir) )
@ -602,7 +602,10 @@ public class HashSessionManager extends AbstractSessionManager
}
}
else
file.delete(); //delete successfully restored file
{
// delete successfully restored file
file.delete();
}
}
return null;
}
@ -640,8 +643,10 @@ public class HashSessionManager extends AbstractSessionManager
if (session == null)
session = (HashedSession)newSession(created, accessed, clusterId);
session.setRequests(requests);
// Attributes
int size = di.readInt();
restoreSessionAttributes(di, size, session);
@ -651,7 +656,7 @@ public class HashSessionManager extends AbstractSessionManager
int maxIdle = di.readInt();
session.setMaxInactiveInterval(maxIdle);
}
catch (EOFException e)
catch (IOException e)
{
LOG.debug("No maxInactiveInterval persisted for session "+clusterId);
LOG.ignore(e);
@ -666,6 +671,8 @@ public class HashSessionManager extends AbstractSessionManager
{
if (size>0)
{
// input stream should not be closed here
@SuppressWarnings("resource")
ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is);
for (int i=0; i<size;i++)
{

View File

@ -145,24 +145,23 @@ public class HashedSession extends MemSession
throws Exception
{
File file = null;
FileOutputStream fos = null;
if (!_saveFailed && _hashSessionManager._storeDir != null)
{
try
file = new File(_hashSessionManager._storeDir, super.getId());
if (file.exists())
{
file.delete();
}
try(FileOutputStream fos = new FileOutputStream(file,false))
{
file = new File(_hashSessionManager._storeDir, super.getId());
if (file.exists())
file.delete();
file.createNewFile();
fos = new FileOutputStream(file);
save(fos);
IO.close(fos);
}
catch (Exception e)
{
saveFailed(); // We won't try again for this session
if (fos != null) IO.close(fos);
if (file != null) file.delete(); // No point keeping the file if we didn't save the whole session
if (file != null)
file.delete(); // No point keeping the file if we didn't save the whole session
throw e;
}
}

View File

@ -22,6 +22,7 @@ import java.io.File;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Log;
@ -33,24 +34,6 @@ import org.junit.Test;
public class HashSessionManagerTest
{
@After
public void enableStacks()
{
enableStacks(true);
}
@Before
public void quietStacks()
{
enableStacks(false);
}
protected void enableStacks(boolean enabled)
{
StdErrLog log = (StdErrLog)Log.getLogger("org.eclipse.jetty.server.session");
log.setHideStacks(!enabled);
}
@Test
public void testDangerousSessionIdRemoval() throws Exception
{
@ -78,7 +61,8 @@ public class HashSessionManagerTest
manager.setDeleteUnrestorableSessions(true);
manager.setLazyLoad(true);
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
testDir.mkdirs();
FS.ensureEmpty(testDir);
manager.setStoreDirectory(testDir);
Assert.assertTrue(new File(testDir, "validFile.session").createNewFile());
@ -88,7 +72,6 @@ public class HashSessionManagerTest
manager.getSession("validFile.session");
Assert.assertTrue("File shouldn't exist!", !new File(testDir,"validFile.session").exists());
}
@Test
@ -116,7 +99,6 @@ public class HashSessionManagerTest
server.start();
manager.start();
HashedSession session = (HashedSession)manager.newHttpSession(new Request(null, null));
String sessionId = session.getId();
@ -124,7 +106,7 @@ public class HashSessionManagerTest
session.setAttribute("two", new Integer(2));
//stop will persist sessions
manager.setMaxInactiveInterval(30); //change max inactive interval for *new* sessions
manager.setMaxInactiveInterval(30); // change max inactive interval for *new* sessions
manager.stop();
Assert.assertTrue("File should exist!", new File(testDir, session.getId()).exists());