aboutsummaryrefslogtreecommitdiffstats
path: root/src/httpclient.cpp
blob: 0682be864b45f875cde5dbb719eafde0cf9e3380 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* Copyright (C) 2022 The Qt Company Ltd.
 *
 * SPDX-License-Identifier: GPL-3.0-only WITH Qt-GPL-exception-1.0
*/

#include "httpclient.h"

size_t WriteCallback(char *contents, size_t size, size_t nmemb, void *userp)
{
    //std::cout << "Reading data\n";
    ((std::string *)userp)->append(contents, size * nmemb);
    return size * nmemb;
}

HttpClient::HttpClient( const std::string &serverUrl,
                        const std::string &requestAccessPoint,
                        const std::string &permanentAccessPoint,
                        const std::string &versionAccessPoint) :
    m_serverUrl(serverUrl),
    m_requestAccessPoint(requestAccessPoint),
    m_permanentAccessPoint(permanentAccessPoint),
    m_versionAccessPoint(versionAccessPoint)
{
    m_userAgent += DAEMON_VERSION;
}

int HttpClient::sendRequest(std::string &reply, const std::string &payload,
                    const std::string &server, const std::string &authKey)
{
    HttpRequest request;
    m_lastError = "No errors";

    /* specify URL to POST */
    request.url = server;
    request.payload = payload;

    if (server.empty()) {
        // If server URL is not given as param, we use the default
        request.url = m_serverUrl;
    }
    if (!authKey.empty()) {
        // normal request
        request.url += m_requestAccessPoint;
        std::string auth = "Authorization: " + authKey;
        //std::cout << "Setting authorization: " << auth << std::endl;
        request.headers = curl_slist_append(request.headers, auth.c_str());
    } else {
        if (payload.empty()) {
            // version query
            request.url += m_versionAccessPoint;
        } else {
            // permanentrequest
            request.url += m_permanentAccessPoint;
        }
    }

    std::string agent = "User-Agent: " + m_userAgent;
    request.headers = curl_slist_append(request.headers, agent.c_str());
    request.headers = curl_slist_append(request.headers, "Accept: */*");
    request.headers = curl_slist_append(request.headers, "Content-Type: application/json");
    request.headers = curl_slist_append(request.headers, "charset: utf-8");

    //std::cout << "HTTPClient() -- server URL " << request.url << std::endl;

    int retVal = 0;

    /* init the curl session */
    curl_global_init(CURL_GLOBAL_ALL);
    CURL *curl = curl_easy_init();
    try {
        if (doRequest(curl, request) != 0) {
            retVal = 1;
        }
    } catch(...) {
        m_lastError = "Connection failed";
        retVal = 1;
    }
    if (retVal == 0) {
        std::cout << request.reply.length() << " bytes retrieved from license server\n";
        //std::cout << request.reply << std::endl;
    } else {
        std::cout << m_lastError << std::endl;
    }

    /* cleanup curl stuff */

    curl_easy_cleanup(curl);
    curl_global_cleanup();
    curl_slist_free_all(request.headers);
    reply = request.reply;
    return retVal;
}

int HttpClient::doRequest(CURL *curl, HttpRequest &request)
{
    // Set all received data to be send to our callback function
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);

    std::string readBuffer;
    // Pass the buffer to a callback
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);

    // Set the URL / headers
    curl_easy_setopt(curl, CURLOPT_URL, request.url.c_str());
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, request.headers);
    if (!request.payload.empty()) {
        curl_easy_setopt(curl, CURLOPT_POST, 1);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request.payload.c_str());
    }
    else {
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
    }
    if(curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL) != CURLE_OK) {
        std::cout << "Warning! No SSL support available\n";
    }
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, SERVER_CONN_TIMEOUT);

    // get it
    CURLcode res;
    res = curl_easy_perform(curl);

    // check for errors
    if (res != CURLE_OK) {
        std::cout << "HTTP transfer failed, URL: " << request.url << std::endl;
        m_lastError = curl_easy_strerror(res);
        return 1;
    }
    request.reply = readBuffer;
    return 0;
}