Merge pull request #1829 from G10h4ck/rsfiles_links

RsFiles links support in libretroshare + a bunch of fixes
This commit is contained in:
G10h4ck 2020-04-20 17:12:04 +02:00 committed by GitHub
commit 2b44492cb6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
77 changed files with 2949 additions and 1667 deletions

View file

@ -3,7 +3,9 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2019-2020 Retroshare Team <contact@retroshare.cc> *
* Copyright (C) 2019-2020 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2020 Asociación Civil Altermundi <info@altermundi.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -50,7 +52,7 @@ extern RsEvents* rsEvents;
*/
enum class RsEventType : uint32_t
{
NONE = 0, /// Used to detect uninitialized event
__NONE = 0, /// Used internally to detect invalid event type passed
/// @see RsBroadcastDiscovery
BROADCAST_DISCOVERY = 1,
@ -64,7 +66,7 @@ enum class RsEventType : uint32_t
/// @see pqissl
PEER_CONNECTION = 4,
/// @see RsGxsChanges // this one is used in RsGxsBroadcast
/// @see RsGxsChanges, used also in @see RsGxsBroadcast
GXS_CHANGES = 5,
/// Emitted when a peer state changes, @see RsPeers
@ -95,11 +97,62 @@ enum class RsEventType : uint32_t
FILE_TRANSFER = 14,
/// @see RsMsgs
CHAT_MESSAGE = 15,
CHAT_MESSAGE = 15,
MAX /// Used to detect invalid event type passed
__MAX /// Used internally, keep last
};
enum class RsEventsErrorNum : int32_t
{
EVENT_TYPE_UNDEFINED = 3004,
EVENT_TYPE_OUT_OF_RANGE = 3005,
INVALID_HANDLER_ID = 3006,
NULL_EVENT_POINTER = 3007
};
struct RsEventsErrorCategory: std::error_category
{
const char* name() const noexcept override
{ return "RetroShare Events"; }
std::string message(int ev) const override
{
switch (static_cast<RsEventsErrorNum>(ev))
{
case RsEventsErrorNum::EVENT_TYPE_UNDEFINED:
return "Undefined event type";
case RsEventsErrorNum::EVENT_TYPE_OUT_OF_RANGE:
return "Event type out of range";
case RsEventsErrorNum::INVALID_HANDLER_ID:
return "Invalid handler id";
default:
return "Error message for error: " + std::to_string(ev) +
" not available in category: " + name();
}
}
std::error_condition default_error_condition(int ev) const noexcept override;
const static RsEventsErrorCategory instance;
};
namespace std
{
/** Register RsJsonApiErrorNum as an error condition enum, must be in std
* namespace */
template<> struct is_error_condition_enum<RsEventsErrorNum> : true_type {};
}
/** Provide RsEventsErrorNum conversion to std::error_condition, must be in
* same namespace of RsJsonApiErrorNum */
inline std::error_condition make_error_condition(RsEventsErrorNum e) noexcept
{
return std::error_condition(
static_cast<int>(e), RsEventsErrorCategory::instance );
};
/**
* This struct is not meant to be used directly, you should create events type
* deriving from it.
@ -107,7 +160,7 @@ enum class RsEventType : uint32_t
struct RsEvent : RsSerializable
{
protected:
RsEvent(RsEventType type) :
explicit RsEvent(RsEventType type) :
mType(type), mTimePoint(std::chrono::system_clock::now()) {}
RsEvent() = delete;
@ -144,12 +197,10 @@ public:
* @param[in] event
* @param[out] errorMessage Optional storage for error messsage, meaningful
* only on failure.
* @return False on error, true otherwise.
* @return Success or error details.
*/
virtual bool postEvent(
std::shared_ptr<const RsEvent> event,
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
) = 0;
virtual std::error_condition postEvent(
std::shared_ptr<const RsEvent> event ) = 0;
/**
* @brief Send event directly to handlers. Blocking API
@ -157,12 +208,10 @@ public:
* @param[in] event
* @param[out] errorMessage Optional storage for error messsage, meaningful
* only on failure.
* @return False on error, true otherwise.
* @return Success or error details.
*/
virtual bool sendEvent(
std::shared_ptr<const RsEvent> event,
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
) = 0;
virtual std::error_condition sendEvent(
std::shared_ptr<const RsEvent> event ) = 0;
/**
* @brief Generate unique handler identifier
@ -174,8 +223,9 @@ public:
* @brief Register events handler
* Every time an event is dispatced the registered events handlers will get
* their method handleEvent called with the event passed as paramether.
* @attention Callbacks must not fiddle internally with methods of this
* class otherwise a deadlock will happen.
* @jsonapi{development,manualwrapper}
* @param eventType Type of event for which the callback is called
* @param multiCallback Function that will be called each time an event
* is dispatched.
* @param[inout] hId Optional storage for handler id, useful to
@ -183,21 +233,23 @@ public:
* value may be provided to the function call but
* must habe been generated with
* @see generateUniqueHandlerId()
* @return False on error, true otherwise.
* @param[in] eventType Optional type of event for which the callback is
* called, if __NONE is passed multiCallback is
* called for every events without filtering.
* @return Success or error details.
*/
virtual bool registerEventsHandler(
RsEventType eventType,
virtual std::error_condition registerEventsHandler(
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback,
RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0)
) = 0;
RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0),
RsEventType eventType = RsEventType::__NONE ) = 0;
/**
* @brief Unregister event handler
* @param[in] hId Id of the event handler to unregister
* @return True if the handler id has been found, false otherwise.
* @return Success or error details.
*/
virtual bool unregisterEventsHandler(RsEventsHandlerId_t hId) = 0;
virtual std::error_condition unregisterEventsHandler(
RsEventsHandlerId_t hId ) = 0;
virtual ~RsEvents();
};

View file

