On 9/4/25 14:10, Stefan Kober wrote: > This allows users to call API endpoints that require passing data in a > generic way. Previously, only virCHMonitorPutNoContent was offered. > > On-behalf-of: SAP stefan.ko...@sap.com > Signed-off-by: Stefan Kober <stefan.ko...@cyberus-technology.de> > --- > src/ch/ch_monitor.c | 49 ++++++++++++++++++++++++++++++++++++++------- > 1 file changed, 42 insertions(+), 7 deletions(-) > > diff --git a/src/ch/ch_monitor.c b/src/ch/ch_monitor.c > index f65cca648b..2ebeb46ad4 100644 > --- a/src/ch/ch_monitor.c > +++ b/src/ch/ch_monitor.c > @@ -62,6 +62,10 @@ VIR_ONCE_GLOBAL_INIT(virCHMonitor); > int virCHMonitorShutdownVMM(virCHMonitor *mon); > int virCHMonitorPutNoContent(virCHMonitor *mon, const char *endpoint, > domainLogContext *logCtxt); > +int > +virCHMonitorPut(virCHMonitor *mon, const char *endpoint, > + virJSONValue *payload, domainLogContext *logCtxt, > + virJSONValue** answer);
This function should be static. It's not exposed outside of this source file. > > static int > virCHMonitorBuildCPUJson(virJSONValue *content, virDomainDef *vmdef) > @@ -868,11 +872,15 @@ curl_callback(void *contents, size_t size, size_t > nmemb, void *userp) > } > > int > -virCHMonitorPutNoContent(virCHMonitor *mon, const char *endpoint, > - domainLogContext *logCtxt) > +virCHMonitorPut(virCHMonitor *mon, > + const char *endpoint, > + virJSONValue *payload, > + domainLogContext *logCtxt, > + virJSONValue **answer) > { > VIR_LOCK_GUARD lock = virObjectLockGuard(mon); > g_autofree char *url = NULL; > + g_autofree char *payload_str = NULL; > int responseCode = 0; > int ret = -1; > struct curl_data data = {0}; > @@ -890,28 +898,55 @@ virCHMonitorPutNoContent(virCHMonitor *mon, const char > *endpoint, > curl_easy_setopt(mon->handle, CURLOPT_INFILESIZE, 0L); > > headers = curl_slist_append(headers, "Accept: application/json"); > + > curl_easy_setopt(mon->handle, CURLOPT_HTTPHEADER, headers); > curl_easy_setopt(mon->handle, CURLOPT_WRITEFUNCTION, curl_callback); > curl_easy_setopt(mon->handle, CURLOPT_WRITEDATA, (void *)&data); > > + if (payload) { > + payload_str = virJSONValueToString(payload, false); > + curl_easy_setopt(mon->handle, CURLOPT_POSTFIELDS, payload_str); > + curl_easy_setopt(mon->handle, CURLOPT_CUSTOMREQUEST, "PUT"); > + headers = curl_slist_append(headers, "Content-Type: > application/json"); > + } > + > responseCode = virCHMonitorCurlPerform(mon->handle); > > + data.content = g_realloc(data.content, data.size + 1); > + data.content[data.size] = 0; Even though I don't know of any architecture, where '\0' byte would be different to zero we somehow prefer the former. Mostly, because it shows we're working with characters. > + > if (logCtxt && data.size) { > /* Do this to append a NULL char at the end of data */ > - data.content = g_realloc(data.content, data.size + 1); > - data.content[data.size] = 0; > domainLogContextWrite(logCtxt, "HTTP response code from CH: %d\n", > responseCode); > domainLogContextWrite(logCtxt, "Response = %s\n", data.content); > } > > - if (responseCode == 200 || responseCode == 204) > - ret = 0; > + if (responseCode != 200 && responseCode != 204) { > + ret = -1; > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("Invalid HTTP response code from CH: %1$d"), > + responseCode); > + goto cleanup; > + } > > - curl_slist_free_all(headers); > + if (answer) > + *answer = virJSONValueFromString(data.content); > + > + ret = 0; > > + cleanup: > + curl_slist_free_all(headers); > + g_free(data.content); > return ret; > } > > +int > +virCHMonitorPutNoContent(virCHMonitor *mon, const char *endpoint, > + domainLogContext *logCtxt) > +{ > + return virCHMonitorPut(mon, endpoint, NULL, logCtxt, NULL); > +} > + > static int > virCHMonitorGet(virCHMonitor *mon, const char *endpoint, virJSONValue > **response) > { Michal