static void hev_scgi_handler_filebox_handle (HevSCGIHandler *self, GObject *scgi_task) { HevSCGIHandlerFileboxPrivate *priv = HEV_SCGI_HANDLER_FILEBOX_GET_PRIVATE(self); GObject *request = NULL; GHashTable *req_hash_table = NULL; gchar *request_uri = NULL; gsize request_uri_len; g_debug("%s:%d[%s]", __FILE__, __LINE__, __FUNCTION__); request = hev_scgi_task_get_request (HEV_SCGI_TASK (scgi_task)); req_hash_table = hev_scgi_request_get_header_hash_table (HEV_SCGI_REQUEST (request)); request_uri = g_hash_table_lookup (req_hash_table, "REQUEST_URI"); request_uri_len = strlen (request_uri); request_uri += (priv->base_uri_len > request_uri_len) ? request_uri_len : priv->base_uri_len; if (g_regex_match_simple ("^upload$", request_uri, 0, 0)) { /* uploader */ hev_scgi_handler_filebox_handle_upload (self, scgi_task); } else if (g_regex_match_simple ("^query\\?(.+)$", request_uri, 0, 0)) { /* querier */ hev_scgi_handler_filebox_handle_query (self, scgi_task); } else if (g_regex_match_simple ("^delete\\?(.+)$", request_uri, 0, 0)) { /* deleter */ hev_scgi_handler_filebox_handle_delete (self, scgi_task); } else { /* downloader */ hev_scgi_handler_filebox_handle_download (self, scgi_task); } }
void hev_scgi_task_dispatcher_push(HevSCGITaskDispatcher *self, GObject *scgi_task) { HevSCGITaskDispatcherPrivate * priv = HEV_SCGI_TASK_DISPATCHER_GET_PRIVATE(self); GObject *scgi_request = NULL; HevClosure0 *closure = NULL; g_debug("%s:%d[%s]", __FILE__, __LINE__, __FUNCTION__); closure = g_slice_new(HevClosure0); closure->task = scgi_task; closure->dispatcher = self; scgi_request = hev_scgi_task_get_request(HEV_SCGI_TASK(scgi_task)); _hev_scgi_request_read_header_async(HEV_SCGI_REQUEST(scgi_request), NULL, hev_scgi_request_read_header_async_handler, closure); }
static void hev_scgi_task_dispatcher_dispatch(HevSCGITaskDispatcher *self, GObject *scgi_task) { HevSCGITaskDispatcherPrivate * priv = HEV_SCGI_TASK_DISPATCHER_GET_PRIVATE(self); GObject *scgi_request = NULL; GHashTable *header_hash_table = NULL; gchar *request_uri = NULL; GSList *sl = NULL; g_debug("%s:%d[%s]", __FILE__, __LINE__, __FUNCTION__); scgi_request = hev_scgi_task_get_request(HEV_SCGI_TASK(scgi_task)); header_hash_table = hev_scgi_request_get_header_hash_table( HEV_SCGI_REQUEST(scgi_request)); request_uri = g_hash_table_lookup(header_hash_table, "REQUEST_URI"); if(!request_uri) { g_object_unref(scgi_task); return; } for(sl=priv->handler_slist; sl; sl=g_slist_next(sl)) { const gchar *pattern = NULL; pattern = hev_scgi_handler_get_pattern(HEV_SCGI_HANDLER_CAST(sl->data)); if(g_regex_match_simple(pattern, request_uri, 0, 0)) { _hev_scgi_task_set_handler(HEV_SCGI_TASK(scgi_task), G_OBJECT(sl->data)); hev_scgi_handler_handle(HEV_SCGI_HANDLER_CAST(sl->data), scgi_task); break; } } g_object_unref(scgi_task); }
static void hev_scgi_handler_cgi_handle(HevSCGIHandler *handler, GObject *scgi_task) { HevSCGIHandlerCGI *self = HEV_SCGI_HANDLER_CGI(handler); HevSCGIHandlerCGIPrivate *priv = HEV_SCGI_HANDLER_CGI_GET_PRIVATE(self); HevSCGIHandlerCGITaskData *task_data = NULL; gchar *str = NULL, **argv = NULL, *workdir = NULL; GPid pid = 0; GError *error = NULL; GObject *connection = NULL; GSocket *socket = NULL; g_debug("%s:%d[%s]", __FILE__, __LINE__, __FUNCTION__); task_data = g_slice_new0(HevSCGIHandlerCGITaskData); if(!task_data) { g_critical("%s:%d[%s]", __FILE__, __LINE__, __FUNCTION__); return; } connection = hev_scgi_task_get_socket_connection(HEV_SCGI_TASK(scgi_task)); socket = g_socket_connection_get_socket(G_SOCKET_CONNECTION(connection)); task_data->fd = g_socket_get_fd(socket); task_data->scgi_task = scgi_task; task_data->scgi_request = hev_scgi_task_get_request(HEV_SCGI_TASK(scgi_task)); task_data->scgi_response = hev_scgi_task_get_response(HEV_SCGI_TASK(scgi_task)); task_data->req_hash_table = hev_scgi_request_get_header_hash_table(HEV_SCGI_REQUEST(task_data->scgi_request)); task_data->envp = g_malloc0_n(g_hash_table_size(task_data->req_hash_table)+1, sizeof(gchar *)); g_hash_table_foreach(task_data->req_hash_table, req_hash_table_foreach_handler, task_data); /* Script file and Work dir */ str = g_hash_table_lookup(task_data->req_hash_table, "SCRIPT_FILE"); argv = g_malloc0_n(2, sizeof(gchar *)); if(str) { argv[0] = g_strdup(str); workdir = g_path_get_dirname(str); } else { argv[0] = g_key_file_get_string(priv->config, "Module", "CGIBinPath", NULL); workdir = g_key_file_get_string(priv->config, "Module", "WorkDir", NULL); if(NULL == argv[0]) argv[0] = g_strdup(HEV_SCGI_HANDLER_CGI_BIN_PATH); if(NULL == workdir) workdir = g_strdup(HEV_SCGI_HANDLER_CGI_WORK_DIR); } #ifdef G_OS_UNIX /* User and Group */ str = g_hash_table_lookup(task_data->req_hash_table, "_USER"); if(str) task_data->user = g_strdup(str); else task_data->user = g_key_file_get_string(priv->config, "Module", "User", NULL); str = g_hash_table_lookup(task_data->req_hash_table, "_GROUP"); if(str) task_data->group = g_strdup(str); else task_data->group = g_key_file_get_string(priv->config, "Module", "Group", NULL); #endif /* G_OS_UNIX */ if(g_spawn_async(workdir, argv, task_data->envp, G_SPAWN_DO_NOT_REAP_CHILD, hev_scgi_handler_spawn_child_setup_handler, task_data, &pid, &error)) { g_object_ref(scgi_task); g_child_watch_add(pid, hev_scgi_handler_child_watch_handler, task_data); } else { g_critical("%s:%d[%s]=>(%s)", __FILE__, __LINE__, __FUNCTION__, error->message); g_error_free(error); } g_strfreev(argv); g_free(workdir); }
static void file_ptr_array_foreach_write_meta_handler (gpointer data, gpointer user_data) { GFile *file = G_FILE (data), *meta_file = NULL; GObject *scgi_task = G_OBJECT (user_data); GObject *request = NULL; GHashTable *req_htb = NULL; gchar *duration = NULL, *one_off = NULL, *rand_pass = NULL; GKeyFile *meta = NULL; GDateTime *crt_time = NULL, *exp_time = NULL; GFileOutputStream *file_ostream = NULL; guint64 dur = 0; g_debug ("%s:%d[%s]", __FILE__, __LINE__, __FUNCTION__); request = hev_scgi_task_get_request (HEV_SCGI_TASK (scgi_task)); req_htb = hev_scgi_request_get_header_hash_table (HEV_SCGI_REQUEST (request)); duration = g_object_get_data (scgi_task, "duration"); one_off = g_object_get_data (scgi_task, "one-off"); rand_pass = g_object_get_data (scgi_task, "rand-pass"); meta_file = g_object_get_data (G_OBJECT (file), "meta"); g_file_delete (meta_file, NULL, NULL); meta = g_key_file_new (); /* set meta contents */ crt_time = g_date_time_new_now_utc (); g_key_file_set_int64 (meta, "Meta", "CrtDate", g_date_time_to_unix (crt_time)); if (duration) { dur = g_ascii_strtoull (duration, NULL, 10); if ((0 >= dur) || (7 < dur)) dur = 1; } else { dur = 1; } exp_time = g_date_time_add_days (crt_time, dur); g_key_file_set_int64 (meta, "Meta", "ExpDate", g_date_time_to_unix (exp_time)); g_date_time_unref (exp_time); g_date_time_unref (crt_time); g_key_file_set_boolean (meta, "Meta", "OneOff", one_off ? TRUE : FALSE); g_key_file_set_string (meta, "Meta", "IP", g_hash_table_lookup (req_htb, "REMOTE_ADDR")); g_key_file_set_string (meta, "Meta", "RandPass", rand_pass); /* create and write to meta file */ file_ostream = g_file_create (meta_file, G_FILE_CREATE_PRIVATE, NULL, NULL); if (file_ostream) { gchar *data = NULL; gsize length = 0; data = g_key_file_to_data (meta, &length, NULL); g_output_stream_write_all (G_OUTPUT_STREAM (file_ostream), data, length, NULL, NULL, NULL); g_free (data); g_object_unref (file_ostream); } g_key_file_unref (meta); }
static void filebox_uploader_handle_task_handler (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { HevFileboxUploader *self = HEV_FILEBOX_UPLOADER (source_object); HevFileboxUploaderPrivate *priv = HEV_FILEBOX_UPLOADER_GET_PRIVATE (self); GObject *scgi_task = task_data; gboolean status = TRUE; GObject *request = NULL; GInputStream *req_stream = NULL; GHashTable *req_htb = NULL; GObject *response = NULL; GOutputStream *res_stream = NULL; GHashTable *res_htb = NULL; const gchar *content_type = NULL, *content_length = NULL; GRegex *regex = NULL; GMatchInfo *match_info = NULL; gchar rand_pass[16], *boundary = NULL, *fp_path = NULL, *fm_path = NULL, *ft_path = NULL; gint rand_pass_len; guint64 length = 0; GFile *file_tmp = NULL; g_debug ("%s:%d[%s]", __FILE__, __LINE__, __FUNCTION__); request = hev_scgi_task_get_request (HEV_SCGI_TASK (scgi_task)); req_stream = hev_scgi_request_get_input_stream (HEV_SCGI_REQUEST (request)); req_htb = hev_scgi_request_get_header_hash_table (HEV_SCGI_REQUEST (request)); response = hev_scgi_task_get_response (HEV_SCGI_TASK (scgi_task)); res_stream = hev_scgi_response_get_output_stream (HEV_SCGI_RESPONSE (response)); res_htb = hev_scgi_response_get_header_hash_table (HEV_SCGI_RESPONSE (response)); content_type = g_hash_table_lookup (req_htb, "CONTENT_TYPE"); content_length = g_hash_table_lookup (req_htb, "CONTENT_LENGTH"); /* get boundary string from content type */ regex = g_regex_new ("^multipart/form-data;\\s*boundary=(.+)$", 0, 0, NULL); if (!g_regex_match (regex, content_type, 0, &match_info)) { g_hash_table_insert (res_htb, g_strdup ("Status"), g_strdup ("400 Bad Request")); hev_scgi_response_write_header (HEV_SCGI_RESPONSE (response), NULL); g_regex_unref (regex); g_task_return_boolean (task, FALSE); return; } boundary = g_match_info_fetch (match_info, 1); g_match_info_unref (match_info); g_regex_unref (regex); fp_path = g_key_file_get_string (priv->config, "Module", "FilePoolPath", NULL); fm_path = g_key_file_get_string (priv->config, "Module", "FileMetaPath", NULL); ft_path = g_key_file_get_string (priv->config, "Module", "FileTempPath", NULL); length = g_ascii_strtoull (content_length, NULL, 10); rand_pass_len = g_snprintf (rand_pass, 16, "%u", g_random_int_range (99999, 999999)); g_object_set_data (scgi_task, "rand-pass", rand_pass); /* create tmp file */ file_tmp = filebox_uploader_handle_task_create_tmp (self, scgi_task, req_stream, req_htb, res_htb, ft_path, length); if (file_tmp) { gchar *path = NULL; GMappedFile *mapped_file = NULL; path = g_file_get_path (file_tmp); mapped_file = g_mapped_file_new (path, FALSE, NULL); g_free (path); if (mapped_file) { GPtrArray *files = NULL; gchar *duration = NULL, *one_off = NULL; /* split files from tmp file */ files = filebox_uploader_handle_task_split_tmp (self, scgi_task, mapped_file, res_htb, fp_path, fm_path, boundary, &duration, &one_off); if (files) { /* write meta files */ g_object_set_data (scgi_task, "duration", duration); g_object_set_data (scgi_task, "one-off", one_off); g_ptr_array_foreach (files, file_ptr_array_foreach_write_meta_handler, scgi_task); g_ptr_array_unref (files); } g_free (duration); g_free (one_off); g_mapped_file_unref (mapped_file); } g_file_delete (file_tmp, NULL, NULL); g_object_unref (file_tmp); } g_free (boundary); g_free (fp_path); g_free (fm_path); g_free (ft_path); if (!g_hash_table_contains (res_htb, "Status")) g_hash_table_insert (res_htb, g_strdup ("Status"), g_strdup ("200 OK")); hev_scgi_response_write_header (HEV_SCGI_RESPONSE (response), NULL); g_output_stream_write_all (res_stream, rand_pass, rand_pass_len, NULL, NULL, NULL); g_task_return_boolean (task, status); }