📄 webserverconnection.java
字号:
// read and parse the Content-Length line
int count = InOutUtil.readLine(inStream, rowOut);
int offset = rowOut.size() - count;
// get buffer always after reading into rowOut, else old buffer may
// be returned
byte[] byteArray = rowOut.getBuffer();
if (!ArrayUtil.containsAt(byteArray, offset, BYTES_CONTENT)) {
throw new Exception();
}
count -= BYTES_CONTENT.length;
offset += BYTES_CONTENT.length;
// omit the last two characters
String lenStr = new String(byteArray, offset, count - 2);
int length = Integer.parseInt(lenStr);
InOutUtil.readLine(inStream, rowOut);
} catch (Exception e) {
processError(HttpURLConnection.HTTP_BAD_REQUEST);
return;
}
processQuery(inStream);
}
/**
* Processes a database query in HSQL protocol that has been
* tunneled over HTTP protocol.
*
* @param inStream the incoming byte stream representing the HSQL protocol
* database query
*/
void processQuery(InputStream inStream) {
try {
Result resultIn = Result.read(rowIn,
new DataInputStream(inStream));
//
Result resultOut;
if (resultIn.mode == ResultConstants.SQLCONNECT) {
try {
int dbID = server.getDBID(resultIn.subSubString);
Session session = DatabaseManager.newSession(dbID,
resultIn.getMainString(), resultIn.getSubString());
resultOut = new Result(ResultConstants.UPDATECOUNT);
resultOut.databaseID = dbID;
resultOut.sessionID = session.getId();
} catch (HsqlException e) {
resultOut = new Result(e, null);
} catch (RuntimeException e) {
resultOut = new Result(e, null);
}
} else {
int dbID = resultIn.databaseID;
Session session = DatabaseManager.getSession(dbID,
resultIn.sessionID);
resultOut =
session == null
? new Result(Trace.error(Trace.DATABASE_NOT_EXISTS), null)
: session.execute(resultIn);
}
//
rowOut.reset();
resultOut.write(rowOut);
OutputStream outStream = socket.getOutputStream();
String header = getHead(HEADER_OK, false,
"application/octet-stream",
rowOut.size());
outStream.write(header.getBytes(ENCODING));
outStream.write(rowOut.getOutputStream().getBuffer(), 0,
rowOut.getOutputStream().size());
outStream.flush();
outStream.close();
} catch (Exception e) {
server.printStackTrace(e);
}
}
/**
* Processes an HTTP GET request
*
* @param name the name of the content to get
* @param send whether to send the content as well, or just the header
*/
private void processGet(String name, boolean send) {
try {
String hdr;
OutputStream os;
InputStream is;
int b;
if (name.endsWith("/")) {
name = name + server.getDefaultWebPage();
}
// traversing up the directory structure is forbidden.
if (name.indexOf("..") != -1) {
processError(HttpURLConnection.HTTP_FORBIDDEN);
return;
}
name = server.getWebRoot() + name;
if (File.separatorChar != '/') {
name = name.replace('/', File.separatorChar);
}
is = null;
server.printWithThread("GET " + name);
try {
File file = new File(name);
is = new DataInputStream(new FileInputStream(file));
hdr = getHead(HEADER_OK, true, getMimeTypeString(name),
(int) file.length());
} catch (IOException e) {
processError(HttpURLConnection.HTTP_NOT_FOUND);
if (is != null) {
is.close();
}
return;
}
os = new BufferedOutputStream(socket.getOutputStream());
os.write(hdr.getBytes(ENCODING));
if (send) {
while ((b = is.read()) != -1) {
os.write(b);
}
}
os.flush();
os.close();
is.close();
} catch (Exception e) {
server.printError("processGet: " + e.toString()); server.printStackTrace(e);
}
}
/**
* Retrieves an HTTP protocol header given the supplied arguments.
*
* @param responseCodeString the HTTP response code
* @param addInfo true if additional header info is to be added
* @param mimeType the Content-Type field value
* @param length the Content-Length field value
* @return an HTTP protocol header
*/
String getHead(String responseCodeString, boolean addInfo,
String mimeType, int length) {
StringBuffer sb = new StringBuffer(128);
sb.append(responseCodeString).append("\r\n");
if (addInfo) {
sb.append("Allow: GET, HEAD, POST\nMIME-Version: 1.0\r\n");
sb.append("Server: ").append(
HsqlDatabaseProperties.PRODUCT_NAME).append("\r\n");
}
if (mimeType != null) {
sb.append("Content-Type: ").append(mimeType).append("\r\n");
sb.append("Content-Length: ").append(length).append("\r\n");
}
sb.append("\r\n");
return sb.toString();
}
/**
* Processess an HTTP error condition, sending an error response to
* the client.
*
* @param code the error condition code
*/
private void processError(int code) {
String msg;
server.printWithThread("processError " + code);
switch (code) {
case HttpURLConnection.HTTP_BAD_REQUEST :
msg = getHead(HEADER_BAD_REQUEST, false, null, 0);
msg += BundleHandler.getString(WebServer.webBundleHandle,
"BAD_REQUEST");
break;
case HttpURLConnection.HTTP_FORBIDDEN :
msg = getHead(HEADER_FORBIDDEN, false, null, 0);
msg += BundleHandler.getString(WebServer.webBundleHandle,
"FORBIDDEN");
break;
case HttpURLConnection.HTTP_NOT_FOUND :
default :
msg = getHead(HEADER_NOT_FOUND, false, null, 0);
msg += BundleHandler.getString(WebServer.webBundleHandle,
"NOT_FOUND");
break;
}
try {
OutputStream os =
new BufferedOutputStream(socket.getOutputStream());
os.write(msg.getBytes(ENCODING));
os.flush();
os.close();
} catch (Exception e) {
server.printError("processError: " + e.toString()); server.printStackTrace(e);
}
}
/**
* Retrieves the thread name to be used when
* this object is the Runnable object of a Thread.
*
* @return the thread name to be used when
* this object is the Runnable object of a Thread.
*/
String getConnectionThreadName() {
return "HSQLDB HTTP Connection @" + Integer.toString(hashCode(), 16);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -