static void update_cb(evhtp_request_t *req, void *arg) { RecvFSM *fsm = arg; SearpcClient *rpc_client = NULL; char *target_file, *parent_dir = NULL, *filename = NULL; const char *head_id = NULL; GError *error = NULL; int error_code = ERROR_INTERNAL; if (!fsm || fsm->state == RECV_ERROR) return; if (!fsm->tmp_files) { seaf_warning ("[update] No file uploaded.\n"); evhtp_send_reply (req, EVHTP_RES_BADREQ); return; } target_file = g_hash_table_lookup (fsm->form_kvs, "target_file"); if (!target_file) { seaf_warning ("[Update] No target file given.\n"); evbuffer_add_printf(req->buffer_out, "Invalid URL.\n"); evhtp_send_reply (req, EVHTP_RES_BADREQ); return; } parent_dir = g_path_get_dirname (target_file); filename = g_path_get_basename (target_file); if (!check_tmp_file_list (fsm->tmp_files, &error_code)) goto error; head_id = evhtp_kv_find (req->uri->query, "head"); rpc_client = ccnet_create_pooled_rpc_client (seaf->client_pool, NULL, "seafserv-threaded-rpcserver"); if (seafile_check_quota (rpc_client, fsm->repo_id, NULL) < 0) { seaf_warning ("[update] Out of quota.\n"); error_code = ERROR_QUOTA; goto error; } seafile_put_file (rpc_client, fsm->repo_id, (char *)(fsm->tmp_files->data), parent_dir, filename, fsm->user, head_id, &error); if (error) { if (g_strcmp0 (error->message, "file does not exist") == 0) { error_code = ERROR_NOT_EXIST; } if (error->message) printf ("%s\n", error->message); g_clear_error (&error); goto error; } ccnet_rpc_client_free (rpc_client); /* Redirect to repo dir page after upload finishes. */ redirect_to_success_page (req, fsm->repo_id, parent_dir); g_free (parent_dir); g_free (filename); return; error: if (rpc_client) ccnet_rpc_client_free (rpc_client); redirect_to_update_error (req, fsm->repo_id, target_file, error_code); g_free (parent_dir); g_free (filename); }
static void upload_cb(evhtp_request_t *req, void *arg) { RecvFSM *fsm = arg; SearpcClient *rpc_client = NULL; char *parent_dir; GError *error = NULL; int error_code = ERROR_INTERNAL; char *err_file = NULL; char *filenames_json, *tmp_files_json; /* After upload_headers_cb() returns an error, libevhtp may still * receive data from the web browser and call into this cb. * In this case fsm will be NULL. */ if (!fsm || fsm->state == RECV_ERROR) return; if (!fsm->tmp_files) { seaf_warning ("[upload] No file uploaded.\n"); evhtp_send_reply (req, EVHTP_RES_BADREQ); return; } parent_dir = g_hash_table_lookup (fsm->form_kvs, "parent_dir"); if (!parent_dir) { seaf_warning ("[upload] No parent dir given.\n"); evbuffer_add_printf(req->buffer_out, "Invalid URL.\n"); evhtp_send_reply (req, EVHTP_RES_BADREQ); return; } if (!check_tmp_file_list (fsm->tmp_files, &error_code)) goto error; rpc_client = ccnet_create_pooled_rpc_client (seaf->client_pool, NULL, "seafserv-threaded-rpcserver"); if (seafile_check_quota (rpc_client, fsm->repo_id, NULL) < 0) { seaf_warning ("[upload] Out of quota.\n"); error_code = ERROR_QUOTA; goto error; } filenames_json = file_list_to_json (fsm->uploaded_files); tmp_files_json = file_list_to_json (fsm->tmp_files); seafile_post_multi_files (rpc_client, fsm->repo_id, parent_dir, filenames_json, tmp_files_json, fsm->user, &error); g_free (filenames_json); g_free (tmp_files_json); if (error) { if (error->code == POST_FILE_ERR_FILENAME) { error_code = ERROR_FILENAME; err_file = g_strdup(error->message); } g_clear_error (&error); goto error; } ccnet_rpc_client_free (rpc_client); /* Redirect to repo dir page after upload finishes. */ redirect_to_success_page (req, fsm->repo_id, parent_dir); return; error: if (rpc_client) ccnet_rpc_client_free (rpc_client); redirect_to_upload_error (req, fsm->repo_id, parent_dir, err_file, error_code); g_free (err_file); }
/* Handle AJAX file upload. @return an array of json data, e.g. [{"name": "foo.txt"}] */ static void upload_ajax_cb(evhtp_request_t *req, void *arg) { RecvFSM *fsm = arg; SearpcClient *rpc_client = NULL; char *parent_dir; GError *error = NULL; int error_code = ERROR_INTERNAL; char *filenames_json, *tmp_files_json; evhtp_headers_add_header (req->headers_out, evhtp_header_new("Access-Control-Allow-Headers", "x-requested-with, content-type, accept, origin, authorization", 1, 1)); evhtp_headers_add_header (req->headers_out, evhtp_header_new("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS", 1, 1)); evhtp_headers_add_header (req->headers_out, evhtp_header_new("Access-Control-Allow-Origin", "*", 1, 1)); evhtp_headers_add_header (req->headers_out, evhtp_header_new("Access-Control-Max-Age", "86400", 1, 1)); if (evhtp_request_get_method(req) == htp_method_OPTIONS) { /* If CORS preflight header, then create an empty body response (200 OK) * and return it. */ evhtp_headers_add_header (req->headers_out, evhtp_header_new("Content-Type", "text/html; charset=utf-8", 1, 1)); set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_OK); return; } /* After upload_headers_cb() returns an error, libevhtp may still * receive data from the web browser and call into this cb. * In this case fsm will be NULL. */ if (!fsm || fsm->state == RECV_ERROR) return; if (!fsm->files) { seaf_warning ("[upload] No file uploaded.\n"); set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_BADREQ); return; } parent_dir = g_hash_table_lookup (fsm->form_kvs, "parent_dir"); if (!parent_dir) { seaf_warning ("[upload] No parent dir given.\n"); evbuffer_add_printf(req->buffer_out, "Invalid URL.\n"); set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_BADREQ); return; } if (!check_tmp_file_list (fsm->files, &error_code)) goto error; rpc_client = ccnet_create_pooled_rpc_client (seaf->client_pool, NULL, "seafserv-threaded-rpcserver"); if (seafile_check_quota (rpc_client, fsm->repo_id, NULL) < 0) { seaf_warning ("[upload] Out of quota.\n"); error_code = ERROR_QUOTA; goto error; } filenames_json = file_list_to_json (fsm->filenames); tmp_files_json = file_list_to_json (fsm->files); seafile_post_multi_files (rpc_client, fsm->repo_id, parent_dir, filenames_json, tmp_files_json, fsm->user, &error); g_free (filenames_json); g_free (tmp_files_json); if (error) { if (error->code == POST_FILE_ERR_FILENAME) { error_code = ERROR_FILENAME; seaf_warning ("[upload] Bad filename.\n"); } g_clear_error (&error); goto error; } ccnet_rpc_client_free (rpc_client); GString *res_buf = g_string_new (NULL); GList *ptr; g_string_append (res_buf, "["); for (ptr = fsm->filenames; ptr; ptr = ptr->next) { char *filename = ptr->data; if (ptr->next) g_string_append_printf (res_buf, "{\"name\": \"%s\"}, ", filename); else g_string_append_printf (res_buf, "{\"name\": \"%s\"}", filename); } g_string_append (res_buf, "]"); evbuffer_add (req->buffer_out, res_buf->str, res_buf->len); g_string_free (res_buf, TRUE); set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_OK); return; error: if (rpc_client) ccnet_rpc_client_free (rpc_client); switch (error_code) { case ERROR_FILENAME: evbuffer_add_printf(req->buffer_out, "Invalid filename.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_BADFILENAME); break; case ERROR_EXISTS: evbuffer_add_printf(req->buffer_out, "File already exists.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_EXISTS); break; case ERROR_SIZE: evbuffer_add_printf(req->buffer_out, "File size is too large.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_TOOLARGE); break; case ERROR_QUOTA: evbuffer_add_printf(req->buffer_out, "Out of quota.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_NOQUOTA); break; case ERROR_RECV: case ERROR_INTERNAL: set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_SERVERR); break; } }
static void update_api_cb(evhtp_request_t *req, void *arg) { RecvFSM *fsm = arg; SearpcClient *rpc_client = NULL; char *target_file, *parent_dir = NULL, *filename = NULL; const char *head_id = NULL; GError *error = NULL; int error_code = ERROR_INTERNAL; char *new_file_id = NULL; if (!fsm || fsm->state == RECV_ERROR) return; if (!fsm->files) { seaf_warning ("[update] No file uploaded.\n"); set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_BADREQ); return; } target_file = g_hash_table_lookup (fsm->form_kvs, "target_file"); if (!target_file) { seaf_warning ("[Update] No target file given.\n"); evbuffer_add_printf(req->buffer_out, "Invalid URL.\n"); set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_BADREQ); return; } parent_dir = g_path_get_dirname (target_file); filename = g_path_get_basename (target_file); if (!check_tmp_file_list (fsm->files, &error_code)) goto error; head_id = evhtp_kv_find (req->uri->query, "head"); rpc_client = ccnet_create_pooled_rpc_client (seaf->client_pool, NULL, "seafserv-threaded-rpcserver"); if (seafile_check_quota (rpc_client, fsm->repo_id, NULL) < 0) { seaf_warning ("[update] Out of quota.\n"); error_code = ERROR_QUOTA; goto error; } new_file_id = seafile_put_file (rpc_client, fsm->repo_id, (char *)(fsm->files->data), parent_dir, filename, fsm->user, head_id, &error); g_free (parent_dir); g_free (filename); if (error) { if (g_strcmp0 (error->message, "file does not exist") == 0) { error_code = ERROR_NOT_EXIST; } if (error->message) seaf_warning ("%s\n", error->message); g_clear_error (&error); goto error; } ccnet_rpc_client_free (rpc_client); /* Send back the new file id, so that the mobile client can update local cache */ evbuffer_add(req->buffer_out, new_file_id, strlen(new_file_id)); set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_OK); g_free (new_file_id); return; error: if (rpc_client) ccnet_rpc_client_free (rpc_client); switch (error_code) { case ERROR_FILENAME: evbuffer_add_printf(req->buffer_out, "Invalid filename.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_BADFILENAME); break; case ERROR_EXISTS: evbuffer_add_printf(req->buffer_out, "File already exists.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_EXISTS); break; case ERROR_SIZE: evbuffer_add_printf(req->buffer_out, "File size is too large.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_TOOLARGE); break; case ERROR_QUOTA: evbuffer_add_printf(req->buffer_out, "Out of quota.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_NOQUOTA); break; case ERROR_NOT_EXIST: evbuffer_add_printf(req->buffer_out, "File does not exist.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_NOT_EXISTS); break; case ERROR_RECV: case ERROR_INTERNAL: default: set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_SERVERR); break; } }
static void upload_api_cb(evhtp_request_t *req, void *arg) { RecvFSM *fsm = arg; SearpcClient *rpc_client = NULL; char *parent_dir; GError *error = NULL; int error_code = ERROR_INTERNAL; char *filenames_json, *tmp_files_json; /* After upload_headers_cb() returns an error, libevhtp may still * receive data from the web browser and call into this cb. * In this case fsm will be NULL. */ if (!fsm || fsm->state == RECV_ERROR) return; if (!fsm->files) { seaf_warning ("[upload] No file uploaded.\n"); set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_BADREQ); return; } parent_dir = g_hash_table_lookup (fsm->form_kvs, "parent_dir"); if (!parent_dir) { seaf_warning ("[upload] No parent dir given.\n"); evbuffer_add_printf(req->buffer_out, "Invalid URL.\n"); set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_BADREQ); return; } if (!check_tmp_file_list (fsm->files, &error_code)) goto error; rpc_client = ccnet_create_pooled_rpc_client (seaf->client_pool, NULL, "seafserv-threaded-rpcserver"); if (seafile_check_quota (rpc_client, fsm->repo_id, NULL) < 0) { seaf_warning ("[upload] Out of quota.\n"); error_code = ERROR_QUOTA; goto error; } filenames_json = file_list_to_json (fsm->filenames); tmp_files_json = file_list_to_json (fsm->files); char *new_file_ids = seafile_post_multi_files (rpc_client, fsm->repo_id, parent_dir, filenames_json, tmp_files_json, fsm->user, &error); g_free (filenames_json); g_free (tmp_files_json); if (error) { if (error->code == POST_FILE_ERR_FILENAME) { error_code = ERROR_FILENAME; seaf_warning ("[upload] Bad filename.\n"); } g_clear_error (&error); goto error; } ccnet_rpc_client_free (rpc_client); evbuffer_add (req->buffer_out, new_file_ids, strlen(new_file_ids)); g_free (new_file_ids); set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_OK); return; error: if (rpc_client) ccnet_rpc_client_free (rpc_client); switch (error_code) { case ERROR_FILENAME: evbuffer_add_printf(req->buffer_out, "Invalid filename.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_BADFILENAME); break; case ERROR_EXISTS: evbuffer_add_printf(req->buffer_out, "File already exists.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_EXISTS); break; case ERROR_SIZE: evbuffer_add_printf(req->buffer_out, "File size is too large.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_TOOLARGE); break; case ERROR_QUOTA: evbuffer_add_printf(req->buffer_out, "Out of quota.\n"); set_content_length_header (req); evhtp_send_reply (req, SEAF_HTTP_RES_NOQUOTA); break; case ERROR_RECV: case ERROR_INTERNAL: set_content_length_header (req); evhtp_send_reply (req, EVHTP_RES_SERVERR); break; } }