提交 39376f76 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 c427908d
...@@ -273,6 +273,7 @@ ...@@ -273,6 +273,7 @@
</target> </target>
<target name="warConsole" depends="compileServlet, jar"> <target name="warConsole" depends="compileServlet, jar">
<fail unless="servlet.jar.present" message="Servlet API jar not found"/>
<war destfile="bin/h2console.war" webxml="src/tools/WEB-INF/web.xml" basedir="src/tools/WEB-INF" includes="console.html"> <war destfile="bin/h2console.war" webxml="src/tools/WEB-INF/web.xml" basedir="src/tools/WEB-INF" includes="console.html">
<lib file="bin/h2.jar" /> <lib file="bin/h2.jar" />
</war> </war>
......
...@@ -92,20 +92,46 @@ This may not have the desired effect if a default value in the target table is o ...@@ -92,20 +92,46 @@ This may not have the desired effect if a default value in the target table is o
<br /><a name="transaction_isolation"></a> <br /><a name="transaction_isolation"></a>
<h2>Transaction Isolation</h2> <h2>Transaction Isolation</h2>
This database supports the transaction isolation level 'serializable', in which dirty reads, non-repeatable <p>
reads and phantom reads are prohibited. This database supports the following transaction isolation levels:
</p>
<ul>
<li><b>Serializable</b><br />
This is the default level.<br />
To enable, execute the SQL statement 'SET LOCK_MODE 0'<br />
or append ;LOCK_MODE=1 to the database URL: jdbc:h2:~/test;LOCK_MODE=1
</li><li><b>Read Committed</b><br />
Higer concurrency is possible when using this level.<br />
This is the isolation level used for many database systems.<br />
To enable, execute the SQL statement 'SET LOCK_MODE 0'<br />
or append ;LOCK_MODE=3 to the database URL: jdbc:h2:~/test;LOCK_MODE=3
</li><li><b>Read Uncommitted</b><br />
This level means that transaction isolation is disabled.<br />
To enable, execute the SQL statement 'SET LOCK_MODE 0'<br />
or append ;LOCK_MODE=0 to the database URL: jdbc:h2:~/test;LOCK_MODE=0
</li>
</ul>
<p>
When using the isolation level 'serializable', dirty reads, non-repeatable reads, and phantom reads are prohibited.
</p>
<ul> <ul>
<li><b>Dirty Reads</b><br /> <li><b>Dirty Reads</b><br />
Means a connection can read uncommitted changes made by another connection. Means a connection can read uncommitted changes made by another connection.<br />
Possible with: read uncommitted
</li><li><b>Non-Repeatable Reads</b><br /> </li><li><b>Non-Repeatable Reads</b><br />
A connection reads a row, another connection changes a row and commits, A connection reads a row, another connection changes a row and commits,
and the first connection re-reads the same row and gets the new result. and the first connection re-reads the same row and gets the new result.<br />
Possible with: read uncommitted, read committed
</li><li><b>Phantom Reads</b><br /> </li><li><b>Phantom Reads</b><br />
A connection reads a set of rows using a condition, another connection A connection reads a set of rows using a condition, another connection
inserts a row that falls in this condition and commits, then the first connection inserts a row that falls in this condition and commits, then the first connection
re-reads using the same condition and gets the new row. re-reads using the same condition and gets the new row.<br />
</li></ul> Possible with: read uncommitted, read committed
</li>
</ul>
<h3>Table Level Locking</h3> <h3>Table Level Locking</h3>
The database allows multiple concurrent connections to the same database. The database allows multiple concurrent connections to the same database.
......
...@@ -824,13 +824,13 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -824,13 +824,13 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Priority 1</h3> <h3>Priority 1</h3>
<ul> <ul>
<li>RECOVER=1 should automatically recover, =2 should run the recovery tool if required <li>MVCC (Multi Version Concurrency Control)
</li><li>RECOVER=1 should automatically recover, =2 should run the recovery tool if required
</li><li>More tests with MULTI_THREADED=1 </li><li>More tests with MULTI_THREADED=1
</li><li>Improve performance for create table (if this is possible) </li><li>Improve performance for create table (if this is possible)
</li><li>Test with Spatial DB in a box / JTS (http://docs.codehaus.org/display/GEOS/SpatialDBBox) </li><li>Test with Spatial DB in a box / JTS (http://docs.codehaus.org/display/GEOS/SpatialDBBox)
</li><li>Document how to use H2 with PHP (generic database API) </li><li>Document how to use H2 with PHP (generic database API)
</li><li>Optimization: result set caching (like MySQL) </li><li>Optimization: result set caching (like MySQL)
</li><li>MVCC (Multi Version Concurrency Control)
</li><li>Server side cursors </li><li>Server side cursors
</li><li>Row level locking </li><li>Row level locking
</li><li>Read-only databases inside a jar (splitting large files to speed up random access) </li><li>Read-only databases inside a jar (splitting large files to speed up random access)
......
...@@ -763,25 +763,27 @@ public class Database implements DataHandler { ...@@ -763,25 +763,27 @@ public class Database implements DataHandler {
} }
} }
synchronized void close(boolean fromShutdownHook) { void close(boolean fromShutdownHook) {
this.closing = true; synchronized(this) {
if(sessions.size() > 0) { this.closing = true;
if(!fromShutdownHook) { if(sessions.size() > 0) {
return; if(!fromShutdownHook) {
} return;
traceSystem.getTrace(Trace.DATABASE).info("closing " + databaseName + " from shutdown hook"); }
Session[] all = new Session[sessions.size()]; traceSystem.getTrace(Trace.DATABASE).info("closing " + databaseName + " from shutdown hook");
sessions.toArray(all); Session[] all = new Session[sessions.size()];
for(int i=0; i<all.length; i++) { sessions.toArray(all);
Session s = all[i]; for(int i=0; i<all.length; i++) {
try { Session s = all[i];
s.close(); try {
} catch(SQLException e) { s.close();
traceSystem.getTrace(Trace.SESSION).error("disconnecting #" + s.getId(), e); } catch(SQLException e) {
} traceSystem.getTrace(Trace.SESSION).error("disconnecting #" + s.getId(), e);
} }
} }
traceSystem.getTrace(Trace.DATABASE).info("closing " + databaseName); }
}
traceSystem.getTrace(Trace.DATABASE).info("closing " + databaseName);
if(eventListener != null) { if(eventListener != null) {
eventListener.closingDatabase(); eventListener.closingDatabase();
eventListener = null; eventListener = null;
......
...@@ -61,7 +61,7 @@ public class WebServer implements Service { ...@@ -61,7 +61,7 @@ public class WebServer implements Service {
"Generic Derby (Embedded)|org.apache.derby.jdbc.EmbeddedDriver|jdbc:derby:test;create=true|sa", "Generic Derby (Embedded)|org.apache.derby.jdbc.EmbeddedDriver|jdbc:derby:test;create=true|sa",
"Generic Derby (Server)|org.apache.derby.jdbc.ClientDriver|jdbc:derby://localhost:1527/test;create=true|sa", "Generic Derby (Server)|org.apache.derby.jdbc.ClientDriver|jdbc:derby://localhost:1527/test;create=true|sa",
"Generic HSQLDB|org.hsqldb.jdbcDriver|jdbc:hsqldb:test;hsqldb.default_table_type=cached|sa" , "Generic HSQLDB|org.hsqldb.jdbcDriver|jdbc:hsqldb:test;hsqldb.default_table_type=cached|sa" ,
"Generic H2|org.h2.Driver|jdbc:h2:test|sa", "Generic H2|org.h2.Driver|jdbc:h2:~/test|sa",
}; };
// private URLClassLoader urlClassLoader; // private URLClassLoader urlClassLoader;
...@@ -247,7 +247,11 @@ public class WebServer implements Service { ...@@ -247,7 +247,11 @@ public class WebServer implements Service {
void trace(String s) { void trace(String s) {
// System.out.println(s); // System.out.println(s);
} }
public void traceError(Exception e) {
e.printStackTrace();
}
public boolean supportsLanguage(String language) { public boolean supportsLanguage(String language) {
return languages.contains(language); return languages.contains(language);
} }
......
...@@ -50,6 +50,8 @@ class WebThread extends Thread { ...@@ -50,6 +50,8 @@ class WebThread extends Thread {
private InputStream input; private InputStream input;
private String ifModifiedSince; private String ifModifiedSince;
String mimeType;
boolean cache;
// TODO web: support online data editing like http://numsum.com/ // TODO web: support online data editing like http://numsum.com/
...@@ -60,45 +62,63 @@ class WebThread extends Thread { ...@@ -60,45 +62,63 @@ class WebThread extends Thread {
} }
void setSession(WebSession session, Properties attributes) { void setSession(WebSession session, Properties attributes) {
int todoRefactor;
this.session = session; this.session = session;
this.attributes = attributes; this.attributes = attributes;
} }
protected String getComboBox(String[] elements, String selected) { private String getAllowedFile(String requestedFile) {
StringBuffer buff = new StringBuffer(); if(!allow()) {
for(int i=0; i<elements.length; i++) { return "notAllowed.jsp";
String value = elements[i];
buff.append("<option value=\"");
buff.append(PageParser.escapeHtml(value));
buff.append("\"");
if(value.equals(selected)) {
buff.append(" selected");
}
buff.append(">");
buff.append(PageParser.escapeHtml(value));
buff.append("</option>");
} }
return buff.toString(); if(requestedFile.length() == 0) {
return "index.do";
}
return requestedFile;
} }
protected String getComboBox(String[][] elements, String selected) { public String processRequest(String file, String hostname) {
StringBuffer buff = new StringBuffer(); int index = file.lastIndexOf('.');
for(int i=0; i<elements.length; i++) { String suffix;
String[] n = elements[i]; if(index >= 0) {
buff.append("<option value=\""); suffix = file.substring(index+1);
buff.append(PageParser.escapeHtml(n[0])); } else {
buff.append("\""); suffix = "";
if(n[0].equals(selected)) { }
buff.append(" selected"); if(suffix.equals("ico")) {
mimeType = "image/x-icon";
cache=true;
} else if(suffix.equals("gif")) {
mimeType = "image/gif";
cache=true;
} else if(suffix.equals("css")) {
cache=true;
mimeType = "text/css";
} else if(suffix.equals("html") || suffix.equals("do") || suffix.equals("jsp")) {
cache=false;
mimeType = "text/html";
if (session == null) {
session = server.createNewSession(hostname);
if (!file.equals("notAllowed.jsp")) {
file = "index.do";
}
} }
buff.append(">"); } else if(suffix.equals("js")) {
buff.append(PageParser.escapeHtml(n[1])); cache=true;
buff.append("</option>"); mimeType = "text/javascript";
} else {
cache = false;
mimeType = "text/html";
file = "error.jsp";
server.trace("unknown mime type, file "+file);
} }
return buff.toString(); server.trace("mimeType="+mimeType);
server.trace(file);
if(file.endsWith(".do")) {
file = process(file);
}
return file;
} }
public void run() { public void run() {
try { try {
input = socket.getInputStream(); input = socket.getInputStream();
...@@ -106,13 +126,8 @@ class WebThread extends Thread { ...@@ -106,13 +126,8 @@ class WebThread extends Thread {
if(head.startsWith("GET ") || head.startsWith("POST ")) { if(head.startsWith("GET ") || head.startsWith("POST ")) {
int begin = head.indexOf('/'), end = head.lastIndexOf(' '); int begin = head.indexOf('/'), end = head.lastIndexOf(' ');
String file = head.substring(begin+1, end).trim(); String file = head.substring(begin+1, end).trim();
if(file.length() == 0) { server.trace(head + ": " + file);
file = "index.do"; file = getAllowedFile(file);
}
if(!allow()) {
file = "notAllowed.jsp";
}
server.trace(head + " :" + file);
attributes = new Properties(); attributes = new Properties();
int paramIndex = file.indexOf("?"); int paramIndex = file.indexOf("?");
session = null; session = null;
...@@ -123,50 +138,11 @@ class WebThread extends Thread { ...@@ -123,50 +138,11 @@ class WebThread extends Thread {
file = file.substring(0, paramIndex); file = file.substring(0, paramIndex);
session = server.getSession(sessionId); session = server.getSession(sessionId);
} }
// TODO web: support errors
String mimeType;
boolean cache;
int index = file.lastIndexOf('.');
String suffix;
if(index >= 0) {
suffix = file.substring(index+1);
} else {
suffix = "";
}
if(suffix.equals("ico")) {
mimeType = "image/x-icon";
cache=true;
} else if(suffix.equals("gif")) {
mimeType = "image/gif";
cache=true;
} else if(suffix.equals("css")) {
cache=true;
mimeType = "text/css";
} else if(suffix.equals("html") || suffix.equals("do") || suffix.equals("jsp")) {
cache=false;
mimeType = "text/html";
if (session == null) {
String hostname = socket.getInetAddress().getHostName();
session = server.createNewSession(hostname);
if (!file.equals("notAllowed.jsp")) {
file = "index.do";
}
}
} else if(suffix.equals("js")) {
cache=true;
mimeType = "text/javascript";
} else {
cache = false;
mimeType = "text/html";
file = "error.jsp";
server.trace("unknown mime type, file "+file);
}
server.trace("mimeType="+mimeType);
parseHeader(); parseHeader();
server.trace(file); String hostname = socket.getInetAddress().getHostName();
if(file.endsWith(".do")) {
file = process(file); file = processRequest(file, hostname);
}
String message; String message;
byte[] bytes; byte[] bytes;
if(cache && ifModifiedSince!=null && ifModifiedSince.equals(server.getStartDateTime())) { if(cache && ifModifiedSince!=null && ifModifiedSince.equals(server.getStartDateTime())) {
...@@ -179,7 +155,13 @@ class WebThread extends Thread { ...@@ -179,7 +155,13 @@ class WebThread extends Thread {
bytes = StringUtils.utf8Encode("File not found: "+file); bytes = StringUtils.utf8Encode("File not found: "+file);
} else { } else {
if(session != null && file.endsWith(".jsp")) { if(session != null && file.endsWith(".jsp")) {
bytes = StringUtils.utf8Encode(fill(StringUtils.utf8Decode(bytes))); String page = StringUtils.utf8Decode(bytes);
page = PageParser.parse(server, page, session.map);
try {
bytes = StringUtils.utf8Encode(page);
} catch(SQLException e) {
server.traceError(e);
}
} }
message = "HTTP/1.1 200 OK\n"; message = "HTTP/1.1 200 OK\n";
message += "Content-Type: "+mimeType+"\n"; message += "Content-Type: "+mimeType+"\n";
...@@ -202,7 +184,6 @@ class WebThread extends Thread { ...@@ -202,7 +184,6 @@ class WebThread extends Thread {
} }
output.flush(); output.flush();
output.close(); output.close();
output.close();
socket.close(); socket.close();
return; return;
} }
...@@ -211,6 +192,40 @@ class WebThread extends Thread { ...@@ -211,6 +192,40 @@ class WebThread extends Thread {
} }
} }
protected String getComboBox(String[] elements, String selected) {
StringBuffer buff = new StringBuffer();
for(int i=0; i<elements.length; i++) {
String value = elements[i];
buff.append("<option value=\"");
buff.append(PageParser.escapeHtml(value));
buff.append("\"");
if(value.equals(selected)) {
buff.append(" selected");
}
buff.append(">");
buff.append(PageParser.escapeHtml(value));
buff.append("</option>");
}
return buff.toString();
}
protected String getComboBox(String[][] elements, String selected) {
StringBuffer buff = new StringBuffer();
for(int i=0; i<elements.length; i++) {
String[] n = elements[i];
buff.append("<option value=\"");
buff.append(PageParser.escapeHtml(n[0]));
buff.append("\"");
if(n[0].equals(selected)) {
buff.append(" selected");
}
buff.append(">");
buff.append(PageParser.escapeHtml(n[1]));
buff.append("</option>");
}
return buff.toString();
}
private String readHeaderLine() throws IOException { private String readHeaderLine() throws IOException {
StringBuffer buff=new StringBuffer(); StringBuffer buff=new StringBuffer();
while (true) { while (true) {
...@@ -310,10 +325,6 @@ class WebThread extends Thread { ...@@ -310,10 +325,6 @@ class WebThread extends Thread {
} }
} }
private String fill(String page) {
return PageParser.parse(server, page, session.map);
}
String process(String file) { String process(String file) {
server.trace("process " + file); server.trace("process " + file);
while(file.endsWith(".do")) { while(file.endsWith(".do")) {
...@@ -1505,5 +1516,17 @@ class WebThread extends Thread { ...@@ -1505,5 +1516,17 @@ class WebThread extends Thread {
} }
return NetUtils.isLoopbackAddress(socket); return NetUtils.isLoopbackAddress(socket);
} }
public String getMimeType() {
return mimeType;
}
public boolean getCache() {
return cache;
}
public WebSession getSession() {
return session;
}
} }
...@@ -306,7 +306,6 @@ public class FileStore { ...@@ -306,7 +306,6 @@ public class FileStore {
public void sync() { public void sync() {
try { try {
file.getFD().sync(); file.getFD().sync();
} catch(IOException e) { } catch(IOException e) {
// TODO log exception // TODO log exception
......
...@@ -493,7 +493,7 @@ public class FileUtils { ...@@ -493,7 +493,7 @@ public class FileUtils {
return new File(fileName).canWrite(); return new File(fileName).canWrite();
} }
private static void trace(String method, String fileName, Object o) { static void trace(String method, String fileName, Object o) {
if(Constants.TRACE_IO) { if(Constants.TRACE_IO) {
System.out.println("FileUtils." + method + " " + fileName + " " + o); System.out.println("FileUtils." + method + " " + fileName + " " + o);
} }
......
...@@ -21,13 +21,13 @@ import org.h2.message.Message; ...@@ -21,13 +21,13 @@ import org.h2.message.Message;
public class ReaderInputStream extends InputStream { public class ReaderInputStream extends InputStream {
private Reader reader; private final Reader reader;
private final char[] chars;
private final ByteArrayOutputStream out;
private final OutputStreamWriter writer;
private int pos; private int pos;
private int remaining; private int remaining;
private char[] chars;
private byte[] buffer; private byte[] buffer;
private ByteArrayOutputStream out;
private OutputStreamWriter writer;
public ReaderInputStream(Reader reader) throws SQLException { public ReaderInputStream(Reader reader) throws SQLException {
chars = new char[Constants.IO_BUFFER_SIZE]; chars = new char[Constants.IO_BUFFER_SIZE];
......
...@@ -18,6 +18,7 @@ public class TempFileDeleter { ...@@ -18,6 +18,7 @@ public class TempFileDeleter {
private static HashMap refMap = new HashMap(); private static HashMap refMap = new HashMap();
public static synchronized Reference addFile(String fileName, Object file) { public static synchronized Reference addFile(String fileName, Object file) {
FileUtils.trace("TempFileDeleter.addFile", fileName, file);
PhantomReference ref = new PhantomReference(file, queue); PhantomReference ref = new PhantomReference(file, queue);
refMap.put(ref, fileName); refMap.put(ref, fileName);
deleteUnused(); deleteUnused();
...@@ -33,6 +34,7 @@ public class TempFileDeleter { ...@@ -33,6 +34,7 @@ public class TempFileDeleter {
} }
if(fileName != null && FileUtils.exists(fileName)) { if(fileName != null && FileUtils.exists(fileName)) {
try { try {
FileUtils.trace("TempFileDeleter.deleteFile", fileName, null);
FileUtils.delete(fileName); FileUtils.delete(fileName);
} catch(Exception e) { } catch(Exception e) {
// TODO log such errors? // TODO log such errors?
...@@ -52,6 +54,7 @@ public class TempFileDeleter { ...@@ -52,6 +54,7 @@ public class TempFileDeleter {
} }
public static void stopAutoDelete(Reference ref, String fileName) { public static void stopAutoDelete(Reference ref, String fileName) {
FileUtils.trace("TempFileDeleter.stopAutoDelete", fileName, ref);
if(ref != null) { if(ref != null) {
String f2 = (String) refMap.remove(ref); String f2 = (String) refMap.remove(ref);
if(Constants.CHECK && (f2 == null || !f2.equals(fileName))) { if(Constants.CHECK && (f2 == null || !f2.equals(fileName))) {
......
...@@ -33,7 +33,7 @@ public class ValueLob extends Value { ...@@ -33,7 +33,7 @@ public class ValueLob extends Value {
// TODO lob: concatenate function for blob and clob (to create a large blob from pieces) // TODO lob: concatenate function for blob and clob (to create a large blob from pieces)
// and a getpart function (to get it in pieces) and make sure a file is created! // and a getpart function (to get it in pieces) and make sure a file is created!
private int type; private final int type;
private long precision; private long precision;
private DataHandler handler; private DataHandler handler;
private int tableId; private int tableId;
......
...@@ -95,6 +95,10 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2 ...@@ -95,6 +95,10 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
/* /*
read committed: read locks are acquired but they are released immediately
make read-committed the default
------------------------------------
make sure INDEX_LOOKUP_NEW = is true by default. make sure INDEX_LOOKUP_NEW = is true by default.
Test Console (batch, javaw, different platforms) Test Console (batch, javaw, different platforms)
test with openoffice (metadata changes) test with openoffice (metadata changes)
......
db1 = H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000, sa, sa db1 = H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
xdb2 = H2 (XTEA), org.h2.Driver, jdbc:h2:data/test_xtea;LOCK_TIMEOUT=10000;CIPHER=XTEA, sa, sa 123 xdb2 = H2 (XTEA), org.h2.Driver, jdbc:h2:data/test_xtea;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=XTEA, sa, sa 123
xdb3 = H2 (AES), org.h2.Driver, jdbc:h2:data/test_aes;LOCK_TIMEOUT=10000;CIPHER=AES, sa, sa 123 xdb3 = H2 (AES), org.h2.Driver, jdbc:h2:data/test_aes;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=AES, sa, sa 123
xdb4 = H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;write_mode_log=rws;write_delay=0, sa, sa xdb4 = H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3;write_mode_log=rws;write_delay=0, sa, sa
db2 = HSQLDB, org.hsqldb.jdbcDriver, jdbc:hsqldb:data/test;hsqldb.default_table_type=cached;sql.enforce_size=true, sa db2 = HSQLDB, org.hsqldb.jdbcDriver, jdbc:hsqldb:data/test;hsqldb.default_table_type=cached;sql.enforce_size=true, sa
db3 = Derby, org.apache.derby.jdbc.EmbeddedDriver, jdbc:derby:data/test;create=true, sa, sa db3 = Derby, org.apache.derby.jdbc.EmbeddedDriver, jdbc:derby:data/test;create=true, sa, sa
db4 = H2, org.h2.Driver, jdbc:h2:tcp://localhost/data/testServer;LOCK_TIMEOUT=10000, sa, sa db4 = H2, org.h2.Driver, jdbc:h2:tcp://localhost/data/testServer;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
db5 = HSQLDB, org.hsqldb.jdbcDriver, jdbc:hsqldb:hsql://localhost/xdb, sa db5 = HSQLDB, org.hsqldb.jdbcDriver, jdbc:hsqldb:hsql://localhost/xdb, sa
db6 = Derby, org.apache.derby.jdbc.ClientDriver, jdbc:derby://localhost/data/testServer;create=true, sa, sa db6 = Derby, org.apache.derby.jdbc.ClientDriver, jdbc:derby://localhost/data/testServer;create=true, sa, sa
db7 = PostgreSQL, org.postgresql.Driver, jdbc:postgresql:test, sa, sa db7 = PostgreSQL, org.postgresql.Driver, jdbc:postgresql:test, sa, sa
......
...@@ -26,8 +26,6 @@ public class WebServlet extends HttpServlet { ...@@ -26,8 +26,6 @@ public class WebServlet extends HttpServlet {
private static final long serialVersionUID = 9171446624885086692L; private static final long serialVersionUID = 9171446624885086692L;
private WebServer server; private WebServer server;
private int todoRefactorRemoveDuplicateCode;
private int todoRemoveSystem_out;
private int todoTestWithTomcat; private int todoTestWithTomcat;
private int todoTestWithJetty; private int todoTestWithJetty;
...@@ -58,7 +56,7 @@ public class WebServlet extends HttpServlet { ...@@ -58,7 +56,7 @@ public class WebServlet extends HttpServlet {
public void destroy() { public void destroy() {
} }
boolean allow(HttpServletRequest req) { private boolean allow(HttpServletRequest req) {
if(server.getAllowOthers()) { if(server.getAllowOthers()) {
return true; return true;
} }
...@@ -72,6 +70,16 @@ public class WebServlet extends HttpServlet { ...@@ -72,6 +70,16 @@ public class WebServlet extends HttpServlet {
return address.isLoopbackAddress(); return address.isLoopbackAddress();
} }
private String getAllowedFile(HttpServletRequest req, String requestedFile) {
if(!allow(req)) {
return "notAllowed.jsp";
}
if(requestedFile.length() == 0) {
return "index.do";
}
return requestedFile;
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String file = req.getPathInfo(); String file = req.getPathInfo();
if(file == null) { if(file == null) {
...@@ -80,12 +88,7 @@ public class WebServlet extends HttpServlet { ...@@ -80,12 +88,7 @@ public class WebServlet extends HttpServlet {
} else if(file.startsWith("/")) { } else if(file.startsWith("/")) {
file = file.substring(1); file = file.substring(1);
} }
if(file.length() == 0) { file = getAllowedFile(req, file);
file = "index.do";
}
if(!allow(req)) {
file = "notAllowed.jsp";
}
byte[] bytes = null; byte[] bytes = null;
Properties attributes = new Properties(); Properties attributes = new Properties();
Enumeration en = req.getAttributeNames(); Enumeration en = req.getAttributeNames();
...@@ -105,54 +108,17 @@ public class WebServlet extends HttpServlet { ...@@ -105,54 +108,17 @@ public class WebServlet extends HttpServlet {
if(sessionId != null) { if(sessionId != null) {
session = server.getSession(sessionId); session = server.getSession(sessionId);
} }
String mimeType;
boolean cache;
int index = file.lastIndexOf('.');
String suffix;
if(index >= 0) {
suffix = file.substring(index+1);
} else {
suffix = "";
}
if(suffix.equals("ico")) {
mimeType = "image/x-icon";
cache=true;
} else if(suffix.equals("gif")) {
mimeType = "image/gif";
cache=true;
} else if(suffix.equals("css")) {
cache=true;
mimeType = "text/css";
} else if(suffix.equals("html") || suffix.equals("do") || suffix.equals("jsp")) {
cache = false;
mimeType = "text/html";
if (session == null) {
int todoTest;
String hostname = req.getRemoteHost();
session = server.createNewSession(hostname);
if (!file.equals("notAllowed.jsp")) {
file = "index.do";
}
}
} else if(suffix.equals("js")) {
cache = true;
mimeType = "text/javascript";
} else {
cache = false;
mimeType = "text/html";
file = "error.jsp";
server.trace("unknown mime type, file "+file);
}
server.trace("mimeType="+mimeType);
// parseHeader();
String ifModifiedSince = req.getHeader("if-modified-since");
server.trace(file);
WebThread app = new WebThread(null, server); WebThread app = new WebThread(null, server);
app.setSession(session, attributes);
String ifModifiedSince = req.getHeader("if-modified-since");
if(file.endsWith(".do")) { String hostname = req.getRemoteHost();
app.setSession(session, attributes); file = app.processRequest(file, hostname);
file = app.process(file); session = app.getSession();
}
String mimeType = app.getMimeType();
boolean cache = app.getCache();
if(cache && server.getStartDateTime().equals(ifModifiedSince)) { if(cache && server.getStartDateTime().equals(ifModifiedSince)) {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return; return;
...@@ -164,7 +130,7 @@ public class WebServlet extends HttpServlet { ...@@ -164,7 +130,7 @@ public class WebServlet extends HttpServlet {
try { try {
bytes = StringUtils.utf8Encode("File not found: "+file); bytes = StringUtils.utf8Encode("File not found: "+file);
} catch(SQLException e) { } catch(SQLException e) {
int todoNotIgnore; server.traceError(e);
} }
} else { } else {
if(session != null && file.endsWith(".jsp")) { if(session != null && file.endsWith(".jsp")) {
...@@ -173,7 +139,7 @@ public class WebServlet extends HttpServlet { ...@@ -173,7 +139,7 @@ public class WebServlet extends HttpServlet {
try { try {
bytes = StringUtils.utf8Encode(page); bytes = StringUtils.utf8Encode(page);
} catch(SQLException e) { } catch(SQLException e) {
int todoNotIgnore; server.traceError(e);
} }
} }
resp.setContentType(mimeType); resp.setContentType(mimeType);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论