@ -4,7 +4,8 @@
* libretroshare: retroshare core library *
* *
* Copyright (C) 2008 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2018-2020 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2019-2020 Asociación Civil Altermundi <info@altermundi.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -28,12 +29,14 @@
#include <functional>
#include <chrono>
#include <cstdint>
#include <system_error>
#include "rstypes.h"
#include "serialiser/rsserializable.h"
#include "rsturtle.h"
#include "util/rstime.h"
#include "retroshare/rsevents.h"
#include "util/rsmemory.h"
class RsFiles;
@ -43,6 +46,50 @@ class RsFiles;
*/
extern RsFiles* rsFiles;
enum class RsFilesErrorNum : int32_t
{
FILES_HANDLE_NOT_FOUND = 2004,
};
struct RsFilesErrorCategory: std::error_category
{
const char* name() const noexcept override
{ return "RetroShare Files"; }
std::string message(int ev) const override
{
switch (static_cast<RsFilesErrorNum>(ev))
{
case RsFilesErrorNum::FILES_HANDLE_NOT_FOUND:
return "Files handle not found";
default:
return "Error message for error: " + std::to_string(ev) +
" not available in category: " + name();
}
}
std::error_condition default_error_condition(int ev) const noexcept override;
const static RsFilesErrorCategory instance;
};
namespace std
{
/** Register RsFilesErrorNum as an error condition enum, must be in std
* namespace */
template<> struct is_error_condition_enum<RsFilesErrorNum> : true_type {};
}
/** Provide RsJsonApiErrorNum conversion to std::error_condition, must be in
* same namespace of RsJsonApiErrorNum */
inline std::error_condition make_error_condition(RsFilesErrorNum e) noexcept
{
return std::error_condition(
static_cast<int>(e), RsFilesErrorCategory::instance );
};
namespace RsRegularExpression { class Expression; }
/* These are used mainly by ftController at the moment */
@ -96,8 +143,28 @@ const FileSearchFlags RS_FILE_HINTS_BROWSABLE ( 0x00000100 );// bro
const FileSearchFlags RS_FILE_HINTS_SEARCHABLE ( 0x00000200 );// can be searched anonymously
const FileSearchFlags RS_FILE_HINTS_PERMISSION_MASK ( 0x00000380 );// OR of the last tree flags. Used to filter out.
// Flags used when requesting a transfer
//
/** Flags used when requesting a new file transfer */
enum class FileRequestFlags: uint32_t
{
/// Enable requesting file via turtle routing.
ANONYMOUS_ROUTING = 0x00000040,
/// Asks (TODO: or enforce?) for end-to-end encryption of file trasfer
ENCRYPTED = 0x00000080,
/// Asks (TODO: or enforce?) no end-to-end encryption of file trasfer
UNENCRYPTED = 0x00000100,
/// Start trasfer very slow
SLOW = 0x00002000,
/// Disable searching for potential direct sources
NO_DIRECT_SEARCH = 0x02000000
};
RS_REGISTER_ENUM_FLAGS_TYPE(FileRequestFlags)
/// @deprecated Flags used when requesting a transfer
/// @see FileRequestFlags instead
const TransferRequestFlags RS_FILE_REQ_ANONYMOUS_ROUTING ( 0x00000040 ); // Use to ask turtle router to download the file.
const TransferRequestFlags RS_FILE_REQ_ENCRYPTED ( 0x00000080 ); // Asks for end-to-end encryption of file at the level of ftServer
const TransferRequestFlags RS_FILE_REQ_UNENCRYPTED ( 0x00000100 ); // Asks for no end-to-end encryption of file at the level of ftServer
@ -111,10 +178,6 @@ const TransferRequestFlags RS_FILE_REQ_NO_SEARCH ( 0x02000000 ); // di
// const uint32_t RS_FILE_HINTS_SHARE_FLAGS_MASK = RS_FILE_HINTS_NETWORK_WIDE_OTHERS | RS_FILE_HINTS_BROWSABLE_OTHERS
// | RS_FILE_HINTS_NETWORK_WIDE_GROUPS | RS_FILE_HINTS_BROWSABLE_GROUPS ;
/* Callback Codes */
const uint32_t RS_FILE_EXTRA_DELETE = 0x0010;
enum class RsSharedDirectoriesEventCode: uint8_t {
UNKNOWN = 0x00,
STARTING_DIRECTORY_SWEEP = 0x01, // (void)
@ -202,36 +265,117 @@ struct SharedDirStats
uint64_t total_shared_size ;
};
// This class represents a tree of directories and files, only with their names size and hash. It is used to create collection links in the GUI
// and to transmit directory information between services. This class is independent from the existing FileHierarchy classes used in storage because
// we need a very copact serialization and storage size since we create links with it. Besides, we cannot afford to risk the leak of other local information
// by using the orignal classes.
class FileTree
/** This class represents a tree of directories and files, only with their names
* size and hash. It is used to create collection links in the GUI and to
* transmit directory information between services. This class is independent
* from the existing FileHierarchy classes used in storage because we need a
* very copact serialization and storage size since we create links with it.
* Besides, we cannot afford to risk the leak of other local information
* by using the orignal classes.
*/
struct RsFileTree : RsSerializable
{
public:
virtual ~FileTree() {}
RsFileTree() : mTotalFiles(0), mTotalSize(0) {}
static FileTree *create(const DirDetails& dd, bool remote, bool remove_top_dirs = true) ;
static FileTree *create(const std::string& radix64_string) ;
/**
* @brief Create a RsFileTree from directory details
* @param dd directory or file details
* @param remote
* @param remove_top_dirs
* @return pointer to the created file-tree
*/
static std::unique_ptr<RsFileTree> fromDirDetails(
const DirDetails& dd, bool remote, bool remove_top_dirs = true );
virtual std::string toRadix64() const =0 ;
/**
* @brief Create a RsFileTree from Base64 representation
* @param base64 base64 or base64url string representation of the file-tree
* @return pointer to the parsed file-tree on success, nullptr plus error
* details on failure
*/
static std::tuple<std::unique_ptr<RsFileTree>, std::error_condition>
fromBase64(const std::string& base64);
// These methods allow the user to browse the hierarchy
/** @brief Convert to base64 representetion */
std::string toBase64() const;
struct FileData {
std::string name ;
uint64_t size ;
RsFileHash hash ;
/// @see RsSerializable
virtual void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mFiles);
RS_SERIAL_PROCESS(mDirs);
RS_SERIAL_PROCESS(mTotalFiles);
RS_SERIAL_PROCESS(mTotalSize);
}
struct FileData: RsSerializable
{
std::string name;
uint64_t size;
RsFileHash hash;
void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override;
};
virtual uint32_t root() const { return 0;}
virtual bool getDirectoryContent(uint32_t index,std::string& name,std::vector<uint32_t>& subdirs,std::vector<FileData>& subfiles) const = 0;
/// Allow browsing the hierarchy
bool getDirectoryContent(
std::string& name, std::vector<uint64_t>& subdirs,
std::vector<FileData>& subfiles, uint64_t handle = 0 ) const;
virtual void print() const=0;
struct DirData: RsSerializable
{
std::string name;
std::vector<uint64_t> subdirs;
std::vector<uint64_t> subfiles;
uint32_t mTotalFiles ;
uint64_t mTotalSize ;
void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override;
};
static void recurs_buildFileTree(
RsFileTree& ft, uint32_t index, const DirDetails& dd, bool remote,
bool remove_top_dirs );
std::vector<FileData> mFiles;
std::vector<DirData> mDirs;
uint32_t mTotalFiles;
uint64_t mTotalSize;
virtual ~RsFileTree();
/**
* @brief Create a RsFileTree from Radix64 representation
* @deprecated kept for retrocompatibility with RetroShare-gui
* The format is not compatible with the new methods
* @param radix64_string
* @return nullptr if on failure, pointer to the created FileTree on success
*/
RS_DEPRECATED_FOR(fromBase64)
static std::unique_ptr<RsFileTree> fromRadix64(
const std::string& radix64_string );
/** @brief Convert to radix64 representetion
* @deprecated kept for retrocompatibility with RetroShare-gui
* The format is not compatible with the new methods
*/
RS_DEPRECATED_FOR(toBase64)
std::string toRadix64() const;
private:
/** @deprecated kept for retrocompatibility with RetroShare-gui */
RS_DEPRECATED_FOR(serial_process)
bool serialise(unsigned char *& data,uint32_t& data_size) const;
/** @deprecated kept for retrocompatibility with RetroShare-gui */
RS_DEPRECATED_FOR(serial_process)
bool deserialise(unsigned char* data, uint32_t data_size);
};
struct BannedFileEntry : RsSerializable
@ -258,12 +402,12 @@ struct TurtleFileInfoV2 : RsSerializable
{
TurtleFileInfoV2() : fSize(0), fWeight(0) {}
TurtleFileInfoV2(const TurtleFileInfo& oldInfo) :
explicit TurtleFileInfoV2(const TurtleFileInfo& oldInfo) :
fSize(oldInfo.size), fHash(oldInfo.hash), fName(oldInfo.name),
fWeight(0) {}
#ifdef RS_DEEP_FILES_INDEX
TurtleFileInfoV2(const DeepFilesSearchResult& dRes);
explicit TurtleFileInfoV2(const DeepFilesSearchResult& dRes);
#endif // def RS_DEEP_FILES_INDEX
uint64_t fSize; /// File size
@ -301,9 +445,6 @@ struct TurtleFileInfoV2 : RsSerializable
class RsFiles
{
public:
RsFiles() {}
virtual ~RsFiles() {}
/**
* @brief Provides file data for the GUI, media streaming or API clients.
* It may return unverified chunks. This allows streaming without having to
@ -344,10 +485,10 @@ public:
/**
* @brief Initiate downloading of a file
* @jsonapi{development}
* @param[in] fileName
* @param[in] hash
* @param[in] size
* @param[in] destPath in not empty specify a destination path
* @param[in] fileName file name
* @param[in] hash file hash
* @param[in] size file size
* @param[in] destPath optional specify the destination directory
* @param[in] flags you usually want RS_FILE_REQ_ANONYMOUS_ROUTING
* @param[in] srcIds eventually specify known sources
* @return false if we already have the file, true otherwhise
@ -357,6 +498,25 @@ public:
const std::string& destPath, TransferRequestFlags flags,
const std::list<RsPeerId>& srcIds ) = 0;
/**
* @brief Initiate download of a files collection
* @jsonapi{development}
* An usually useful companion method of this is @see parseFilesLink()
* @param[in] collection collection of files to download
* @param[in] destPath optional base path on which to download the
* collection, if left empty the default download directory will be used
* @param[in] srcIds optional peers id known as direct source of the
* collection
* @param[in] flags optional flags to fine tune search and download
* algorithm
* @return success or error details.
*/
virtual std::error_condition requestFiles(
const RsFileTree& collection,
const std::string& destPath = "",
const std::vector<RsPeerId>& srcIds = std::vector<RsPeerId>(),
FileRequestFlags flags = FileRequestFlags::ANONYMOUS_ROUTING ) = 0;
/**
* @brief Cancel file downloading
* @jsonapi{development}
@ -575,7 +735,7 @@ public:
* @return false if error occurred, true otherwise
*/
virtual bool requestDirDetails(
DirDetails &details, std::uintptr_t handle = 0,
DirDetails &details, uint64_t handle = 0,
FileSearchFlags flags = RS_FILE_HINTS_LOCAL ) = 0;
/***
@ -584,8 +744,9 @@ public:
/**
* Kept for retrocompatibility, it was originally written for easier
* interaction with Qt. As soon as you can, you should prefer to use the
* version of this methodn which take `std::uintptr_t handle` as paramether.
* version of this method which take `uint64_t handle` as paramether.
*/
RS_DEPRECATED_FOR(requestDirDetails)
virtual int RequestDirDetails(
void* handle, DirDetails& details, FileSearchFlags flags ) = 0;
@ -726,6 +887,76 @@ public:
*/
virtual bool removeSharedDirectory(std::string dir) = 0;
/// Default base URL used for files links @see exportFilesLink
static const std::string DEFAULT_FILES_BASE_URL;
/** Link query field used to store collection files count
* @see exportFilesLink */
static const std::string FILES_URL_COUNT_FIELD;
/// Link query field used to store collection data @see exportFilesLink
static const std::string FILES_URL_DATA_FIELD;
/** Link query FILES_URL_DATA_FIELD field value used to instruct the parser
* to look for the data into the link fragment
* @see exportFilesLink and parseFilesLink */
static const std::string FILES_URL_FAGMENT_FORWARD;
/// Link query field used to store collection name @see exportFilesLink
static const std::string FILES_URL_NAME_FIELD;
/// Link query field used to store collection size @see exportFilesLink
static const std::string FILES_URL_SIZE_FIELD;
/**
* @brief Export link to a collection of files
* @jsonapi{development}
* @param[out] link storage for the generated link
* @param[in] handle directory RetroShare handle
* @param[in] fragSneak when true the file data is sneaked into fragment
* instead of FILES_URL_DATA_FIELD query field, this way if using an
* http[s] link to pass around a disguised file link a misconfigured host
* attempting to visit that link with a web browser will not send the file
* data to the server thus protecting at least some of the privacy of the
* user even in a misconfiguration scenario.
* @param[in] baseUrl URL into which to sneak in the RetroShare file link
* base64, this is primarly useful to induce applications into making the
* link clickable, or to disguise the RetroShare link into a "normal"
* looking web link. If empty the collection data link will be outputted in
* plain base64 format.
* @return error information if some error occurred, 0/SUCCESS otherwise
*/
virtual std::error_condition exportCollectionLink(
std::string& link, uint64_t handle, bool fragSneak = false,
const std::string& baseUrl = RsFiles::DEFAULT_FILES_BASE_URL ) = 0;
/**
* @brief Export link to a file
* @jsonapi{development}
* @param[out] link @see exportCollectionLink
* @param[in] fileHash hash of the file
* @param[in] fileSize size of the file
* @param[in] fileName name of the file
* @param[in] fragSneak @see exportCollectionLink
* @param[in] baseUrl @see exportCollectionLink
* @return error @see exportCollectionLink
*/
virtual std::error_condition exportFileLink(
std::string& link, const RsFileHash& fileHash, uint64_t fileSize,
const std::string& fileName, bool fragSneak = false,
const std::string& baseUrl = RsFiles::DEFAULT_FILES_BASE_URL ) = 0;
/**
* @brief Parse RetroShare files link
* @jsonapi{development}
* Support also old RetroShare-gui file and collections links format.
* @param[in] link files link either in base64 or URL format
* @param[out] collection storage for parsed files link
* @return error information if some error occurred, 0/SUCCESS otherwise
*/
virtual std::error_condition parseFilesLink(
const std::string& link, RsFileTree& collection ) = 0;
/**
* @brief Get list of ignored file name prefixes and suffixes
* @param[out] ignoredPrefixes storage for ingored prefixes
@ -757,4 +988,6 @@ public:
virtual bool ignoreDuplicates() = 0;
virtual void setIgnoreDuplicates(bool ignore) = 0;
virtual ~RsFiles() = default;
};

View file

@ -24,6 +24,7 @@
#include <type_traits>
#include <ostream>
#include <bitset>
/** Check if given type is a scoped enum */
template<typename E>
@ -128,13 +129,7 @@ typename std::enable_if<Rs__BitFlagsOps<EFT>::enabled, std::ostream>::type&
operator <<(std::ostream& stream, EFT flags)
{
using u_t = typename std::underlying_type<EFT>::type;
for(int i = sizeof(u_t); i>=0; --i)
{
stream << (flags & ( 1 << i ) ? "1" : "0");
if( i % 8 == 0 ) stream << " ";
}
return stream;
return stream << std::bitset<sizeof(u_t)>(static_cast<u_t>(flags));
}
#include <cstdint>
@ -170,6 +165,7 @@ template<int n> class RS_DEPRECATED_FOR(RS_REGISTER_ENUM_FLAGS_TYPE) t_RsFlags32
inline t_RsFlags32() : _bits(0) {}
inline explicit t_RsFlags32(uint32_t N) : _bits(N) {} // allows initialization from a set of uint32_t
inline t_RsFlags32<n> operator| (const t_RsFlags32<n>& f) const { return t_RsFlags32<n>(_bits | f._bits) ; }
inline t_RsFlags32<n> operator^ (const t_RsFlags32<n>& f) const { return t_RsFlags32<n>(_bits ^ f._bits) ; }
inline t_RsFlags32<n> operator* (const t_RsFlags32<n>& f) const { return t_RsFlags32<n>(_bits & f._bits) ; }
@ -187,6 +183,19 @@ template<int n> class RS_DEPRECATED_FOR(RS_REGISTER_ENUM_FLAGS_TYPE) t_RsFlags32
//inline explicit operator bool() const { return _bits>0; }
inline uint32_t toUInt32() const { return _bits ; }
/// Easier porting to new flag system
template<typename EFT> inline
typename std::enable_if<(Rs__BitFlagsOps<EFT>::enabled &&
sizeof(EFT) >= sizeof(uint32_t) ), EFT>::type
toEFT() { return static_cast<EFT>(_bits); }
/// Easier porting to new flag system
template<typename EFT>
static inline typename std::enable_if<
Rs__BitFlagsOps<EFT>::enabled &&
sizeof(EFT) <= sizeof(uint32_t), t_RsFlags32>::type
fromEFT(EFT e) { return t_RsFlags32(static_cast<uint32_t>(e)); }
void clear() { _bits = 0 ; }
friend std::ostream& operator<<(std::ostream& o,const t_RsFlags32<n>& f) // friendly print with 0 and I
@ -199,8 +208,10 @@ template<int n> class RS_DEPRECATED_FOR(RS_REGISTER_ENUM_FLAGS_TYPE) t_RsFlags32
}
return o ;
}
private:
uint32_t _bits ;
private:
friend struct RsTypeSerializer;
uint32_t _bits;
};
#define FLAGS_TAG_TRANSFER_REQS 0x4228af
@ -210,9 +221,9 @@ template<int n> class RS_DEPRECATED_FOR(RS_REGISTER_ENUM_FLAGS_TYPE) t_RsFlags32
#define FLAGS_TAG_SERVICE_CHAT 0x839042
#define FLAGS_TAG_SERIALIZER 0xa0338d
// Flags for requesting transfers, ask for turtle, cache, speed, etc.
//
typedef t_RsFlags32<FLAGS_TAG_TRANSFER_REQS> TransferRequestFlags ;
/// @deprecated Flags for requesting transfers, ask for turtle, cache, speed, etc.
RS_DEPRECATED_FOR(FileRequestFlags)
typedef t_RsFlags32<FLAGS_TAG_TRANSFER_REQS> TransferRequestFlags;
// Flags for file storage. Mainly permissions like BROWSABLE/NETWORK_WIDE for groups and peers.
//
@ -230,7 +241,3 @@ typedef t_RsFlags32<FLAGS_TAG_SERVICE_PERM > ServicePermissionFlags ;
//
typedef t_RsFlags32<FLAGS_TAG_SERVICE_CHAT > ChatLobbyFlags ;
// Flags for serializer
//
typedef t_RsFlags32<FLAGS_TAG_SERIALIZER > SerializationFlags ;

