Merge remote-tracking branch 'origin/jetty-8'

This commit is contained in:
Jan Bartel 2013-06-17 14:39:17 +10:00
commit 2ea7843d86
5 changed files with 181 additions and 64 deletions

View File

@ -40,6 +40,7 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme
private int _savePeriod=0; private int _savePeriod=0;
private int _idlePeriod=-1; private int _idlePeriod=-1;
private boolean _invalidateOnStop; private boolean _invalidateOnStop;
private boolean _preserveOnStop;
private boolean _saveAllAttributes; private boolean _saveAllAttributes;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -104,9 +105,12 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme
for (NoSqlSession session : sessions) for (NoSqlSession session : sessions)
{ {
session.save(false); session.save(false);
if (!_preserveOnStop) {
removeSession(session,false); removeSession(session,false);
} }
} }
}
else else
{ {
for (NoSqlSession session : sessions) for (NoSqlSession session : sessions)
@ -277,6 +281,16 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme
return _invalidateOnStop; return _invalidateOnStop;
} }
/* ------------------------------------------------------------ */
/**
* Preserve sessions when the session manager is stopped otherwise remove them from the DB.
* @return the removeOnStop
*/
public boolean isPreserveOnStop()
{
return _preserveOnStop;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Invalidate sessions when the session manager is stopped otherwise save them to the DB. * Invalidate sessions when the session manager is stopped otherwise save them to the DB.
@ -287,6 +301,16 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme
_invalidateOnStop = invalidateOnStop; _invalidateOnStop = invalidateOnStop;
} }
/* ------------------------------------------------------------ */
/**
* Preserve sessions when the session manager is stopped otherwise remove them from the DB.
* @param removeOnStop the removeOnStop to set
*/
public void setPreserveOnStop(boolean preserveOnStop)
{
_preserveOnStop = preserveOnStop;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Save all attributes of a session or only update the dirty attributes. * Save all attributes of a session or only update the dirty attributes.

View File

@ -137,6 +137,9 @@ public class MongoSessionManager extends NoSqlSessionManager
BasicDBObject sets = new BasicDBObject(); BasicDBObject sets = new BasicDBObject();
BasicDBObject unsets = new BasicDBObject(); BasicDBObject unsets = new BasicDBObject();
// handle valid or invalid
if (session.isValid())
{
// handle new or existing // handle new or existing
if (version == null) if (version == null)
{ {
@ -153,9 +156,6 @@ public class MongoSessionManager extends NoSqlSessionManager
update.put("$inc",__version_1); update.put("$inc",__version_1);
} }
// handle valid or invalid
if (session.isValid())
{
sets.put(__ACCESSED,session.getAccessed()); sets.put(__ACCESSED,session.getAccessed());
Set<String> names = session.takeDirty(); Set<String> names = session.takeDirty();
if (isSaveAllAttributes() || upsert) if (isSaveAllAttributes() || upsert)
@ -253,6 +253,7 @@ public class MongoSessionManager extends NoSqlSessionManager
DBObject attrs = (DBObject)getNestedValue(o,getContextKey()); DBObject attrs = (DBObject)getNestedValue(o,getContextKey());
if (attrs != null) if (attrs != null)
{ {
for (String name : attrs.keySet()) for (String name : attrs.keySet())
@ -286,6 +287,22 @@ public class MongoSessionManager extends NoSqlSessionManager
} }
} }
/*
* We are refreshing so we should update the last accessed time.
*/
BasicDBObject key = new BasicDBObject(__ID,session.getClusterId());
BasicDBObject sets = new BasicDBObject();
// Form updates
BasicDBObject update = new BasicDBObject();
sets.put(__ACCESSED,System.currentTimeMillis());
// Do the upsert
if (!sets.isEmpty())
{
update.put("$set",sets);
}
_sessions.update(key,update,false,false);
session.didActivate(); session.didActivate();
return version; return version;

View File

@ -665,6 +665,8 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
Servlet servlet=_servlet; Servlet servlet=_servlet;
synchronized(this) synchronized(this)
{ {
if (!isStarted())
throw new UnavailableException("Servlet not initialized", -1);
if (_unavailable!=0 || !_initOnStartup) if (_unavailable!=0 || !_initOnStartup)
servlet=getServlet(); servlet=getServlet();
if (servlet==null) if (servlet==null)

View File

@ -22,6 +22,9 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
@ -32,8 +35,11 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.MultiMap;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.UrlEncoded;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
@ -222,35 +228,55 @@ public class CGI extends HttpServlet
if ((pathTranslated == null) || (pathTranslated.length() == 0)) if ((pathTranslated == null) || (pathTranslated.length() == 0))
pathTranslated = path; pathTranslated = path;
String bodyFormEncoded = null;
if ((HttpMethod.POST.equals(req.getMethod()) || HttpMethod.PUT.equals(req.getMethod())) && "application/x-www-form-urlencoded".equals(req.getContentType()))
{
MultiMap<String> parameterMap = new MultiMap<String>();
Enumeration names = req.getParameterNames();
while (names.hasMoreElements())
{
String parameterName = (String)names.nextElement();
parameterMap.addValues(parameterName, req.getParameterValues(parameterName));
}
bodyFormEncoded = UrlEncoded.encode(parameterMap, Charset.forName(req.getCharacterEncoding()), true);
}
EnvList env = new EnvList(_env); EnvList env = new EnvList(_env);
// these ones are from "The WWW Common Gateway Interface Version 1.1" // these ones are from "The WWW Common Gateway Interface Version 1.1"
// look at : // look at :
// http://Web.Golux.Com/coar/cgi/draft-coar-cgi-v11-03-clean.html#6.1.1 // http://Web.Golux.Com/coar/cgi/draft-coar-cgi-v11-03-clean.html#6.1.1
env.set("AUTH_TYPE",req.getAuthType()); env.set("AUTH_TYPE", req.getAuthType());
env.set("CONTENT_LENGTH",Integer.toString(len)); if (bodyFormEncoded != null)
env.set("CONTENT_TYPE",req.getContentType()); {
env.set("GATEWAY_INTERFACE","CGI/1.1"); env.set("CONTENT_LENGTH", Integer.toString(bodyFormEncoded.length()));
}
else
{
env.set("CONTENT_LENGTH", Integer.toString(len));
}
env.set("CONTENT_TYPE", req.getContentType());
env.set("GATEWAY_INTERFACE", "CGI/1.1");
if ((pathInfo != null) && (pathInfo.length() > 0)) if ((pathInfo != null) && (pathInfo.length() > 0))
{ {
env.set("PATH_INFO",pathInfo); env.set("PATH_INFO", pathInfo);
} }
env.set("PATH_TRANSLATED",pathTranslated); env.set("PATH_TRANSLATED", pathTranslated);
env.set("QUERY_STRING",req.getQueryString()); env.set("QUERY_STRING", req.getQueryString());
env.set("REMOTE_ADDR",req.getRemoteAddr()); env.set("REMOTE_ADDR", req.getRemoteAddr());
env.set("REMOTE_HOST",req.getRemoteHost()); env.set("REMOTE_HOST", req.getRemoteHost());
// The identity information reported about the connection by a // The identity information reported about the connection by a
// RFC 1413 [11] request to the remote agent, if // RFC 1413 [11] request to the remote agent, if
// available. Servers MAY choose not to support this feature, or // available. Servers MAY choose not to support this feature, or
// not to request the data for efficiency reasons. // not to request the data for efficiency reasons.
// "REMOTE_IDENT" => "NYI" // "REMOTE_IDENT" => "NYI"
env.set("REMOTE_USER",req.getRemoteUser()); env.set("REMOTE_USER", req.getRemoteUser());
env.set("REQUEST_METHOD",req.getMethod()); env.set("REQUEST_METHOD", req.getMethod());
env.set("SCRIPT_NAME",scriptName); env.set("SCRIPT_NAME", scriptName);
env.set("SCRIPT_FILENAME",scriptPath); env.set("SCRIPT_FILENAME", scriptPath);
env.set("SERVER_NAME",req.getServerName()); env.set("SERVER_NAME", req.getServerName());
env.set("SERVER_PORT",Integer.toString(req.getServerPort())); env.set("SERVER_PORT", Integer.toString(req.getServerPort()));
env.set("SERVER_PROTOCOL",req.getProtocol()); env.set("SERVER_PROTOCOL", req.getProtocol());
env.set("SERVER_SOFTWARE",getServletContext().getServerInfo()); env.set("SERVER_SOFTWARE", getServletContext().getServerInfo());
Enumeration enm = req.getHeaderNames(); Enumeration enm = req.getHeaderNames();
while (enm.hasMoreElements()) while (enm.hasMoreElements())
@ -261,7 +287,7 @@ public class CGI extends HttpServlet
} }
// these extra ones were from printenv on www.dev.nomura.co.uk // these extra ones were from printenv on www.dev.nomura.co.uk
env.set("HTTPS",(req.isSecure()?"ON":"OFF")); env.set("HTTPS", (req.isSecure()?"ON":"OFF"));
// "DOCUMENT_ROOT" => root + "/docs", // "DOCUMENT_ROOT" => root + "/docs",
// "SERVER_URL" => "NYI - http://us0245", // "SERVER_URL" => "NYI - http://us0245",
// "TZ" => System.getProperty("user.timezone"), // "TZ" => System.getProperty("user.timezone"),
@ -275,31 +301,22 @@ public class CGI extends HttpServlet
if (_cmdPrefix != null) if (_cmdPrefix != null)
execCmd = _cmdPrefix + " " + execCmd; execCmd = _cmdPrefix + " " + execCmd;
Process p = (dir == null)?Runtime.getRuntime().exec(execCmd,env.getEnvArray()):Runtime.getRuntime().exec(execCmd,env.getEnvArray(),dir); LOG.debug("Environment: " + env.getExportString());
LOG.debug("Command: " + execCmd);
Process p;
if (dir == null)
p = Runtime.getRuntime().exec(execCmd, env.getEnvArray());
else
p = Runtime.getRuntime().exec(execCmd, env.getEnvArray(), dir);
// hook processes input to browser's output (async) // hook processes input to browser's output (async)
final InputStream inFromReq = req.getInputStream(); if (bodyFormEncoded != null)
final OutputStream outToCgi = p.getOutputStream(); writeProcessInput(p, bodyFormEncoded);
final int inLength = len; else if (len > 0)
writeProcessInput(p, req.getInputStream(), len);
IO.copyThread(p.getErrorStream(),System.err); IO.copyThread(p.getErrorStream(), System.err);
new Thread(new Runnable()
{
public void run()
{
try
{
if (inLength > 0)
IO.copy(inFromReq,outToCgi,inLength);
outToCgi.close();
}
catch (IOException e)
{
LOG.ignore(e);
}
}
}).start();
// hook processes output to browser's input (sync) // hook processes output to browser's input (sync)
// if browser closes stream, we should detect it and kill process... // if browser closes stream, we should detect it and kill process...
@ -376,15 +393,56 @@ public class CGI extends HttpServlet
} }
catch (Exception e) catch (Exception e)
{ {
LOG.ignore(e); LOG.debug(e);
} }
} }
os = null;
p.destroy(); p.destroy();
// LOG.debug("CGI: terminated!"); // LOG.debug("CGI: terminated!");
} }
} }
private static void writeProcessInput(final Process p, final String input)
{
new Thread(new Runnable()
{
public void run()
{
try
{
Writer outToCgi = new OutputStreamWriter(p.getOutputStream());
outToCgi.write(input);
outToCgi.close();
}
catch (IOException e)
{
LOG.debug(e);
}
}
}).start();
}
private static void writeProcessInput(final Process p, final InputStream input, final int len)
{
if (len <= 0) return;
new Thread(new Runnable()
{
public void run()
{
try
{
OutputStream outToCgi = p.getOutputStream();
IO.copy(input, outToCgi, len);
outToCgi.close();
}
catch (IOException e)
{
LOG.debug(e);
}
}
}).start();
}
/** /**
* Utility method to get a line of text from the input stream. * Utility method to get a line of text from the input stream.
* *
@ -393,7 +451,7 @@ public class CGI extends HttpServlet
* @return the line of text * @return the line of text
* @throws IOException * @throws IOException
*/ */
private String getTextLineFromStream(InputStream is) throws IOException private static String getTextLineFromStream(InputStream is) throws IOException
{ {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
int b; int b;
@ -411,16 +469,16 @@ public class CGI extends HttpServlet
*/ */
private static class EnvList private static class EnvList
{ {
private Map envMap; private Map<String, String> envMap;
EnvList() EnvList()
{ {
envMap = new HashMap(); envMap = new HashMap<String, String>();
} }
EnvList(EnvList l) EnvList(EnvList l)
{ {
envMap = new HashMap(l.envMap); envMap = new HashMap<String,String>(l.envMap);
} }
/** /**
@ -434,7 +492,19 @@ public class CGI extends HttpServlet
/** Get representation suitable for passing to exec. */ /** Get representation suitable for passing to exec. */
public String[] getEnvArray() public String[] getEnvArray()
{ {
return (String[])envMap.values().toArray(new String[envMap.size()]); return envMap.values().toArray(new String[envMap.size()]);
}
public String getExportString()
{
StringBuilder sb = new StringBuilder();
for (String variable : getEnvArray())
{
sb.append("export \"");
sb.append(variable);
sb.append("\"; ");
}
return sb.toString();
} }
@Override @Override

View File

@ -0,0 +1,4 @@
# Setup default logging implementation for during testing
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
#org.eclipse.jetty.server.LEVEL=DEBUG