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

Reply via email to