From c13c9166e28716eeaef992e2f02b1936e1995b36 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Tue, 19 Aug 2025 10:17:27 -0400 Subject: [PATCH] MT#61977 add up/download capability to HTTP Change-Id: I50334482c9316aed5315ad5814ae54081856ef90 --- lib/http.c | 29 +++++++++++++++++++++++++++++ lib/http.h | 10 ++++++++++ recording-daemon/notify.c | 2 +- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/http.c b/lib/http.c index 7f4ba24b2..15f1b5cb9 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1,8 +1,12 @@ #include "http.h" +#include "log.h" +#include CURL *http_create_req(const char *uri, size_t (*write_fn)(char *, size_t, size_t, void *), + GString *download, size_t (*read_fn)(char *, size_t, size_t, void *), + http_upload *upload, const struct curl_slist *headers, bool tls_verify, CURLcode *errcode, @@ -23,10 +27,18 @@ CURL *http_create_req(const char *uri, if ((ret = curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, write_fn)) != CURLE_OK) goto fail; + err = "setting CURLOPT_WRITEDATA"; + if ((ret = curl_easy_setopt(c, CURLOPT_WRITEDATA, download)) != CURLE_OK) + goto fail; + err = "setting CURLOPT_READFUNCTION"; if ((ret = curl_easy_setopt(c, CURLOPT_READFUNCTION, read_fn)) != CURLE_OK) goto fail; + err = "setting CURLOPT_READDATA"; + if ((ret = curl_easy_setopt(c, CURLOPT_READDATA, upload)) != CURLE_OK) + goto fail; + /* allow redirects */ err = "setting CURLOPT_FOLLOWLOCATION"; if ((ret = curl_easy_setopt(c, CURLOPT_FOLLOWLOCATION, 1L)) != CURLE_OK) @@ -80,3 +92,20 @@ 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) { return 0; } + + +size_t http_upload_read(char *ptr, size_t size, size_t nmemb, void *userdata) { + http_upload *u = userdata; + assert(size == 1); // as per docs + size_t len = MIN(nmemb, u->s.len); + memcpy(ptr, u->s.s, len); + str_shift(&u->s, len); + return len; +} + +size_t http_download_write(char *ptr, size_t size, size_t nmemb, void *userdata) { + assert(size == 1); // as per docs + GString *s = userdata; + g_string_append_len(s, ptr, nmemb); + return nmemb; +} diff --git a/lib/http.h b/lib/http.h index 2f1af743b..436f9af82 100644 --- a/lib/http.h +++ b/lib/http.h @@ -1,14 +1,21 @@ #ifndef _HTTP_H_ #define _HTTP_H_ +#include "str.h" #include #include #include +typedef struct { + str s; +} http_upload; + CURL *http_create_req(const char *uri, size_t (*write_fn)(char *, size_t, size_t, void *), + GString *, size_t (*read_fn)(char *, size_t, size_t, void *), + http_upload *, const struct curl_slist *headers, bool tls_verify, CURLcode *errcode, @@ -21,6 +28,9 @@ 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); +size_t http_download_write(char *ptr, size_t size, size_t nmemb, void *userdata); +size_t http_upload_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) diff --git a/recording-daemon/notify.c b/recording-daemon/notify.c index 30df1046c..75f190f33 100644 --- a/recording-daemon/notify.c +++ b/recording-daemon/notify.c @@ -27,7 +27,7 @@ static bool do_notify_http(notif_req_t *req) { #endif g_autoptr(CURL) c = http_create_req(notify_uri, - http_dummy_write, http_dummy_read, + http_dummy_write, NULL, http_dummy_read, NULL, req->headers, !notify_nverify, &ret, &err); if (!c) goto fail;