NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
http.cpp
Go to the documentation of this file.
1
2/***************************************************************************
3 * _ _ ____ _
4 * Project ___| | | | _ \| |
5 * / __| | | | |_) | |
6 * | (__| |_| | _ <| |___
7 * \___|\___/|_| \_\_____|
8 *
9 * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
10 *
11 * This software is licensed as described in the file COPYING, which
12 * you should have received as part of this distribution. The terms
13 * are also available at https://curl.se/docs/copyright.html.
14 *
15 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
16 * copies of the Software, and permit persons to whom the Software is
17 * furnished to do so, under the terms of the COPYING file.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ***************************************************************************/
23
24#include "http.h"
25#include <curl/curl.h>
26#include <fstream>
27
28// Further possible features enabled in cURL:
29// DICT FILE FTPS GOPHER GOPHERS IMAP IMAPS LDAP MQTT POP3 POP3S RTSP SCP SFTP SMB SMBS SMTP SMTPS TELNET TFTP
30
31namespace url
32{
37 static char errorBuffer[CURL_ERROR_SIZE];
38
39
50 static size_t writer(char* data, size_t size, size_t nmemb, std::string* writerData)
51 {
52 if (writerData == NULL)
53 return 0;
54
55 writerData->append(data, size * nmemb);
56
57 return size * nmemb;
58 }
59
60
71 static size_t reader(char *ptr, size_t size, size_t nmemb, void *stream)
72 {
73 std::ifstream* filestream = static_cast<std::ifstream*>(stream);
74 size_t bytes = filestream->readsome(ptr, size * nmemb);
75 return bytes;
76 }
77
78
88 static CURL* common_init(const std::string& sUrl, const std::string& sUserName, const std::string& sPassWord)
89 {
90 CURLcode code;
91
92 CURL* conn = curl_easy_init();
93
94 if (conn == nullptr)
95 throw Error("Failed to create CURL connection.");
96
97 try
98 {
99 code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer);
100
101 if (code != CURLE_OK)
102 throw Error("Failed to set error buffer [" + std::to_string(code) + "].");
103
104 code = curl_easy_setopt(conn, CURLOPT_URL, sUrl.c_str());
105
106 if (code != CURLE_OK)
107 throw Error("Failed to set URL [" + std::string(errorBuffer) + "].");
108
109 code = curl_easy_setopt(conn, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0");
110
111 if (code != CURLE_OK)
112 throw Error("Failed to set user agent [" + std::string(errorBuffer) + "].");
113
114 if (sUserName.length() && sPassWord.length())
115 {
116 code = curl_easy_setopt(conn, CURLOPT_USERPWD, (sUserName + ":" + sPassWord).c_str());
117
118 if (code != CURLE_OK)
119 throw Error("Failed to set username and password [" + std::string(errorBuffer) + "].");
120 }
121
122 code = curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L);
123
124 if (code != CURLE_OK)
125 throw Error("Failed to set SSL peer verify option [" + std::string(errorBuffer) + "].");
126
127 code = curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L);
128
129 if (code != CURLE_OK)
130 throw Error("Failed to set SSL host verify option [" + std::string(errorBuffer) + "].");
131
132 code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1L);
133
134 if (code != CURLE_OK)
135 throw Error("Failed to set redirect option [" + std::string(errorBuffer) + "].");
136
137 code = curl_easy_setopt(conn, CURLOPT_CONNECTTIMEOUT, 10L);
138
139 if (code != CURLE_OK)
140 throw Error("Failed to set connection time-out option [" + std::string(errorBuffer) + "].");
141
142 code = curl_easy_setopt(conn, CURLOPT_TIMEOUT, 10L);
143
144 if (code != CURLE_OK)
145 throw Error("Failed to set time-out option [" + std::string(errorBuffer) + "].");
146 }
147 catch (...)
148 {
149 curl_easy_cleanup(conn);
150 throw;
151 }
152
153 return conn;
154 }
155
156
168 static CURL* get_init(const std::string& sUrl, const std::string& sUserName, const std::string& sPassWord, std::string* buffer)
169 {
170 CURLcode code;
171
172 CURL* conn = common_init(sUrl, sUserName, sPassWord);
173
174 try
175 {
176 code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writer);
177
178 if (code != CURLE_OK)
179 throw Error("Failed to set writer [" + std::string(errorBuffer) + "].");
180
181 code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, buffer);
182
183 if (code != CURLE_OK)
184 throw Error("Failed to set write data [" + std::string(errorBuffer) + "].");
185 }
186 catch (...)
187 {
188 curl_easy_cleanup(conn);
189 throw;
190 }
191
192 return conn;
193 }
194
195
207 static CURL* put_init(const std::string& sUrl, const std::string& sUserName, const std::string& sPassWord, std::ifstream* filestream, size_t filesize)
208 {
209 CURLcode code;
210
211 CURL* conn = common_init(sUrl, sUserName, sPassWord);
212
213 try
214 {
215 code = curl_easy_setopt(conn, CURLOPT_UPLOAD, 1L);
216
217 if (code != CURLE_OK)
218 throw Error("Failed to set upload option [" + std::string(errorBuffer) + "].");
219
220 code = curl_easy_setopt(conn, CURLOPT_READFUNCTION, reader);
221
222 if (code != CURLE_OK)
223 throw Error("Failed to set reader [" + std::string(errorBuffer) + "].");
224
225 code = curl_easy_setopt(conn, CURLOPT_READDATA, filestream);
226
227 if (code != CURLE_OK)
228 throw Error("Failed to set filestream [" + std::string(errorBuffer) + "].");
229
230 curl_easy_setopt(conn, CURLOPT_INFILESIZE, filesize);
231 }
232 catch (...)
233 {
234 curl_easy_cleanup(conn);
235 throw;
236 }
237
238 return conn;
239 }
240
241
251 std::string get(const std::string& sUrl, const std::string& sUserName, const std::string& sPassWord)
252 {
253 CURL* conn = nullptr;
254 CURLcode code;
255 std::string buffer;
256 buffer.clear();
257
258 curl_global_init(CURL_GLOBAL_DEFAULT);
259
260 // Initialize CURL connection
261 conn = get_init(sUrl, sUserName, sPassWord, &buffer);
262
263 // Retrieve content for the URL
264 code = curl_easy_perform(conn);
265 curl_easy_cleanup(conn);
266
267 if (code != CURLE_OK)
268 throw Error("Failed to get '" + sUrl + "': " + std::string(errorBuffer) + ".");
269
270 // Return the buffer contents
271 return buffer;
272 }
273
274
286 size_t put(const std::string& sUrl, const std::string& sFileName, const std::string& sUserName, const std::string& sPassWord)
287 {
288 CURL* conn = nullptr;
289 CURLcode code;
290 std::ifstream filestream(sFileName.c_str(), std::ios_base::binary);
291
292 if (!filestream.good())
293 throw Error("Cannot open file '" + sFileName + "'.");
294
295 filestream.seekg(0, std::ios_base::end);
296 size_t s = filestream.tellg();
297 filestream.seekg(0, std::ios_base::beg);
298
299 if (!s)
300 throw Error("File size of '" + sFileName + "' is zero.");
301
302 curl_global_init(CURL_GLOBAL_DEFAULT);
303
304 // Initialize CURL connection
305 conn = put_init(sUrl, sUserName, sPassWord, &filestream, s);
306
307 // Retrieve content for the URL
308 code = curl_easy_perform(conn);
309 curl_easy_cleanup(conn);
310
311 if (code != CURLE_OK)
312 throw Error("Failed to upload to '" + sUrl + "': " + std::string(errorBuffer) + ".");
313
314 // Return the file size
315 return s;
316 }
317}
318
A class for URL exceptions.
Definition: http.h:32
Definition: http.cpp:32
static size_t reader(char *ptr, size_t size, size_t nmemb, void *stream)
libcurl read callback function.
Definition: http.cpp:71
size_t put(const std::string &sUrl, const std::string &sFileName, const std::string &sUserName, const std::string &sPassWord)
Upload a file to a destination and return the transmitted bytes.
Definition: http.cpp:286
std::string get(const std::string &sUrl, const std::string &sUserName, const std::string &sPassWord)
Get the contents of a URL.
Definition: http.cpp:251
static CURL * common_init(const std::string &sUrl, const std::string &sUserName, const std::string &sPassWord)
Perform common CURL initialization.
Definition: http.cpp:88
static size_t writer(char *data, size_t size, size_t nmemb, std::string *writerData)
libcurl write callback function.
Definition: http.cpp:50
static CURL * get_init(const std::string &sUrl, const std::string &sUserName, const std::string &sPassWord, std::string *buffer)
libcurl get connection initialization.
Definition: http.cpp:168
static char errorBuffer[CURL_ERROR_SIZE]
libcurl variable for error strings.
Definition: http.cpp:37
static CURL * put_init(const std::string &sUrl, const std::string &sUserName, const std::string &sPassWord, std::ifstream *filestream, size_t filesize)
libcurl put connection initialization.
Definition: http.cpp:207