diff --git a/common/rpc-service.c b/common/rpc-service.c index a64acad2..c8cc0267 100644 --- a/common/rpc-service.c +++ b/common/rpc-service.c @@ -2620,6 +2620,7 @@ seafile_put_file (const char *repo_id, const char *temp_file_path, seaf_repo_manager_put_file (seaf->repo_mgr, repo_id, temp_file_path, rpath, norm_file_name, user, head_id, + 0, &new_file_id, error); out: diff --git a/fileserver/fileop.go b/fileserver/fileop.go index 0ecf93cb..513acec2 100644 --- a/fileserver/fileop.go +++ b/fileserver/fileop.go @@ -1005,7 +1005,10 @@ func doUpload(rsp http.ResponseWriter, r *http.Request, fsm *recvData, isAjax bo lastModifyStr := normalizeUTF8Path(r.FormValue("last_modify")) var lastModify int64 if lastModifyStr != "" { - lastModify, _ = strconv.ParseInt(lastModifyStr, 10, 64) + t, err := time.Parse(time.RFC3339, lastModifyStr) + if err == nil { + lastModify = t.Unix() + } } relativePath := normalizeUTF8Path(r.FormValue("relative_path")) @@ -1533,7 +1536,7 @@ func postMultiFiles(rsp http.ResponseWriter, r *http.Request, repoID, parentDir, } } - retStr, err := postFilesAndGenCommit(fileNames, repo.ID, user, canonPath, replace, lastModify, ids, sizes) + retStr, err := postFilesAndGenCommit(fileNames, repo.ID, user, canonPath, replace, ids, sizes, lastModify) if err != nil { err := fmt.Errorf("failed to post files and gen commit: %v", err) return &appError{err, "", http.StatusInternalServerError} @@ -1589,7 +1592,7 @@ func checkFilesWithSameName(repo *repomgr.Repo, canonPath string, fileNames []st return false } -func postFilesAndGenCommit(fileNames []string, repoID string, user, canonPath string, replace bool, lastModify int64, ids []string, sizes []int64) (string, error) { +func postFilesAndGenCommit(fileNames []string, repoID string, user, canonPath string, replace bool, ids []string, sizes []int64, lastModify int64) (string, error) { repo := repomgr.Get(repoID) if repo == nil { err := fmt.Errorf("failed to get repo %s", repoID) @@ -2771,6 +2774,15 @@ func doUpdate(rsp http.ResponseWriter, r *http.Request, fsm *recvData, isAjax bo return &appError{nil, msg, http.StatusBadRequest} } + lastModifyStr := normalizeUTF8Path(r.FormValue("last_modify")) + var lastModify int64 + if lastModifyStr != "" { + t, err := time.Parse(time.RFC3339, lastModifyStr) + if err == nil { + lastModify = t.Unix() + } + } + parentDir := filepath.Dir(targetFile) fileName := filepath.Base(targetFile) @@ -2877,7 +2889,7 @@ func doUpdate(rsp http.ResponseWriter, r *http.Request, fsm *recvData, isAjax bo headID = headIDs[0] } - if err := putFile(rsp, r, repoID, parentDir, user, fileName, fsm, headID, isAjax); err != nil { + if err := putFile(rsp, r, repoID, parentDir, user, fileName, fsm, headID, lastModify, isAjax); err != nil { return err } @@ -2887,7 +2899,7 @@ func doUpdate(rsp http.ResponseWriter, r *http.Request, fsm *recvData, isAjax bo return nil } -func putFile(rsp http.ResponseWriter, r *http.Request, repoID, parentDir, user, fileName string, fsm *recvData, headID string, isAjax bool) *appError { +func putFile(rsp http.ResponseWriter, r *http.Request, repoID, parentDir, user, fileName string, fsm *recvData, headID string, lastModify int64, isAjax bool) *appError { files := fsm.files repo := repomgr.Get(repoID) if repo == nil { @@ -2982,6 +2994,9 @@ func putFile(rsp http.ResponseWriter, r *http.Request, repoID, parentDir, user, } mtime := time.Now().Unix() + if lastModify > 0 { + mtime = lastModify + } mode := (syscall.S_IFREG | 0644) newDent := fsmgr.NewDirent(fileID, fileName, uint32(mode), mtime, user, size) diff --git a/server/index-blocks-mgr.c b/server/index-blocks-mgr.c index a24db603..be9839d3 100644 --- a/server/index-blocks-mgr.c +++ b/server/index-blocks-mgr.c @@ -175,10 +175,10 @@ start_index_task (gpointer data, gpointer user_data) idx_para->user, idx_para->ret_json ? &ret_json : NULL, idx_para->replace_existed, - 0, idx_para->canon_path, id_list, size_list, + 0, NULL); progress->status = ret; if (idx_para->ret_json) { diff --git a/server/repo-mgr.h b/server/repo-mgr.h index a23f21b1..c9b16bde 100644 --- a/server/repo-mgr.h +++ b/server/repo-mgr.h @@ -406,6 +406,7 @@ seaf_repo_manager_put_file (SeafRepoManager *mgr, const char *file_name, const char *user, const char *head_id, + gint64 mtime, char **new_file_id, GError **error); @@ -912,10 +913,10 @@ post_files_and_gen_commit (GList *filenames, const char *user, char **ret_json, int replace_existed, - gint64 mtime, const char *canon_path, GList *id_list, GList *size_list, + gint64 mtime, GError **error); char * diff --git a/server/repo-op.c b/server/repo-op.c index 83741642..69f207e2 100644 --- a/server/repo-op.c +++ b/server/repo-op.c @@ -48,10 +48,10 @@ post_files_and_gen_commit (GList *filenames, const char *user, char **ret_json, int replace_existed, - gint64 mtime, const char *canon_path, GList *id_list, GList *size_list, + gint64 mtime, GError **error); /* @@ -1173,10 +1173,10 @@ seaf_repo_manager_post_multi_files (SeafRepoManager *mgr, user, ret_json, replace_existed, - mtime, canon_path, id_list, size_list, + mtime, error); } else { ret = index_blocks_mgr_start_index (seaf->index_blocks_mgr, @@ -1212,10 +1212,10 @@ post_files_and_gen_commit (GList *filenames, const char *user, char **ret_json, int replace_existed, - gint64 mtime, const char *canon_path, GList *id_list, GList *size_list, + gint64 mtime, GError **error) { SeafRepo *repo = NULL; @@ -4321,6 +4321,7 @@ seaf_repo_manager_put_file (SeafRepoManager *mgr, const char *file_name, const char *user, const char *head_id, + gint64 mtime, char **new_file_id, GError **error) { @@ -4398,9 +4399,12 @@ seaf_repo_manager_put_file (SeafRepoManager *mgr, } rawdata_to_hex(sha1, hex, 20); + if (mtime <= 0) { + mtime = (gint64)time(NULL); + } new_dent = seaf_dirent_new (dir_version_from_repo_version(repo->version), hex, STD_FILE_MODE, file_name, - (gint64)time(NULL), user, size); + mtime, user, size); if (!fullpath) fullpath = g_build_filename(parent_dir, file_name, NULL); diff --git a/server/upload-file.c b/server/upload-file.c index 3ad53a4d..88a8efa5 100755 --- a/server/upload-file.c +++ b/server/upload-file.c @@ -422,6 +422,22 @@ file_id_list_from_json (const char *ret_json) return g_string_free (id_list, FALSE); } +static gint64 +rfc3339_to_timestamp (const char *last_modify) +{ + if (!last_modify) { + return -1; + } + GDateTime *date_time = g_date_time_new_from_iso8601(last_modify, NULL); + if (!date_time) { + return -1; + } + gint64 mtime = g_date_time_to_unix(date_time); + + g_date_time_unref(date_time); + return mtime; +} + static void upload_api_cb(evhtp_request_t *req, void *arg) { @@ -472,7 +488,7 @@ upload_api_cb(evhtp_request_t *req, void *arg) last_modify = g_hash_table_lookup (fsm->form_kvs, "last_modify"); if (last_modify) { - mtime = atoll(last_modify); + mtime = rfc3339_to_timestamp (last_modify); } replace_str = g_hash_table_lookup (fsm->form_kvs, "replace"); @@ -1103,7 +1119,7 @@ upload_ajax_cb(evhtp_request_t *req, void *arg) last_modify = g_hash_table_lookup (fsm->form_kvs, "last_modify"); if (last_modify) { - mtime = atoll(last_modify); + mtime = rfc3339_to_timestamp (last_modify); } if (!fsm->filenames) { @@ -1252,6 +1268,8 @@ update_api_cb(evhtp_request_t *req, void *arg) { RecvFSM *fsm = arg; char *target_file, *parent_dir = NULL, *filename = NULL; + char *last_modify = NULL; + gint64 mtime = 0; const char *head_id = NULL; GError *error = NULL; int error_code = -1; @@ -1294,6 +1312,11 @@ update_api_cb(evhtp_request_t *req, void *arg) return; } + last_modify = g_hash_table_lookup (fsm->form_kvs, "last_modify"); + if (last_modify) { + mtime = rfc3339_to_timestamp (last_modify); + } + parent_dir = g_path_get_dirname (target_file); filename = g_path_get_basename (target_file); if (!filename || filename[0] == '\0') { @@ -1364,6 +1387,7 @@ update_api_cb(evhtp_request_t *req, void *arg) filename, fsm->user, head_id, + mtime, &new_file_id, &error); if (rc < 0) { @@ -1653,6 +1677,8 @@ update_ajax_cb(evhtp_request_t *req, void *arg) { RecvFSM *fsm = arg; char *target_file, *parent_dir = NULL, *filename = NULL; + char *last_modify = NULL; + gint64 mtime = 0; const char *head_id = NULL; GError *error = NULL; int error_code = -1; @@ -1697,6 +1723,11 @@ update_ajax_cb(evhtp_request_t *req, void *arg) return; } + last_modify = g_hash_table_lookup (fsm->form_kvs, "last_modify"); + if (last_modify) { + mtime = rfc3339_to_timestamp (last_modify); + } + parent_dir = g_path_get_dirname (target_file); filename = g_path_get_basename (target_file); @@ -1732,6 +1763,7 @@ update_ajax_cb(evhtp_request_t *req, void *arg) filename, fsm->user, head_id, + mtime, &new_file_id, &error); diff --git a/tests/test_file_operation/test_upload_and_update.py b/tests/test_file_operation/test_upload_and_update.py index 94d64223..4dd5fd7c 100644 --- a/tests/test_file_operation/test_upload_and_update.py +++ b/tests/test_file_operation/test_upload_and_update.py @@ -519,7 +519,7 @@ def test_api(repo): def test_ajax_mtime(repo): create_test_file() obj_id = '{"parent_dir":"/"}' - mtime = '1695809905' + mtime = '2023-09-27T18:18:25+08:00' token = api.get_fileserver_access_token(repo.id, obj_id, 'upload', USER, False) upload_url_base = 'http://127.0.0.1:8082/upload-aj/'+ token @@ -541,7 +541,7 @@ def test_api_mtime(repo): create_test_file() params = {'ret-json':'1'} obj_id = '{"parent_dir":"/"}' - mtime = '1695809905' + mtime = '2023-09-27T18:18:25+08:00' token = api.get_fileserver_access_token(repo.id, obj_id, 'upload', USER, False) upload_url_base = 'http://127.0.0.1:8082/upload-api/' + token