mirror of
https://github.com/haiwen/seafile-server.git
synced 2025-09-25 14:42:52 +00:00
Merge branch '8.0'
This commit is contained in:
@@ -35,11 +35,12 @@ struct SeafDBRow {
|
||||
|
||||
struct SeafDBTrans {
|
||||
DBConnection *conn;
|
||||
gboolean need_close;
|
||||
};
|
||||
|
||||
typedef struct DBOperations {
|
||||
DBConnection* (*get_connection)(SeafDB *db);
|
||||
void (*release_connection)(DBConnection *conn);
|
||||
void (*release_connection)(DBConnection *conn, gboolean need_close);
|
||||
int (*execute_sql_no_stmt)(DBConnection *conn, const char *sql);
|
||||
int (*execute_sql)(DBConnection *conn, const char *sql,
|
||||
int n, va_list args);
|
||||
@@ -138,7 +139,7 @@ out:
|
||||
}
|
||||
|
||||
static void
|
||||
mysql_conn_pool_release_connection (DBConnection *conn)
|
||||
mysql_conn_pool_release_connection (DBConnection *conn, gboolean need_close)
|
||||
{
|
||||
if (!conn)
|
||||
return;
|
||||
@@ -148,6 +149,14 @@ mysql_conn_pool_release_connection (DBConnection *conn)
|
||||
return;
|
||||
}
|
||||
|
||||
if (need_close) {
|
||||
pthread_mutex_lock (&conn->pool->lock);
|
||||
g_ptr_array_remove (conn->pool->connections, conn);
|
||||
pthread_mutex_unlock (&conn->pool->lock);
|
||||
mysql_db_release_connection (conn);
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock (&conn->pool->lock);
|
||||
conn->is_available = TRUE;
|
||||
pthread_mutex_unlock (&conn->pool->lock);
|
||||
@@ -227,7 +236,7 @@ sqlite_db_new (const char *db_path);
|
||||
static DBConnection *
|
||||
sqlite_db_get_connection (SeafDB *db);
|
||||
static void
|
||||
sqlite_db_release_connection (DBConnection *vconn);
|
||||
sqlite_db_release_connection (DBConnection *vconn, gboolean need_close);
|
||||
static int
|
||||
sqlite_db_execute_sql_no_stmt (DBConnection *vconn, const char *sql);
|
||||
static int
|
||||
@@ -284,7 +293,7 @@ seaf_db_query (SeafDB *db, const char *sql)
|
||||
int ret;
|
||||
ret = db_ops.execute_sql_no_stmt (conn, sql);
|
||||
|
||||
db_ops.release_connection (conn);
|
||||
db_ops.release_connection (conn, ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -358,7 +367,7 @@ seaf_db_statement_query (SeafDB *db, const char *sql, int n, ...)
|
||||
ret = db_ops.execute_sql (conn, sql, n, args);
|
||||
va_end (args);
|
||||
|
||||
db_ops.release_connection (conn);
|
||||
db_ops.release_connection (conn, ret < 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -380,7 +389,7 @@ seaf_db_statement_exists (SeafDB *db, const char *sql, gboolean *db_err, int n,
|
||||
n_rows = db_ops.query_foreach_row (conn, sql, NULL, NULL, n, args);
|
||||
va_end (args);
|
||||
|
||||
db_ops.release_connection(conn);
|
||||
db_ops.release_connection(conn, n_rows < 0);
|
||||
|
||||
if (n_rows < 0) {
|
||||
*db_err = TRUE;
|
||||
@@ -408,7 +417,7 @@ seaf_db_statement_foreach_row (SeafDB *db, const char *sql,
|
||||
ret = db_ops.query_foreach_row (conn, sql, callback, data, n, args);
|
||||
va_end (args);
|
||||
|
||||
db_ops.release_connection (conn);
|
||||
db_ops.release_connection (conn, ret < 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -439,7 +448,7 @@ seaf_db_statement_get_int (SeafDB *db, const char *sql, int n, ...)
|
||||
rc = db_ops.query_foreach_row (conn, sql, get_int_cb, &ret, n, args);
|
||||
va_end (args);
|
||||
|
||||
db_ops.release_connection (conn);
|
||||
db_ops.release_connection (conn, rc < 0);
|
||||
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
@@ -473,7 +482,7 @@ seaf_db_statement_get_int64 (SeafDB *db, const char *sql, int n, ...)
|
||||
rc = db_ops.query_foreach_row (conn, sql, get_int64_cb, &ret, n, args);
|
||||
va_end(args);
|
||||
|
||||
db_ops.release_connection (conn);
|
||||
db_ops.release_connection (conn, rc < 0);
|
||||
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
@@ -507,7 +516,7 @@ seaf_db_statement_get_string (SeafDB *db, const char *sql, int n, ...)
|
||||
rc = db_ops.query_foreach_row (conn, sql, get_string_cb, &ret, n, args);
|
||||
va_end(args);
|
||||
|
||||
db_ops.release_connection (conn);
|
||||
db_ops.release_connection (conn, rc < 0);
|
||||
|
||||
if (rc < 0)
|
||||
return NULL;
|
||||
@@ -527,7 +536,7 @@ seaf_db_begin_transaction (SeafDB *db)
|
||||
}
|
||||
|
||||
if (db_ops.execute_sql_no_stmt (conn, "BEGIN") < 0) {
|
||||
db_ops.release_connection (conn);
|
||||
db_ops.release_connection (conn, TRUE);
|
||||
return trans;
|
||||
}
|
||||
|
||||
@@ -540,7 +549,7 @@ seaf_db_begin_transaction (SeafDB *db)
|
||||
void
|
||||
seaf_db_trans_close (SeafDBTrans *trans)
|
||||
{
|
||||
db_ops.release_connection (trans->conn);
|
||||
db_ops.release_connection (trans->conn, trans->need_close);
|
||||
g_free (trans);
|
||||
}
|
||||
|
||||
@@ -550,6 +559,7 @@ seaf_db_commit (SeafDBTrans *trans)
|
||||
DBConnection *conn = trans->conn;
|
||||
|
||||
if (db_ops.execute_sql_no_stmt (conn, "COMMIT") < 0) {
|
||||
trans->need_close = TRUE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -562,6 +572,7 @@ seaf_db_rollback (SeafDBTrans *trans)
|
||||
DBConnection *conn = trans->conn;
|
||||
|
||||
if (db_ops.execute_sql_no_stmt (conn, "ROLLBACK") < 0) {
|
||||
trans->need_close = TRUE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -578,6 +589,9 @@ seaf_db_trans_query (SeafDBTrans *trans, const char *sql, int n, ...)
|
||||
ret = db_ops.execute_sql (trans->conn, sql, n, args);
|
||||
va_end (args);
|
||||
|
||||
if (ret < 0)
|
||||
trans->need_close = TRUE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -595,6 +609,7 @@ seaf_db_trans_check_for_existence (SeafDBTrans *trans,
|
||||
va_end (args);
|
||||
|
||||
if (n_rows < 0) {
|
||||
trans->need_close = TRUE;
|
||||
*db_err = TRUE;
|
||||
return FALSE;
|
||||
} else {
|
||||
@@ -615,6 +630,9 @@ seaf_db_trans_foreach_selected_row (SeafDBTrans *trans, const char *sql,
|
||||
ret = db_ops.query_foreach_row (trans->conn, sql, callback, data, n, args);
|
||||
va_end (args);
|
||||
|
||||
if (ret < 0)
|
||||
trans->need_close = TRUE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -679,6 +697,8 @@ mysql_db_new (const char *host,
|
||||
return (SeafDB *)db;
|
||||
}
|
||||
|
||||
typedef char my_bool;
|
||||
|
||||
static DBConnection *
|
||||
mysql_db_get_connection (SeafDB *vdb)
|
||||
{
|
||||
@@ -1200,7 +1220,7 @@ sqlite_db_get_connection (SeafDB *vdb)
|
||||
}
|
||||
|
||||
static void
|
||||
sqlite_db_release_connection (DBConnection *vconn)
|
||||
sqlite_db_release_connection (DBConnection *vconn, gboolean need_close)
|
||||
{
|
||||
if (!vconn)
|
||||
return;
|
||||
|
@@ -90,6 +90,7 @@ seafile_session_new(const char *central_config_dir,
|
||||
session->ccnet_dir = abs_ccnet_dir;
|
||||
session->tmp_file_dir = tmp_file_dir;
|
||||
session->config = config;
|
||||
session->ccnet_config = ccnet_config;
|
||||
session->excluded_users = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, NULL);
|
||||
|
||||
|
4
scripts/upgrade/sql/8.0.0/mysql/seafevents.sql
Normal file
4
scripts/upgrade/sql/8.0.0/mysql/seafevents.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE `VirusFile` ADD COLUMN IF NOT EXISTS `has_ignored` TINYINT(1) NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `VirusFile` CHANGE `has_handle` `has_deleted` TINYINT(1);
|
||||
ALTER TABLE `VirusFile` ADD INDEX IF NOT EXISTS `has_deleted` (`has_deleted`);
|
||||
ALTER TABLE `VirusFile` ADD INDEX IF NOT EXISTS `has_ignored` (`has_ignored`);
|
@@ -38,7 +38,10 @@ CREATE TABLE IF NOT EXISTS `ocm_share_received` (
|
||||
KEY `ocm_share_received_provider_id_60c873e0` (`provider_id`)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
ALTER TABLE `VirusFile` ADD COLUMN IF NOT EXISTS `has_ignored` TINYINT(1) NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `VirusFile` CHANGE `has_handle` `has_deleted` TINYINT(1);
|
||||
ALTER TABLE `VirusFile` ADD INDEX IF NOT EXISTS `has_deleted` (`has_deleted`);
|
||||
ALTER TABLE `VirusFile` ADD INDEX IF NOT EXISTS `has_ignored` (`has_ignored`);
|
||||
CREATE TABLE IF NOT EXISTS `repo_auto_delete` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`repo_id` varchar(36) NOT NULL,
|
||||
`days` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `repo_id` (`repo_id`)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET=utf8;
|
||||
|
9
scripts/upgrade/sql/8.0.0/sqlite3/seafevents.sql
Normal file
9
scripts/upgrade/sql/8.0.0/sqlite3/seafevents.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
DROP TABLE IF EXISTS "VirusFile_old";
|
||||
ALTER TABLE "VirusFile" RENAME TO "VirusFile_old";
|
||||
CREATE TABLE IF NOT EXISTS "VirusFile" ("vid" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "repo_id" varchar(36) NOT NULL, "commit_id" varchar(40) NOT NULL, "file_path" text NOT NULL, "has_deleted" tinyint(1) NOT NULL, "has_ignored" TINYINT(1) NOT NULL DEFAULT 0);
|
||||
INSERT INTO "VirusFile" ("vid", "repo_id", "commit_id", "file_path", "has_deleted") SELECT "vid", "repo_id", "commit_id", "file_path", "has_handle" FROM "VirusFile_old";
|
||||
DROP TABLE "VirusFile_old";
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "VirusFile_repo_id_yewnci4gd" ON "VirusFile" ("repo_id");
|
||||
CREATE INDEX IF NOT EXISTS "VirusFile_has_deleted_834ndyts" ON "VirusFile" ("has_deleted");
|
||||
CREATE INDEX IF NOT EXISTS "VirusFile_has_ignored_d84tvuwg" ON "VirusFile" ("has_ignored");
|
@@ -11,12 +11,4 @@ CREATE INDEX IF NOT EXISTS "ocm_share_received_from_server_url_10527b80" ON "ocm
|
||||
CREATE INDEX IF NOT EXISTS "ocm_share_received_repo_id_9e77a1b9" ON "ocm_share_received" ("repo_id");
|
||||
CREATE INDEX IF NOT EXISTS "ocm_share_received_provider_id_60c873e0" ON "ocm_share_received" ("provider_id");
|
||||
|
||||
DROP TABLE IF EXISTS "VirusFile_old";
|
||||
ALTER TABLE "VirusFile" RENAME TO "VirusFile_old";
|
||||
CREATE TABLE IF NOT EXISTS "VirusFile" ("vid" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "repo_id" varchar(36) NOT NULL, "commit_id" varchar(40) NOT NULL, "file_path" text NOT NULL, "has_deleted" tinyint(1) NOT NULL, "has_ignored" TINYINT(1) NOT NULL DEFAULT 0);
|
||||
INSERT INTO "VirusFile" ("vid", "repo_id", "commit_id", "file_path", "has_deleted") SELECT "vid", "repo_id", "commit_id", "file_path", "has_handle" FROM "VirusFile_old";
|
||||
DROP TABLE "VirusFile_old";
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "VirusFile_repo_id_yewnci4gd" ON "VirusFile" ("repo_id");
|
||||
CREATE INDEX IF NOT EXISTS "VirusFile_has_deleted_834ndyts" ON "VirusFile" ("has_deleted");
|
||||
CREATE INDEX IF NOT EXISTS "VirusFile_has_ignored_d84tvuwg" ON "VirusFile" ("has_ignored");
|
||||
CREATE TABLE IF NOT EXISTS "repo_auto_delete" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "repo_id" varchar(36) NOT NULL UNIQUE, "days" integer NOT NULL);
|
||||
|
@@ -54,6 +54,9 @@
|
||||
#define PERM_EXPIRE_TIME 7200 /* 2 hours */
|
||||
#define VIRINFO_EXPIRE_TIME 7200 /* 2 hours */
|
||||
|
||||
#define FS_ID_LIST_MAX_WORKERS 3
|
||||
#define FS_ID_LIST_TOKEN_LEN 36
|
||||
|
||||
struct _HttpServer {
|
||||
evbase_t *evbase;
|
||||
evhtp_t *evhtp;
|
||||
@@ -69,6 +72,11 @@ struct _HttpServer {
|
||||
pthread_mutex_t vir_repo_info_cache_lock;
|
||||
|
||||
event_t *reap_timer;
|
||||
|
||||
GThreadPool *compute_fs_obj_id_pool;
|
||||
|
||||
GHashTable *fs_obj_ids;
|
||||
pthread_mutex_t fs_obj_ids_lock;
|
||||
};
|
||||
typedef struct _HttpServer HttpServer;
|
||||
|
||||
@@ -115,6 +123,9 @@ const char *GET_HEAD_COMMITS_MULTI_REGEX = "^/repo/head-commits-multi";
|
||||
const char *COMMIT_OPER_REGEX = "^/repo/[\\da-z]{8}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{12}/commit/[\\da-z]{40}";
|
||||
const char *PUT_COMMIT_INFO_REGEX = "^/repo/[\\da-z]{8}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{12}/commit/[\\da-z]{40}";
|
||||
const char *GET_FS_OBJ_ID_REGEX = "^/repo/[\\da-z]{8}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{12}/fs-id-list/.*";
|
||||
const char *START_FS_OBJ_ID_REGEX = "^/repo/[\\da-z]{8}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{12}/start-fs-id-list/.*";
|
||||
const char *QUERY_FS_OBJ_ID_REGEX = "^/repo/[\\da-z]{8}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{12}/query-fs-id-list/.*";
|
||||
const char *RETRIEVE_FS_OBJ_ID_REGEX = "^/repo/[\\da-z]{8}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{12}/retrieve-fs-id-list/.*";
|
||||
const char *BLOCK_OPER_REGEX = "^/repo/[\\da-z]{8}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{12}/block/[\\da-z]{40}";
|
||||
const char *POST_CHECK_FS_REGEX = "^/repo/[\\da-z]{8}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{12}/check-fs";
|
||||
const char *POST_CHECK_BLOCK_REGEX = "^/repo/[\\da-z]{8}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{4}-[\\da-z]{12}/check-blocks";
|
||||
@@ -1531,6 +1542,293 @@ out:
|
||||
seaf_repo_unref (repo);
|
||||
}
|
||||
|
||||
typedef struct ComputeObjTask {
|
||||
HttpServer *htp_server;
|
||||
char *token;
|
||||
char *repo_id;
|
||||
char *client_head;
|
||||
char *server_head;
|
||||
gboolean dir_only;
|
||||
} ComputeObjTask;
|
||||
|
||||
typedef struct CalObjResult {
|
||||
GList *list;
|
||||
gboolean done;
|
||||
} CalObjResult;
|
||||
|
||||
static void
|
||||
free_compute_obj_task(ComputeObjTask *task)
|
||||
{
|
||||
if (!task)
|
||||
return;
|
||||
|
||||
if (task->token)
|
||||
g_free(task->token);
|
||||
if (task->repo_id)
|
||||
g_free(task->repo_id);
|
||||
if (task->client_head)
|
||||
g_free(task->client_head);
|
||||
if (task->server_head)
|
||||
g_free(task->server_head);
|
||||
g_free(task);
|
||||
}
|
||||
|
||||
static void
|
||||
free_obj_cal_result (gpointer data)
|
||||
{
|
||||
CalObjResult *result = (CalObjResult *)data;
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
if (result->list)
|
||||
g_list_free (result->list);
|
||||
|
||||
g_free(result);
|
||||
}
|
||||
|
||||
static void
|
||||
compute_fs_obj_id (gpointer ptask, gpointer ppara)
|
||||
{
|
||||
SeafRepo *repo = NULL;
|
||||
ComputeObjTask *task = ptask;
|
||||
const char *client_head = task->client_head;
|
||||
const char *server_head = task->server_head;
|
||||
char *repo_id = task->repo_id;
|
||||
gboolean dir_only = task->dir_only;
|
||||
HttpServer *htp_server = task->htp_server;
|
||||
CalObjResult *result = NULL;
|
||||
|
||||
pthread_mutex_lock (&htp_server->fs_obj_ids_lock);
|
||||
result = g_hash_table_lookup (htp_server->fs_obj_ids, task->token);
|
||||
pthread_mutex_unlock (&htp_server->fs_obj_ids_lock);
|
||||
if (!result) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id);
|
||||
if (!repo) {
|
||||
seaf_warning ("Failed to find repo %.8s.\n", repo_id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (calculate_send_object_list (repo, server_head, client_head, dir_only, &result->list) < 0) {
|
||||
pthread_mutex_lock (&htp_server->fs_obj_ids_lock);
|
||||
g_hash_table_remove (htp_server->fs_obj_ids, task->token);
|
||||
pthread_mutex_unlock (&htp_server->fs_obj_ids_lock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
result->done = TRUE;
|
||||
out:
|
||||
seaf_repo_unref (repo);
|
||||
free_compute_obj_task(task);
|
||||
}
|
||||
|
||||
static void
|
||||
start_fs_obj_id_cb (evhtp_request_t *req, void *arg)
|
||||
{
|
||||
HttpServer *htp_server = arg;
|
||||
char **parts;
|
||||
char *repo_id;
|
||||
gboolean dir_only = FALSE;
|
||||
json_t *obj;
|
||||
|
||||
const char *server_head = evhtp_kv_find (req->uri->query, "server-head");
|
||||
if (server_head == NULL || !is_object_id_valid (server_head)) {
|
||||
char *error = "Invalid server-head parameter.\n";
|
||||
evbuffer_add (req->buffer_out, error, strlen (error));
|
||||
evhtp_send_reply (req, EVHTP_RES_BADREQ);
|
||||
return;
|
||||
}
|
||||
|
||||
const char *client_head = evhtp_kv_find (req->uri->query, "client-head");
|
||||
if (client_head && !is_object_id_valid (client_head)) {
|
||||
char *error = "Invalid client-head parameter.\n";
|
||||
evbuffer_add (req->buffer_out, error, strlen (error));
|
||||
evhtp_send_reply (req, EVHTP_RES_BADREQ);
|
||||
return;
|
||||
}
|
||||
|
||||
const char *dir_only_arg = evhtp_kv_find (req->uri->query, "dir-only");
|
||||
if (dir_only_arg)
|
||||
dir_only = TRUE;
|
||||
|
||||
parts = g_strsplit (req->uri->path->full + 1, "/", 0);
|
||||
repo_id = parts[1];
|
||||
|
||||
int token_status = validate_token (htp_server, req, repo_id, NULL, FALSE);
|
||||
if (token_status != EVHTP_RES_OK) {
|
||||
evhtp_send_reply (req, token_status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
char uuid[37];
|
||||
char *new_token;
|
||||
gen_uuid_inplace (uuid);
|
||||
new_token = g_strndup(uuid, FS_ID_LIST_TOKEN_LEN);
|
||||
|
||||
CalObjResult *result = g_new0(CalObjResult, 1);
|
||||
if (!result) {
|
||||
evhtp_send_reply (req, EVHTP_RES_SERVERR);
|
||||
goto out;
|
||||
}
|
||||
result->done = FALSE;
|
||||
|
||||
ComputeObjTask *task = g_new0 (ComputeObjTask, 1);
|
||||
if (!task) {
|
||||
evhtp_send_reply (req, EVHTP_RES_SERVERR);
|
||||
goto out;
|
||||
}
|
||||
|
||||
task->token = new_token;
|
||||
task->dir_only = dir_only;
|
||||
task->htp_server = htp_server;
|
||||
task->repo_id = g_strdup(repo_id);
|
||||
task->client_head = g_strdup(client_head);
|
||||
task->server_head = g_strdup(server_head);
|
||||
|
||||
pthread_mutex_lock (&htp_server->fs_obj_ids_lock);
|
||||
g_hash_table_insert (htp_server->fs_obj_ids, g_strdup(task->token), result);
|
||||
pthread_mutex_unlock (&htp_server->fs_obj_ids_lock);
|
||||
g_thread_pool_push (htp_server->compute_fs_obj_id_pool, task, NULL);
|
||||
obj = json_object ();
|
||||
json_object_set_new (obj, "token", json_string (new_token));
|
||||
|
||||
char *json_str = json_dumps (obj, JSON_COMPACT);
|
||||
evbuffer_add (req->buffer_out, json_str, strlen(json_str));
|
||||
evhtp_send_reply (req, EVHTP_RES_OK);
|
||||
|
||||
g_free (json_str);
|
||||
json_decref (obj);
|
||||
out:
|
||||
g_strfreev (parts);
|
||||
}
|
||||
|
||||
static void
|
||||
query_fs_obj_id_cb (evhtp_request_t *req, void *arg)
|
||||
{
|
||||
json_t *obj;
|
||||
const char *token = NULL;
|
||||
CalObjResult *result = NULL;
|
||||
char **parts;
|
||||
char *repo_id = NULL;
|
||||
HttpServer *htp_server = (HttpServer *)arg;
|
||||
|
||||
parts = g_strsplit (req->uri->path->full + 1, "/", 0);
|
||||
repo_id = parts[1];
|
||||
|
||||
int token_status = validate_token (htp_server, req, repo_id, NULL, FALSE);
|
||||
if (token_status != EVHTP_RES_OK) {
|
||||
evhtp_send_reply (req, token_status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
token = evhtp_kv_find (req->uri->query, "token");
|
||||
if (!token || strlen(token)!=FS_ID_LIST_TOKEN_LEN) {
|
||||
evhtp_send_reply (req, EVHTP_RES_BADREQ);
|
||||
goto out;
|
||||
}
|
||||
|
||||
obj = json_object ();
|
||||
|
||||
pthread_mutex_lock (&htp_server->fs_obj_ids_lock);
|
||||
result = g_hash_table_lookup (htp_server->fs_obj_ids, token);
|
||||
if (!result) {
|
||||
pthread_mutex_unlock (&htp_server->fs_obj_ids_lock);
|
||||
evhtp_send_reply (req, EVHTP_RES_NOTFOUND);
|
||||
goto out;
|
||||
} else {
|
||||
if (!result->done) {
|
||||
json_object_set_new (obj, "success", json_false());
|
||||
} else {
|
||||
json_object_set_new (obj, "success", json_true());
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock (&htp_server->fs_obj_ids_lock);
|
||||
|
||||
json_object_set_new (obj, "token", json_string (token));
|
||||
|
||||
char *json_str = json_dumps (obj, JSON_COMPACT);
|
||||
evbuffer_add (req->buffer_out, json_str, strlen(json_str));
|
||||
evhtp_send_reply (req, EVHTP_RES_OK);
|
||||
|
||||
g_free (json_str);
|
||||
|
||||
out:
|
||||
if (obj)
|
||||
json_decref (obj);
|
||||
g_strfreev (parts);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
retrieve_fs_obj_id_cb (evhtp_request_t *req, void *arg)
|
||||
{
|
||||
char **parts;
|
||||
const char *token = NULL;
|
||||
char *repo_id = NULL;
|
||||
GList *list = NULL;
|
||||
CalObjResult *result = NULL;
|
||||
HttpServer *htp_server = (HttpServer *)arg;
|
||||
|
||||
parts = g_strsplit (req->uri->path->full + 1, "/", 0);
|
||||
repo_id = parts[1];
|
||||
|
||||
int token_status = validate_token (htp_server, req, repo_id, NULL, FALSE);
|
||||
if (token_status != EVHTP_RES_OK) {
|
||||
evhtp_send_reply (req, token_status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
token = evhtp_kv_find (req->uri->query, "token");
|
||||
if (!token || strlen(token)!=FS_ID_LIST_TOKEN_LEN) {
|
||||
evhtp_send_reply (req, EVHTP_RES_BADREQ);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pthread_mutex_lock (&htp_server->fs_obj_ids_lock);
|
||||
result = g_hash_table_lookup (htp_server->fs_obj_ids, token);
|
||||
if (!result) {
|
||||
pthread_mutex_unlock (&htp_server->fs_obj_ids_lock);
|
||||
evhtp_send_reply (req, EVHTP_RES_NOTFOUND);
|
||||
|
||||
return;
|
||||
}
|
||||
if (!result->done) {
|
||||
pthread_mutex_unlock (&htp_server->fs_obj_ids_lock);
|
||||
|
||||
char *error = "The cauculation task is not completed.\n";
|
||||
evbuffer_add (req->buffer_out, error, strlen(error));
|
||||
evhtp_send_reply (req, EVHTP_RES_BADREQ);
|
||||
return;
|
||||
}
|
||||
list = result->list;
|
||||
pthread_mutex_unlock (&htp_server->fs_obj_ids_lock);
|
||||
|
||||
GList *ptr;
|
||||
json_t *obj_array = json_array ();
|
||||
|
||||
for (ptr = list; ptr; ptr = ptr->next) {
|
||||
json_array_append_new (obj_array, json_string (ptr->data));
|
||||
g_free (ptr->data);
|
||||
}
|
||||
|
||||
pthread_mutex_lock (&htp_server->fs_obj_ids_lock);
|
||||
g_hash_table_remove (htp_server->fs_obj_ids, token);
|
||||
pthread_mutex_unlock (&htp_server->fs_obj_ids_lock);
|
||||
|
||||
char *obj_list = json_dumps (obj_array, JSON_COMPACT);
|
||||
evbuffer_add (req->buffer_out, obj_list, strlen (obj_list));
|
||||
evhtp_send_reply (req, EVHTP_RES_OK);
|
||||
|
||||
g_free (obj_list);
|
||||
json_decref (obj_array);
|
||||
|
||||
out:
|
||||
g_strfreev (parts);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
get_block_cb (evhtp_request_t *req, void *arg)
|
||||
{
|
||||
@@ -2346,6 +2644,18 @@ http_request_init (HttpServerStruct *server)
|
||||
GET_FS_OBJ_ID_REGEX, get_fs_obj_id_cb,
|
||||
priv);
|
||||
|
||||
evhtp_set_regex_cb (priv->evhtp,
|
||||
START_FS_OBJ_ID_REGEX, start_fs_obj_id_cb,
|
||||
priv);
|
||||
|
||||
evhtp_set_regex_cb (priv->evhtp,
|
||||
QUERY_FS_OBJ_ID_REGEX, query_fs_obj_id_cb,
|
||||
priv);
|
||||
|
||||
evhtp_set_regex_cb (priv->evhtp,
|
||||
RETRIEVE_FS_OBJ_ID_REGEX, retrieve_fs_obj_id_cb,
|
||||
priv);
|
||||
|
||||
evhtp_set_regex_cb (priv->evhtp,
|
||||
BLOCK_OPER_REGEX, block_oper_cb,
|
||||
priv);
|
||||
@@ -2530,6 +2840,13 @@ seaf_http_server_new (struct _SeafileSession *session)
|
||||
|
||||
server->http_temp_dir = g_build_filename (session->seaf_dir, "httptemp", NULL);
|
||||
|
||||
priv->compute_fs_obj_id_pool = g_thread_pool_new (compute_fs_obj_id, NULL,
|
||||
FS_ID_LIST_MAX_WORKERS, FALSE, NULL);
|
||||
|
||||
priv->fs_obj_ids = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, free_obj_cal_result);
|
||||
pthread_mutex_init (&priv->fs_obj_ids_lock, NULL);
|
||||
|
||||
server->seaf_session = session;
|
||||
server->priv = priv;
|
||||
|
||||
|
Reference in New Issue
Block a user