diff options
Diffstat (limited to 'plugins/CloudFile/src/Services')
-rw-r--r-- | plugins/CloudFile/src/Services/dropbox_api.h | 18 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/dropbox_service.cpp | 59 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/dropbox_service.h | 6 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/google_api.h | 10 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/google_service.cpp | 87 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/google_service.h | 8 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/microsoft_api.h | 31 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/microsoft_service.cpp | 54 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/microsoft_service.h | 6 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/yandex_api.h | 24 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/yandex_service.cpp | 93 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/yandex_service.h | 5 |
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); |