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