From: Michael Tremer Date: Tue, 24 Jun 2025 15:21:13 +0000 (+0000) Subject: xfer: Implement an API response callback X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce8c2f4fca08e1809683952c48715d3d8b1ec787;p=pakfire.git xfer: Implement an API response callback Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/xfer.c b/src/pakfire/xfer.c index 6eaa8d15..47e86b4e 100644 --- a/src/pakfire/xfer.c +++ b/src/pakfire/xfer.c @@ -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; diff --git a/src/pakfire/xfer.h b/src/pakfire/xfer.h index 48e1b3eb..ca6ad710 100644 --- a/src/pakfire/xfer.h +++ b/src/pakfire/xfer.h @@ -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);