// ***************************************************************************** // * This file is part of the FreeFileSync project. It is distributed under * // * GNU General Public License: https://www.gnu.org/licenses/gpl-3.0 * // * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * // ***************************************************************************** #ifndef CURL_WRAP_H_2879058325032785032789645 #define CURL_WRAP_H_2879058325032785032789645 #include #include //------------------------------------------------- #include //------------------------------------------------- #ifndef CURLINC_CURL_H #error curl.h header guard changed #endif namespace zen { struct CurlOption { template CurlOption(CURLoption o, T val) : option(o), value(static_cast(val)) { static_assert(sizeof(val) <= sizeof(value)); } template CurlOption(CURLoption o, T* val) : option(o), value(reinterpret_cast(val)) { static_assert(sizeof(val) <= sizeof(value)); } CURLoption option = CURLOPT_LASTENTRY; uint64_t value = 0; }; namespace { std::wstring formatCurlStatusCode(CURLcode sc) { switch (sc) { ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OK); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_UNSUPPORTED_PROTOCOL); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FAILED_INIT); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_URL_MALFORMAT); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_NOT_BUILT_IN); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_COULDNT_RESOLVE_PROXY); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_COULDNT_RESOLVE_HOST); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_COULDNT_CONNECT); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_WEIRD_SERVER_REPLY); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_REMOTE_ACCESS_DENIED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FTP_ACCEPT_FAILED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FTP_WEIRD_PASS_REPLY); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FTP_ACCEPT_TIMEOUT); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FTP_WEIRD_PASV_REPLY); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FTP_WEIRD_227_FORMAT); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FTP_CANT_GET_HOST); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_HTTP2); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FTP_COULDNT_SET_TYPE); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_PARTIAL_FILE); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FTP_COULDNT_RETR_FILE); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OBSOLETE20); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_QUOTE_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_HTTP_RETURNED_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_WRITE_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OBSOLETE24); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_UPLOAD_FAILED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_READ_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OUT_OF_MEMORY); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OPERATION_TIMEDOUT); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OBSOLETE29); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FTP_PORT_FAILED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FTP_COULDNT_USE_REST); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OBSOLETE32); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_RANGE_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_HTTP_POST_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSL_CONNECT_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_BAD_DOWNLOAD_RESUME); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FILE_COULDNT_READ_FILE); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_LDAP_CANNOT_BIND); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_LDAP_SEARCH_FAILED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OBSOLETE40); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FUNCTION_NOT_FOUND); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_ABORTED_BY_CALLBACK); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_BAD_FUNCTION_ARGUMENT); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OBSOLETE44); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_INTERFACE_FAILED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OBSOLETE46); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_TOO_MANY_REDIRECTS); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_UNKNOWN_OPTION); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_TELNET_OPTION_SYNTAX); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OBSOLETE50); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OBSOLETE51); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_PEER_FAILED_VERIFICATION); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_GOT_NOTHING); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSL_ENGINE_NOTFOUND); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSL_ENGINE_SETFAILED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SEND_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_RECV_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_OBSOLETE57); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSL_CERTPROBLEM); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSL_CIPHER); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_BAD_CONTENT_ENCODING); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_LDAP_INVALID_URL); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FILESIZE_EXCEEDED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_USE_SSL_FAILED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SEND_FAIL_REWIND); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSL_ENGINE_INITFAILED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_LOGIN_DENIED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_TFTP_NOTFOUND); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_TFTP_PERM); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_REMOTE_DISK_FULL); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_TFTP_ILLEGAL); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_TFTP_UNKNOWNID); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_REMOTE_FILE_EXISTS); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_TFTP_NOSUCHUSER); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_CONV_FAILED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_CONV_REQD); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSL_CACERT_BADFILE); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_REMOTE_FILE_NOT_FOUND); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSH); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSL_SHUTDOWN_FAILED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_AGAIN); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSL_CRL_BADFILE); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSL_ISSUER_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FTP_PRET_FAILED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_RTSP_CSEQ_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_RTSP_SESSION_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_FTP_BAD_FILE_LIST); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_CHUNK_FAILED); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_NO_CONNECTION_AVAILABLE); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSL_PINNEDPUBKEYNOTMATCH); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_SSL_INVALIDCERTSTATUS); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_HTTP2_STREAM); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_RECURSIVE_API_CALL); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_AUTH_ERROR); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_HTTP3); ZEN_CHECK_CASE_FOR_CONSTANT(CURL_LAST); ZEN_CHECK_CASE_FOR_CONSTANT(CURLE_QUIC_CONNECT_ERROR); } static_assert(CURL_LAST == CURLE_QUIC_CONNECT_ERROR + 1); return replaceCpy(L"Curl status %x", L"%x", numberTo(static_cast(sc))); } void applyCurlOptions(CURL* easyHandle, const std::vector& options) //throw SysError { for (const CurlOption& opt : options) { const CURLcode rc = ::curl_easy_setopt(easyHandle, opt.option, opt.value); if (rc != CURLE_OK) throw SysError(formatSystemError("curl_easy_setopt(" + numberTo(static_cast(opt.option)) + ")", formatCurlStatusCode(rc), utfTo(::curl_easy_strerror(rc)))); } } } } #else #error Why is this header already defined? Do not include in other headers: encapsulate the gory details! #endif //CURL_WRAP_H_2879058325032785032789645