diff options
author | Jan Bartel | 2013-06-17 04:39:17 +0000 |
---|---|---|
committer | Jan Bartel | 2013-06-17 04:39:17 +0000 |
commit | 2ea7843d867b69b61691541cadc8f091b14a7d28 (patch) | |
tree | d7726916d6cac6bc4a4464d402476d9b4cd3019d | |
parent | 59889bc14985aa92e0c217b16158d627bc2fa75a (diff) | |
parent | 1908fff38fe66c40382ec4ff404b21637bf10efb (diff) | |
download | org.eclipse.jetty.project-2ea7843d867b69b61691541cadc8f091b14a7d28.tar.gz org.eclipse.jetty.project-2ea7843d867b69b61691541cadc8f091b14a7d28.tar.xz org.eclipse.jetty.project-2ea7843d867b69b61691541cadc8f091b14a7d28.zip |
Merge remote-tracking branch 'origin/jetty-8'
5 files changed, 181 insertions, 64 deletions
diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java index e5f0e17fd5..f8027958a8 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java @@ -40,6 +40,7 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme private int _savePeriod=0; private int _idlePeriod=-1; private boolean _invalidateOnStop; + private boolean _preserveOnStop; private boolean _saveAllAttributes; /* ------------------------------------------------------------ */ @@ -104,7 +105,10 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme for (NoSqlSession session : sessions) { session.save(false); - removeSession(session,false); + + if (!_preserveOnStop) { + removeSession(session,false); + } } } else @@ -279,6 +283,16 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme /* ------------------------------------------------------------ */ /** + * 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. * @param invalidateOnStop the invalidateOnStop to set */ @@ -289,6 +303,16 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme /* ------------------------------------------------------------ */ /** + * 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. * @return the saveAllAttributes */ diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java index b078f08e90..0d1a0bb42c 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java @@ -137,25 +137,25 @@ public class MongoSessionManager extends NoSqlSessionManager BasicDBObject sets = new BasicDBObject(); BasicDBObject unsets = new BasicDBObject(); - // handle new or existing - if (version == null) - { - // New session - upsert = true; - version = new Long(1); - sets.put(__CREATED,session.getCreationTime()); - sets.put(__VALID,true); - sets.put(getContextKey(__VERSION),version); - } - else - { - version = new Long(((Number)version).longValue() + 1); - update.put("$inc",__version_1); - } - // handle valid or invalid if (session.isValid()) { + // handle new or existing + if (version == null) + { + // New session + upsert = true; + version = new Long(1); + sets.put(__CREATED,session.getCreationTime()); + sets.put(__VALID,true); + sets.put(getContextKey(__VERSION),version); + } + else + { + version = new Long(((Number)version).longValue() + 1); + update.put("$inc",__version_1); + } + sets.put(__ACCESSED,session.getAccessed()); Set<String> names = session.takeDirty(); if (isSaveAllAttributes() || upsert) @@ -253,6 +253,7 @@ public class MongoSessionManager extends NoSqlSessionManager DBObject attrs = (DBObject)getNestedValue(o,getContextKey()); + if (attrs != null) { 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(); return version; diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java index 297300199f..28fce42830 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java @@ -665,6 +665,8 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope Servlet servlet=_servlet; synchronized(this) { + if (!isStarted()) + throw new UnavailableException("Servlet not initialized", -1); if (_unavailable!=0 || !_initOnStartup) servlet=getServlet(); if (servlet==null) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java index c7b2b4f1fb..9a34873f4e 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java @@ -22,6 +22,9 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.Charset; import java.util.Enumeration; import java.util.HashMap; import java.util.Locale; @@ -32,8 +35,11 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.MultiMap; 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.Logger; @@ -222,35 +228,55 @@ public class CGI extends HttpServlet if ((pathTranslated == null) || (pathTranslated.length() == 0)) 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); // these ones are from "The WWW Common Gateway Interface Version 1.1" // look at : // http://Web.Golux.Com/coar/cgi/draft-coar-cgi-v11-03-clean.html#6.1.1 - env.set("AUTH_TYPE",req.getAuthType()); - env.set("CONTENT_LENGTH",Integer.toString(len)); - env.set("CONTENT_TYPE",req.getContentType()); - env.set("GATEWAY_INTERFACE","CGI/1.1"); + env.set("AUTH_TYPE", req.getAuthType()); + if (bodyFormEncoded != null) + { + 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)) { - env.set("PATH_INFO",pathInfo); + env.set("PATH_INFO", pathInfo); } - env.set("PATH_TRANSLATED",pathTranslated); - env.set("QUERY_STRING",req.getQueryString()); - env.set("REMOTE_ADDR",req.getRemoteAddr()); - env.set("REMOTE_HOST",req.getRemoteHost()); + env.set("PATH_TRANSLATED", pathTranslated); + env.set("QUERY_STRING", req.getQueryString()); + env.set("REMOTE_ADDR", req.getRemoteAddr()); + env.set("REMOTE_HOST", req.getRemoteHost()); // The identity information reported about the connection by a // RFC 1413 [11] request to the remote agent, if // available. Servers MAY choose not to support this feature, or // not to request the data for efficiency reasons. // "REMOTE_IDENT" => "NYI" - env.set("REMOTE_USER",req.getRemoteUser()); - env.set("REQUEST_METHOD",req.getMethod()); - env.set("SCRIPT_NAME",scriptName); - env.set("SCRIPT_FILENAME",scriptPath); - env.set("SERVER_NAME",req.getServerName()); - env.set("SERVER_PORT",Integer.toString(req.getServerPort())); - env.set("SERVER_PROTOCOL",req.getProtocol()); - env.set("SERVER_SOFTWARE",getServletContext().getServerInfo()); + env.set("REMOTE_USER", req.getRemoteUser()); + env.set("REQUEST_METHOD", req.getMethod()); + env.set("SCRIPT_NAME", scriptName); + env.set("SCRIPT_FILENAME", scriptPath); + env.set("SERVER_NAME", req.getServerName()); + env.set("SERVER_PORT", Integer.toString(req.getServerPort())); + env.set("SERVER_PROTOCOL", req.getProtocol()); + env.set("SERVER_SOFTWARE", getServletContext().getServerInfo()); Enumeration enm = req.getHeaderNames(); while (enm.hasMoreElements()) @@ -261,7 +287,7 @@ public class CGI extends HttpServlet } // 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", // "SERVER_URL" => "NYI - http://us0245", // "TZ" => System.getProperty("user.timezone"), @@ -275,31 +301,22 @@ public class CGI extends HttpServlet if (_cmdPrefix != null) 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); - // hook processes input to browser's output (async) - final InputStream inFromReq = req.getInputStream(); - final OutputStream outToCgi = p.getOutputStream(); - final int inLength = len; + Process p; + if (dir == null) + p = Runtime.getRuntime().exec(execCmd, env.getEnvArray()); + else + p = Runtime.getRuntime().exec(execCmd, env.getEnvArray(), dir); - IO.copyThread(p.getErrorStream(),System.err); + // hook processes input to browser's output (async) + if (bodyFormEncoded != null) + writeProcessInput(p, bodyFormEncoded); + else if (len > 0) + writeProcessInput(p, req.getInputStream(), len); - 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(); + IO.copyThread(p.getErrorStream(), System.err); // hook processes output to browser's input (sync) // if browser closes stream, we should detect it and kill process... @@ -376,15 +393,56 @@ public class CGI extends HttpServlet } catch (Exception e) { - LOG.ignore(e); + LOG.debug(e); } } - os = null; p.destroy(); // 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. * @@ -393,7 +451,7 @@ public class CGI extends HttpServlet * @return the line of text * @throws IOException */ - private String getTextLineFromStream(InputStream is) throws IOException + private static String getTextLineFromStream(InputStream is) throws IOException { StringBuilder buffer = new StringBuilder(); int b; @@ -411,16 +469,16 @@ public class CGI extends HttpServlet */ private static class EnvList { - private Map envMap; + private Map<String, String> envMap; EnvList() { - envMap = new HashMap(); + envMap = new HashMap<String, String>(); } 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. */ 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 diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/resources/jetty-logging.properties b/tests/test-sessions/test-mongodb-sessions/src/test/resources/jetty-logging.properties new file mode 100644 index 0000000000..fd2d21f974 --- /dev/null +++ b/tests/test-sessions/test-mongodb-sessions/src/test/resources/jetty-logging.properties @@ -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
\ No newline at end of file |