fix: bugs in ghttp;

also bugs left for download and delete in firefox, chrome and Edge;

by zengli
This commit is contained in:
bookug 2017-07-30 14:17:56 +08:00
parent bd538450e4
commit 0ed7148287
11 changed files with 181 additions and 330 deletions

119
Main/GMonitor.java Normal file
View File

@ -0,0 +1,119 @@
import java.io.*;
import java.net.*;
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
public class GMonitor {
public static final String defaultServerIP = "127.0.0.1";
public static final int defaultServerPort = 9000;
//private Socket socket = null;
private String serverIP;
private int serverPort;
//private Socket socket = null;
public GMonitor() {
this.serverIP = GMonitor.defaultServerIP;
this.serverPort = GMonitor.defaultServerPort;
}
public GMonitor(int _port) {
this.serverIP = GMonitor.defaultServerIP;
this.serverPort = _port;
}
public GMonitor(String _ip, int _port) {
this.serverIP = _ip;
this.serverPort = _port;
}
public String sendGet(String param) {
String url = "http://" + this.serverIP + ":" + this.serverPort;
String result = "";
BufferedReader in = null;
System.out.println("parameter: "+param);
try {
param = URLEncoder.encode(param, "UTF-8");
}
catch (UnsupportedEncodingException ex) {
throw new RuntimeException("Broken VM does not support UTF-8");
}
try {
String urlNameString = url + "/" + param;
System.out.println("request: "+urlNameString);
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("error in get request: " + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
public boolean connect() {
return true;
}
public boolean disconnect() {
return true;
}
public static void main(String[] args) {
if(args.length != 3)
{
System.err.println("Invalid parameter, the parammeters should be operation, ip/url and port!");
return;
}
String op = args[0];
String serverIP = args[1];
int serverPort = Integer.parseInt(args[2]);
// initialize the GStore server's IP address and port.
GMonitor gm = new GMonitor(serverIP, serverPort);
gm.connect();
String cmd = "?operation=" + op;
String msg = gm.sendGet(cmd);
gm.disconnect();
System.out.println(msg);
}
}

View File

@ -10,8 +10,8 @@
//operation.log: not used
//query.log: query string, result num, and time of answering
//TODO: to add db_name to all URLs, and change the index.js using /show to get name
//TODO: modify gmonitor.java
//TODO: to add db_name to all URLs, and change the index.js using /show to get name, save and set
//TODO: use gzip for network transfer, it is ok to download a gzip file instead of the original one
//TODO: mutiple threads , multiple users and multiple databases
//How to acquire http connection ID? getSocket() or use username to login?
@ -31,6 +31,7 @@
//Also the checkpoint function!!!
//http://bookug.cc/rwbuffer
//BETTER: add a sync function in Util to support FILE*, fd, and fstream
//In addition, query log in endpoint should also be synced!
#include "../Server/server_http.hpp"
#include "../Server/client_http.hpp"
@ -275,7 +276,7 @@ int initialize(int argc, char *argv[])
#ifndef USED_AS_ENDPOINT
#ifndef SPARQL_ENDPOINT
//GET-example for the path /?operation=build&db_name=[db_name]&ds_path=[ds_path], responds with the matched string in path
//i.e. database name and dataset path
server.resource["^/%3[F|f]operation%3[D|d]build%26db_name%3[D|d](.*)%26ds_path%3[D|d](.*)$"]["GET"]=[&server](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request)
@ -583,6 +584,7 @@ bool build_handler(const HttpServer& server, const shared_ptr<HttpServer::Respon
cout<<"HTTP: this is build"<<endl;
string db_name=request->path_match[1];
string db_path=request->path_match[2];
db_name = UrlDecode(db_name);
db_path = UrlDecode(db_path);
if(db_name=="" || db_path=="")
{
@ -638,6 +640,7 @@ bool load_handler(const HttpServer& server, const shared_ptr<HttpServer::Respons
{
cout<<"HTTP: this is load"<<endl;
string db_name = request->path_match[1];
db_name = UrlDecode(db_name);
// string db_name = argv[1];
if(db_name=="")
@ -690,6 +693,10 @@ bool load_handler(const HttpServer& server, const shared_ptr<HttpServer::Respons
bool unload_handler(const HttpServer& server, const shared_ptr<HttpServer::Response>& response, const shared_ptr<HttpServer::Request>& request)
{
cout<<"HTTP: this is unload"<<endl;
string db_name = request->path_match[1];
db_name = UrlDecode(db_name);
if(current_database == NULL)
{
string error = "No database used now.";
@ -697,19 +704,29 @@ bool unload_handler(const HttpServer& server, const shared_ptr<HttpServer::Respo
return false;
}
if(current_database->getName() != db_name)
{
string error = "Database Name not matched.";
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << error.length() << "\r\n\r\n" << error;
return false;
}
delete current_database;
current_database = NULL;
string success = "Database unloaded.";
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << success.length() << "\r\n\r\n" << success;
return true;
}
bool query_handler(const HttpServer& server, const shared_ptr<HttpServer::Response>& response, const shared_ptr<HttpServer::Request>& request)
{
cout<<"HTTP: this is query"<<endl;
string format = request->path_match[1];
//string format = "html";
cout<<"HTTP: this is query"<<endl;
string db_query=request->path_match[2];
format = UrlDecode(format);
db_query = UrlDecode(db_query);
cout<<"check: "<<db_query<<endl;
string str = db_query;
@ -841,7 +858,6 @@ bool query_handler(const HttpServer& server, const shared_ptr<HttpServer::Respon
*response << "\r\nContent-Type: application/octet-stream";
*response << "\r\nContent-Disposition: attachment; filename=\"" << filename << '"';
*response << "\r\n\r\n" << success;
return 0;
//outfile.open(localname);
//outfile << success;
@ -868,6 +884,7 @@ bool query_handler(const HttpServer& server, const shared_ptr<HttpServer::Respon
bool monitor_handler(const HttpServer& server, const shared_ptr<HttpServer::Response>& response, const shared_ptr<HttpServer::Request>& request)
{
cout<<"HTTP: this is monitor"<<endl;
if(current_database == NULL)
{
string error = "No database used now.";
@ -881,20 +898,20 @@ bool monitor_handler(const HttpServer& server, const shared_ptr<HttpServer::Resp
string name = current_database->getName();
success = success + "database: " + name + "\n";
TYPE_TRIPLE_NUM triple_num = current_database->getTripleNum();
success = success + "triple num: " + Util::int2string(triple_num) + "\n";
success = success + "triple num: " + Util::int2string(triple_num) + "\r\n";
TYPE_ENTITY_LITERAL_ID entity_num = current_database->getEntityNum();
success = success + "entity num: " + Util::int2string(entity_num) + "\n";
success = success + "entity num: " + Util::int2string(entity_num) + "\r\n";
TYPE_ENTITY_LITERAL_ID literal_num = current_database->getLiteralNum();
success = success + "literal num: " + Util::int2string(literal_num) + "\n";
success = success + "literal num: " + Util::int2string(literal_num) + "\r\n";
TYPE_ENTITY_LITERAL_ID sub_num = current_database->getSubNum();
success = success + "subject num: " + Util::int2string(sub_num) + "\n";
success = success + "subject num: " + Util::int2string(sub_num) + "\r\n";
TYPE_PREDICATE_ID pre_num = current_database->getPreNum();
success = success + "predicate num: " + Util::int2string(pre_num) + "\n";
success = success + "predicate num: " + Util::int2string(pre_num) + "\r\n";
//BETTER: how to compute the connection num in Boost::asio?
int conn_num = connection_num / 2;
//int conn_num = 3; //currectly connected sessions
//this connection num is countint the total(no break)
success = success + "connection num: " + Util::int2string(conn_num) + "\n";
success = success + "connection num: " + Util::int2string(conn_num) + "\r\n";
//TODO: add the info of memory and thread, operation num and IO frequency
//success = "<p>" + success + "</p>";
@ -906,6 +923,7 @@ bool monitor_handler(const HttpServer& server, const shared_ptr<HttpServer::Resp
bool delete_handler(const HttpServer& server, const shared_ptr<HttpServer::Response>& response, const shared_ptr<HttpServer::Request>& request)
{
cout << "HTTP: this is delete" << endl;
/*
string download = request->path_match[1];
download = UrlDecode(download);
@ -922,6 +940,7 @@ bool delete_handler(const HttpServer& server, const shared_ptr<HttpServer::Respo
bool download_handler(const HttpServer& server, const shared_ptr<HttpServer::Response>& response, const shared_ptr<HttpServer::Request>& request)
{
cout << "HTTP: this is download" << endl;
/*
string download = request->path_match[1];
download = UrlDecode(download);
@ -940,6 +959,7 @@ bool download_handler(const HttpServer& server, const shared_ptr<HttpServer::Res
bool default_handler(const HttpServer& server, const shared_ptr<HttpServer::Response>& response, const shared_ptr<HttpServer::Request>& request)
{
cout<<"HTTP: this is default"<<endl;
//BETTER: use lock to ensure thread safe
connection_num++;
//NOTICE: it seems a visit will output twice times
@ -987,6 +1007,8 @@ bool default_handler(const HttpServer& server, const shared_ptr<HttpServer::Resp
//If user send this command too frequently, the performance may be awful if updates are large
bool checkpoint_handler(const HttpServer& server, const shared_ptr<HttpServer::Response>& response, const shared_ptr<HttpServer::Request>& request)
{
cout<<"HTTP: this is checkpoint"<<endl;
if(current_database == NULL)
{
string error = "No database used.";
@ -1010,6 +1032,8 @@ bool checkpoint_handler(const HttpServer& server, const shared_ptr<HttpServer::R
//BETTER+TODO: indicate the db_name when query
bool show_handler(const HttpServer& server, const shared_ptr<HttpServer::Response>& response, const shared_ptr<HttpServer::Request>& request)
{
cout<<"HTTP: this is show"<<endl;
if(current_database == NULL)
{
string error = "No database used.";

View File

@ -1,312 +0,0 @@
package jgsc;
import java.io.*;
import java.net.*;
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
public class GstoreConnector {
public static final String defaultServerIP = "127.0.0.1";
public static final int defaultServerPort = 3305;
private String serverIP;
private int serverPort;
//private Socket socket = null;
public GstoreConnector() {
this.serverIP = GstoreConnector.defaultServerIP;
this.serverPort = GstoreConnector.defaultServerPort;
}
public GstoreConnector(int _port) {
this.serverIP = GstoreConnector.defaultServerIP;
this.serverPort = _port;
}
public GstoreConnector(String _ip, int _port) {
this.serverIP = _ip;
this.serverPort = _port;
}
//TODO: what if the query result is too large?
//how about get next (need to record the connection or user in db server)
public String sendGet(String param) {
String url = "http://" + this.serverIP + ":" + this.serverPort;
String result = "";
BufferedReader in = null;
System.out.println("parameter: "+param);
try {
param = URLEncoder.encode(param, "UTF-8");
}
catch (UnsupportedEncodingException ex) {
throw new RuntimeException("Broken VM does not support UTF-8");
}
try {
String urlNameString = url + "/" + param;
System.out.println("request: "+urlNameString);
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("error in get request: " + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
//NOTICE: no need to connect now, HTTP connection is kept by default
public boolean load(String _db_name) {
boolean connect_return = this.connect();
if (!connect_return) {
System.err.println("connect to server error. @GstoreConnector.load");
return false;
}
String cmd = "?operation=load&db_name=" + _db_name;
String msg = this.sendGet(cmd);
//if (!send_return) {
//System.err.println("send load command error. @GstoreConnector.load");
//return false;
//}
this.disconnect();
System.out.println(msg);
if (msg.equals("load database done.")) {
return true;
}
return false;
}
public boolean unload(String _db_name) {
boolean connect_return = this.connect();
if (!connect_return) {
System.err.println("connect to server error. @GstoreConnector.unload");
return false;
}
//String cmd = "unload/" + _db_name;
String cmd = "?operation=unload&db_name=" + _db_name;
String msg = this.sendGet(cmd);
this.disconnect();
System.out.println(msg);
if (msg.equals("unload database done.")) {
return true;
}
return false;
}
public boolean build(String _db_name, String _rdf_file_path) {
boolean connect_return = this.connect();
if (!connect_return) {
System.err.println("connect to server error. @GstoreConnector.build");
return false;
}
//TODO: also use encode to support spaces?
//Consider change format into ?name=DBname
String cmd = "?operation=build&db_name=" + _db_name + "&ds_path=" + _rdf_file_path;
String msg = this.sendGet(cmd);
this.disconnect();
System.out.println(msg);
if (msg.equals("import RDF file to database done.")) {
return true;
}
return false;
}
//TODO: not implemented
public boolean drop(String _db_name) {
boolean connect_return = this.connect();
if (!connect_return) {
System.err.println("connect to server error. @GstoreConnector.drop");
return false;
}
String cmd = "drop/" + _db_name;
String msg = this.sendGet(cmd);
this.disconnect();
System.out.println(msg);
return msg.equals("drop database done.");
}
public String query(String _sparql) {
boolean connect_return = this.connect();
if (!connect_return) {
System.err.println("connect to server error. @GstoreConnector.query");
return "connect to server error.";
}
//URL encode should be used here
//try {
//_sparql = URLEncoder.encode("\""+_sparql+"\"", "UTF-8");
//}
//catch (UnsupportedEncodingException ex) {
//throw new RuntimeException("Broken VM does not support UTF-8");
//}
String cmd = "?operation=query&format=json&sparql=" + _sparql;
//String cmd = "query/\"" + _sparql + "\"";
String msg = this.sendGet(cmd);
this.disconnect();
return msg;
}
public String show() {
return this.show(false);
}
//TODO: not implemented
public String show(boolean _type) {
boolean connect_return = this.connect();
if (!connect_return) {
System.err.println("connect to server error. @GstoreConnector.show");
return "connect to server error.";
}
String cmd;
if (_type) {
cmd = "show/all";
}
else {
cmd = "show/databases";
}
String msg = this.sendGet(cmd);
this.disconnect();
return msg;
}
private boolean connect() {
return true;
}
private boolean disconnect() {
return true;
}
private static byte[] packageMsgData(String _msg) {
//byte[] data_context = _msg.getBytes();
byte[] data_context = null;
try {
data_context = _msg.getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println("utf-8 charset is unsupported.");
data_context = _msg.getBytes();
}
int context_len = data_context.length + 1; // 1 byte for '\0' at the end of the context.
int data_len = context_len + 4; // 4 byte for one int(data_len at the data's head).
byte[] data = new byte[data_len];
// padding head(context_len).
byte[] head = GstoreConnector.intToByte4(context_len);
for (int i = 0; i < 4; i++) {
data[i] = head[i];
}
// padding context.
for (int i = 0; i < data_context.length; i++) {
data[i + 4] = data_context[i];
}
// in C, there should be '\0' as the terminator at the end of a char array. so we need add '\0' at the end of sending message.
data[data_len - 1] = 0;
return data;
}
private static byte[] intToByte4(int _x) // with Little Endian format.
{
byte[] ret = new byte[4];
ret[0] = (byte) (_x);
ret[1] = (byte) (_x >>> 8);
ret[2] = (byte) (_x >>> 16);
ret[3] = (byte) (_x >>> 24);
return ret;
}
private static int byte4ToInt(byte[] _b) // with Little Endian format.
{
int byte0 = _b[0] & 0xFF, byte1 = _b[1] & 0xFF, byte2 = _b[2] & 0xFF, byte3 = _b[3] & 0xFF;
int ret = (byte0) | (byte1 << 8) | (byte2 << 16) | (byte3 << 24);
return ret;
}
public static void main(String[] args) {
// initialize the GStore server's IP address and port.
GstoreConnector gc = new GstoreConnector("172.31.19.15", 3305);
// build a new database by a RDF file.
// note that the relative path is related to gserver.
//gc.build("db_LUBM10", "example/rdf_triple/LUBM_10_GStore.n3");
String sparql = "select ?x where {"
+ "?x <rdf:type> <cdblp.cn/class/Paper>. "
+ "?x <cdblp.cn/schema/property/has_author> <cdblp.cn/author/wangshan>. "
+ "}";
boolean flag = gc.load("db_cdblp");
System.out.println(flag);
String answer = gc.query(sparql);
System.out.println(answer);
answer = gc.query(sparql);
System.out.println(answer);
sparql = "select ?x where {"
+ "?x <rdf:type> <cdblp.cn/class/Paper>. "
+ "?x <cdblp.cn/schema/property/has_author> <cdblp.cn/author/yuge>. "
+ "}";
answer = gc.query(sparql);
System.out.println(answer);
}
}

View File

@ -22,7 +22,7 @@
<li id="li_1" >
<label class="description" for="element_1">Database Name </label>
<div>
<input id="element_1" name="databasename" class="element text medium" type="text" maxlength="255" value="tourist.nt">
<input id="element_1" name="databasename" class="element text medium" type="text" maxlength="255" value="tourist.nt" readonly="readonly">
</input>
</div>

View File

@ -119,6 +119,7 @@ function query(dp) {
// {
var tmp2 = "?operation=delete&filepath=" + fileName;
var request2 = escape(tmp2);
//alert(request2);
$.get(request2, function(data, status){});
// }
}

View File

@ -44,7 +44,7 @@
<li><strong>Emergency</strong></li>
<li><a href="http://emergency.gstore-pku.com" class="cc-active">emergency.gstore-pku.com</a></li>
<li><strong>Breast Cancer</strong></li>
<li><a href="http://breastcancer0.gstore-pku.com<" class="cc-active">breastcancer0.gstore-pku.com</a></li>
<li><a href="http://breastcancer0.gstore-pku.com" class="cc-active">breastcancer0.gstore-pku.com</a></li>
<li><a href="http://breastcancer1.gstore-pku.com" class="cc-active">breastcancer1.gstore-pku.com</a></li>
<li><a href="http://breastcancer2.gstore-pku.com" class="cc-active">breastcancer2.gstore-pku.com</a></li>
<li><a href="http://breastcancer3.gstore-pku.com" class="cc-active">breastcancer3.gstore-pku.com</a></li>

View File

@ -111,8 +111,8 @@ in the sparql query can point to the same node in data graph)
//if used as only-read application(like sparql endpoint)
//#define ONLY_READ 1
//#define USED_AS_ENDPOINT 1
#ifdef USED_AS_ENDPOINT
//#define SPARQL_ENDPOINT 1
#ifdef SPARQL_ENDPOINT
#ifndef ONLY_READ
#define ONLY_READ 1
#endif

View File

@ -11,7 +11,7 @@ import java.util.Map;
public class GstoreConnector {
public static final String defaultServerIP = "127.0.0.1";
public static final int defaultServerPort = 3305;
public static final int defaultServerPort = 9000;
private String serverIP;
private int serverPort;
@ -302,7 +302,7 @@ public class GstoreConnector {
public static void main(String[] args) {
// initialize the GStore server's IP address and port.
GstoreConnector gc = new GstoreConnector("172.31.19.15", 3305);
GstoreConnector gc = new GstoreConnector("127.0.0.1", 9000);
// build a new database by a RDF file.
// note that the relative path is related to gserver.

View File

@ -111,7 +111,7 @@ inc = -I./tools/libantlr3c-3.4/ -I./tools/libantlr3c-3.4/include
TARGET = $(exedir)gbuild $(exedir)gserver $(exedir)gserver_backup_scheduler $(exedir)gclient $(exedir)gquery $(exedir)gconsole $(api_java) $(exedir)gadd $(exedir)gsub $(exedir)ghttp
all: $(TARGET)
all: $(TARGET) bin/GMonitor.class
test_index: test_index.cpp
$(CC) $(EXEFLAG) -o test_index test_index.cpp $(objfile) $(library)
@ -171,6 +171,10 @@ $(objdir)gconsole.o: Main/gconsole.cpp Database/Database.h Util/Util.h api/socke
$(objdir)ghttp.o: Main/ghttp.cpp Server/server_http.hpp Server/client_http.hpp Database/Database.h Util/Util.h $(lib_antlr)
$(CC) $(CFLAGS) Main/ghttp.cpp $(inc) -o $(objdir)ghttp.o -DUSE_BOOST_REGEX $(def64IO)
bin/GMonitor.class: Main/GMonitor.java
javac -d bin/ Main/GMonitor.java
cp test/gmonitor bin/
cp test/gshow bin/
#objects in Main/ end
@ -441,6 +445,7 @@ clean:
$(MAKE) -C api/socket/java/example clean
#$(MAKE) -C KVstore clean
rm -rf $(exedir)g* $(objdir)*.o $(exedir).gserver*
rm -rf bin/*.class
#rm -rf .project .cproject .settings just for eclipse
#rm -rf cscope* just for vim
rm -rf logs/*.log

7
test/gmonitor Executable file
View File

@ -0,0 +1,7 @@
#! /usr/bin/bash
echo "require ip/url and port as parameters"
echo "to show the status of server"
java GMonitor "monitor" $1 $2

7
test/gshow Executable file
View File

@ -0,0 +1,7 @@
#! /usr/bin/bash
echo "require ip/url and port as parameters"
echo "to show database used"
java GMonitor "show" $1 $2