summaryrefslogtreecommitdiff
path: root/plugins/CloudFile/src/Services
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/CloudFile/src/Services')
-rw-r--r--plugins/CloudFile/src/Services/dropbox_api.h18
-rw-r--r--plugins/CloudFile/src/Services/dropbox_service.cpp59
-rw-r--r--plugins/CloudFile/src/Services/dropbox_service.h6
-rw-r--r--plugins/CloudFile/src/Services/google_api.h10
-rw-r--r--plugins/CloudFile/src/Services/google_service.cpp87
-rw-r--r--plugins/CloudFile/src/Services/google_service.h8
-rw-r--r--plugins/CloudFile/src/Services/microsoft_api.h31
-rw-r--r--plugins/CloudFile/src/Services/microsoft_service.cpp54
-rw-r--r--plugins/CloudFile/src/Services/microsoft_service.h6
-rw-r--r--plugins/CloudFile/src/Services/yandex_api.h24
-rw-r--r--plugins/CloudFile/src/Services/yandex_service.cpp93
-rw-r--r--plugins/CloudFile/src/Services/yandex_service.h5
12 files changed, 217 insertions, 184 deletions
diff --git a/plugins/CloudFile/src/Services/dropbox_api.h b/plugins/CloudFile/src/Services/dropbox_api.h
index 3db69250e8..890ff420f6 100644
--- a/plugins/CloudFile/src/Services/dropbox_api.h
+++ b/plugins/CloudFile/src/Services/dropbox_api.h
@@ -58,23 +58,23 @@ namespace DropboxAPI
}
};
- class StartUploadSessionRequest : public HttpRequest
+ class CreateUploadSessionRequest : public HttpRequest
{
public:
- StartUploadSessionRequest(const char *token, const char *data, size_t size) :
+ CreateUploadSessionRequest(const char *token, const char *chunk, size_t chunkSize) :
HttpRequest(REQUEST_POST, DROPBOX_API_CU "/files/upload_session/start")
{
AddBearerAuthHeader(token);
AddHeader("Content-Type", "application/octet-stream");
- SetData(data, size);
+ SetData(chunk, chunkSize);
}
};
- class AppendToUploadSessionRequest : public HttpRequest
+ class UploadFileChunkRequest : public HttpRequest
{
public:
- AppendToUploadSessionRequest(const char *token, const char *sessionId, size_t offset, const char *data, size_t size) :
+ UploadFileChunkRequest(const char *token, const char *sessionId, size_t offset, const char *chunk, size_t chunkSize) :
HttpRequest(REQUEST_POST, DROPBOX_API_CU "/files/upload_session/append_v2")
{
AddBearerAuthHeader(token);
@@ -92,14 +92,14 @@ namespace DropboxAPI
AddHeader("Dropbox-API-Arg", param.write().c_str());
- SetData(data, size);
+ SetData(chunk, chunkSize);
}
};
- class FinishUploadSessionRequest : public HttpRequest
+ class CommitUploadSessionRequest : public HttpRequest
{
public:
- FinishUploadSessionRequest(const char *token, const char *sessionId, size_t offset, const char *path, const char *data, size_t size) :
+ CommitUploadSessionRequest(const char *token, const char *sessionId, size_t offset, const char *path, const char *chunk, size_t chunkSize) :
HttpRequest(REQUEST_POST, DROPBOX_API_CU "/files/upload_session/finish")
{
AddBearerAuthHeader(token);
@@ -124,7 +124,7 @@ namespace DropboxAPI
AddHeader("Dropbox-API-Arg", params.write().c_str());
- SetData(data, size);
+ SetData(chunk, chunkSize);
}
};
diff --git a/plugins/CloudFile/src/Services/dropbox_service.cpp b/plugins/CloudFile/src/Services/dropbox_service.cpp
index 409494e9d3..fdd904e5e3 100644
--- a/plugins/CloudFile/src/Services/dropbox_service.cpp
+++ b/plugins/CloudFile/src/Services/dropbox_service.cpp
@@ -119,10 +119,10 @@ char* CDropboxService::UploadFile(const char *data, size_t size, char *path)
return path;
}
-void CDropboxService::StartUploadSession(const char *data, size_t size, char *sessionId)
+void CDropboxService::CreateUploadSession(const char *chunk, size_t chunkSize, char *sessionId)
{
ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
- DropboxAPI::StartUploadSessionRequest request(token, data, size);
+ DropboxAPI::CreateUploadSessionRequest request(token, chunk, chunkSize);
NLHR_PTR response(request.Send(hConnection));
JSONNode root = GetJsonResponse(response);
@@ -130,19 +130,19 @@ void CDropboxService::StartUploadSession(const char *data, size_t size, char *se
mir_strcpy(sessionId, node.as_string().c_str());
}
-void CDropboxService::AppendToUploadSession(const char *data, size_t size, const char *sessionId, size_t offset)
+void CDropboxService::UploadFileChunk(const char *chunk, size_t chunkSize, const char *sessionId, size_t offset)
{
ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
- DropboxAPI::AppendToUploadSessionRequest request(token, sessionId, offset, data, size);
+ DropboxAPI::UploadFileChunkRequest request(token, sessionId, offset, chunk, chunkSize);
NLHR_PTR response(request.Send(hConnection));
GetJsonResponse(response);
}
-char* CDropboxService::FinishUploadSession(const char *data, size_t size, const char *sessionId, size_t offset, char *path)
+char* CDropboxService::CommitUploadSession(const char *data, size_t size, const char *sessionId, size_t offset, char *path)
{
ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
- DropboxAPI::FinishUploadSessionRequest request(token, sessionId, offset, path, data, size);
+ DropboxAPI::CommitUploadSessionRequest request(token, sessionId, offset, path, data, size);
NLHR_PTR response(request.Send(hConnection));
JSONNode root = GetJsonResponse(response);
@@ -214,62 +214,57 @@ UINT CDropboxService::Upload(FileTransferParam *ftp)
Login();
try {
- const wchar_t *folderName = ftp->GetFolderName();
- if (folderName) {
- char path[MAX_PATH], url[MAX_PATH];
+ if (ftp->IsFolder()) {
+ T2Utf folderName(ftp->GetFolderName());
+
+ char path[MAX_PATH];
PreparePath(folderName, path);
CreateFolder(path);
- CreateSharedLink(path, url);
- ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(url)));
+
+ char link[MAX_PATH];
+ CreateSharedLink(path, link);
+ ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(link)));
}
ftp->FirstFile();
do
{
- const wchar_t *fileName = ftp->GetCurrentRelativeFilePath();
+ T2Utf fileName(ftp->GetCurrentRelativeFilePath());
uint64_t fileSize = ftp->GetCurrentFileSize();
int chunkSize = ftp->GetCurrentFileChunkSize();
mir_ptr<char>data((char*)mir_calloc(chunkSize));
- size_t size = ftp->ReadCurrentFile(data, chunkSize);
- size_t offset = 0;
char sessionId[64];
- StartUploadSession(data, size, sessionId);
+ size_t size = ftp->ReadCurrentFile(data, chunkSize);
+ CreateUploadSession(data, size, sessionId);
- offset += size;
ftp->Progress(size);
- for (size_t chunk = 0; chunk < (fileSize / chunkSize) - 1; chunk++)
+ size_t offset = size;
+ size_t chunkCount = ceil(fileSize / chunkSize) - 2;
+ while (chunkCount--)
{
ftp->CheckCurrentFile();
size = ftp->ReadCurrentFile(data, chunkSize);
- AppendToUploadSession(data, size, sessionId, offset);
+ UploadFileChunk(data, size, sessionId, offset);
offset += size;
ftp->Progress(size);
}
- if (offset < fileSize)
- size = ftp->ReadCurrentFile(data, fileSize - offset);
- else
- size = 0;
+ size = offset < fileSize
+ ? ftp->ReadCurrentFile(data, fileSize - offset)
+ : 0;
char path[MAX_PATH];
- const wchar_t *serverFolder = ftp->GetServerFolder();
- if (serverFolder) {
- wchar_t serverPath[MAX_PATH] = { 0 };
- mir_snwprintf(serverPath, L"%s\\%s", serverFolder, fileName);
- PreparePath(serverPath, path);
- }
- else
- PreparePath(fileName, path);
- FinishUploadSession(data, size, sessionId, offset, path);
+ PreparePath(fileName, path);
+ CommitUploadSession(data, size, sessionId, offset, path);
ftp->Progress(size);
- if (!wcschr(fileName, L'\\')) {
+ if (!ftp->IsFolder()) {
char url[MAX_PATH];
CreateSharedLink(path, url);
ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(url)));
diff --git a/plugins/CloudFile/src/Services/dropbox_service.h b/plugins/CloudFile/src/Services/dropbox_service.h
index 362a9751fc..c498b52178 100644
--- a/plugins/CloudFile/src/Services/dropbox_service.h
+++ b/plugins/CloudFile/src/Services/dropbox_service.h
@@ -10,9 +10,9 @@ private:
void HandleJsonError(JSONNode &node);
char* UploadFile(const char *data, size_t size, char *path);
- void StartUploadSession(const char *data, size_t size, char *sessionId);
- void AppendToUploadSession(const char *data, size_t size, const char *sessionId, size_t offset);
- char* FinishUploadSession(const char *data, size_t size, const char *sessionId, size_t offset, char *path);
+ void CreateUploadSession(const char *chunk, size_t chunkSize, char *sessionId);
+ void UploadFileChunk(const char *chunk, size_t chunkSize, const char *sessionId, size_t offset);
+ char* CommitUploadSession(const char *chunk, size_t chunkSize, const char *sessionId, size_t offset, char *path);
void CreateFolder(const char *path);
void CreateSharedLink(const char *path, char *url);
diff --git a/plugins/CloudFile/src/Services/google_api.h b/plugins/CloudFile/src/Services/google_api.h
index b609507caa..c73124cdad 100644
--- a/plugins/CloudFile/src/Services/google_api.h
+++ b/plugins/CloudFile/src/Services/google_api.h
@@ -54,7 +54,7 @@ namespace GDriveAPI
class UploadFileRequest : public HttpRequest
{
public:
- UploadFileRequest(const char *token, const char *name, const char *data, size_t size) :
+ UploadFileRequest(const char *token, const char *parentId, const char *name, const char *data, size_t size) :
HttpRequest(REQUEST_POST, GDRIVE_UPLOAD)
{
AddBearerAuthHeader(token);
@@ -67,6 +67,8 @@ namespace GDriveAPI
body.AppendChar(0x0A);
body.Append("{");
body.AppendFormat("\"name\": \"%s\"", name);
+ if (parentId)
+ body.AppendFormat("\"parents\": [\"%s\"]", parentId);
body.Append("}");
body.AppendChar(0x0A);
body.AppendChar(0x0A);
@@ -86,7 +88,7 @@ namespace GDriveAPI
class CreateUploadSessionRequest : public HttpRequest
{
public:
- CreateUploadSessionRequest(const char *token, const char *name) :
+ CreateUploadSessionRequest(const char *token, const char *parentId, const char *name) :
HttpRequest(REQUEST_POST, GDRIVE_UPLOAD)
{
AddUrlParameter("uploadType=resumable");
@@ -94,8 +96,12 @@ namespace GDriveAPI
AddBearerAuthHeader(token);
AddHeader("Content-Type", "application/json");
+ JSONNode parents(JSON_ARRAY);
+ parents << JSONNode("", parentId);
+
JSONNode params(JSON_NODE);
params << JSONNode("name", name);
+ params << parents;
json_string data = params.write();
SetData(data.c_str(), data.length());
diff --git a/plugins/CloudFile/src/Services/google_service.cpp b/plugins/CloudFile/src/Services/google_service.cpp
index bf6c7de90e..ac1d71b0f1 100644
--- a/plugins/CloudFile/src/Services/google_service.cpp
+++ b/plugins/CloudFile/src/Services/google_service.cpp
@@ -80,14 +80,14 @@ unsigned CGDriveService::RequestAccessTokenThread(void *owner, void *param)
: service->HttpStatusToError(response->resultCode);
Netlib_Logf(service->hConnection, "%s: %s", service->GetModule(), error);
- ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);
+ //ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);
return 0;
}
JSONNode root = JSONNode::parse(response->pData);
if (root.empty()) {
Netlib_Logf(service->hConnection, "%s: %s", service->GetModule(), service->HttpStatusToError(response->resultCode));
- ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);
+ //ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);
return 0;
}
@@ -95,7 +95,7 @@ unsigned CGDriveService::RequestAccessTokenThread(void *owner, void *param)
if (!node.isnull()) {
ptrW error_description(mir_a2u_cp(node.as_string().c_str(), CP_UTF8));
Netlib_Logf(service->hConnection, "%s: %s", service->GetModule(), service->HttpStatusToError(response->resultCode));
- ShowNotification((wchar_t*)error_description, MB_ICONERROR);
+ //ShowNotification((wchar_t*)error_description, MB_ICONERROR);
return 0;
}
@@ -136,10 +136,10 @@ void CGDriveService::HandleJsonError(JSONNode &node)
}
}
-void CGDriveService::UploadFile(const char *name, const char *data, size_t size, char *fileId)
+void CGDriveService::UploadFile(const char *parentId, const char *name, const char *data, size_t size, char *fileId)
{
ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
- GDriveAPI::UploadFileRequest request(token, name, data, size);
+ GDriveAPI::UploadFileRequest request(token, parentId, name, data, size);
NLHR_PTR response(request.Send(hConnection));
JSONNode root = GetJsonResponse(response);
@@ -147,14 +147,13 @@ void CGDriveService::UploadFile(const char *name, const char *data, size_t size,
mir_strcpy(fileId, node.as_string().c_str());
}
-void CGDriveService::CreateUploadSession(char *uploadUri, const char *name)
+void CGDriveService::CreateUploadSession(const char *parentId, const char *name, char *uploadUri)
{
ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
- GDriveAPI::CreateUploadSessionRequest request(token, name);
+ GDriveAPI::CreateUploadSessionRequest request(token, parentId, name);
NLHR_PTR response(request.Send(hConnection));
- if (response == NULL)
- throw Exception(HttpStatusToError());
+ HandleHttpError(response);
if (HTTP_CODE_SUCCESS(response->resultCode)) {
for (int i = 0; i < response->headersCount; i++)
@@ -167,9 +166,7 @@ void CGDriveService::CreateUploadSession(char *uploadUri, const char *name)
}
}
- if (response->dataLength)
- throw Exception(response->pData);
- throw Exception(HttpStatusToError(response->resultCode));
+ HttpResponseToError(response);
}
void CGDriveService::UploadFileChunk(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize, char *fileId)
@@ -177,8 +174,7 @@ void CGDriveService::UploadFileChunk(const char *uploadUri, const char *chunk, s
GDriveAPI::UploadFileChunkRequest request(uploadUri, chunk, chunkSize, offset, fileSize);
NLHR_PTR response(request.Send(hConnection));
- if (response == NULL)
- throw Exception(HttpStatusToError());
+ HandleHttpError(response);
if (response->resultCode == HTTP_CODE_PERMANENT_REDIRECT)
return;
@@ -190,38 +186,35 @@ void CGDriveService::UploadFileChunk(const char *uploadUri, const char *chunk, s
return;
}
- if (response->dataLength)
- throw Exception(response->pData);
- throw Exception(HttpStatusToError(response->resultCode));
+ HttpResponseToError(response);
}
-void CGDriveService::CreateFolder(const char *path)
+void CGDriveService::CreateFolder(const char *path, char *folderId)
{
ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
GDriveAPI::CreateFolderRequest request(token, path);
NLHR_PTR response(request.Send(hConnection));
- GetJsonResponse(response);
+ JSONNode root = GetJsonResponse(response);
+ JSONNode node = root.at("id");
+ mir_strcpy(folderId, node.as_string().c_str());
}
-void CGDriveService::CreateSharedLink(const char *fileId, char *url)
+void CGDriveService::CreateSharedLink(const char *itemId, char *url)
{
ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
- GDriveAPI::GrantPermissionsRequest request(token, fileId);
+ GDriveAPI::GrantPermissionsRequest request(token, itemId);
NLHR_PTR response(request.Send(hConnection));
- if (response == NULL)
- throw Exception(HttpStatusToError());
+ HandleHttpError(response);
if (HTTP_CODE_SUCCESS(response->resultCode)) {
- CMStringA sharedUrl(CMStringDataFormat::FORMAT, GDRIVE_SHARE, fileId);
+ CMStringA sharedUrl(CMStringDataFormat::FORMAT, GDRIVE_SHARE, itemId);
mir_strcpy(url, sharedUrl);
return;
}
- if (response->dataLength)
- throw Exception(response->pData);
- throw Exception(HttpStatusToError(response->resultCode));
+ HttpResponseToError(response);
}
UINT CGDriveService::Upload(FileTransferParam *ftp)
@@ -235,22 +228,23 @@ UINT CGDriveService::Upload(FileTransferParam *ftp)
return ACKRESULT_FAILED;
}
- const wchar_t *folderName = ftp->GetFolderName();
- if (folderName) {
- char path[MAX_PATH], link[MAX_PATH];
- PreparePath(folderName, path);
- CreateFolder(path);
- CreateSharedLink(path, link);
+ char folderId[32] = { 0 };
+ if (ftp->IsFolder()) {
+ T2Utf folderName(ftp->GetFolderName());
+
+ CreateFolder(folderName, folderId);
+ char link[MAX_PATH];
+
+ CreateSharedLink(folderId, link);
ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(link)));
}
ftp->FirstFile();
do
{
- const wchar_t *fileName = ftp->GetCurrentRelativeFilePath();
+ T2Utf fileName(ftp->GetCurrentRelativeFilePath());
uint64_t fileSize = ftp->GetCurrentFileSize();
- uint64_t offset = 0;
char fileId[32];
size_t chunkSize = ftp->GetCurrentFileChunkSize();
@@ -259,24 +253,21 @@ UINT CGDriveService::Upload(FileTransferParam *ftp)
if (chunkSize == fileSize)
{
ftp->CheckCurrentFile();
-
size_t size = ftp->ReadCurrentFile(chunk, chunkSize);
- UploadFile(chunk, T2Utf(fileName), size, fileId);
+ UploadFile(folderId, fileName, chunk, size, fileId);
}
else
{
char uploadUri[1024];
- CreateUploadSession(uploadUri, T2Utf(fileName));
+ CreateUploadSession(uploadUri, folderId, fileName);
- size_t size = 0;
- for (size_t i = 0; i < (fileSize / chunkSize); i++)
+ uint64_t offset = 0;
+ size_t chunkCount = ceil(fileSize / chunkSize);
+ while (chunkCount--)
{
ftp->CheckCurrentFile();
-
- size = ftp->ReadCurrentFile(chunk, chunkSize);
- if (size == 0)
- break;
+ size_t size = ftp->ReadCurrentFile(chunk, chunkSize);
UploadFileChunk(uploadUri, chunk, size, offset, fileSize, fileId);
@@ -285,10 +276,10 @@ UINT CGDriveService::Upload(FileTransferParam *ftp)
}
}
- if (!wcschr(fileName, L'\\')) {
- char url[MAX_PATH];
- CreateSharedLink(fileId, url);
- ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(url)));
+ if (!ftp->IsFolder()) {
+ char link[MAX_PATH];
+ CreateSharedLink(fileId, link);
+ ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(link)));
}
} while (ftp->NextFile());
}
diff --git a/plugins/CloudFile/src/Services/google_service.h b/plugins/CloudFile/src/Services/google_service.h
index 1da21b5fef..878fa8f442 100644
--- a/plugins/CloudFile/src/Services/google_service.h
+++ b/plugins/CloudFile/src/Services/google_service.h
@@ -9,11 +9,11 @@ private:
void HandleJsonError(JSONNode &node);
- void UploadFile(const char *name, const char *data, size_t size, char *fileId);
- void CreateUploadSession(char *uploadUri, const char *name);
+ void UploadFile(const char *parentId, const char *name, const char *data, size_t size, char *fileId);
+ void CreateUploadSession(const char *parentId, const char *name, char *uploadUri);
void UploadFileChunk(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize, char *fileId);
- void CreateFolder(const char *path);
- void CreateSharedLink(const char *fileId, char *url);
+ void CreateFolder(const char *path, char *folderId);
+ void CreateSharedLink(const char *itemId, char *url);
public:
CGDriveService(HNETLIBUSER hConnection);
diff --git a/plugins/CloudFile/src/Services/microsoft_api.h b/plugins/CloudFile/src/Services/microsoft_api.h
index 395d6e434d..cc27a80756 100644
--- a/plugins/CloudFile/src/Services/microsoft_api.h
+++ b/plugins/CloudFile/src/Services/microsoft_api.h
@@ -40,20 +40,26 @@ namespace OneDriveAPI
class UploadFileRequest : public HttpRequest
{
public:
- UploadFileRequest(const char *token, const char *name, const char *data, size_t size) :
+ UploadFileRequest(const char *token, const char *name, const char *data, size_t size, OnConflict strategy = NONE) :
HttpRequest(REQUEST_PUT, FORMAT, ONEDRIVE_API "/special/approot:/%s:/content", ptrA(mir_urlEncode(name)))
{
- AddUrlParameter("@microsoft.graph.conflictBehavior=rename");
+ if (strategy == OnConflict::RENAME)
+ AddUrlParameter("@microsoft.graph.conflictBehavior=rename");
+ else if (strategy == OnConflict::REPLACE)
+ AddUrlParameter("@microsoft.graph.conflictBehavior=replace");
AddBearerAuthHeader(token);
SetData(data, size);
}
- UploadFileRequest(const char *token, const char *parentId, const char *name, const char *data, size_t size) :
+ UploadFileRequest(const char *token, const char *parentId, const char *name, const char *data, size_t size, OnConflict strategy = NONE) :
HttpRequest(REQUEST_PUT, FORMAT, ONEDRIVE_API "/items/{parent-id}:/{filename}:/content", parentId, ptrA(mir_urlEncode(name)))
{
- AddUrlParameter("@microsoft.graph.conflictBehavior=rename");
+ if (strategy == OnConflict::RENAME)
+ AddUrlParameter("@microsoft.graph.conflictBehavior=rename");
+ else if (strategy == OnConflict::REPLACE)
+ AddUrlParameter("@microsoft.graph.conflictBehavior=replace");
AddBearerAuthHeader(token);
@@ -64,7 +70,7 @@ namespace OneDriveAPI
class CreateUploadSessionRequest : public HttpRequest
{
public:
- CreateUploadSessionRequest(const char *token, const char *name) :
+ CreateUploadSessionRequest(const char *token, const char *name, OnConflict strategy = NONE) :
HttpRequest(REQUEST_POST, FORMAT, ONEDRIVE_API "/special/approot:/%s:/createUploadSession", ptrA(mir_urlEncode(name)))
{
AddBearerAuthHeader(token);
@@ -72,8 +78,10 @@ namespace OneDriveAPI
JSONNode item(JSON_NODE);
item.set_name("item");
- item
- << JSONNode("@microsoft.graph.conflictBehavior", "rename");
+ if (strategy == OnConflict::RENAME)
+ item << JSONNode("@microsoft.graph.conflictBehavior", "rename");
+ if (strategy == OnConflict::REPLACE)
+ item << JSONNode("@microsoft.graph.conflictBehavior", "replace");
JSONNode params(JSON_NODE);
params << item;
@@ -82,7 +90,7 @@ namespace OneDriveAPI
SetData(data.c_str(), data.length());
}
- CreateUploadSessionRequest(const char *token, const char *parentId, const char *name) :
+ CreateUploadSessionRequest(const char *token, const char *parentId, const char *name, OnConflict strategy = NONE) :
HttpRequest(REQUEST_POST, FORMAT, ONEDRIVE_API "/items/%s:/%s:/createUploadSession", parentId, name)
{
AddBearerAuthHeader(token);
@@ -90,9 +98,10 @@ namespace OneDriveAPI
JSONNode item(JSON_NODE);
item.set_name("item");
- item
- << JSONNode("@microsoft.graph.conflictBehavior", "rename")
- << JSONNode("name", name);
+ if (strategy == OnConflict::RENAME)
+ item << JSONNode("@microsoft.graph.conflictBehavior", "rename");
+ if (strategy == OnConflict::REPLACE)
+ item << JSONNode("@microsoft.graph.conflictBehavior", "replace");
JSONNode params(JSON_NODE);
params << item;
diff --git a/plugins/CloudFile/src/Services/microsoft_service.cpp b/plugins/CloudFile/src/Services/microsoft_service.cpp
index 0cf41eb738..77919574e0 100644
--- a/plugins/CloudFile/src/Services/microsoft_service.cpp
+++ b/plugins/CloudFile/src/Services/microsoft_service.cpp
@@ -82,14 +82,14 @@ unsigned COneDriveService::RequestAccessTokenThread(void *owner, void *param)
: service->HttpStatusToError(response->resultCode);
Netlib_Logf(service->hConnection, "%s: %s", service->GetModule(), error);
- ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);
+ //ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);
return 0;
}
JSONNode root = JSONNode::parse(response->pData);
if (root.empty()) {
Netlib_Logf(service->hConnection, "%s: %s", service->GetModule(), service->HttpStatusToError(response->resultCode));
- ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);
+ //ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);
return 0;
}
@@ -97,7 +97,7 @@ unsigned COneDriveService::RequestAccessTokenThread(void *owner, void *param)
if (!node.isnull()) {
ptrW error_description(mir_a2u_cp(node.as_string().c_str(), CP_UTF8));
Netlib_Logf(service->hConnection, "%s: %s", service->GetModule(), service->HttpStatusToError(response->resultCode));
- ShowNotification((wchar_t*)error_description, MB_ICONERROR);
+ //ShowNotification((wchar_t*)error_description, MB_ICONERROR);
return 0;
}
@@ -141,7 +141,7 @@ void COneDriveService::UploadFile(const char *parentId, const char *name, const
mir_strcpy(fileId, node.as_string().c_str());
}
-void COneDriveService::CreateUploadSession(char *uploadUri, const char *name, const char *parentId)
+void COneDriveService::CreateUploadSession(const char *parentId, const char *name, char *uploadUri)
{
ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
OneDriveAPI::CreateUploadSessionRequest *request = mir_strlen(parentId)
@@ -155,13 +155,12 @@ void COneDriveService::CreateUploadSession(char *uploadUri, const char *name, co
mir_strcpy(uploadUri, node.as_string().c_str());
}
-void COneDriveService::UploadFileChunk(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize, char *itemId)
+void COneDriveService::UploadFileChunk(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize, char *fileId)
{
OneDriveAPI::UploadFileChunkRequest request(uploadUri, chunk, chunkSize, offset, fileSize);
NLHR_PTR response(request.Send(hConnection));
- if (response == NULL)
- throw Exception(HttpStatusToError());
+ HandleHttpError(response);
if (response->resultCode == HTTP_CODE_ACCEPTED)
return;
@@ -169,16 +168,14 @@ void COneDriveService::UploadFileChunk(const char *uploadUri, const char *chunk,
if (HTTP_CODE_SUCCESS(response->resultCode)) {
JSONNode root = GetJsonResponse(response);
JSONNode node = root.at("id");
- mir_strcpy(itemId, node.as_string().c_str());
+ mir_strcpy(fileId, node.as_string().c_str());
return;
}
- if (response->dataLength)
- throw Exception(response->pData);
- throw Exception(HttpStatusToError(response->resultCode));
+ HttpResponseToError(response);
}
-void COneDriveService::CreateFolder(const char *path, char *itemId)
+void COneDriveService::CreateFolder(const char *path, char *folderId)
{
ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
OneDriveAPI::CreateFolderRequest request(token, path);
@@ -186,7 +183,7 @@ void COneDriveService::CreateFolder(const char *path, char *itemId)
JSONNode root = GetJsonResponse(response);
JSONNode node = root.at("id");
- mir_strcpy(itemId, node.as_string().c_str());
+ mir_strcpy(folderId, node.as_string().c_str());
}
void COneDriveService::CreateSharedLink(const char *itemId, char *url)
@@ -213,11 +210,14 @@ UINT COneDriveService::Upload(FileTransferParam *ftp)
}
char folderId[32] = { 0 };
- const wchar_t *folderName = ftp->GetFolderName();
- if (folderName) {
- char path[MAX_PATH], link[MAX_PATH];
+ if (ftp->IsFolder()) {
+ T2Utf folderName(ftp->GetFolderName());
+
+ char path[MAX_PATH];
PreparePath(folderName, path);
CreateFolder(path, folderId);
+
+ char link[MAX_PATH];
CreateSharedLink(path, link);
ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(link)));
}
@@ -225,10 +225,9 @@ UINT COneDriveService::Upload(FileTransferParam *ftp)
ftp->FirstFile();
do
{
- const wchar_t *fileName = ftp->GetCurrentRelativeFilePath();
+ T2Utf fileName(ftp->GetCurrentRelativeFilePath());
uint64_t fileSize = ftp->GetCurrentFileSize();
- uint64_t offset = 0;
char fileId[32];
size_t chunkSize = ftp->GetCurrentFileChunkSize();
@@ -237,7 +236,6 @@ UINT COneDriveService::Upload(FileTransferParam *ftp)
if (chunkSize == fileSize)
{
ftp->CheckCurrentFile();
-
size_t size = ftp->ReadCurrentFile(chunk, chunkSize);
UploadFile(folderId, T2Utf(fileName), chunk, size, fileId);
@@ -247,14 +245,10 @@ UINT COneDriveService::Upload(FileTransferParam *ftp)
char uploadUri[1024];
CreateUploadSession(uploadUri, T2Utf(fileName), folderId);
- size_t size = 0;
- for (size_t i = 0; i < (fileSize / chunkSize); i++)
- {
+ uint64_t offset = 0;
+ for (size_t i = 0; i < (fileSize / chunkSize); i++) {
ftp->CheckCurrentFile();
-
- size = ftp->ReadCurrentFile(chunk, chunkSize);
- if (size == 0)
- break;
+ size_t size = ftp->ReadCurrentFile(chunk, chunkSize);
UploadFileChunk(uploadUri, chunk, size, offset, fileSize, fileId);
@@ -263,10 +257,10 @@ UINT COneDriveService::Upload(FileTransferParam *ftp)
}
}
- if (!wcschr(fileName, L'\\')) {
- char url[MAX_PATH];
- CreateSharedLink(fileId, url);
- ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(url)));
+ if (!ftp->IsFolder()) {
+ char link[MAX_PATH];
+ CreateSharedLink(fileId, link);
+ ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(link)));
}
} while (ftp->NextFile());
}
diff --git a/plugins/CloudFile/src/Services/microsoft_service.h b/plugins/CloudFile/src/Services/microsoft_service.h
index 3b49e1f6f3..cdd9d53976 100644
--- a/plugins/CloudFile/src/Services/microsoft_service.h
+++ b/plugins/CloudFile/src/Services/microsoft_service.h
@@ -9,9 +9,9 @@ private:
void HandleJsonError(JSONNode &node);
void UploadFile(const char *parentId, const char *name, const char *data, size_t size, char *fileId);
- void CreateUploadSession(char *uploadUri, const char *name, const char *parentId = NULL);
- void UploadFileChunk(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize, char *itemId);
- void CreateFolder(const char *path, char *itemId);
+ void CreateUploadSession(const char *parentId, const char *name, char *uploadUri);
+ void UploadFileChunk(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize, char *fileId);
+ void CreateFolder(const char *path, char *folderId);
void CreateSharedLink(const char *itemId, char *url);
public:
diff --git a/plugins/CloudFile/src/Services/yandex_api.h b/plugins/CloudFile/src/Services/yandex_api.h
index 2a83abb634..56d77feb8c 100644
--- a/plugins/CloudFile/src/Services/yandex_api.h
+++ b/plugins/CloudFile/src/Services/yandex_api.h
@@ -52,27 +52,41 @@ namespace YandexAPI
class GetUploadUrlRequest : public HttpRequest
{
public:
- GetUploadUrlRequest(const char *token, const char *path) :
+ GetUploadUrlRequest(const char *token, const char *path, OnConflict strategy = NONE) :
HttpRequest(REQUEST_GET, YADISK_API "/upload")
{
AddOAuthHeader(token);
AddUrlParameter("path=%s", ptrA(mir_urlEncode(path)));
- AddUrlParameter("overwrite=true");
+ if (strategy == OnConflict::REPLACE)
+ AddUrlParameter("overwrite=true");
}
};
class UploadFileRequest : public HttpRequest
{
public:
- UploadFileRequest(const char *token, const char *url, const char *data, size_t size) :
+ UploadFileRequest(const char *url, const char *data, size_t size) :
HttpRequest(REQUEST_PUT, url)
{
- AddOAuthHeader(token);
-
SetData(data, size);
}
};
+ class UploadFileChunkRequest : public HttpRequest
+ {
+ public:
+ UploadFileChunkRequest(const char *url, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize) :
+ HttpRequest(REQUEST_PUT, url)
+ {
+ uint64_t rangeMin = offset;
+ uint64_t rangeMax = offset + chunkSize - 1;
+ CMStringA range(CMStringDataFormat::FORMAT, "bytes %I64u-%I64u/%I64u", rangeMin, rangeMax, fileSize);
+ AddHeader("Content-Range", range);
+
+ SetData(chunk, chunkSize);
+ }
+ };
+
class CreateFolderRequest : public HttpRequest
{
public:
diff --git a/plugins/CloudFile/src/Services/yandex_service.cpp b/plugins/CloudFile/src/Services/yandex_service.cpp
index 1b8abecf96..bce62324a1 100644
--- a/plugins/CloudFile/src/Services/yandex_service.cpp
+++ b/plugins/CloudFile/src/Services/yandex_service.cpp
@@ -83,14 +83,14 @@ unsigned CYandexService::RequestAccessTokenThread(void *owner, void *param)
: service->HttpStatusToError(response->resultCode);
Netlib_Logf(service->hConnection, "%s: %s", service->GetModule(), error);
- ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);
+ //ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);
return 0;
}
JSONNode root = JSONNode::parse(response->pData);
if (root.empty()) {
Netlib_Logf(service->hConnection, "%s: %s", service->GetModule(), service->HttpStatusToError(response->resultCode));
- ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);
+ //ShowNotification(TranslateT("server does not respond"), MB_ICONERROR);
return 0;
}
@@ -98,7 +98,7 @@ unsigned CYandexService::RequestAccessTokenThread(void *owner, void *param)
if (!node.isnull()) {
ptrW error_description(mir_a2u_cp(node.as_string().c_str(), CP_UTF8));
Netlib_Logf(service->hConnection, "%s: %s", service->GetModule(), service->HttpStatusToError(response->resultCode));
- ShowNotification((wchar_t*)error_description, MB_ICONERROR);
+ //ShowNotification((wchar_t*)error_description, MB_ICONERROR);
return 0;
}
@@ -139,7 +139,7 @@ void CYandexService::HandleJsonError(JSONNode &node)
}
}
-void CYandexService::GetUploadUrl(char *path, char *url)
+void CYandexService::CreateUploadSession(const char *path, char *uploadUri)
{
ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
YandexAPI::GetUploadUrlRequest request(token, path);
@@ -147,26 +147,34 @@ void CYandexService::GetUploadUrl(char *path, char *url)
JSONNode root = GetJsonResponse(response);
JSONNode node = root.at("href");
- mir_strcpy(url, node.as_string().c_str());
+ mir_strcpy(uploadUri, node.as_string().c_str());
}
-void CYandexService::UploadFile(const char *url, const char *data, size_t size)
+void CYandexService::UploadFile(const char *uploadUri, const char *data, size_t size)
{
- ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
- YandexAPI::UploadFileRequest request(token, url, data, size);
+ YandexAPI::UploadFileRequest request(uploadUri, data, size);
NLHR_PTR response(request.Send(hConnection));
- if (response == NULL)
- throw Exception(HttpStatusToError());
+ HandleHttpError(response);
- if (response->resultCode >= HTTP_CODE_OK &&
- response->resultCode <= HTTP_CODE_MULTIPLE_CHOICES) {
+ if (response->resultCode == HTTP_CODE_CREATED)
return;
- }
- if (response->dataLength)
- throw Exception(response->pData);
- throw Exception(HttpStatusToError(response->resultCode));
+ HttpResponseToError(response);
+}
+
+void CYandexService::UploadFileChunk(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize)
+{
+ YandexAPI::UploadFileChunkRequest request(uploadUri, chunk, chunkSize, offset, fileSize);
+ NLHR_PTR response(request.Send(hConnection));
+
+ HandleHttpError(response);
+
+ if (response->resultCode == HTTP_CODE_ACCEPTED ||
+ response->resultCode == HTTP_CODE_CREATED)
+ return;
+
+ HttpResponseToError(response);
}
void CYandexService::CreateFolder(const char *path)
@@ -206,11 +214,14 @@ UINT CYandexService::Upload(FileTransferParam *ftp)
return ACKRESULT_FAILED;
}
- const wchar_t *folderName = ftp->GetFolderName();
- if (folderName) {
- char path[MAX_PATH], link[MAX_PATH];
+ if (ftp->IsFolder()) {
+ T2Utf folderName(ftp->GetFolderName());
+
+ char path[MAX_PATH];
PreparePath(folderName, path);
CreateFolder(path);
+
+ char link[MAX_PATH];
CreateSharedLink(path, link);
ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(link)));
}
@@ -218,28 +229,40 @@ UINT CYandexService::Upload(FileTransferParam *ftp)
ftp->FirstFile();
do
{
- const wchar_t *fileName = ftp->GetCurrentRelativeFilePath();
+ T2Utf fileName(ftp->GetCurrentRelativeFilePath());
uint64_t fileSize = ftp->GetCurrentFileSize();
char path[MAX_PATH];
- const wchar_t *serverFolder = ftp->GetServerFolder();
- if (serverFolder) {
- wchar_t serverPath[MAX_PATH] = { 0 };
- mir_snwprintf(serverPath, L"%s\\%s", serverFolder, fileName);
- PreparePath(serverPath, path);
- }
- else
- PreparePath(fileName, path);
- char url[MAX_PATH];
- GetUploadUrl(path, url);
+ PreparePath(fileName, path);
+
+ char uploadUri[1024];
+ CreateUploadSession(path, uploadUri);
+
+ size_t chunkSize = ftp->GetCurrentFileChunkSize();
+ mir_ptr<char>chunk((char*)mir_calloc(chunkSize));
- mir_ptr<char>data((char*)mir_calloc(fileSize));
- size_t size = ftp->ReadCurrentFile(data, fileSize);
- UploadFile(url, data, size);
+ if (chunkSize == fileSize) {
+ ftp->CheckCurrentFile();
+ size_t size = ftp->ReadCurrentFile(chunk, chunkSize);
- ftp->Progress(size);
+ UploadFile(uploadUri, chunk, size);
+ }
+ else {
+ uint64_t offset = 0;
+ size_t chunkCount = ceil(fileSize / chunkSize);
+ while (chunkCount--)
+ {
+ ftp->CheckCurrentFile();
+ size_t size = ftp->ReadCurrentFile(chunk, chunkSize);
+
+ UploadFileChunk(uploadUri, chunk, size, offset, fileSize);
+
+ offset += size;
+ ftp->Progress(size);
+ }
+ }
- if (!wcschr(fileName, L'\\')) {
+ if (!ftp->IsFolder()) {
char url[MAX_PATH];
CreateSharedLink(path, url);
ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(url)));
diff --git a/plugins/CloudFile/src/Services/yandex_service.h b/plugins/CloudFile/src/Services/yandex_service.h
index e3b122ffa1..85c0ad12de 100644
--- a/plugins/CloudFile/src/Services/yandex_service.h
+++ b/plugins/CloudFile/src/Services/yandex_service.h
@@ -9,8 +9,9 @@ private:
void HandleJsonError(JSONNode &node);
- void GetUploadUrl(char *path, char *url);
- void UploadFile(const char *url, const char *data, size_t size);
+ void CreateUploadSession(const char *path, char *uploadUri);
+ void UploadFile(const char *uploadUri, const char *data, size_t size);
+ void UploadFileChunk(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize);
void CreateFolder(const char *path);
void CreateSharedLink(const char *path, char *url);