diff options
author | Haridass Selvaraj <haridasj@axis.com> | 2013-12-17 12:06:13 +0100 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2013-12-17 12:18:01 +0100 |
commit | 23ab7d8c4979bff05e37e2e4aff5a74da2b36c3a (patch) | |
tree | 4afc6da3586e92a6cc6bb1a1f0eb6c53a7a20caf /ext/curl | |
parent | 46b62c72d873fdaa51d7c69ad008962e00d3df0f (diff) | |
download | gstreamer-plugins-bad-23ab7d8c4979bff05e37e2e4aff5a74da2b36c3a.tar.gz |
curlftpsink: Optionally create a temporary file during FTP transfer/upload
https://bugzilla.gnome.org/show_bug.cgi?id=711620
Diffstat (limited to 'ext/curl')
-rw-r--r-- | ext/curl/gstcurlftpsink.c | 91 | ||||
-rw-r--r-- | ext/curl/gstcurlftpsink.h | 3 |
2 files changed, 91 insertions, 3 deletions
diff --git a/ext/curl/gstcurlftpsink.c b/ext/curl/gstcurlftpsink.c index de248f978..988e89926 100644 --- a/ext/curl/gstcurlftpsink.c +++ b/ext/curl/gstcurlftpsink.c @@ -65,7 +65,8 @@ /* Default values */ #define GST_CAT_DEFAULT gst_curl_ftp_sink_debug - +#define RENAME_TO "RNTO " +#define RENAME_FROM "RNFR " /* Plugin specific settings */ @@ -76,6 +77,8 @@ enum PROP_0, PROP_FTP_PORT_ARG, PROP_EPSV_MODE, + PROP_CREATE_TEMP_FILE, + PROP_CREATE_TEMP_FILE_NAME, PROP_CREATE_DIRS }; @@ -131,6 +134,18 @@ gst_curl_ftp_sink_class_init (GstCurlFtpSinkClass * klass) g_param_spec_boolean ("epsv-mode", "Extended passive mode", "Enable the use of the EPSV command when doing passive FTP transfers", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_CREATE_TEMP_FILE, + g_param_spec_boolean ("create-tmp-file", "Enable or disable temporary file transfer", + "Use a temporary file name when uploading a a file. When the transfer is complete, \ + this temporary file is renamed to the final file name. This is useful for ensuring \ + that remote systems do not read a partially uploaded file", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_CREATE_TEMP_FILE_NAME, + g_param_spec_string ("temp-file-name", "Creates a temporary file name with date and time", + "Filename pattern to use when generating a temporary filename for uploads", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_CREATE_DIRS, g_param_spec_boolean ("create-dirs", "Create missing directories", "Attempt to create missing directory included in the path", @@ -149,6 +164,12 @@ gst_curl_ftp_sink_finalize (GObject * gobject) GST_DEBUG ("finalizing curlftpsink"); g_free (this->ftp_port_arg); + g_free (this->tmpfile_name); + + if (this->headerlist) { + curl_slist_free_all (this->headerlist); + this->headerlist = NULL; + } G_OBJECT_CLASS (parent_class)->finalize (gobject); } @@ -156,9 +177,58 @@ gst_curl_ftp_sink_finalize (GObject * gobject) static gboolean set_ftp_dynamic_options_unlocked (GstCurlBaseSink * basesink) { - gchar *tmp = g_strdup_printf ("%s%s", basesink->url, basesink->file_name); + gchar *tmp = NULL; + GstCurlFtpSink *sink = GST_CURL_FTP_SINK (basesink); + + if(sink->tmpfile_create) { + gchar *rename_from = NULL; + gchar *rename_to = NULL; + gchar *uploadfile_as = NULL; + gchar *last_slash = NULL; + gchar *dir_name = NULL; + gchar *tmpfile_name = NULL; + + if (sink->headerlist != NULL) { + curl_slist_free_all (sink->headerlist); + sink->headerlist = NULL; + } + + if (sink->tmpfile_name != NULL) { + tmpfile_name = g_strdup_printf ("%s", sink->tmpfile_name); + } else { + tmpfile_name = g_strdup_printf (".tmp.%04X%04X", g_random_int (), g_random_int ()); + } - curl_easy_setopt (basesink->curl, CURLOPT_URL, tmp); + rename_from = g_strdup_printf ("%s%s", RENAME_FROM, tmpfile_name); + + last_slash = strrchr (basesink->file_name, '/'); + if (last_slash != NULL) { + dir_name = g_strndup (basesink->file_name, last_slash - basesink->file_name); + rename_to = g_strdup_printf ("%s%s", RENAME_TO, last_slash+1); + uploadfile_as = g_strdup_printf ("%s/%s", dir_name, tmpfile_name); + } else { + rename_to = g_strdup_printf ("%s%s", RENAME_TO, basesink->file_name); + uploadfile_as = g_strdup_printf ("%s", tmpfile_name); + } + + tmp = g_strdup_printf ("%s%s", basesink->url, uploadfile_as); + curl_easy_setopt (basesink->curl, CURLOPT_URL, tmp); + sink->headerlist = curl_slist_append (sink->headerlist, rename_from); + sink->headerlist = curl_slist_append (sink->headerlist, rename_to); + curl_easy_setopt (basesink->curl, CURLOPT_POSTQUOTE, sink->headerlist); + + g_free (rename_from); + g_free (rename_to); + g_free (uploadfile_as); + g_free (dir_name); + g_free (tmpfile_name); + if(last_slash != NULL) { + *last_slash = '\0'; + } + } else { + tmp = g_strdup_printf ("%s%s", basesink->url, basesink->file_name); + curl_easy_setopt (basesink->curl, CURLOPT_URL, tmp); + } g_free (tmp); @@ -230,6 +300,15 @@ gst_curl_ftp_sink_set_property (GObject * object, guint prop_id, sink->epsv_mode = g_value_get_boolean (value); GST_DEBUG_OBJECT (sink, "epsv-mode set to %d", sink->epsv_mode); break; + case PROP_CREATE_TEMP_FILE: + sink->tmpfile_create = g_value_get_boolean (value); + GST_DEBUG_OBJECT (sink, "create-tmp-file set to %d", sink->tmpfile_create); + break; + case PROP_CREATE_TEMP_FILE_NAME: + g_free (sink->tmpfile_name); + sink->tmpfile_name = g_value_dup_string (value); + GST_DEBUG_OBJECT (sink, "tmp-file-name set to %s", sink->tmpfile_name); + break; case PROP_CREATE_DIRS: sink->create_dirs = g_value_get_boolean (value); GST_DEBUG_OBJECT (sink, "create-dirs set to %d", sink->create_dirs); @@ -260,6 +339,12 @@ gst_curl_ftp_sink_get_property (GObject * object, guint prop_id, case PROP_EPSV_MODE: g_value_set_boolean (value, sink->epsv_mode); break; + case PROP_CREATE_TEMP_FILE: + g_value_set_boolean (value, sink->tmpfile_create); + break; + case PROP_CREATE_TEMP_FILE_NAME: + g_value_set_string (value, sink->tmpfile_name); + break; case PROP_CREATE_DIRS: g_value_set_boolean (value, sink->create_dirs); break; diff --git a/ext/curl/gstcurlftpsink.h b/ext/curl/gstcurlftpsink.h index 4cfc4b63d..95555eaa9 100644 --- a/ext/curl/gstcurlftpsink.h +++ b/ext/curl/gstcurlftpsink.h @@ -44,8 +44,11 @@ struct _GstCurlFtpSink GstCurlTlsSink parent; /*< private > */ + struct curl_slist *headerlist; gchar *ftp_port_arg; gboolean epsv_mode; + gboolean tmpfile_create; + gchar *tmpfile_name; gboolean create_dirs; }; |