otsdaq_utilities  v2_02_00
ECLConnection.cpp
1 #include <otsdaq-utilities/ECLWriter/ECLConnection.h>
2 #include <iomanip>
3 #include <openssl/md5.h>
4 #include <sstream>
5 #include <cstring>
6 #include <fstream>
7 #include "otsdaq-core/MessageFacility/MessageFacility.h"
8 #include "otsdaq-core/Macros/CoutMacros.h"
9 
10 ECLConnection::ECLConnection(std::string user,
11  std::string pwd,
12  std::string url)
13 {
14  _user = user;
15  _pwd = pwd;
16  _url = url;
17 
18  srand(time(NULL));
19 
20 }
21 
22 size_t ECLConnection::WriteMemoryCallback(char *data, size_t size,
23  size_t nmemb, std::string* buffer)
24 {
25  size_t realsize = 0;
26 
27  if (buffer != NULL) {
28  buffer->append(data, size*nmemb);
29  realsize = size * nmemb;
30  }
31 
32  return realsize;
33 }
34 
35 bool ECLConnection::Get(std::string s, std::string& response)
36 {
37  response = "NULL";
38 
39  char errorBuffer[CURL_ERROR_SIZE];
40  std::string buffer;
41  CURL *curl_handle;
42 
43  curl_global_init(CURL_GLOBAL_ALL);
44 
45  /* init the curl session */
46  curl_handle = curl_easy_init();
47 
48  curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, errorBuffer);
49 
50  std::string fullURL = _url + s;
51 
52  /* specify URL to get */
53  curl_easy_setopt(curl_handle, CURLOPT_URL, fullURL.c_str());
54  curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
55 
56  /* send all data to this function */
57  curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, ECLConnection::WriteMemoryCallback);
58 
59  /* we pass our 'chunk' struct to the callback function */
60  curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &buffer);
61 
62  /* some servers don't like requests that are made without a user-agent
63  field, so we provide one */
64  curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
65 
66  /* get it! */
67  CURLcode result = curl_easy_perform(curl_handle);
68 
69  /* cleanup curl stuff */
70  curl_easy_cleanup(curl_handle);
71 
72  if (result == CURLE_OK)
73  response = buffer;
74  else {
75  std::cerr << "Error: [" << result << "] - " << errorBuffer << std::endl;
76  return false;
77  }
78 
79  curl_global_cleanup();
80 
81  return true;
82 }
83 
84 bool ECLConnection::Search(std::string s)
85 {
86  return false;
87 }
88 
89 std::string ECLConnection::MakeSaltString()
90 {
91  std::string rndString = "";
92 
93  std::string chars("abcdefghijklmnopqrstuvwxyz"
94  // "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
95  "1234567890");
96  for (int i = 0; i < 10; ++i) {
97  rndString += chars[rand() % chars.size()];
98  }
99 
100  return rndString;
101 }
102 
103 
104 bool ECLConnection::Post(ECLEntry_t& e)
105 {
106  std::string safe_url;
107  if (!Get("/secureURL", safe_url)) return false;
108 
109  std::string rndString = MakeSaltString();
110 
111  std::string myURL = "/E/xml_post?";
112  std::string mySalt = "salt=" + rndString;
113  std::string fullURL = _url + myURL + mySalt;
114 
115  std::string myData = mySalt + ":" + _pwd + ":";
116 
117  // create text from xml form, but need to remove all \n's
118  std::ostringstream oss;
119  entry(oss, e);
120  std::string eclString = oss.str();
121  __COUT__ << "ECL XML is: " << eclString << std::endl;
122  //std::string eclString = e.entry();
123  eclString = eclString.substr(eclString.find_first_of(">") + 2);
124 
125  while (eclString.find('\n') != std::string::npos)
126  {
127  eclString = eclString.erase(eclString.find('\n'), 1);
128  }
129  while (eclString.find('\r') != std::string::npos)
130  {
131  eclString = eclString.erase(eclString.find('\r'), 1);
132  }
133  while (eclString.find(" <") != std::string::npos)
134  {
135  eclString = eclString.erase(eclString.find(" <"), 1);
136  }
137  boost::trim(eclString);
138  myData += eclString;
139  __COUT__ << "ECL Hash string is: " << myData << std::endl;
140  unsigned char resultMD5[MD5_DIGEST_LENGTH];
141  MD5((unsigned char*)myData.c_str(), myData.size(), resultMD5);
142 
143  std::string xSig;
144  char buf[3];
145  for (auto i = 0; i < MD5_DIGEST_LENGTH; i++) {
146  sprintf(buf, "%02x", resultMD5[i]);
147  xSig.append(buf);
148  }
149  __COUT__ << "ECL MD5 Signature is: " << xSig << std::endl;
150 
151  CURL *curl_handle;
152  char errorBuffer[CURL_ERROR_SIZE];
153 
154  curl_global_init(CURL_GLOBAL_ALL);
155 
156  /* init the curl session */
157 
158  curl_handle = curl_easy_init();
159 
160  curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, errorBuffer);
161 
162  /* specify URL to get */
163 
164  struct curl_slist* headers = NULL;
165  std::string buff = "X-User: " + _user;
166  headers = curl_slist_append(headers, buff.c_str());
167  headers = curl_slist_append(headers, "Content-type: text/xml");
168  headers = curl_slist_append(headers, "X-Signature-Method: md5");
169  buff = "X-Signature: " + xSig;
170  headers = curl_slist_append(headers, buff.c_str());
171 
172  const char* estr = eclString.c_str();
173 
174  __COUT__ << "ECL Setting message headers" << std::endl;
175  curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, estr);
176  curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
177  curl_easy_setopt(curl_handle, CURLOPT_URL, fullURL.c_str());
178  // curl_easy_setopt(curl_handle, CURLOPT_VERBOSE,1);
179 
180  // post it!
181 
182  __COUT__ << "ECL Posting message" << std::endl;
183  CURLcode result = curl_easy_perform(curl_handle);
184 
185  if (result != CURLE_OK) {
186  std::cerr << "Error: [" << result << "] - " << errorBuffer << std::endl;
187  return false;
188  }
189 
190  __COUT__ << "ECL Cleanup" << std::endl;
191  // cleanup curl stuff
192  curl_easy_cleanup(curl_handle);
193  curl_slist_free_all(headers);
194 
195  curl_global_cleanup();
196 
197  return true;
198 
199 }
200 
201 
202 Attachment_t ECLConnection::MakeAttachmentImage(std::string const& imageFileName) {
203  Attachment_t attachment;
204  std::string fileNameShort = imageFileName;
205  if (fileNameShort.rfind('/') != std::string::npos) {
206  fileNameShort = fileNameShort.substr(imageFileName.rfind('/'));
207  }
208  std::ifstream fin(imageFileName, std::ios::in | std::ios::binary);
209  fin.seekg(0, std::ios::end);
210  std::streamsize size = fin.tellg();
211  fin.seekg(0, std::ios::beg);
212  std::vector<char> buffer(size);
213  if (!fin.read(buffer.data(), size))
214  {
215  __COUT__ << "ECLConnection: Error reading file: " << imageFileName << std::endl;
216  attachment = Attachment_t("Image=none", fileNameShort);
217  }
218  else {
219  attachment = Attachment_t(::xml_schema::base64_binary(&buffer[0], size), "image", fileNameShort);
220  }
221  return attachment;
222 }
223 
224 
225 Attachment_t ECLConnection::MakeAttachmentFile(std::string const& fileName) {
226  Attachment_t attachment;
227  std::string fileNameShort = fileName;
228  if (fileNameShort.rfind('/') != std::string::npos) {
229  fileNameShort = fileNameShort.substr(fileName.rfind('/'));
230  }
231  std::ifstream fin(fileName, std::ios::in | std::ios::binary);
232  fin.seekg(0, std::ios::end);
233  std::streamsize size = fin.tellg();
234  fin.seekg(0, std::ios::beg);
235 
236  std::vector<char> buffer(size);
237  if (!fin.read(buffer.data(), size))
238  {
239  __COUT__ << "ECLConnection: Error reading file: " << fileName;
240  attachment = Attachment_t("File=none", fileNameShort);
241  }
242  else {
243  attachment = Attachment_t(::xml_schema::base64_binary(&buffer[0], size), "file", fileNameShort);
244  }
245  return attachment;
246 }
Definition: ECL.hxx:547