HTTPAPI_RESULT HTTPAPI_SetOption()

in adapters/httpapi_curl.c [891:1147]


HTTPAPI_RESULT HTTPAPI_SetOption(HTTP_HANDLE handle, const char* optionName, const void* value)
{
    HTTPAPI_RESULT result;
    if (
        (handle == NULL) ||
        (optionName == NULL) ||
        (value == NULL)
        )
    {
        result = HTTPAPI_INVALID_ARG;
        LogError("invalid parameter (NULL) passed to HTTPAPI_SetOption");
    }
    else
    {
        HTTP_HANDLE_DATA* httpHandleData = (HTTP_HANDLE_DATA*)handle;
        if (strcmp(OPTION_HTTP_TIMEOUT, optionName) == 0)
        {
            long timeout = (long)(*(unsigned int*)value);
            httpHandleData->timeout = timeout;
            result = HTTPAPI_OK;
        }
        else if (strcmp(OPTION_CURL_LOW_SPEED_LIMIT, optionName) == 0)
        {
            httpHandleData->lowSpeedLimit = *(const long*)value;
            result = HTTPAPI_OK;
        }
        else if (strcmp(OPTION_CURL_LOW_SPEED_TIME, optionName) == 0)
        {
            httpHandleData->lowSpeedTime = *(const long*)value;
            result = HTTPAPI_OK;
        }
        else if (strcmp(OPTION_CURL_FRESH_CONNECT, optionName) == 0)
        {
            httpHandleData->freshConnect = *(const long*)value;
            result = HTTPAPI_OK;
        }
        else if (strcmp(OPTION_CURL_FORBID_REUSE, optionName) == 0)
        {
            httpHandleData->forbidReuse = *(const long*)value;
            result = HTTPAPI_OK;
        }
        else if (strcmp(OPTION_CURL_VERBOSE, optionName) == 0)
        {
            httpHandleData->verbose = *(const long*)value;
            result = HTTPAPI_OK;
        }
#ifdef USE_OPENSSL
        else if (strcmp(OPTION_OPENSSL_PRIVATE_KEY_TYPE, optionName) == 0)
        {
            const OPTION_OPENSSL_KEY_TYPE type = *(const OPTION_OPENSSL_KEY_TYPE*)value;
            if (type == KEY_TYPE_DEFAULT || type == KEY_TYPE_ENGINE)
            {
                httpHandleData->x509privatekeytype = type;
                result = HTTPAPI_OK;
            }
            else
            {
                LogError("Unknown x509PrivatekeyType: %i", type);
                result = HTTPAPI_ERROR;
            }
        }
#ifndef OPENSSL_NO_ENGINE
        else if (strcmp(OPTION_OPENSSL_ENGINE, optionName) == 0)
        {
            if (mallocAndStrcpy_s((char**)&httpHandleData->engineId, value) != 0)
            {
                LogError("unable to mallocAndStrcpy_s x509PrivatekeyType");
                result = HTTPAPI_ERROR;
            }
            else
            {
                result = HTTPAPI_OK;
            }
        }
#endif // OPENSSL_NO_ENGINE
#endif
        else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 || strcmp(OPTION_X509_ECC_KEY, optionName) == 0)
        {
            httpHandleData->x509privatekey = value;
            if (httpHandleData->x509certificate != NULL)
            {
                if (curl_easy_setopt(httpHandleData->curl, CURLOPT_SSL_CTX_FUNCTION, ssl_ctx_callback) != CURLE_OK)
                {
                    LogError("unable to curl_easy_setopt");
                    result = HTTPAPI_ERROR;
                }
                else
                {
                    if (curl_easy_setopt(httpHandleData->curl, CURLOPT_SSL_CTX_DATA, httpHandleData) != CURLE_OK)
                    {
                        LogError("unable to curl_easy_setopt");
                        result = HTTPAPI_ERROR;
                    }
                    else
                    {
                        result = HTTPAPI_OK;
                    }
                }
            }
            else
            {
                /*if privatekey comes 1st and certificate is not set yet, then return OK and wait for the certificate to be set*/
                result = HTTPAPI_OK;
            }
        }
        else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 || strcmp(OPTION_X509_ECC_CERT, optionName) == 0)
        {
            httpHandleData->x509certificate = value;
            if (httpHandleData->x509privatekey != NULL)
            {
                if (curl_easy_setopt(httpHandleData->curl, CURLOPT_SSL_CTX_FUNCTION, ssl_ctx_callback) != CURLE_OK)
                {
                    LogError("unable to curl_easy_setopt");
                    result = HTTPAPI_ERROR;
                }
                else
                {
                    if (curl_easy_setopt(httpHandleData->curl, CURLOPT_SSL_CTX_DATA, httpHandleData) != CURLE_OK)
                    {
                        LogError("unable to curl_easy_setopt");
                        result = HTTPAPI_ERROR;
                    }
                    else
                    {
                        result = HTTPAPI_OK;
                    }
                }
            }
            else
            {
                /*if certificate comes 1st and private key is not set yet, then return OK and wait for the private key to be set*/
                result = HTTPAPI_OK;
            }
        }
        else if (strcmp(OPTION_HTTP_PROXY, optionName) == 0)
        {
            char proxy[MAX_HOSTNAME_LEN];
            char* proxy_auth;

            HTTP_PROXY_OPTIONS* proxy_data = (HTTP_PROXY_OPTIONS*)value;

            if (sprintf_s(proxy, MAX_HOSTNAME_LEN, "%s:%d", proxy_data->host_address, proxy_data->port) <= 0)
            {
                LogError("failure constructing proxy address");
                result = HTTPAPI_ERROR;
            }
            else
            {
                if (curl_easy_setopt(httpHandleData->curl, CURLOPT_PROXY, proxy) != CURLE_OK)
                {
                    LogError("failure setting curl proxy address");
                    result = HTTPAPI_ERROR;
                }
                else
                {
                    if (proxy_data->username != NULL && proxy_data->password != NULL)
                    {
                        size_t authLen = safe_add_size_t(strlen(proxy_data->username), strlen(proxy_data->password));
                        authLen = safe_add_size_t(authLen, 2);
                        if (authLen == SIZE_MAX)
                        {
                            LogError("Invalid malloc size");
                            proxy_auth = NULL;
                        }
                        else
                        {
                            proxy_auth = malloc(authLen);
                        }

                        if (proxy_auth == NULL)
                        {
                            LogError("failure allocating proxy authentication");
                            result = HTTPAPI_ERROR;
                        }
                        else
                        {
                            // From curl website 'Pass a char * as parameter, which should be [user name]:[password]'
                            if (sprintf_s(proxy_auth, MAX_HOSTNAME_LEN, "%s:%s", proxy_data->username, proxy_data->password) <= 0)
                            {
                                LogError("failure constructing proxy authentication");
                                result = HTTPAPI_ERROR;
                            }
                            else
                            {
                                if (curl_easy_setopt(httpHandleData->curl, CURLOPT_PROXYUSERPWD, proxy_auth) != CURLE_OK)
                                {
                                    LogError("failure setting curl proxy authentication");
                                    result = HTTPAPI_ERROR;
                                }
                                else
                                {
                                    result = HTTPAPI_OK;
                                }
                            }
                            free(proxy_auth);
                            proxy_auth = NULL;
                        }
                    }
                    else
                    {
                        result = HTTPAPI_OK;
                    }
                }
            }
        }
        else if (strcmp("TrustedCerts", optionName) == 0)
        {
            /*TrustedCerts needs to trigger the CURLOPT_SSL_CTX_FUNCTION in curl so we can pass the CAs*/
            if (curl_easy_setopt(httpHandleData->curl, CURLOPT_SSL_CTX_FUNCTION, ssl_ctx_callback) != CURLE_OK)
            {
                LogError("failure in curl_easy_setopt - CURLOPT_SSL_CTX_FUNCTION");
                result = HTTPAPI_ERROR;
            }
            else
            {
                if (curl_easy_setopt(httpHandleData->curl, CURLOPT_SSL_CTX_DATA, httpHandleData) != CURLE_OK)
                {
                    LogError("failure in curl_easy_setopt - CURLOPT_SSL_CTX_DATA");
                    result = HTTPAPI_ERROR;
                }
                else
                {
                    httpHandleData->certificates = (const char*)value;
                    result = HTTPAPI_OK;
                }
            }
        }
        else if (strcmp(OPTION_CURL_INTERFACE, optionName) == 0)
        {
            const char *interfaceName = (const char*)value;
            if (interfaceName != NULL && interfaceName[0] != '\0')
            {
                if (curl_easy_setopt(httpHandleData->curl, CURLOPT_INTERFACE, interfaceName) != CURLE_OK)
                {
                    LogError("unable to curl_easy_setopt for CURLOPT_INTERFACE");
                    result = HTTPAPI_ERROR;
                }
                else
                {
                    result = HTTPAPI_OK;
                }
            }
            else
            {
                LogError("unable to curl_easy_setopt for CURLOPT_INTERFACE option as option-value is invalid/empty");
                result = HTTPAPI_ERROR;
            }
        }
        else
        {
            result = HTTPAPI_INVALID_ARG;
            LogError("unknown option %s", optionName);
        }
    }

    return result;
}