crawlserv++  [under development]
Application for crawling and analyzing textual content of websites.
FTPUpload.hpp
Go to the documentation of this file.
1 /*
2  *
3  * ---
4  *
5  * Copyright (C) 2022 Anselm Schmidt (ans[ät]ohai.su)
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version in addition to the terms of any
11  * licences already herein identified.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  *
21  * ---
22  *
23  * FTPUpload.hpp
24  *
25  * Created on: Jan 25, 2022
26  * Author: ans
27  */
28 
29 #ifndef NETWORK_FTPUPLOAD_HPP_
30 #define NETWORK_FTPUPLOAD_HPP_
31 
32 #include "../Wrapper/Curl.hpp"
33 
34 #ifndef CRAWLSERVPP_TESTING
35 
36 #include "../Helper/Portability/curl.h"
37 
38 #else
39 
40 #include "FakeCurl/FakeCurl.hpp"
41 
42 #endif
43 
44 #include <cstddef> // std::size_t
45 #include <cstring> // std::memcpy
46 #include <stdexcept> // std::runtime_error
47 #include <string> // std::string
48 
50 
51  /*
52  * DECLARATION
53  */
54 
56 
69  void write(
70  const std::string& content,
71  const std::string& url,
72  const std::string& proxy = std::string{},
73  bool verbose = false
74  );
75 
77 
86  std::size_t read(char * bufptr, std::size_t size, std::size_t nitems, void * userp);
87 
89 
96  void check(CURLcode code);
97 
98  /*
99  * STRUCTURE
100  */
101 
103  struct State {
105  State() = default;
106 
108  const char * content{nullptr};
109 
111  std::size_t size{};
112 
114  std::size_t transferred{};
115 
117  State(State&) = delete;
118 
120  State(State&&) = delete;
121 
123  State& operator=(State&) = delete;
124 
126  State& operator=(State&&) = delete;
127  };
128 
129  /*
130  * IMPLEMENTATION
131  */
132 
133  void inline write(
134  const std::string& content,
135  const std::string& url,
136  const std::string& proxy,
137  bool verbose
138  ) {
139  Wrapper::Curl curl;
140  State state;
141 
142  state.content = content.c_str();
143  state.size = content.size();
144 
145  if(!curl.valid()) {
146  throw std::runtime_error("Could not initialize libcurl wrapper");
147  }
148 
149  FTPUpload::check(curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str()));
150  FTPUpload::check(curl_easy_setopt(curl.get(), CURLOPT_USE_SSL, CURLUSESSL_TRY));
151  FTPUpload::check(curl_easy_setopt(curl.get(), CURLOPT_UPLOAD, 1L));
152  FTPUpload::check(curl_easy_setopt(curl.get(), CURLOPT_READFUNCTION, FTPUpload::read));
153  FTPUpload::check(curl_easy_setopt(curl.get(), CURLOPT_READDATA, &state));
155  curl_easy_setopt(
156  curl.get(),
157  CURLOPT_INFILESIZE_LARGE,
158  static_cast<curl_off_t>(state.size)
159  )
160  );
161 
162  if(!proxy.empty()) {
163  FTPUpload::check(curl_easy_setopt(curl.get(), CURLOPT_PROXY, proxy.c_str()));
164  }
165 
166  if(verbose) {
167  FTPUpload::check(curl_easy_setopt(curl.get(), CURLOPT_VERBOSE, 1L));
168  }
169 
170  FTPUpload::check(curl_easy_perform(curl.get()));
171  }
172 
173  inline std::size_t read(char * bufptr, std::size_t size, std::size_t nitems, void * userp) {
174  auto toRead{size * nitems};
175  auto * state{static_cast<State *>(userp)};
176  const auto restSize{state->size - state->transferred};
177 
178  if(toRead > restSize) {
179  toRead = restSize;
180  }
181 
182  if(toRead == 0) {
183  return 0;
184  }
185 
186  std::memcpy(bufptr, state->content + state->transferred, toRead);
187 
188  state->transferred += toRead;
189 
190  return toRead;
191  }
192 
193  inline void check(CURLcode code) {
194  if(code != CURLE_OK) {
195  throw std::runtime_error(curl_easy_strerror(code));
196  }
197  }
198 
199 } /* namespace crawlservpp::Network::FTPUpload */
200 
201 #endif /* NETWORK_FTPUPLOAD_HPP_ */
void write(const std::string &content, const std::string &url, const std::string &proxy=std::string{}, bool verbose=false)
Writes data into a FTP file using the libcurl library.
Definition: FTPUpload.hpp:133
std::size_t read(char *bufptr, std::size_t size, std::size_t nitems, void *userp)
Custom reader function for FTP transfers.
Definition: FTPUpload.hpp:173
void check(CURLcode code)
Checks the result of a libcurl operation and throws an exception if an error occured.
Definition: FTPUpload.hpp:193
bool valid() const noexcept
Checks whether the underlying libcurl handle is valid.
Definition: Curl.hpp:214
Definition: FTPUpload.hpp:49
State & operator=(State &)=delete
Deleted copy operator.
RAII wrapper for handles of the libcurl API.
Definition: Curl.hpp:70
CURL * get() noexcept
Gets a pointer to the underlying libcurl handle.
Definition: Curl.hpp:193
State()=default
Default constructor.
Stores content and status of a FTP upload.
Definition: FTPUpload.hpp:103
std::size_t transferred
Number of bytes that have already been uploaded.
Definition: FTPUpload.hpp:114
const char * content
Constant pointer to the content to be uploaded.
Definition: FTPUpload.hpp:108
std::size_t size
Size of the content to be uploaded.
Definition: FTPUpload.hpp:111