Loading...
Searching...
No Matches
fichier_libcurl.hpp
Go to the documentation of this file.
/*********************************************************************/
// dar - disk archive - a backup/restoration program
// Copyright (C) 2002-2024 Denis Corbin
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// to contact the author, see the AUTHOR file
/*********************************************************************/
#ifndef FICHIER_LIBCURL_HPP
#define FICHIER_LIBCURL_HPP
#include "../my_config.h"
extern "C"
{
#if LIBCURL_AVAILABLE
#if HAVE_CURL_CURL_H
#include <curl/curl.h>
#endif
#endif
} // end extern "C"
#include <string>
#ifdef LIBTHREADAR_AVAILABLE
#include <libthreadar/libthreadar.hpp>
#endif
#include "integers.hpp"
#include "user_interaction.hpp"
#include "fichier_global.hpp"
#include "mycurl_protocol.hpp"
#include "mycurl_easyhandle_node.hpp"
namespace libdar
{
#if defined ( LIBCURL_AVAILABLE ) && defined ( LIBTHREADAR_AVAILABLE )
class fichier_libcurl : public fichier_global, protected libthreadar::thread
{
public:
fichier_libcurl(const std::shared_ptr<user_interaction> & dialog, //< for user interaction requested by fichier_global
const std::string & chemin, //< full path of the file to open
mycurl_protocol proto, //< to workaround some libcurl strange behavior for some protocols
const std::shared_ptr<mycurl_easyhandle_node> & handle, //< the easy handle wrapper object
gf_mode m, //< open mode
U_I waiting, //< retry timeout in case of network error
bool force_permission, //< whether file permission should be modified
U_I permission, //< file permission to enforce if force_permission is set
bool erase); //< whether to erase the file before writing to it
fichier_libcurl(const fichier_libcurl & ref) = delete;
fichier_libcurl(fichier_libcurl && ref) = delete;
fichier_libcurl & operator = (const fichier_libcurl & ref) = delete;
fichier_libcurl & operator = (fichier_libcurl && ref) = delete;
~fichier_libcurl() noexcept { kill(); join(); detruit(); };
virtual void change_permission(U_I perm) override;
virtual void change_ownership(const std::string & user, const std::string & group) override
{ throw Efeature(gettext("user/group ownership not supported for this repository")); }; // not supported
virtual infinint get_size() const override;
virtual void fadvise(advise adv) const override {}; // not supported and ignored
// inherited from generic_file
virtual bool skippable(skippability direction, const infinint & amount) override;
virtual bool skip(const infinint & pos) override;
virtual bool skip_to_eof() override;
virtual bool skip_relative(S_I x) override;
virtual bool truncatable(const infinint & pos) const override { return pos == get_position(); };
virtual infinint get_position() const override { return current_offset; };
protected:
// inherited from generic_file grand-parent class
virtual void inherited_read_ahead(const infinint & amount) override;
virtual void inherited_truncate(const infinint & pos) override;
virtual void inherited_sync_write() override;
virtual void inherited_flush_read() override;
virtual void inherited_terminate() override;
// inherited from fichier_global parent class
virtual U_I fichier_global_inherited_write(const char *a, U_I size) override;
virtual bool fichier_global_inherited_read(char *a, U_I size, U_I & read, std::string & message) override;
// inherited from thread
virtual void inherited_run() override;
private:
static const U_I tampon_size = CURL_MAX_WRITE_SIZE;
//
// implementation internals
//
// the object has two modes:
// - meta data mode (skip, get_position() and other non read/write operations)
// - data mode (read or write operations)
//
// in metadata mode each method is a simple code execution (no subthread, no callback)
//
// in data mode, a subthread is used to interact with libcurl. It sends or receives
// data through the interthread pipe. A callback is occasionally run by libcurl in this
// subthread.
// in read mode, the subthread is run only if the interthread is empty. the subthread may
// survive the inherited_read call and may suspend on writing data to interthread being full
// - "subthread_net_offset" is updated by the callback and read by the subthread when
// libcurl has returned it keeps trace of the amount of data sent to interthread.
// - "network_block" is set by the main thread to define the amount of data to be fetched. It
// it used to setup libcurl and is read by the subthread for control/validation purposes
bool end_data_mode;
bool sub_is_dying;
bool sync_write_asked;
bool weof;
std::shared_ptr<mycurl_easyhandle_node> ehandle;
bool metadatamode;
infinint current_offset;
bool has_maxpos;
infinint maxpos;
bool append_write;
U_I meta_inbuf;
U_I wait_delay;
infinint network_block;
infinint subthread_net_offset;
infinint subthread_cur_offset;
libthreadar::fast_tampon<char> interthread;
libthreadar::barrier synchronize;
mycurl_protocol x_proto;
void set_range(const infinint & begin, const infinint & range_size);
void unset_range();
void switch_to_metadata(bool mode);
void detruit();
void run_thread();
void stop_thread();
void relaunch_thread(const infinint & block_size);
void initialize_subthread();
void finalize_subthread();
void set_subthread(U_I & needed_bytes);
bool still_data_to_write();
static size_t write_data_callback(char *buffer, size_t size, size_t nmemb, void *userp);
static size_t read_data_callback(char *bufptr, size_t size, size_t nitems, void *userp);
static size_t write_meta_callback(char *buffer, size_t size, size_t nmemb, void *userp);
static size_t read_meta_callback(char *bufptr, size_t size, size_t nitems, void *userp);
};
#endif
} // end of namespace
#endif
fichier_global.hpp
class fichier_global definition. This class is a pure virtual class class fichier_global is an abstra...
integers.hpp
are defined here basic integer types that tend to be portable
my_config.h
include macro defined by the configure script and some specific additional ones
mycurl_easyhandle_node.hpp
used to optimize session creation done by libcurl
mycurl_protocol.hpp
datastructure defining the network protocols available for entrepot_libcurl class
libdar
libdar namespace encapsulate all libdar symbols
Definition archive.hpp:47
user_interaction.hpp
defines the interaction interface between libdar and users.