ReactOS 0.4.16-dev-1946-g52006dd
CWebServiceLibCurl.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Automatic Testing Utility
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Class implementing the curl interface to the "testman" Web Service
5 * COPYRIGHT: Copyright 2025 Mark Jansen <mark.jansen@reactos.org>
6 */
7
8#include "precomp.h"
9#include <curl/curl.h>
10
11static HMODULE g_hLibCurl = nullptr;
12static decltype(&curl_global_init) pcurl_global_init = nullptr;
13static decltype(&curl_easy_init) pcurl_easy_init = nullptr;
14static decltype(&curl_easy_setopt) pcurl_easy_setopt = nullptr;
15static decltype(&curl_easy_perform) pcurl_easy_perform = nullptr;
16static decltype(&curl_easy_strerror) pcurl_easy_strerror = nullptr;
17static decltype(&curl_easy_cleanup) pcurl_easy_cleanup = nullptr;
18static decltype(&curl_global_cleanup) pcurl_global_cleanup = nullptr;
19
20
21bool
23{
24 static bool initialized = false;
25 if (!initialized)
26 {
27 initialized = true;
28 g_hLibCurl = LoadLibraryA("___libcurl.dll");
29 if (!g_hLibCurl)
30 return false;
31
32 pcurl_global_init = (decltype(&curl_global_init))GetProcAddress(g_hLibCurl, "curl_global_init");
33 pcurl_easy_init = (decltype(&curl_easy_init))GetProcAddress(g_hLibCurl, "curl_easy_init");
34 pcurl_easy_setopt = (decltype(&curl_easy_setopt))GetProcAddress(g_hLibCurl, "curl_easy_setopt");
35 pcurl_easy_perform = (decltype(&curl_easy_perform))GetProcAddress(g_hLibCurl, "curl_easy_perform");
36 pcurl_easy_strerror = (decltype(&curl_easy_strerror))GetProcAddress(g_hLibCurl, "curl_easy_strerror");
37 pcurl_easy_cleanup = (decltype(&curl_easy_cleanup))GetProcAddress(g_hLibCurl, "curl_easy_cleanup");
38 pcurl_global_cleanup = (decltype(&curl_global_cleanup))GetProcAddress(g_hLibCurl, "curl_global_cleanup");
39 }
42 {
43 return false;
44 }
45 return true;
46}
47
52{
53 /* Initialize libcurl */
55 {
56 FATAL("Failed to initialize libcurl\n");
57 }
58
60 if (!m_hCurl)
61 {
62 FATAL("Failed to create a libcurl handle\n");
63 }
64
65 CHAR BaseName[MAX_PATH*2];
66 GetModuleFileNameA(g_hLibCurl, BaseName, _countof(BaseName));
67 PCHAR FileName = strrchr(BaseName, '\\');
68 FileName = FileName ? (FileName + 1) : BaseName;
69 strcpy(FileName, "curl-ca-bundle.crt");
70 pcurl_easy_setopt(m_hCurl, CURLOPT_CAINFO, BaseName);
71}
72
77{
78 if (m_hCurl)
79 {
81 m_hCurl = nullptr;
82 }
83
85}
86
87
88static size_t
89callback_func(void *ptr, size_t size, size_t count, void *userdata)
90{
91 string *ResultData = (string *)userdata;
92 ResultData->append((const char*)ptr, count);
93 return count;
94}
95
106PCHAR
107CWebServiceLibCurl::DoRequest(const char *Hostname, INTERNET_PORT Port, const char *ServerFile, const string &InputData)
108{
109 char buffer[1024];
110 sprintf(buffer, "https://%s:%u/%s", Hostname, Port, ServerFile);
111
112 pcurl_easy_setopt(m_hCurl, CURLOPT_URL, buffer);
113 pcurl_easy_setopt(m_hCurl, CURLOPT_POSTFIELDS, InputData.c_str());
114 pcurl_easy_setopt(m_hCurl, CURLOPT_USERAGENT, "rosautotest/curl");
115
116 string ResultData;
117 pcurl_easy_setopt(m_hCurl, CURLOPT_WRITEFUNCTION, callback_func);
118 pcurl_easy_setopt(m_hCurl, CURLOPT_WRITEDATA, &ResultData);
119
121 if (res != CURLE_OK)
122 {
123 string errorMsg = string("curl_easy_perform failed: ") + pcurl_easy_strerror(res);
124 FATAL(errorMsg.c_str());
125 }
126
128 Data.reset(new char[ResultData.size() + 1]);
129 strncpy(Data, ResultData.c_str(), ResultData.size());
130 Data[ResultData.size()] = '\0';
131
132 return Data.release();
133}
134
static decltype(&curl_easy_perform) pcurl_easy_perform
static HMODULE g_hLibCurl
static decltype(&curl_global_cleanup) pcurl_global_cleanup
static decltype(&curl_easy_init) pcurl_easy_init
static size_t callback_func(void *ptr, size_t size, size_t count, void *userdata)
static decltype(&curl_easy_setopt) pcurl_easy_setopt
static decltype(&curl_easy_strerror) pcurl_easy_strerror
static decltype(&curl_easy_cleanup) pcurl_easy_cleanup
static decltype(&curl_global_init) pcurl_global_init
static bool CanUseLibCurl()
PCHAR DoRequest(const char *Hostname, INTERNET_PORT Port, const char *ServerFile, const string &InputData) override
_Self & append(const _CharT *__first, const _CharT *__last)
Definition: _string.h:509
#define CURL_GLOBAL_ALL
Definition: curl.h:2845
CURL_EXTERN void curl_global_cleanup(void)
CURL_EXTERN CURLcode curl_global_init(long flags)
CURLcode
Definition: curl.h:490
@ CURLE_OK
Definition: curl.h:491
CURL_EXTERN const char * curl_easy_strerror(CURLcode)
#define GetProcAddress(x, y)
Definition: compat.h:753
#define MAX_PATH
Definition: compat.h:34
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
CURL_EXTERN void curl_easy_cleanup(CURL *curl)
CURL_EXTERN CURLcode curl_easy_perform(CURL *curl)
CURL_EXTERN CURL * curl_easy_init(void)
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
CPPORT Port[4]
Definition: headless.c:35
char string[160]
Definition: util.h:11
static PVOID ptr
Definition: dispmode.c:27
#define sprintf
Definition: sprintf.c:45
#define FATAL(Message)
Definition: precomp.h:59
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
strncpy
Definition: string.h:335
strcpy
Definition: string.h:131
#define _countof(array)
Definition: sndvol32.h:70
static BOOL initialized
Definition: syslog.c:39
#define curl_easy_setopt(handle, option, value)
Definition: typecheck-gcc.h:43
char * PCHAR
Definition: typedefs.h:51
WORD INTERNET_PORT
Definition: winhttp.h:38
char CHAR
Definition: xmlstorage.h:175