static celix_status_t remoteServiceAdmin_send()

in bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c [1053:1142]


static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_t *endpointDescription, char *request, celix_properties_t *metadata, char **reply) {
    remote_service_admin_t * rsa = handle;
    struct celix_post_data post;
    post.readptr = request;
    post.size = strlen(request);
    post.read = 0;

    struct celix_get_data_reply get;
    get.buf = NULL;
    get.size = 0;
    get.stream = open_memstream(&get.buf, &get.size);

    const char *serviceUrl = celix_properties_get(endpointDescription->properties, (char*) RSA_DFI_ENDPOINT_URL, NULL);
    char url[256];
    snprintf(url, 256, "%s", serviceUrl);

    // assume the default timeout
    int timeout = DEFAULT_TIMEOUT;

    const char *timeoutStr = NULL;
    // Check if the endpoint has a timeout, if so, use it.
    timeoutStr = (char*) celix_properties_get(endpointDescription->properties, (char*) CELIX_RSA_REMOTE_PROXY_TIMEOUT, NULL);
    if (timeoutStr == NULL) {
        // If not, get the global variable and use that one.
        bundleContext_getProperty(rsa->context, (char*) CELIX_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr);
    }

    // Update timeout if a property is used to set it.
    if (timeoutStr != NULL) {
        timeout = atoi(timeoutStr);
    }

    celix_status_t status = CELIX_SUCCESS;
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init();
    if(!curl) {
        fclose(get.stream);
        free(get.buf);
        status = CELIX_ILLEGAL_STATE;
    } else {
        struct curl_slist *metadataHeader = NULL;
        if (metadata != NULL && celix_properties_size(metadata) > 0) {
            CELIX_PROPERTIES_ITERATE(metadata, iter) {
                size_t length = strlen(iter.key) + strlen(iter.entry.value) + 18; // "X-RSA-Metadata-key: val\0"
                char header[length];
                snprintf(header, length, "X-RSA-Metadata-%s: %s", iter.key, iter.entry.value);
                metadataHeader = curl_slist_append(metadataHeader, header);
            }

            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, metadataHeader);
        }

        curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        curl_easy_setopt(curl, CURLOPT_READFUNCTION, remoteServiceAdmin_readCallback);
        curl_easy_setopt(curl, CURLOPT_READDATA, &post);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
        if (rsa->curlShareEnabled) {
            curl_easy_setopt(curl, CURLOPT_SHARE, rsa->curlShare);
        }

        const char *ipaddresses = celix_properties_get(endpointDescription->properties, CELIX_RSA_IP_ADDRESSES, NULL);
        if (ipaddresses == NULL) {
            curl_easy_setopt(curl, CURLOPT_URL, url);
            res = curl_easy_perform(curl);
            status = (res == CURLE_OK) ? CELIX_SUCCESS:CELIX_ERROR_MAKE(CELIX_FACILITY_CURL,res);
        } else {
            status = remoteServiceAdmin_useDynamicIpUrlsForEndpoint(rsa, endpointDescription, onUseUrlCallback, curl);
        }

        fputc('\0', get.stream);
        fclose(get.stream);
        *reply = get.buf;
        if (status == CELIX_SUCCESS) {
            long httpCode = 0;
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
            status = (httpCode == 200/*HTTP OK*/) ? CELIX_SUCCESS : CELIX_ERROR_MAKE(CELIX_FACILITY_HTTP,httpCode);
        }

        curl_easy_cleanup(curl);
        curl_slist_free_all(metadataHeader);
    }

    return status;
}