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