]> git.ipfire.org Git - pakfire.git/commitdiff
downloader: Add support for POST request parameters
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 18 Oct 2023 09:49:48 +0000 (09:49 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 18 Oct 2023 09:49:48 +0000 (09:49 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/downloader.c
src/libpakfire/include/pakfire/downloader.h

index e08657c562ebc374c996684618b2ca11591492a3..f0a51563706d46cf4a0e3f5b18fe80028cc3e369 100644 (file)
@@ -67,6 +67,9 @@ struct pakfire_transfer {
        enum pakfire_transfer_flags flags;
        int tries;
 
+       // POST MIME Object
+       curl_mime* mime;
+
        // Size
        size_t expected_size;
        size_t transferred;
@@ -146,6 +149,8 @@ static void pakfire_downloader_transfer_free(struct pakfire_transfer* transfer)
        if (transfer->evp)
                EVP_MD_CTX_free(transfer->evp);
 
+       if (transfer->mime)
+               curl_mime_free(transfer->mime);
        if (transfer->fullurl)
                curl_url_cleanup(transfer->fullurl);
 
@@ -530,6 +535,66 @@ int pakfire_downloader_transfer_verify_digest(
        return 0;
 }
 
+int pakfire_downloader_transfer_add_param(struct pakfire_transfer* transfer,
+               const char* key, const char* format, ...) {
+       curl_mimepart* part = NULL;
+       char* buffer = NULL;
+       va_list args;
+       int r;
+
+       // Allocate the MIME object if not done, yet
+       if (!transfer->mime) {
+               transfer->mime = curl_mime_init(transfer->handle);
+
+               if (!transfer->mime) {
+                       CTX_ERROR(transfer->ctx, "Could not allocate the MIME object: %s\n",
+                               strerror(errno));
+                       r = -errno;
+                       goto ERROR;
+               }
+       }
+
+       // Format value
+       va_start(args, format);
+       r = vasprintf(&buffer, format, args);
+       va_end(args);
+
+       // Abort if we could not format the value
+       if (r < 0)
+               goto ERROR;
+
+       // Allocate another MIME part
+       part = curl_mime_addpart(transfer->mime);
+       if (!part) {
+               CTX_ERROR(transfer->ctx, "Could not allocate MIME part: %s\n",
+                       strerror(errno));
+               r = errno;
+               goto ERROR;
+       }
+
+       // Set the key
+       r = curl_mime_name(part, key);
+       if (r) {
+               CTX_ERROR(transfer->ctx, "Could not set parameter key (%s): %s\n",
+                       key, curl_easy_strerror(r));
+               goto ERROR;
+       }
+
+       // Set the data
+       r = curl_mime_data(part, buffer, CURL_ZERO_TERMINATED);
+       if (r) {
+               CTX_ERROR(transfer->ctx, "Could not set parameter data (%s): %s\n",
+                       key, curl_easy_strerror(r));
+               goto ERROR;
+       }
+
+ERROR:
+       if (buffer)
+               free(buffer);
+
+       return r;
+}
+
 int pakfire_downloader_transfer_set_output(struct pakfire_transfer* transfer, FILE* f) {
        transfer->f = f;
 
@@ -976,6 +1041,15 @@ static int pakfire_downloader_transfer_prepare(struct pakfire_downloader* downlo
                return r;
        }
 
+       // Add any payload
+       if (transfer->mime) {
+               r = curl_easy_setopt(transfer->handle, CURLOPT_MIMEPOST, transfer->mime);
+               if (r) {
+                       CTX_ERROR(transfer->ctx, "Could not set POST payload: %s\n", curl_easy_strerror(r));
+                       return r;
+               }
+       }
+
        // If we do not have an output file, we will create a temporary file
        if (!transfer->f) {
                r = pakfire_downloader_transfer_prepare_tmpfile(transfer);
index fdec8ecd2de919199ce556506290dad73fe84129..93d140f2cafee40ff88a076aa4778a1496dbc7f4 100644 (file)
@@ -57,6 +57,8 @@ int pakfire_downloader_transfer_set_size(
 int pakfire_downloader_transfer_verify_digest(
        struct pakfire_transfer* transfer, const enum pakfire_digest_types md,
        const unsigned char* expected_digest, const size_t expected_digest_length);
+int pakfire_downloader_transfer_add_param(struct pakfire_transfer* transfer,
+       const char* key, const char* format, ...) __attribute__((format(printf, 3, 4)));
 int pakfire_downloader_transfer_set_output(struct pakfire_transfer* transfer, FILE* f);
 int pakfire_downloader_transfer_set_target(struct pakfire_transfer* transfer, const char* path);