View file

@ -4,7 +4,8 @@
* libretroshare: retroshare core library *
* *
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2018-2020 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2019-2020 Asociación Civil Altermundi <info@altermundi.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -283,26 +284,6 @@ public:
*/
virtual bool ExtraFileRemove(const RsFileHash& hash) = 0;
/**
* @brief Get auto-download option value for given channel
* @jsonapi{development}
* @param[in] channelId channel id
* @param[out] enabled storage for the auto-download option value
* @return false if something failed, true otherwhise
*/
virtual bool getChannelAutoDownload(
const RsGxsGroupId& channelId, bool& enabled ) = 0;
/**
* @brief Get download directory for the given channel
* @jsonapi{development}
* @param[in] channelId id of the channel
* @param[out] directory reference to string where to store the path
* @return false on error, true otherwise
*/
virtual bool getChannelDownloadDirectory( const RsGxsGroupId& channelId,
std::string& directory ) = 0;
/**
* @brief Get channels summaries list. Blocking API.
* @jsonapi{development}
@ -331,13 +312,15 @@ public:
* @param[out] comments storage for the comments
* @return false if something failed, true otherwhise
*/
virtual bool getChannelAllContent(const RsGxsGroupId& channelId,
virtual bool getChannelAllContent( const RsGxsGroupId& channelId,
std::vector<RsGxsChannelPost>& posts,
std::vector<RsGxsComment>& comments ) = 0;
/**
* @brief Get channel messages and comments corresponding to the given message ID list. If the list is empty, nothing is returned. Since
* comments are themselves messages, it is possible to get comments only by only supplying their message IDs.
* @brief Get channel messages and comments corresponding to the given IDs.
* If the set is empty, nothing is returned.
* @note Since comments are internally themselves messages, it is possible
* to get comments only by supplying their IDs.
* @jsonapi{development}
* @param[in] channelId id of the channel of which the content is requested
* @param[in] contentsIds ids of requested contents
@ -345,8 +328,8 @@ public:
* @param[out] comments storage for the comments
* @return false if something failed, true otherwhise
*/
virtual bool getChannelContent(const RsGxsGroupId& channelId,
const std::set<RsGxsMessageId>& contentIds,
virtual bool getChannelContent( const RsGxsGroupId& channelId,
const std::set<RsGxsMessageId>& contentsIds,
std::vector<RsGxsChannelPost>& posts,
std::vector<RsGxsComment>& comments ) = 0;
@ -369,16 +352,6 @@ public:
*/
virtual bool markRead(const RsGxsGrpMsgIdPair& postId, bool read) = 0;
/**
* @brief Enable or disable auto-download for given channel. Blocking API
* @jsonapi{development}
* @param[in] channelId channel id
* @param[in] enable true to enable, false to disable
* @return false if something failed, true otherwhise
*/
virtual bool setChannelAutoDownload(
const RsGxsGroupId& channelId, bool enable ) = 0;
/**
* @brief Share channel publishing key
* This can be used to authorize other peers to post on the channel
@ -390,16 +363,6 @@ public:
virtual bool shareChannelKeys(
const RsGxsGroupId& channelId, const std::set<RsPeerId>& peers ) = 0;
/**
* @brief Set download directory for the given channel. Blocking API.
* @jsonapi{development}
* @param[in] channelId id of the channel
* @param[in] directory path
* @return false on error, true otherwise
*/
virtual bool setChannelDownloadDirectory(
const RsGxsGroupId& channelId, const std::string& directory) = 0;
/**
* @brief Subscrbe to a channel. Blocking API
* @jsonapi{development}
@ -525,8 +488,62 @@ public:
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
/* Following functions are deprecated as they expose internal functioning
* semantic, instead of a safe to use API */
/* Following functions are deprecated and should not be considered a safe to
* use API */
/**
* @brief Get auto-download option value for given channel
* @jsonapi{development}
* @deprecated This feature rely on very buggy code, the returned value is
* not reliable @see setChannelAutoDownload().
* @param[in] channelId channel id
* @param[out] enabled storage for the auto-download option value
* @return false if something failed, true otherwhise
*/
RS_DEPRECATED
virtual bool getChannelAutoDownload(
const RsGxsGroupId& channelId, bool& enabled ) = 0;
/**
* @brief Enable or disable auto-download for given channel. Blocking API
* @jsonapi{development}
* @deprecated This feature rely on very buggy code, when enabled the
* channel service start flooding erratically log with error messages,
* apparently without more dangerous consequences. Still those messages
* hints that something out of control is happening under the hood, use at
* your own risk. A safe alternative to this method can easly implemented
* at API client level instead.
* @param[in] channelId channel id
* @param[in] enable true to enable, false to disable
* @return false if something failed, true otherwhise
*/
RS_DEPRECATED
virtual bool setChannelAutoDownload(
const RsGxsGroupId& channelId, bool enable ) = 0;
/**
* @brief Get download directory for the given channel
* @jsonapi{development}
* @deprecated @see setChannelAutoDownload()
* @param[in] channelId id of the channel
* @param[out] directory reference to string where to store the path
* @return false on error, true otherwise
*/
RS_DEPRECATED
virtual bool getChannelDownloadDirectory( const RsGxsGroupId& channelId,
std::string& directory ) = 0;
/**
* @brief Set download directory for the given channel. Blocking API.
* @jsonapi{development}
* @deprecated @see setChannelAutoDownload()
* @param[in] channelId id of the channel
* @param[in] directory path
* @return false on error, true otherwise
*/
RS_DEPRECATED
virtual bool setChannelDownloadDirectory(
const RsGxsGroupId& channelId, const std::string& directory) = 0;
/**
* @brief Create channel. Blocking API.

View file

@ -305,10 +305,10 @@ public:
static const std::string FORUM_URL_DATA_FIELD;
/** Link query field used to store forum message title
* @see exportChannelLink */
* @see exportForumLink */
static const std::string FORUM_URL_MSG_TITLE_FIELD;
/// Link query field used to store forum message id @see exportChannelLink
/// Link query field used to store forum message id @see exportForumLink
static const std::string FORUM_URL_MSG_ID_FIELD;
/**

View file

@ -3,8 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2011 by Christopher Evi-Parker *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2011 Christopher Evi-Parker *
* Copyright (C) 2018-2020 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -30,6 +30,7 @@
#include "retroshare/rsreputations.h"
#include "rsgxsflags.h"
#include "util/rsdeprecate.h"
#include "util/rsdebug.h"
/*!
* This class only make method of internal members visible tu upper level to
@ -46,7 +47,7 @@
enum class TokenRequestType: uint8_t
{
UNDEFINED = 0x00,
__NONE = 0x00, /// Used to detect uninitialized
GROUP_DATA = 0x01,
GROUP_META = 0x02,
POSTS = 0x03,
@ -55,6 +56,7 @@ enum class TokenRequestType: uint8_t
GROUP_STATISTICS = 0x06,
SERVICE_STATISTICS = 0x07,
NO_KILL_TYPE = 0x08,
__MAX /// Used to detect out of range
};
class RsGxsIfaceHelper
@ -64,10 +66,11 @@ public:
* @param gxs handle to RsGenExchange instance of service (Usually the
* service class itself)
*/
RsGxsIfaceHelper(RsGxsIface& gxs) :
mGxs(gxs), mTokenService(*gxs.getTokenService()),mMtx("GxsIfaceHelper") {}
explicit RsGxsIfaceHelper(RsGxsIface& gxs) :
mGxs(gxs), mTokenService(*gxs.getTokenService()), mMtx("GxsIfaceHelper")
{}
~RsGxsIfaceHelper(){}
~RsGxsIfaceHelper() = default;
/*!
* Gxs services should call this for automatic handling of
@ -444,9 +447,9 @@ protected:
uint32_t token,
std::chrono::milliseconds maxWait = std::chrono::milliseconds(20000),
std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100),
bool auto_delete_if_unsuccessful=true)
bool auto_delete_if_unsuccessful=true)
{
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
auto wkStartime = std::chrono::steady_clock::now();
int maxWorkAroundCnt = 10;
LLwaitTokenBeginLabel:
@ -454,13 +457,14 @@ LLwaitTokenBeginLabel:
auto timeout = std::chrono::steady_clock::now() + maxWait;
auto st = requestStatus(token);
while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout )
while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE)
&& std::chrono::steady_clock::now() < timeout )
{
std::this_thread::sleep_for(checkEvery);
st = requestStatus(token);
}
if(st != RsTokenService::COMPLETE && auto_delete_if_unsuccessful)
cancelRequest(token);
if(st != RsTokenService::COMPLETE && auto_delete_if_unsuccessful)
cancelRequest(token);
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
/* Work around for very slow/old android devices, we don't expect this
@ -487,35 +491,39 @@ LLwaitTokenBeginLabel:
#endif
{
RS_STACK_MUTEX(mMtx);
RS_STACK_MUTEX(mMtx);
mActiveTokens.erase(token);
}
}
return st;
}
return st;
}
private:
RsGxsIface& mGxs;
RsTokenService& mTokenService;
RsMutex mMtx;
RsMutex mMtx;
std::map<uint32_t,TokenRequestType> mActiveTokens;
std::map<uint32_t,TokenRequestType> mActiveTokens;
void locked_dumpTokens()
{
uint16_t service_id = mGxs.serviceType();
void locked_dumpTokens()
{
const uint16_t service_id = mGxs.serviceType();
const auto countSize = static_cast<size_t>(TokenRequestType::__MAX);
uint32_t count[countSize] = {0};
uint32_t count[7] = {0};
RsDbg() << __PRETTY_FUNCTION__ << "Service 0x" << std::hex << service_id
<< " (" << rsServiceControl->getServiceName(
RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(service_id) )
<< ") this=0x" << static_cast<void*>(this)
<< ") Active tokens (per type): ";
RsDbg() << "Service " << std::hex << service_id << std::dec
<< " (" << rsServiceControl->getServiceName(RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(service_id))
<< ") this=" << std::hex << (void*)this << std::dec << ") Active tokens (per type): " ;
// let's count how many token of each type we've got.
for(auto& it: mActiveTokens) ++count[static_cast<size_t>(it.second)];
for(auto& it: mActiveTokens) // let's count how many token of each type we've got.
++count[static_cast<int>(it.second)];
for(uint32_t i=0; i < countSize; ++i)
RsDbg().uStream() /* << i << ":" */ << count[i] << " ";
RsDbg().uStream() << std::endl;
}
for(uint32_t i=0;i<7;++i)
std::cerr << std::dec /* << i << ":" */ << count[i] << " ";
std::cerr << std::endl;
}
RS_SET_CONTEXT_DEBUG_LEVEL(1)
};

