1#include "Conditions/URLStreamer.h"
9#include "Framework/Exception/Exception.h"
13static unsigned int http_requests = 0;
14static unsigned int http_failures = 0;
16void urlstatistics(
unsigned int& requests,
unsigned int& failures) {
17 requests = http_requests;
18 failures = http_failures;
24static size_t writeCallback(
char* ptr,
size_t size,
size_t nmemb,
26 auto* buffer =
static_cast<std::string*
>(userdata);
27 size_t total = size * nmemb;
28 buffer->append(ptr, total);
32std::unique_ptr<std::istream> urlstream(
const std::string& url) {
33 if (url.find(
"file://") == 0 || (url.length() > 0 && url[0] ==
'/')) {
34 std::string fname = url;
35 if (fname.find(
"file://") == 0) fname = url.substr(7);
36 auto fs = std::make_unique<std::ifstream>(fname);
38 EXCEPTION_RAISE(
"ConditionsException",
39 "Unable to open CSV file '" + fname +
"'");
43 if ((url.find(
"http://") == 0) || (url.find(
"https://") == 0)) {
46 CURL* curl = curl_easy_init();
49 EXCEPTION_RAISE(
"ConditionsException",
50 "Failed to initialize libcurl for URL '" + url +
"'");
53 std::string response_body;
55 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
56 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
57 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_body);
58 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
59 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
60 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
61 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L);
62 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 300L);
64 CURLcode res = curl_easy_perform(curl);
66 if (res != CURLE_OK) {
67 curl_easy_cleanup(curl);
69 EXCEPTION_RAISE(
"ConditionsException",
70 "Curl error (" + std::string(curl_easy_strerror(res)) +
71 ") retrieving URL '" + url +
"'");
75 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
76 curl_easy_cleanup(curl);
78 if (http_code != 200) {
80 EXCEPTION_RAISE(
"ConditionsException",
81 "HTTP error " + std::to_string(http_code) +
82 " retrieving URL '" + url +
"'");
85 auto ss = std::make_unique<std::stringstream>(std::move(response_body));
88 EXCEPTION_RAISE(
"ConditionsException",
"Unable to handle URL '" + url +
"'");
89 return std::unique_ptr<std::istream>(
nullptr);