Browse Source

MT#61977 add http/curl wrappers

Change-Id: Iefa4f0acfadabae38ff1da4c20dda51718f9580f
pull/1998/head
Richard Fuchs 4 months ago
parent
commit
453ede0913
4 changed files with 128 additions and 80 deletions
  1. +82
    -0
      lib/http.c
  2. +31
    -0
      lib/http.h
  3. +1
    -1
      recording-daemon/Makefile
  4. +14
    -79
      recording-daemon/notify.c

+ 82
- 0
lib/http.c View File

@ -0,0 +1,82 @@
#include "http.h"
CURL *http_create_req(const char *uri,
size_t (*write_fn)(char *, size_t, size_t, void *),
size_t (*read_fn)(char *, size_t, size_t, void *),
const struct curl_slist *headers,
bool tls_verify,
CURLcode *errcode,
const char **errmsg)
{
CURLcode ret = CURLE_FAILED_INIT;
const char *err = "failed to create cURL object";
g_autoptr(CURL) c = curl_easy_init();
if (!c)
goto fail;
err = "setting CURLOPT_URL";
if ((ret = curl_easy_setopt(c, CURLOPT_URL, uri)) != CURLE_OK)
goto fail;
err = "setting CURLOPT_WRITEFUNCTION";
if ((ret = curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, write_fn)) != CURLE_OK)
goto fail;
err = "setting CURLOPT_READFUNCTION";
if ((ret = curl_easy_setopt(c, CURLOPT_READFUNCTION, read_fn)) != CURLE_OK)
goto fail;
/* allow redirects */
err = "setting CURLOPT_FOLLOWLOCATION";
if ((ret = curl_easy_setopt(c, CURLOPT_FOLLOWLOCATION, 1L)) != CURLE_OK)
goto fail;
/* max 5 redirects */
err = "setting CURLOPT_MAXREDIRS";
if ((ret = curl_easy_setopt(c, CURLOPT_MAXREDIRS, 5L)) != CURLE_OK)
goto fail;
/* add headers */
err = "setting CURLOPT_HTTPHEADER";
if ((ret = curl_easy_setopt(c, CURLOPT_HTTPHEADER, headers)) != CURLE_OK)
goto fail;
/* cert verify (enabled by default) */
if (!tls_verify) {
err = "setting CURLOPT_SSL_VERIFYPEER";
if ((ret = curl_easy_setopt(c, CURLOPT_SSL_VERIFYPEER, 0L)) != CURLE_OK)
goto fail;
}
// all ok
*errmsg = NULL;
*errcode = CURLE_OK;
CURL *o = c;
c = NULL; // prevent auto cleanup
return o;
fail:
*errmsg = err;
*errcode = ret;
return NULL;
}
void http_add_header(struct curl_slist **hdrs, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
char *s = g_strdup_vprintf(fmt, ap);
*hdrs = curl_slist_append(*hdrs, s);
g_free(s);
va_end(ap);
}
size_t http_dummy_write(char *ptr, size_t size, size_t nmemb, void *userdata) {
return size * nmemb;
}
size_t http_dummy_read(char *ptr, size_t size, size_t nmemb, void *userdata) {
return 0;
}

+ 31
- 0
lib/http.h View File

@ -0,0 +1,31 @@
#ifndef _HTTP_H_
#define _HTTP_H_
#include <curl/curl.h>
#include <stdbool.h>
#include <glib.h>
CURL *http_create_req(const char *uri,
size_t (*write_fn)(char *, size_t, size_t, void *),
size_t (*read_fn)(char *, size_t, size_t, void *),
const struct curl_slist *headers,
bool tls_verify,
CURLcode *errcode,
const char **errmsg);
__attribute__ ((format (printf, 2, 3)))
void http_add_header(struct curl_slist **, const char *fmt, ...);
size_t http_dummy_write(char *ptr, size_t size, size_t nmemb, void *userdata);
size_t http_dummy_read(char *ptr, size_t size, size_t nmemb, void *userdata);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(CURL, curl_easy_cleanup)
#if CURL_AT_LEAST_VERSION(7,56,0)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(curl_mime, curl_mime_free)
#endif
#endif

+ 1
- 1
recording-daemon/Makefile View File

@ -50,7 +50,7 @@ CFLAGS+= -DCUSTOM_POLLER
SRCS= epoll.c garbage.c inotify.c main.c metafile.c stream.c recaux.c packet.c \
decoder.c output.c mix.c db.c log.c forward.c tag.c custom_poller.c notify.c tls_send.c
LIBSRCS= loglib.c auxlib.c rtplib.c codeclib.strhash.c resample.c str.c socket.c streambuf.c ssllib.c \
dtmflib.c bufferpool.c bencode.c
dtmflib.c bufferpool.c bencode.c http.c
LIBASM= mvr2s_x64_avx2.S mvr2s_x64_avx512.S mix_in_x64_avx2.S mix_in_x64_avx512bw.S mix_in_x64_sse2.S
MDS= rtpengine-recording.ronn


