-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmarc_rest_client.h
248 lines (209 loc) · 8.07 KB
/
marc_rest_client.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/*****************************************************************************
*
* Copyright (c) 2018-2020, Oleg `Kanedias` Chernovskiy
*
* This file is part of MARC-FS.
*
* MARC-FS 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 3 of the License, or
* (at your option) any later version.
*
* MARC-FS 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 MARC-FS. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef API_H
#define API_H
#include <memory>
#include <limits>
#include <vector>
#include <string>
#include "account.h"
#include "marc_api_shard.h"
#include "marc_api_cloudfile.h"
#include "curl_cookie.h"
#include "utils.h"
#define MARCFS_MAX_FILE_SIZE ((1L << 31) - (1L << 10)) // 2 GB except 1 KB for multipart boundaries etc.
//#define MARCFS_MAX_FILE_SIZE (1L << 25) // 32 MiB - for tests
#define MARCFS_SUFFIX ".marcfs-part-"
extern const std::string SCLD_PUBLICLINK_ENDPOINT;
class AbstractStorage;
/**
* @brief The MarcRestClient class - Abstraction layer between FUSE API and Mail.ru Cloud API.
*
* This class is used in an object pool to perform various lookups/calls to Mail.ru cloud.
* It operates via cURL calls to specified endpoints. There is no public Cloud docs exposed
* so all calls here are reverse-engineered from browser-to-cloud interaction.
*
* cURL connects via HTTPS protocol, so uses libcrypto PKIX. This means that there are
* engine initialization, handshake, keys and other memory-pressing entities created
* as a result of exchange. Valgrind may report false-positives for calls from here
* that appear because libcrypto initializes its engine partially on garbage heap data.
*
* @see mru_metadata.h
* @see fuse_hooks.cpp
*/
class MarcRestClient
{
public:
using Params = std::map<std::string, std::string>;
MarcRestClient();
/**
* @brief MarcRestClient - for copying already authenticated rest client.
* copies account and cookies from the argument
* @param toCopy - readied client
*/
MarcRestClient(MarcRestClient &toCopy);
/**
* @brief setProxy - set proxy URL to use. Syntax is same as in libcurl API.
* @param proxyUrl - string representing proxy URL (better with scheme). Should not be empty.
*/
void setProxy(std::string proxyUrl);
/**
* @brief setMaxDownloadRate - set maximum download rate for this client, in bytes.
* @param rate - rate to set
*/
void setMaxDownloadRate(uint64_t rate);
/**
* @brief setMaxUploadRate - set maximum upload rate for this client, in bytes.
* @param rate - rate to set
*/
void setMaxUploadRate(uint64_t rate);
/**
* @brief API::login Sends auth info and initializes this API object on successful login.
* @param acc account to auth with
* @return true if authenticated successfully, false otherwise.
*/
bool login(const Account& acc);
/**
* @brief upload uploads bytes in @param body to remote endpoint
* @param remotePath remote path to folder where uploaded file should be (e.g. /newfolder)
*/
void upload(std::string remotePath, AbstractStorage &body, off_t start = 0, off_t count = std::numeric_limits<off_t>::max());
/**
* @brief create - create empty file at path
*/
void create(std::string remotePath);
/**
* @brief mkdir creates a directory noted by remotePath
* @param remote_path new directory absolute path (e.g. /home/newfolder)
*/
void mkdir(std::string remotePath);
/**
* @brief ls list entries in a directory
* @param remote_path absolute path to directory to list
* @return vector of file items
*/
std::vector<CloudFile> ls(std::string remotePath);
/**
* @brief download download file pointed by remotePath to local path
* @param remotePath remote path on cloud server
* @param target target of download operation - resulting bytes are appended there
*/
void download(std::string remotePath, AbstractStorage &target);
/**
* @brief remove removes file pointed by remotePath from cloud storage
* @param remotePath remote path on cloud server
*/
void remove(std::string remotePath);
/**
* @brief df - report file system disk space usage
*
* REST API actually doesn't provide exact numbers of total bytes,
* block size, used blocks etc., so only rough precision may be used.
*
* @return SpaceInfo struct with total and used fields filled in
*/
SpaceInfo df();
/**
* @brief rename - renames (moves) file from @param oldRemotePath
* to @param newRemotePath. Overwrites destination file if
* it's already present.
*
* @param oldRemotePath full path to file to be renamed
* @param newRemotePath full new path to file
*/
void rename(std::string oldRemotePath, std::string newRemotePath);
/**
* @brief share - create a share-link for the existing node
* @param remotePath - path to the remote file
* @return url to shared file as a string
*/
std::string share(std::string remotePath);
private:
// api helpers
// generic
/**
* @brief obtainShard obtains shard for next operation. It contains url to load-balanced
* host to which request will be sent
* @param type type of shard to obtain
* @return Shard of selected type
* @throws MailApiException in case of non-success return code
*/
Shard obtainShard(Shard::ShardType type);
// filesystem-related
/**
* @brief addUploadedFile adds uploaded file by hash to remote dir on cloud server.
* This operation is required after uploading a file because it makes a hard link
* to an uploaded file from your cloud storage.
* @param name name of file to be added
* @param remoteDir remote directory on cloud server
* @param hashSize hash and size of file delimited by colon
*/
void addUploadedFile(std::string name, std::string remoteDir, std::string hash, size_t size);
/**
* @brief move - moves file from one directory to another.
* This operation complements @fn rename call
* if destination file is in another dir.
*
* @param whatToMove - file/folder to be moved
* @param whereToMove - destination directory
*/
void move(std::string whatToMove, std::string whereToMove);
// auth
/**
* @brief API::authenticate - retrieves initial authentication cookies
*
* This actually uses provided auth details to create am authenticated session.
* The cookies gained are stored and later reused in all operations.
*
* @throws MailApiException in case of auth failure
*/
void authenticate();
/**
* @brief API::openMainPage - retrieves main page and all associated cookies
*/
void openMainPage();
/**
* @brief API::openCloudPage - retrieves cloud page and associated CSRF token
*/
void openCloudPage();
/**
* @brief API::obtainAuthToken - retrieve auth token.
*
* This is the first step in Mail.ru Cloud REST API exchange.
* Then token is unique to exchange session, so it is stored and can be reused.
*
* @throws MailApiException in case of failure
*/
void obtainAuthToken();
// cURL helpers
std::string paramString(Params const ¶ms);
std::string performAction(curl::curl_header *forced_headers = nullptr);
void performGet(AbstractStorage &target);
std::unique_ptr<curl::curl_easy> restClient;
curl::curl_cookie cookieStore;
std::string proxyUrl;
uint64_t maxUploadRate = 0;
uint64_t maxDownloadRate = 0;
Account authAccount;
std::string actToken;
std::string csrfToken;
int64_t verbose = 0;
};
#endif // API_H