?? webthread.java
字號:
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.web;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.Socket;
import java.security.SecureClassLoader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.Map.Entry;
import org.h2.api.DatabaseEventListener;
import org.h2.bnf.Bnf;
import org.h2.constant.ErrorCode;
import org.h2.engine.Constants;
import org.h2.jdbc.JdbcSQLException;
import org.h2.message.TraceSystem;
import org.h2.tools.SimpleResultSet;
import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils;
import org.h2.util.MemoryUtils;
import org.h2.util.NetUtils;
import org.h2.util.ObjectArray;
import org.h2.util.ObjectUtils;
import org.h2.util.ScriptReader;
import org.h2.util.StringUtils;
/**
* For each connection to a session, an object of this class is created.
* This class is used by the H2 Console.
*/
class WebThread extends Thread implements DatabaseEventListener {
private WebServer server;
private WebSession session;
private Properties attributes;
private Socket socket;
private InputStream input;
private OutputStream output;
private String ifModifiedSince;
private String mimeType;
private boolean cache;
private int listenerLastState;
private long listenerLastEvent;
private boolean stop;
// TODO web: support online data editing like http://numsum.com/
WebThread(Socket socket, WebServer server) {
this.server = server;
this.socket = socket;
setName("H2 Console thread");
}
void setSession(WebSession session, Properties attributes) {
this.session = session;
this.attributes = attributes;
}
public void stopNow() {
this.stop = true;
}
private String getAllowedFile(String requestedFile) {
if (!allow()) {
return "notAllowed.jsp";
}
if (requestedFile.length() == 0) {
return "index.do";
}
return requestedFile;
}
public String processRequest(String file, String hostAddr) {
int index = file.lastIndexOf('.');
String suffix;
if (index >= 0) {
suffix = file.substring(index + 1);
} else {
suffix = "";
}
if ("ico".equals(suffix)) {
cache = true;
} else if ("gif".equals(suffix)) {
mimeType = "image/gif";
cache = true;
} else if ("css".equals(suffix)) {
cache = true;
mimeType = "text/css";
} else if ("html".equals(suffix) || "do".equals(suffix) || "jsp".equals(suffix)) {
cache = false;
mimeType = "text/html";
if (session == null) {
session = server.createNewSession(hostAddr);
if (!"notAllowed.jsp".equals(file)) {
file = "index.do";
}
}
} else if ("js".equals(suffix)) {
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);
server.trace(file);
if (file.endsWith(".do")) {
file = process(file);
}
return file;
}
public void run() {
try {
input = new BufferedInputStream(socket.getInputStream());
output = new BufferedOutputStream(socket.getOutputStream());
while (true) {
if (!process()) {
break;
}
}
} catch (IOException e) {
TraceSystem.traceThrowable(e);
} catch (SQLException e) {
TraceSystem.traceThrowable(e);
}
IOUtils.closeSilently(output);
IOUtils.closeSilently(input);
try {
socket.close();
} catch (IOException e) {
// ignore
} finally {
server.remove(this);
}
}
public boolean process() throws IOException, SQLException {
boolean keepAlive = false;
String head = readHeaderLine();
if (head.startsWith("GET ") || head.startsWith("POST ")) {
int begin = head.indexOf('/'), end = head.lastIndexOf(' ');
String file = head.substring(begin + 1, end).trim();
server.trace(head + ": " + file);
file = getAllowedFile(file);
attributes = new Properties();
int paramIndex = file.indexOf("?");
session = null;
if (paramIndex >= 0) {
String attrib = file.substring(paramIndex + 1);
parseAttributes(attrib);
String sessionId = attributes.getProperty("jsessionid");
file = file.substring(0, paramIndex);
session = server.getSession(sessionId);
}
keepAlive = parseHeader();
String hostAddr = socket.getInetAddress().getHostAddress();
file = processRequest(file, hostAddr);
if (file.length() == 0) {
// asynchronous request
return true;
}
String message;
byte[] bytes;
if (cache && ifModifiedSince != null && ifModifiedSince.equals(server.getStartDateTime())) {
bytes = null;
message = "HTTP/1.1 304 Not Modified\n";
} else {
bytes = server.getFile(file);
if (bytes == null) {
message = "HTTP/1.0 404 Not Found\n";
bytes = StringUtils.utf8Encode("File not found: " + file);
} else {
if (session != null && file.endsWith(".jsp")) {
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 += "Content-Type: " + mimeType + "\n";
if (!cache) {
message += "Cache-Control: no-cache\n";
} else {
message += "Cache-Control: max-age=10\n";
message += "Last-Modified: " + server.getStartDateTime() + "\n";
}
message += "Content-Length: " + bytes.length + "\n";
}
}
message += "\n";
server.trace(message);
output.write(message.getBytes());
if (bytes != null) {
output.write(bytes);
}
output.flush();
}
return keepAlive;
}
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.escapeHtmlData(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.escapeHtmlData(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 {
StringBuffer buff = new StringBuffer();
while (true) {
int i = input.read();
if (i == -1) {
throw new IOException("Unexpected EOF");
} else if (i == '\r' && input.read() == '\n') {
return buff.length() > 0 ? buff.toString() : null;
} else {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -