Bridges-C++ 3.5.0-dev2-1-ge3e57bf
Bridges(C++ API)
ServerComm.h
Go to the documentation of this file.
1#ifndef SERVER_COMM_H
2#define SERVER_COMM_H
3
4#include <string>
5#include <vector>
6using namespace std;
7#include <curl/curl.h> //curl
9#include "./data_src/Game.h"
14#include "./data_src/Song.h"
15#include "bridges_exception.h"
16
17namespace bridges {
18
24 class ServerComm {
25 //Used to access to this class private functions
26 friend class Bridges;
27 friend class DataSource;
28
29 ServerComm() = delete; //Prevents instantiation
30
34 static size_t curlWriteFunction(void *contents, size_t size,
35 size_t nmemb, void *results) {
36 size_t handled = size * nmemb;
37 if (results) {
38 ((string*)results)->append((char*)contents, handled);
39 }
40 return handled;
41 }
50 static string makeRequest(const string& url, const vector<string>&
51 headers, const string& data = "") {
52 string results;
53 string returned_headers;
54 // first load curl enviornment (only need be called
55 // once in entire session tho)
56 curl_global_init(CURL_GLOBAL_ALL);
57 CURL* curl = curl_easy_init(); // get a curl handle
58 if (curl) {
59 char error_buffer[CURL_ERROR_SIZE];
60 CURLcode res;
61 //setting verbose
62 if (0) {
63 res = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
64 if (res != CURLE_OK)
65 throw "curl_easy_setopt failed";
66 }
67 // setting error buffer
68 res = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer);
69 if (res != CURLE_OK)
70 throw "curl_easy_setopt failed";
71
72 // set the URL to GET from
73 res = curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
74 if (res != CURLE_OK)
75 throw "curl_easy_setopt failed";
76 //pass pointer to callback function
77 res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &results);
78 if (res != CURLE_OK)
79 throw "curl_easy_setopt failed";
80 //sends all data to this function
81 res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlWriteFunction);
82 if (res != CURLE_OK)
83 throw "curl_easy_setopt failed";
84 //sends all header to this function
85 res = curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curlWriteFunction);
86 //pass pointer to callback function
87 res = curl_easy_setopt(curl, CURLOPT_HEADERDATA, &returned_headers);
88 if (res != CURLE_OK)
89 throw "curl_easy_setopt failed";
90 // We should not set
91 // CURLOPT_FAILONERROR because
92 // we want the full content of
93 // the returned document and
94 // headers that may contain
95 // useful information
96 //
97 // res = curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
98 // if (res != CURLE_OK)
99 // throw "curl_easy_setopt failed";
100 if (data.length() > 0) {
101 // Now specify the POST data
102 res = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
103 if (res != CURLE_OK)
104 throw "curl_easy_setopt failed";
105 // Now specify the POST data size
106 res = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.length());
107 if (res != CURLE_OK)
108 throw "curl_easy_setopt failed";
109 // a post request
110 res = curl_easy_setopt(curl, CURLOPT_POST, 1L);
111 if (res != CURLE_OK)
112 throw "curl_easy_setopt failed";
113 }
114
115 struct curl_slist * curlHeaders = nullptr;
116 for (const string& header : headers) {
117 curlHeaders = curl_slist_append(curlHeaders, header.c_str());
118 }
119 res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curlHeaders);
120 if (res != CURLE_OK)
121 throw "curl_easy_setopt failed";
122
123 // Perform the request, res will get the return code
124 res = curl_easy_perform(curl);
125
126 curl_slist_free_all(curlHeaders);
127
128 if (res != CURLE_OK) {
129
130 string footer = string("Root cause: ") + string("curl_easy_perform() failed.\n")
131 + "Curl Error Code " + to_string(res) + "\n" + curl_easy_strerror(res) + "\n"
132 + "ErrorBuffer: " + error_buffer + "\n"
133 + "Headers: " + returned_headers + "\n"
134 + "Results: " + results + "\n";
135 throw footer;
136 }
137
138 if (res == CURLE_OK) {
139 long httpcode = -1;
140 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpcode);
141
142 if (httpcode >= 300) {
143 throw HTTPException(url, httpcode, returned_headers, results);
144 }
145
146 }
147 curl_easy_cleanup(curl);
148 }
149 else {
150 throw "curl_easy_init() failed!\nNothing retrieved from server.\n";
151 }
152
153 curl_global_cleanup();
154 return results;
155 }
156
157 static std::string encodeURLPart (const std::string& s) {
158 std::string returnstr;
159
160 curl_global_init(CURL_GLOBAL_ALL);
161 CURL* curl = curl_easy_init(); // get a curl handle
162
163 char* encodedstr = curl_easy_escape (curl, s.c_str(), 0);
164 returnstr = encodedstr;
165
166 curl_free(encodedstr);
167
168 curl_easy_cleanup(curl);
169 curl_global_cleanup();
170
171 return returnstr;
172 }
173 }; //server comm
174
175}// namespace bridges
176#endif
This class contains methods to connect and transmit a user's data structure representation to the Bri...
Definition: Bridges.h:51
This class provides an API to various data sources used in BRIDGES.
Definition: DataSource.h:69
This is a class for handling calls to the BRIDGES server to transmit JSON to the server and subsequen...
Definition: ServerComm.h:24
these methods convert byte arrays in to base64 codes and are used in BRIDGES to represent the color a...
Definition: alltypes.h:4