]> git.ipfire.org Git - pakfire.git/commitdiff
xfer: Implement an API response callback
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 24 Jun 2025 15:21:13 +0000 (15:21 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 24 Jun 2025 15:21:13 +0000 (15:21 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/xfer.c
src/pakfire/xfer.h

index 6eaa8d15059402f192d841c6b7bada1b616559c8..47e86b4edbeed9474d5df47da55ce2e48385c54c 100644 (file)
@@ -117,8 +117,17 @@ struct pakfire_xfer {
                pakfire_xfer_send_callback send;
                pakfire_xfer_close_callback close;
                void* data;
+
+               // Response
+               pakfire_xfer_response_callback response;
        } callbacks;
 
+       // Output Buffer
+       struct {
+               char* buffer;
+               size_t length;
+       } output;
+
        // WebSocket Receive Buffer
        struct pakfire_buffer recv_buffer;
 
@@ -156,6 +165,10 @@ static void pakfire_xfer_free(struct pakfire_xfer* xfer) {
        if (xfer->payload)
                free(xfer->payload);
 
+       // Output Buffer
+       if (xfer->output.buffer)
+               free(xfer->output.buffer);
+
        // cURL stuff
        if (xfer->handle)
                curl_easy_cleanup(xfer->handle);
@@ -754,6 +767,22 @@ int pakfire_xfer_set_output_buffer(struct pakfire_xfer* xfer,
        return pakfire_xfer_set_output(xfer, f);
 }
 
+int pakfire_xfer_set_response_callback(struct pakfire_xfer* self,
+               pakfire_xfer_response_callback callback, void* data) {
+       int r;
+
+       // Create an output buffer
+       r = pakfire_xfer_set_output_buffer(self, &self->output.buffer, &self->output.length);
+       if (r < 0)
+               return r;
+
+       // Set the callback
+       self->callbacks.response = callback;
+       self->callbacks.data     = data;
+
+       return 0;
+}
+
 int pakfire_xfer_set_input(struct pakfire_xfer* xfer, FILE* f) {
        struct stat stat;
        int r;
@@ -980,6 +1009,37 @@ ERROR:
        return r;
 }
 
+static int pakfire_xfer_call_response_callback(struct pakfire_xfer* self, pakfire_xfer_error_code_t code) {
+       struct json_object* response = NULL;
+       char* error = NULL;
+       int r;
+
+       // Parse the API response
+       switch (code) {
+               case PAKFIRE_XFER_OK:
+                       r = pakfire_json_parse(&response, &error, self->output.buffer, self->output.length);
+                       if (r < 0) {
+                               ERROR(self->ctx, "Failed to parse JSON response: %s\n", error);
+                               goto ERROR;
+                       }
+                       break;
+
+               default:
+                       break;
+       }
+
+       // Run the callback
+       r = self->callbacks.response(self, code, response, self->callbacks.data);
+
+ERROR:
+       if (response)
+               json_object_put(response);
+       if (error)
+               free(error);
+
+       return r;
+}
+
 static int pakfire_xfer_fail(struct pakfire_xfer* xfer, int code) {
        int r;
 
@@ -1034,6 +1094,13 @@ static int pakfire_xfer_fail(struct pakfire_xfer* xfer, int code) {
                }
        }
 
+       // Call the response callback
+       if (xfer->callbacks.response) {
+               r = pakfire_xfer_call_response_callback(xfer, code);
+               if (r < 0)
+                       return r;
+       }
+
        return code;
 }
 
@@ -1281,6 +1348,10 @@ static int pakfire_xfer_save(struct pakfire_xfer* xfer) {
        if (xfer->fin)
                fflush(xfer->fin);
 
+       // Call the output callback if configured
+       if (xfer->callbacks.response)
+               return pakfire_xfer_call_response_callback(xfer, PAKFIRE_XFER_OK);
+
        // Nothing to do if path isn't set
        if (!*xfer->path)
                return 0;
index 48e1b3eba396dc9e4251c331b087a0a849c0749d..ca6ad7107f87e70a666c524b6dc45599e9d5042d 100644 (file)
@@ -129,6 +129,12 @@ int pakfire_xfer_set_output(struct pakfire_xfer* xfer, FILE* f);
 int pakfire_xfer_set_output_buffer(struct pakfire_xfer* xfer, char** buffer, size_t* length);
 int pakfire_xfer_set_output_path(struct pakfire_xfer* xfer, const char* path);
 
+typedef int (*pakfire_xfer_response_callback)(struct pakfire_xfer* xfer,
+       pakfire_xfer_error_code_t status, json_object* response, void* data);
+
+int pakfire_xfer_set_response_callback(struct pakfire_xfer* xfer,
+       pakfire_xfer_response_callback callback, void* data);
+
 // Input
 int pakfire_xfer_set_input(struct pakfire_xfer* xfer, FILE* f);