View file

@ -193,55 +193,50 @@ struct RsMsgMetaData : RsSerializable
struct RsGxsGenericMsgData
{
virtual ~RsGxsGenericMsgData() = default; // making the type polymorphic
virtual ~RsGxsGenericMsgData() = default; // making the type polymorphic
RsMsgMetaData mMeta;
};
class GxsGroupStatistic
struct GxsGroupStatistic : RsSerializable
{
public:
GxsGroupStatistic()
GxsGroupStatistic() :
mNumMsgs(0), mTotalSizeOfMsgs(0), mNumThreadMsgsNew(0),
mNumThreadMsgsUnread(0), mNumChildMsgsNew(0), mNumChildMsgsUnread(0) {}
/// @see RsSerializable
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override
{
mNumMsgs = 0;
mTotalSizeOfMsgs = 0;
mNumThreadMsgsNew = 0;
mNumThreadMsgsUnread = 0;
mNumChildMsgsNew = 0;
mNumChildMsgsUnread = 0;
RS_SERIAL_PROCESS(mGrpId);
RS_SERIAL_PROCESS(mNumMsgs);
RS_SERIAL_PROCESS(mTotalSizeOfMsgs);
RS_SERIAL_PROCESS(mNumThreadMsgsNew);
RS_SERIAL_PROCESS(mNumThreadMsgsUnread);
RS_SERIAL_PROCESS(mNumChildMsgsNew);
RS_SERIAL_PROCESS(mNumChildMsgsUnread);
}
public:
/// number of message
RsGxsGroupId mGrpId;
uint32_t mNumMsgs; // from the database
RsGxsGroupId mGrpId;
uint32_t mNumMsgs; /// number of message, from the database
uint32_t mTotalSizeOfMsgs;
uint32_t mNumThreadMsgsNew;
uint32_t mNumThreadMsgsUnread;
uint32_t mNumChildMsgsNew;
uint32_t mNumChildMsgsUnread;
uint32_t mNumChildMsgsUnread;
~GxsGroupStatistic() override;
};
class GxsServiceStatistic
struct GxsServiceStatistic : RsSerializable
{
public:
GxsServiceStatistic()
{
mNumMsgs = 0;
mNumGrps = 0;
mSizeOfMsgs = 0;
mSizeOfGrps = 0;
mNumGrpsSubscribed = 0;
mNumThreadMsgsNew = 0;
mNumThreadMsgsUnread = 0;
mNumChildMsgsNew = 0;
mNumChildMsgsUnread = 0;
mSizeStore = 0;
}
GxsServiceStatistic() :
mNumMsgs(0), mNumGrps(0), mSizeOfMsgs(0), mSizeOfGrps(0),
mNumGrpsSubscribed(0), mNumThreadMsgsNew(0), mNumThreadMsgsUnread(0),
mNumChildMsgsNew(0), mNumChildMsgsUnread(0), mSizeStore(0) {}
public:
uint32_t mNumMsgs;
uint32_t mNumGrps;
uint32_t mSizeOfMsgs;
@ -252,32 +247,35 @@ public:
uint32_t mNumChildMsgsNew;
uint32_t mNumChildMsgsUnread;
uint32_t mSizeStore;
/// @see RsSerializable
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override
{
RS_SERIAL_PROCESS(mNumMsgs);
RS_SERIAL_PROCESS(mNumGrps);
RS_SERIAL_PROCESS(mSizeOfMsgs);
RS_SERIAL_PROCESS(mSizeOfGrps);
RS_SERIAL_PROCESS(mNumGrpsSubscribed);
RS_SERIAL_PROCESS(mNumThreadMsgsNew);
RS_SERIAL_PROCESS(mNumThreadMsgsUnread);
RS_SERIAL_PROCESS(mNumChildMsgsNew);
RS_SERIAL_PROCESS(mNumChildMsgsUnread);
RS_SERIAL_PROCESS(mSizeStore);
}
~GxsServiceStatistic() override;
};
class UpdateItem
{
public:
virtual ~UpdateItem() { }
};
class StringUpdateItem : public UpdateItem
{
public:
StringUpdateItem(const std::string update) : mUpdate(update) {}
const std::string& getUpdate() const { return mUpdate; }
private:
std::string mUpdate;
};
class RsGxsGroupUpdateMeta
class RS_DEPRECATED RsGxsGroupUpdateMeta
{
public:
// expand as support is added for other utypes
enum UpdateType { DESCRIPTION, NAME };
RsGxsGroupUpdateMeta(const RsGxsGroupId& groupId) : mGroupId(groupId) {}
explicit RsGxsGroupUpdateMeta(const RsGxsGroupId& groupId):
mGroupId(groupId) {}
typedef std::map<UpdateType, std::string> GxsMetaUpdate;

View file

@ -37,7 +37,7 @@
#include "serialiser/rstypeserializer.h"
#include "util/rsdeprecate.h"
struct RsIdentity;
class RsIdentity;
/**
* Pointer to global instance of RsIdentity service implementation

View file

@ -1,7 +1,7 @@
/*
* RetroShare JSON API public header
*
* Copyright (C) 2018-2020 Gioacchino Mazzurco <gio.eigenlab.org>
* Copyright (C) 2018-2020 Gioacchino Mazzurco <gio@eigenlab.org>
* Copyright (C) 2019 Cyril Soler <csoler@users.sourceforge.net>
* Copyright (C) 2020 Asociación Civil Altermundi <info@altermundi.net>
*

View file

@ -3,7 +3,9 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2004-2008 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2004-2008 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2018-2020 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2020 Asociación Civil Altermundi <info@altermundi.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -468,7 +470,7 @@ struct RsGroupInfo : RsSerializable
struct RsPeerStateChangedEvent : RsEvent
{
/// @param[in] sslId is of the peer which changed state
RsPeerStateChangedEvent(RsPeerId sslId);
explicit RsPeerStateChangedEvent(RsPeerId sslId);
/// Storage fot the id of the peer that changed state
RsPeerId mSslId;
@ -605,7 +607,15 @@ public:
virtual bool getAssociatedSSLIds(const RsPgpId& gpg_id, std::list<RsPeerId>& ids) = 0;
virtual bool gpgSignData(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason = "") = 0;
virtual RsPgpId pgpIdFromFingerprint(const RsPgpFingerprint& fpr) = 0;
/**
* @brief Convert PGP fingerprint to PGP id
* @jsonapi{development}
* Helper method useful while we port the whole RetroShare codebase from
* RsPgpId to RsPgpFingerprint
* @param[in] fpr PGP fingerprint to convert
* @return PGP id corresponding to the fingerprint
*/
virtual RsPgpId pgpIdFromFingerprint(const RsPgpFingerprint& fpr) = 0;
// Note: the two methods below could be unified. The fact that one of them can take an optional RsPeerDetails struct as parameter
// seems quite inconsistent.
@ -803,7 +813,7 @@ public:
ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT ) = 0;
/* Auth Stuff */
RS_DEPRECATED /// This function doesn't provide meaningful error reporting
virtual std::string getPGPKey(const RsPgpId& pgp_id,bool include_signatures) = 0;
virtual bool GetPGPBase64StringAndCheckSum(const RsPgpId& gpg_id,std::string& gpg_base64_string,std::string& gpg_base64_checksum) = 0;

