提交 b33f7212 authored 作者: noelgrandin@gmail.com's avatar noelgrandin@gmail.com

Optionally persist session history in the H2 console. (patch from Martin Grajcar)

上级 2462af05
...@@ -18,6 +18,7 @@ Change Log ...@@ -18,6 +18,7 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>The LIRS cache now re-sizes the internal hash map if needed. <ul><li>The LIRS cache now re-sizes the internal hash map if needed.
<ul><li>Optionally persist session history in the H2 console. (patch from Martin Grajcar)
</li></ul> </li></ul>
<h2>Version 1.4.179 Beta (2014-06-23)</h2> <h2>Version 1.4.179 Beta (2014-06-23)</h2>
......
...@@ -48,6 +48,8 @@ import org.h2.util.Utils; ...@@ -48,6 +48,8 @@ import org.h2.util.Utils;
*/ */
public class WebServer implements Service { public class WebServer implements Service {
private static final String COMMAND_HISTORY = "commandHistory";
static final String TRANSFER = "transfer"; static final String TRANSFER = "transfer";
static final String[][] LANGUAGES = { static final String[][] LANGUAGES = {
...@@ -157,6 +159,8 @@ public class WebServer implements Service { ...@@ -157,6 +159,8 @@ public class WebServer implements Service {
private TranslateThread translateThread; private TranslateThread translateThread;
private boolean allowChunked = true; private boolean allowChunked = true;
private String serverPropertiesDir = Constants.SERVER_PROPERTIES_DIR; private String serverPropertiesDir = Constants.SERVER_PROPERTIES_DIR;
/** null means the history is not allowed to be stored */
private String commandHistoryString;
/** /**
* Read the given file from the file system or from the resources. * Read the given file from the file system or from the resources.
...@@ -291,6 +295,7 @@ public class WebServer implements Service { ...@@ -291,6 +295,7 @@ public class WebServer implements Service {
"webSSL", false); "webSSL", false);
allowOthers = SortedProperties.getBooleanProperty(prop, allowOthers = SortedProperties.getBooleanProperty(prop,
"webAllowOthers", false); "webAllowOthers", false);
commandHistoryString = prop.getProperty(COMMAND_HISTORY);
for (int i = 0; args != null && i < args.length; i++) { for (int i = 0; args != null && i < args.length; i++) {
String a = args[i]; String a = args[i];
if (Tool.isOption(a, "-webPort")) { if (Tool.isOption(a, "-webPort")) {
...@@ -524,6 +529,59 @@ public class WebServer implements Service { ...@@ -524,6 +529,59 @@ public class WebServer implements Service {
return port; return port;
} }
public boolean isCommandHistoryAllowed() {
return commandHistoryString != null;
}
public void setCommandHistoryAllowed(boolean allowed) {
if (allowed) {
if (commandHistoryString == null) {
commandHistoryString = "";
}
} else {
commandHistoryString = null;
}
}
public ArrayList<String> getCommandHistoryList() {
ArrayList<String> result = New.arrayList();
if (commandHistoryString == null) {
return result;
}
// Split the commandHistoryString on non-escaped semicolons and unescape it.
StringBuilder sb = new StringBuilder();
for (int end = 0; ; end++) {
if (end == commandHistoryString.length() || commandHistoryString.charAt(end) == ';') {
if (sb.length() > 0) {
result.add(sb.toString());
sb.delete(0, sb.length());
}
if (end == commandHistoryString.length()) {
break;
}
} else if (commandHistoryString.charAt(end) == '\\' && end < commandHistoryString.length() - 1) {
sb.append(commandHistoryString.charAt(++end));
} else {
sb.append(commandHistoryString.charAt(end));
}
}
return result;
}
public void saveCommandHistoryList(ArrayList<String> commandHistory) {
StringBuilder sb = new StringBuilder();
for (String s : commandHistory) {
if (sb.length() > 0) {
sb.append(';');
}
sb.append(s.replace("\\", "\\\\").replace(";", "\\;"));
}
commandHistoryString = sb.toString();
saveProperties(null);
}
/** /**
* Get the connection information for this setting. * Get the connection information for this setting.
* *
...@@ -632,6 +690,9 @@ public class WebServer implements Service { ...@@ -632,6 +690,9 @@ public class WebServer implements Service {
prop.setProperty("webSSL", prop.setProperty("webSSL",
"" + SortedProperties.getBooleanProperty(old, "" + SortedProperties.getBooleanProperty(old,
"webSSL", ssl)); "webSSL", ssl));
if (commandHistoryString != null) {
prop.setProperty(COMMAND_HISTORY, commandHistoryString);
}
} }
ArrayList<ConnectionInfo> settings = getSettings(); ArrayList<ConnectionInfo> settings = getSettings();
int len = settings.size(); int len = settings.size();
......
...@@ -56,7 +56,7 @@ class WebSession { ...@@ -56,7 +56,7 @@ class WebSession {
private final WebServer server; private final WebServer server;
private final ArrayList<String> commandHistory = New.arrayList(); private final ArrayList<String> commandHistory;
private Connection conn; private Connection conn;
private DatabaseMetaData meta; private DatabaseMetaData meta;
...@@ -66,6 +66,10 @@ class WebSession { ...@@ -66,6 +66,10 @@ class WebSession {
WebSession(WebServer server) { WebSession(WebServer server) {
this.server = server; this.server = server;
/* This must be stored in the session rather than in the server.
* Otherwise, one client could allow saving history for others (insecure).
*/
this.commandHistory = server.getCommandHistoryList();
} }
/** /**
...@@ -172,6 +176,9 @@ class WebSession { ...@@ -172,6 +176,9 @@ class WebSession {
commandHistory.remove(idx); commandHistory.remove(idx);
} }
commandHistory.add(sql); commandHistory.add(sql);
if (server.isCommandHistoryAllowed()) {
server.saveCommandHistoryList(commandHistory);
}
} }
/** /**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论