1 #include <openssl/md5.h>
2 #include <otsdaq-utilities/ECLWriter/ECLConnection.h>
3 #include <boost/algorithm/string.hpp>
8 #include "otsdaq/Macros/CoutMacros.h"
9 #include "otsdaq/MessageFacility/MessageFacility.h"
11 ECLConnection::ECLConnection(std::string user, std::string pwd, std::string url)
20 size_t ECLConnection::WriteMemoryCallback(
char* data,
29 buffer->append(data, size * nmemb);
30 realsize = size * nmemb;
36 bool ECLConnection::Get(std::string s, std::string& response)
40 char errorBuffer[CURL_ERROR_SIZE];
44 curl_global_init(CURL_GLOBAL_ALL);
47 curl_handle = curl_easy_init();
49 curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, errorBuffer);
51 std::string fullURL = _url + s;
54 curl_easy_setopt(curl_handle, CURLOPT_URL, fullURL.c_str());
55 curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
59 curl_handle, CURLOPT_WRITEFUNCTION, ECLConnection::WriteMemoryCallback);
62 curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &buffer);
66 curl_easy_setopt(curl_handle, CURLOPT_USERAGENT,
"libcurl-agent/1.0");
69 CURLcode result = curl_easy_perform(curl_handle);
72 curl_easy_cleanup(curl_handle);
74 if(result == CURLE_OK)
78 std::cerr <<
"Error: [" << result <<
"] - " << errorBuffer << std::endl;
82 curl_global_cleanup();
87 bool ECLConnection::Search(std::string ) {
return false; }
89 std::string ECLConnection::MakeSaltString()
91 std::string rndString =
"";
94 "abcdefghijklmnopqrstuvwxyz"
97 for(
int i = 0; i < 10; ++i)
99 rndString += chars[rand() % chars.size()];
107 std::string safe_url;
108 if(!Get(
"/secureURL", safe_url))
111 std::string rndString = MakeSaltString();
113 std::string myURL =
"/E/xml_post?";
114 std::string mySalt =
"salt=" + rndString;
115 std::string fullURL = _url + myURL + mySalt;
117 std::string myData = mySalt +
":" + _pwd +
":";
120 std::ostringstream oss;
122 std::string eclString = oss.str();
123 __COUT__ <<
"ECL XML is: " << eclString << std::endl;
125 eclString = eclString.substr(eclString.find_first_of(
">") + 2);
127 while(eclString.find(
'\n') != std::string::npos)
129 eclString = eclString.erase(eclString.find(
'\n'), 1);
131 while(eclString.find(
'\r') != std::string::npos)
133 eclString = eclString.erase(eclString.find(
'\r'), 1);
135 while(eclString.find(
" <") != std::string::npos)
137 eclString = eclString.erase(eclString.find(
" <"), 1);
139 boost::trim(eclString);
141 __COUT__ <<
"ECL Hash string is: " << myData << std::endl;
142 unsigned char resultMD5[MD5_DIGEST_LENGTH];
143 MD5((
unsigned char*)myData.c_str(), myData.size(), resultMD5);
147 for(
auto i = 0; i < MD5_DIGEST_LENGTH; i++)
149 sprintf(buf,
"%02x", resultMD5[i]);
152 __COUT__ <<
"ECL MD5 Signature is: " << xSig << std::endl;
155 char errorBuffer[CURL_ERROR_SIZE];
157 curl_global_init(CURL_GLOBAL_ALL);
161 curl_handle = curl_easy_init();
163 curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, errorBuffer);
167 struct curl_slist* headers = NULL;
168 std::string buff =
"X-User: " + _user;
169 headers = curl_slist_append(headers, buff.c_str());
170 headers = curl_slist_append(headers,
"Content-type: text/xml");
171 headers = curl_slist_append(headers,
"X-Signature-Method: md5");
172 buff =
"X-Signature: " + xSig;
173 headers = curl_slist_append(headers, buff.c_str());
175 const char* estr = eclString.c_str();
177 __COUT__ <<
"ECL Setting message headers" << std::endl;
178 curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, estr);
179 curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
180 curl_easy_setopt(curl_handle, CURLOPT_URL, fullURL.c_str());
185 __COUT__ <<
"ECL Posting message" << std::endl;
186 CURLcode result = curl_easy_perform(curl_handle);
188 if(result != CURLE_OK)
190 std::cerr <<
"Error: [" << result <<
"] - " << errorBuffer << std::endl;
194 __COUT__ <<
"ECL Cleanup" << std::endl;
196 curl_easy_cleanup(curl_handle);
197 curl_slist_free_all(headers);
199 curl_global_cleanup();
204 std::string ECLConnection::EscapeECLString(std::string input)
206 std::string output = input;
207 size_t pos = output.find(
'&');
208 while(pos != std::string::npos)
210 output = output.replace(pos, 1,
"&");
211 pos = output.find(
'&', pos + 2);
214 pos = output.find(
'"');
215 while(pos != std::string::npos)
217 output = output.replace(pos, 1,
""");
218 pos = output.find(
'"', pos + 1);
221 pos = output.find(
'\'');
222 while(pos != std::string::npos)
224 output = output.replace(pos, 1,
"'");
225 pos = output.find(
'\'', pos + 1);
228 pos = output.find(
'<');
229 while(pos != std::string::npos)
231 output = output.replace(pos, 1,
"<");
232 pos = output.find(
'<', pos + 1);
235 pos = output.find(
'>');
236 while(pos != std::string::npos)
238 output = output.replace(pos, 1,
">");
239 pos = output.find(
'>', pos + 1);
245 Attachment_t ECLConnection::MakeAttachmentImage(std::string
const& imageFileName)
248 std::string fileNameShort = imageFileName;
249 if(fileNameShort.rfind(
'/') != std::string::npos)
251 fileNameShort = fileNameShort.substr(imageFileName.rfind(
'/'));
253 std::ifstream fin(imageFileName, std::ios::in | std::ios::binary);
254 fin.seekg(0, std::ios::end);
255 std::streamsize size = fin.tellg();
256 fin.seekg(0, std::ios::beg);
257 std::vector<char> buffer(size);
258 if(!fin.read(buffer.data(), size))
260 __COUT__ <<
"ECLConnection: Error reading file: " << imageFileName << std::endl;
266 ::xml_schema::base64_binary(&buffer[0], size),
"image", fileNameShort);
271 Attachment_t ECLConnection::MakeAttachmentFile(std::string
const& fileName)
274 std::string fileNameShort = fileName;
275 if(fileNameShort.rfind(
'/') != std::string::npos)
277 fileNameShort = fileNameShort.substr(fileName.rfind(
'/'));
279 std::ifstream fin(fileName, std::ios::in | std::ios::binary);
280 fin.seekg(0, std::ios::end);
281 std::streamsize size = fin.tellg();
282 fin.seekg(0, std::ios::beg);
284 std::vector<char> buffer(size);
285 if(!fin.read(buffer.data(), size))
287 __COUT__ <<
"ECLConnection: Error reading file: " << fileName;
293 ::xml_schema::base64_binary(&buffer[0], size),
"file", fileNameShort);