+ 14
- 79
recording-daemon/notify.c View File

@ -5,6 +5,7 @@
#include "log.h"
#include "recaux.h"
#include "output.h"
#include "http.h"
static GThreadPool *notify_threadpool;
@ -15,56 +16,20 @@ static pthread_t notify_waiter;
static GTree *notify_timers;
static size_t dummy_write(char *ptr, size_t size, size_t nmemb, void *userdata) {
return size * nmemb;
}
static size_t dummy_read(char *ptr, size_t size, size_t nmemb, void *userdata) {
return 0;
}
static bool do_notify_http(notif_req_t *req) {
const char *err = NULL;
CURLcode ret;
bool success = false;
ilog(LOG_DEBUG, "Launching HTTP notification for '%s%s%s'", FMT_M(req->name));
/* set up the CURL request */
#if CURL_AT_LEAST_VERSION(7,56,0)
curl_mime *mime = NULL;
g_autoptr(curl_mime) mime = NULL;
#endif
CURL *c = curl_easy_init();
if (!c)
goto fail;
err = "setting CURLOPT_URL";
if ((ret = curl_easy_setopt(c, CURLOPT_URL, notify_uri)) != CURLE_OK)
goto fail;
/* no output */
err = "setting CURLOPT_WRITEFUNCTION";
if ((ret = curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, dummy_write)) != CURLE_OK)
goto fail;
/* no input */
err = "setting CURLOPT_READFUNCTION";
if ((ret = curl_easy_setopt(c, CURLOPT_READFUNCTION, dummy_read)) != CURLE_OK)
goto fail;
/* allow redirects */
err = "setting CURLOPT_FOLLOWLOCATION";
if ((ret = curl_easy_setopt(c, CURLOPT_FOLLOWLOCATION, 1L)) != CURLE_OK)
goto fail;
/* max 5 redirects */
err = "setting CURLOPT_MAXREDIRS";
if ((ret = curl_easy_setopt(c, CURLOPT_MAXREDIRS, 5L)) != CURLE_OK)
goto fail;
/* add headers */
err = "setting CURLOPT_HTTPHEADER";
if ((ret = curl_easy_setopt(c, CURLOPT_HTTPHEADER, req->headers)) != CURLE_OK)
g_autoptr(CURL) c = http_create_req(notify_uri,
http_dummy_write, http_dummy_read,
req->headers, !notify_nverify, &ret, &err);
if (!c)
goto fail;
/* POST vs GET */
@ -74,13 +39,6 @@ static bool do_notify_http(notif_req_t *req) {
goto fail;
}
/* cert verify (enabled by default) */
if (notify_nverify) {
err = "setting CURLOPT_SSL_VERIFYPEER";
if ((ret = curl_easy_setopt(c, CURLOPT_SSL_VERIFYPEER, 0L)) != CURLE_OK)
goto fail;
}
#if CURL_AT_LEAST_VERSION(7,56,0)
if (req->content) {
err = "initializing curl mime&part";
@ -114,33 +72,17 @@ static bool do_notify_http(notif_req_t *req) {
/* success */
success = true;
ilog(LOG_NOTICE, "HTTP notification for '%s%s%s' was successful", FMT_M(req->name));
goto cleanup;
return true;
fail:
if (c)
ilog(LOG_ERR, "Failed to perform HTTP notification for '%s%s%s': "
"Error while %s: %s",
FMT_M(req->name),
err, curl_easy_strerror(ret));
else
ilog(LOG_ERR, "Failed to perform HTTP notification for '%s%s%s': "
"Failed to create CURL object",
FMT_M(req->name));
ilog(LOG_ERR, "Failed to perform HTTP notification for '%s%s%s': "
"Error while %s: %s",
FMT_M(req->name),
err, curl_easy_strerror(ret));
cleanup:
if (c)
curl_easy_cleanup(c);
#if CURL_AT_LEAST_VERSION(7,56,0)
if (mime)
curl_mime_free(mime);
#endif
return success;
return false;
}
static void failed_http(notif_req_t *req) {
@ -289,15 +231,8 @@ void notify_cleanup(void) {
__attribute__ ((format (printf, 2, 3)))
static void notify_add_header(notif_req_t *req, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
char *s = g_strdup_vprintf(fmt, ap);
req->headers = curl_slist_append(req->headers, s);
g_free(s);
va_end(ap);
}
#define notify_add_header(req, f, ...) http_add_header(&(req)->headers, f, __VA_ARGS__)
static void notify_req_setup_http(notif_req_t *req, output_t *o, metafile_t *mf, tag_t *tag) {
double now = (double) now_us() / 1000000.;


Loading…
Cancel
Save