From 74bc521eab1538924667e3a6a0e9470e6161634b Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 15 Aug 2025 13:50:27 -0400 Subject: [PATCH] MT#61977 use _get_content for notifications Use the new _get_content function to provide the notification content to cURL in memory instead of making it read a file. This makes it possible to use it together with DB storage. This also relieves the notification poster from deleting the file if the "purge" option is set, making it possible to simply roll it into file output being disabled. Retain legacy support for the "purge" option. Change-Id: Ia1d59018d79777759de894aba1d888c927e5ba00 --- docs/rtpengine-recording.md | 15 ++++++++------- recording-daemon/main.c | 5 ++++- recording-daemon/main.h | 1 - recording-daemon/notify.c | 19 ++++++++++--------- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/docs/rtpengine-recording.md b/docs/rtpengine-recording.md index eb1ff28ac..59e5a2034 100644 --- a/docs/rtpengine-recording.md +++ b/docs/rtpengine-recording.md @@ -155,7 +155,9 @@ sufficient for a standard installation of rtpengine. The string __both__ is recognised as legacy alternative to enabling both __file__ and __db__ storage. - __notify__ is an alias for enabling the __notify-record__ option, see below. + The __notify__ output attaches the recording to the HTTP notification + request. If enabled, notification requests behave as HTTP POST (implicitly + enabling __notify-post__). The string __memory__ acts as a modifier and can be used if __file__ storage is not enabled. Without the __memory__ modifier, media is first written @@ -389,15 +391,14 @@ sufficient for a standard installation of rtpengine. - __\-\-notify-record__ - Attach recorded file to HTTP notification request. If enabled, notification - request behaves as HTTP POST (ignoring __\-\-notify-post__). Note that this option - is incompatible with DB-only storage as no recording file exists on storage - (see __output-storage__). + Legacy alias for __output-storage=notify__. If no other output storage is + enabled, then the default __file__ storage remains enabled (unless the + following option is also set). - __\-\-notify-purge__ - Remove the local file if the HTTP request was successful. Note that this - option is only useful if __\-\-notify-record__ is also enabled. + Legacy option to disable the default file storage when notification output + is enabled. - __\-\-output-mixed-per-media__ diff --git a/recording-daemon/main.c b/recording-daemon/main.c index 25347e466..9139b2d29 100644 --- a/recording-daemon/main.c +++ b/recording-daemon/main.c @@ -67,7 +67,6 @@ gboolean notify_nverify; int notify_threads = 5; int notify_retries = 10; char *notify_command; -gboolean notify_purge; gboolean mix_output_per_media = 0; gboolean flush_packets = 0; int resample_audio; @@ -197,6 +196,7 @@ static void options(int *argc, char ***argv) { g_autoptr(char) tcp_send_to = NULL; gboolean notify_record = FALSE; bool no_output_allowed = false; + gboolean notify_purge = false; GOptionEntry e[] = { { "table", 't', 0, G_OPTION_ARG_INT, &ktable, "Kernel table rtpengine uses", "INT" }, @@ -329,6 +329,9 @@ static void options(int *argc, char ***argv) { if ((output_storage & OUTPUT_STORAGE_MASK) || tls_send_to_ep.port) decoding_enabled = true; + if (notify_purge && (output_storage & OUTPUT_STORAGE_FILE)) + output_storage &= ~OUTPUT_STORAGE_FILE; + if (!mix_method_str || !mix_method_str[0] || !strcmp(mix_method_str, "direct")) mix_method = MM_DIRECT; else if (!strcmp(mix_method_str, "channels")) diff --git a/recording-daemon/main.h b/recording-daemon/main.h index 9b7bc4809..9dab3da64 100644 --- a/recording-daemon/main.h +++ b/recording-daemon/main.h @@ -54,7 +54,6 @@ extern gboolean notify_nverify; extern int notify_threads; extern int notify_retries; extern char *notify_command; -extern gboolean notify_purge; extern gboolean mix_output_per_media; extern volatile int shutdown_flag; extern gboolean flush_packets; diff --git a/recording-daemon/notify.c b/recording-daemon/notify.c index 6975dd149..bcf67e485 100644 --- a/recording-daemon/notify.c +++ b/recording-daemon/notify.c @@ -4,12 +4,14 @@ #include "main.h" #include "log.h" #include "recaux.h" +#include "output.h" struct notif_req { char *name; // just for logging struct curl_slist *headers; // NULL = nothing to send char *full_filename_path; + GString *content; unsigned long long db_id; char **argv; @@ -98,7 +100,7 @@ static bool do_notify_http(struct notif_req *req) { } #if CURL_AT_LEAST_VERSION(7,56,0) - if ((output_storage & OUTPUT_STORAGE_NOTIFY) && req->full_filename_path) { + if (req->content) { err = "initializing curl mime&part"; curl_mimepart *part; mime = curl_mime_init(c); @@ -107,7 +109,7 @@ static bool do_notify_http(struct notif_req *req) { if ((ret = curl_mime_name(part, "ngfile")) != CURLE_OK) goto fail; - if ((ret = curl_mime_filedata(part, req->full_filename_path)) != CURLE_OK) + if ((ret = curl_mime_data(part, req->content->str, req->content->len)) != CURLE_OK) goto fail; if ((ret = curl_easy_setopt(c, CURLOPT_MIMEPOST, mime)) != CURLE_OK) @@ -134,13 +136,6 @@ static bool do_notify_http(struct notif_req *req) { ilog(LOG_NOTICE, "HTTP notification for '%s%s%s' was successful", FMT_M(req->name)); - if ((output_storage & OUTPUT_STORAGE_NOTIFY) && notify_purge && req->full_filename_path) { - if (unlink(req->full_filename_path) == 0) - ilog(LOG_NOTICE, "File '%s%s%s' deleted successfully.", FMT_M(req->full_filename_path)); - else - ilog(LOG_ERR, "File '%s%s%s' could not be deleted.", FMT_M(req->full_filename_path)); - } - curl_slist_free_all(req->headers); req->headers = NULL; @@ -232,6 +227,8 @@ static void do_notify(void *p, void *u) { g_strfreev(req->argv); g_free(req->name); g_free(req->full_filename_path); + if (req->content) + g_string_free(req->content, TRUE); g_free(req); } @@ -381,6 +378,10 @@ void notify_push_output(output_t *o, metafile_t *mf, tag_t *tag) { req->name = g_strdup(o->file_name); if ((output_storage & OUTPUT_STORAGE_FILE)) req->full_filename_path = g_strdup_printf("%s.%s", o->full_filename, o->file_format); + if ((output_storage & OUTPUT_STORAGE_NOTIFY)) { + req->content = output_get_content(o); + o->content = NULL; // take over ownership + } req->db_id = o->db_id; notify_req_setup_http(req, o, mf, tag);