View file

@ -201,7 +201,8 @@ struct FileInfo : RsSerializable
std::string path;
std::string fname;
RsFileHash hash;
std::string ext;
RS_DEPRECATED std::string ext; /// @deprecated unused
uint64_t size;
uint64_t avail; /// how much we have
@ -303,10 +304,16 @@ struct DirDetails : RsSerializable
type(DIR_TYPE_UNKNOWN), count(0), mtime(0), max_mtime(0) {}
/* G10h4ck do we still need to keep this as void* instead of uint64_t for
* retroshare-gui sake? */
void* parent;
int prow; /* parent row */
/* G10h4ck do we still need to keep this as void* instead of uint64_t for
* retroshare-gui sake? */
void* ref;
uint8_t type;
RsPeerId id;
std::string name;
@ -322,36 +329,18 @@ struct DirDetails : RsSerializable
/// @see RsSerializable
void serial_process(RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx)
RsGenericSerializer::SerializeContext& ctx) override
{
#if defined(__GNUC__) && !defined(__clang__)
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif // defined(__GNUC__) && !defined(__clang__)
/* Enforce serialization as uint64_t because void* changes size
* depending (usually 4 bytes on 32bit arch and 8 bytes on 64bit archs)
*/
uint64_t handle = reinterpret_cast<uint64_t>(ref);
RS_SERIAL_PROCESS(handle);
ref = reinterpret_cast<void*>(handle);
// (Cyril) We have to do this because on some systems (MacOS) uintptr_t is unsigned long which is not well defined. It is always
// preferable to force type serialization to the correct size rather than letting the compiler choose for us.
// /!\ This structure cannot be sent over the network. The serialization would be inconsistent.
if(sizeof(ref) == 4)
{
std::uint32_t& handle(reinterpret_cast<std::uint32_t&>(ref));
RS_SERIAL_PROCESS(handle);
std::uint32_t& parentHandle(reinterpret_cast<std::uint32_t&>(parent));
RS_SERIAL_PROCESS(parentHandle);
}
else if(sizeof(ref) == 8)
{
std::uint64_t& handle(reinterpret_cast<std::uint64_t&>(ref));
RS_SERIAL_PROCESS(handle);
std::uint64_t& parentHandle(reinterpret_cast<std::uint64_t&>(parent));
RS_SERIAL_PROCESS(parentHandle);
}
else
std::cerr << __PRETTY_FUNCTION__ << ": cannot serialize raw pointer of size " << sizeof(ref) << std::endl;
#if defined(__GNUC__) && !defined(__clang__)
# pragma GCC diagnostic pop
#endif // defined(__GNUC__) && !defined(__clang__)
uint64_t parentHandle = reinterpret_cast<uint64_t>(parent);
RS_SERIAL_PROCESS(parentHandle);
parent = reinterpret_cast<void*>(parentHandle);
RS_SERIAL_PROCESS(prow);
RS_SERIAL_PROCESS(type);
@ -366,6 +355,8 @@ struct DirDetails : RsSerializable
RS_SERIAL_PROCESS(children);
RS_SERIAL_PROCESS(parent_groups);
}
~DirDetails() override = default;
};
class FileDetail