summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authoraunsane <aunsane@gmail.com>2017-04-27 01:53:37 +0300
committeraunsane <aunsane@gmail.com>2017-04-27 01:54:12 +0300
commit7b1d58962694bd6dd1971d6eda673ddc0877f7c2 (patch)
treeab0e4abefcdfbec12bf4fe7de1b5386cf1ac9378 /plugins
parentf27fbe387bede98cf64d7fd7fb3dcff1ba60279d (diff)
CloudFile: fix uploading small files for GDrive and OneDrive
Diffstat (limited to 'plugins')
-rw-r--r--plugins/CloudFile/src/Services/google_api.h40
-rw-r--r--plugins/CloudFile/src/Services/google_service.cpp55
-rw-r--r--plugins/CloudFile/src/Services/google_service.h5
-rw-r--r--plugins/CloudFile/src/Services/microsoft_api.h29
-rw-r--r--plugins/CloudFile/src/Services/microsoft_service.cpp54
-rw-r--r--plugins/CloudFile/src/Services/microsoft_service.h1
-rw-r--r--plugins/CloudFile/src/file_transfer.h2
7 files changed, 141 insertions, 45 deletions
diff --git a/plugins/CloudFile/src/Services/google_api.h b/plugins/CloudFile/src/Services/google_api.h
index 50d12fc5d3..b609507caa 100644
--- a/plugins/CloudFile/src/Services/google_api.h
+++ b/plugins/CloudFile/src/Services/google_api.h
@@ -51,10 +51,42 @@ namespace GDriveAPI
}
};
- class StartUploadFileRequest : public HttpRequest
+ class UploadFileRequest : public HttpRequest
+ {
+ public:
+ UploadFileRequest(const char *token, const char *name, const char *data, size_t size) :
+ HttpRequest(REQUEST_POST, GDRIVE_UPLOAD)
+ {
+ AddBearerAuthHeader(token);
+ AddHeader("Content-Type", "multipart/related; boundary=upload");
+
+ CMStringA body = "--upload";
+ body.AppendChar(0x0A);
+ body.Append("Content-Type: application/json");
+ body.AppendChar(0x0A);
+ body.AppendChar(0x0A);
+ body.Append("{");
+ body.AppendFormat("\"name\": \"%s\"", name);
+ body.Append("}");
+ body.AppendChar(0x0A);
+ body.AppendChar(0x0A);
+ body.Append("--upload");
+ body.AppendChar(0x0A);
+ body.Append("Content-Type: application/octet-stream");
+ body.AppendChar(0x0A);
+ body.AppendChar(0x0A);
+ body.Append(data, size);
+ body.AppendChar(0x0A);
+ body.Append("--upload--");
+
+ SetData(body.GetBuffer(), body.GetLength());
+ }
+ };
+
+ class CreateUploadSessionRequest : public HttpRequest
{
public:
- StartUploadFileRequest(const char *token, const char *name) :
+ CreateUploadSessionRequest(const char *token, const char *name) :
HttpRequest(REQUEST_POST, GDRIVE_UPLOAD)
{
AddUrlParameter("uploadType=resumable");
@@ -70,10 +102,10 @@ namespace GDriveAPI
}
};
- class UploadFileRequest : public HttpRequest
+ class UploadFileChunkRequest : public HttpRequest
{
public:
- UploadFileRequest(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize) :
+ UploadFileChunkRequest(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize):
HttpRequest(REQUEST_PUT, uploadUri)
{
uint64_t rangeMin = offset;
diff --git a/plugins/CloudFile/src/Services/google_service.cpp b/plugins/CloudFile/src/Services/google_service.cpp
index af7d0400bd..bf6c7de90e 100644
--- a/plugins/CloudFile/src/Services/google_service.cpp
+++ b/plugins/CloudFile/src/Services/google_service.cpp
@@ -136,10 +136,21 @@ void CGDriveService::HandleJsonError(JSONNode &node)
}
}
-void CGDriveService::StartUploadFile(char *uploadUri, const char *name)
+void CGDriveService::UploadFile(const char *name, const char *data, size_t size, char *fileId)
{
ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
- GDriveAPI::StartUploadFileRequest request(token, name);
+ GDriveAPI::UploadFileRequest request(token, name, data, size);
+ NLHR_PTR response(request.Send(hConnection));
+
+ JSONNode root = GetJsonResponse(response);
+ JSONNode node = root.at("id");
+ mir_strcpy(fileId, node.as_string().c_str());
+}
+
+void CGDriveService::CreateUploadSession(char *uploadUri, const char *name)
+{
+ ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
+ GDriveAPI::CreateUploadSessionRequest request(token, name);
NLHR_PTR response(request.Send(hConnection));
if (response == NULL)
@@ -161,9 +172,9 @@ void CGDriveService::StartUploadFile(char *uploadUri, const char *name)
throw Exception(HttpStatusToError(response->resultCode));
}
-void CGDriveService::UploadFile(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize, char *fileId)
+void CGDriveService::UploadFileChunk(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize, char *fileId)
{
- GDriveAPI::UploadFileRequest request(uploadUri, chunk, chunkSize, offset, fileSize);
+ GDriveAPI::UploadFileChunkRequest request(uploadUri, chunk, chunkSize, offset, fileSize);
NLHR_PTR response(request.Send(hConnection));
if (response == NULL)
@@ -174,8 +185,8 @@ void CGDriveService::UploadFile(const char *uploadUri, const char *chunk, size_t
if (HTTP_CODE_SUCCESS(response->resultCode)) {
JSONNode root = GetJsonResponse(response);
- JSONNode id = root.at("id");
- mir_strcpy(fileId, id.as_string().c_str());
+ JSONNode node = root.at("id");
+ mir_strcpy(fileId, node.as_string().c_str());
return;
}
@@ -241,25 +252,37 @@ UINT CGDriveService::Upload(FileTransferParam *ftp)
uint64_t offset = 0;
char fileId[32];
- char uploadUri[1024];
- StartUploadFile(uploadUri, T2Utf(fileName));
size_t chunkSize = ftp->GetCurrentFileChunkSize();
mir_ptr<char>chunk((char*)mir_calloc(chunkSize));
- size_t size = 0;
- for (size_t i = 0; i < (fileSize / chunkSize); i++)
+ if (chunkSize == fileSize)
{
ftp->CheckCurrentFile();
- size = ftp->ReadCurrentFile(chunk, chunkSize);
- if (size == 0)
- break;
+ size_t size = ftp->ReadCurrentFile(chunk, chunkSize);
+
+ UploadFile(chunk, T2Utf(fileName), size, fileId);
+ }
+ else
+ {
+ char uploadUri[1024];
+ CreateUploadSession(uploadUri, T2Utf(fileName));
+
+ size_t size = 0;
+ for (size_t i = 0; i < (fileSize / chunkSize); i++)
+ {
+ ftp->CheckCurrentFile();
+
+ size = ftp->ReadCurrentFile(chunk, chunkSize);
+ if (size == 0)
+ break;
- UploadFile(uploadUri, chunk, size, offset, fileSize, fileId);
+ UploadFileChunk(uploadUri, chunk, size, offset, fileSize, fileId);
- offset += size;
- ftp->Progress(size);
+ offset += size;
+ ftp->Progress(size);
+ }
}
if (!wcschr(fileName, L'\\')) {
diff --git a/plugins/CloudFile/src/Services/google_service.h b/plugins/CloudFile/src/Services/google_service.h
index a35827eaf8..1da21b5fef 100644
--- a/plugins/CloudFile/src/Services/google_service.h
+++ b/plugins/CloudFile/src/Services/google_service.h
@@ -9,8 +9,9 @@ private:
void HandleJsonError(JSONNode &node);
- void StartUploadFile(char *uploadUri, const char *name);
- void UploadFile(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize, char *fileId);
+ void UploadFile(const char *name, const char *data, size_t size, char *fileId);
+ void CreateUploadSession(char *uploadUri, const char *name);
+ 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);
diff --git a/plugins/CloudFile/src/Services/microsoft_api.h b/plugins/CloudFile/src/Services/microsoft_api.h
index 1c3c323520..395d6e434d 100644
--- a/plugins/CloudFile/src/Services/microsoft_api.h
+++ b/plugins/CloudFile/src/Services/microsoft_api.h
@@ -37,21 +37,35 @@ namespace OneDriveAPI
}
};
- /*class RevokeAccessTokenRequest : public HttpRequest
+ class UploadFileRequest : public HttpRequest
{
public:
- RevokeAccessTokenRequest(const char *token) :
- HttpRequest(REQUEST_POST, MS_OAUTH "/logout")
+ UploadFileRequest(const char *token, const char *name, const char *data, size_t size) :
+ HttpRequest(REQUEST_PUT, FORMAT, ONEDRIVE_API "/special/approot:/%s:/content", ptrA(mir_urlEncode(name)))
{
- AddUrlParameter("token=%s", token);
+ AddUrlParameter("@microsoft.graph.conflictBehavior=rename");
+
+ AddBearerAuthHeader(token);
+
+ SetData(data, size);
+ }
+
+ UploadFileRequest(const char *token, const char *parentId, const char *name, const char *data, size_t size) :
+ HttpRequest(REQUEST_PUT, FORMAT, ONEDRIVE_API "/items/{parent-id}:/{filename}:/content", parentId, ptrA(mir_urlEncode(name)))
+ {
+ AddUrlParameter("@microsoft.graph.conflictBehavior=rename");
+
+ AddBearerAuthHeader(token);
+
+ SetData(data, size);
}
- };*/
+ };
class CreateUploadSessionRequest : public HttpRequest
{
public:
CreateUploadSessionRequest(const char *token, const char *name) :
- HttpRequest(REQUEST_POST, FORMAT, ONEDRIVE_API "/special/approot:/%s:/createUploadSession", name)
+ HttpRequest(REQUEST_POST, FORMAT, ONEDRIVE_API "/special/approot:/%s:/createUploadSession", ptrA(mir_urlEncode(name)))
{
AddBearerAuthHeader(token);
AddHeader("Content-Type", "application/json");
@@ -59,8 +73,7 @@ namespace OneDriveAPI
JSONNode item(JSON_NODE);
item.set_name("item");
item
- << JSONNode("@microsoft.graph.conflictBehavior", "rename")
- << JSONNode("name", name);
+ << JSONNode("@microsoft.graph.conflictBehavior", "rename");
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 209458b5c5..0cf41eb738 100644
--- a/plugins/CloudFile/src/Services/microsoft_service.cpp
+++ b/plugins/CloudFile/src/Services/microsoft_service.cpp
@@ -127,6 +127,20 @@ void COneDriveService::HandleJsonError(JSONNode &node)
}
}
+void COneDriveService::UploadFile(const char *parentId, const char *name, const char *data, size_t size, char *fileId)
+{
+ ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
+ OneDriveAPI::UploadFileRequest *request = mir_strlen(parentId)
+ ? new OneDriveAPI::UploadFileRequest(token, parentId, name, data, size)
+ : new OneDriveAPI::UploadFileRequest(token, name, data, size);
+ NLHR_PTR response(request->Send(hConnection));
+ delete request;
+
+ JSONNode root = GetJsonResponse(response);
+ JSONNode node = root.at("id");
+ mir_strcpy(fileId, node.as_string().c_str());
+}
+
void COneDriveService::CreateUploadSession(char *uploadUri, const char *name, const char *parentId)
{
ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret"));
@@ -154,8 +168,8 @@ void COneDriveService::UploadFileChunk(const char *uploadUri, const char *chunk,
if (HTTP_CODE_SUCCESS(response->resultCode)) {
JSONNode root = GetJsonResponse(response);
- JSONNode id = root.at("id");
- mir_strcpy(itemId, id.as_string().c_str());
+ JSONNode node = root.at("id");
+ mir_strcpy(itemId, node.as_string().c_str());
return;
}
@@ -183,7 +197,7 @@ void COneDriveService::CreateSharedLink(const char *itemId, char *url)
JSONNode root = GetJsonResponse(response);
JSONNode node = root.at("link");
- JSONNode webUrl = root.at("webUrl");
+ JSONNode webUrl = node.at("webUrl");
mir_strcpy(url, webUrl.as_string().c_str());
}
@@ -216,25 +230,37 @@ UINT COneDriveService::Upload(FileTransferParam *ftp)
uint64_t offset = 0;
char fileId[32];
- char uploadUri[1024];
- CreateUploadSession(uploadUri, T2Utf(fileName), folderId);
size_t chunkSize = ftp->GetCurrentFileChunkSize();
mir_ptr<char>chunk((char*)mir_calloc(chunkSize));
-
- size_t size = 0;
- for (size_t i = 0; i < (fileSize / chunkSize); i++)
+
+ if (chunkSize == fileSize)
{
ftp->CheckCurrentFile();
- size = ftp->ReadCurrentFile(chunk, chunkSize);
- if (size == 0)
- break;
+ size_t size = ftp->ReadCurrentFile(chunk, chunkSize);
+
+ UploadFile(folderId, T2Utf(fileName), chunk, size, fileId);
+ }
+ else
+ {
+ char uploadUri[1024];
+ CreateUploadSession(uploadUri, T2Utf(fileName), folderId);
+
+ size_t size = 0;
+ for (size_t i = 0; i < (fileSize / chunkSize); i++)
+ {
+ ftp->CheckCurrentFile();
+
+ size = ftp->ReadCurrentFile(chunk, chunkSize);
+ if (size == 0)
+ break;
- UploadFileChunk(uploadUri, chunk, size, offset, fileSize, fileId);
+ UploadFileChunk(uploadUri, chunk, size, offset, fileSize, fileId);
- offset += size;
- ftp->Progress(size);
+ offset += size;
+ ftp->Progress(size);
+ }
}
if (!wcschr(fileName, L'\\')) {
diff --git a/plugins/CloudFile/src/Services/microsoft_service.h b/plugins/CloudFile/src/Services/microsoft_service.h
index 8c3c30e035..3b49e1f6f3 100644
--- a/plugins/CloudFile/src/Services/microsoft_service.h
+++ b/plugins/CloudFile/src/Services/microsoft_service.h
@@ -8,6 +8,7 @@ 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);
diff --git a/plugins/CloudFile/src/file_transfer.h b/plugins/CloudFile/src/file_transfer.h
index e7daa3a2a9..700988eaf4 100644
--- a/plugins/CloudFile/src/file_transfer.h
+++ b/plugins/CloudFile/src/file_transfer.h
@@ -196,7 +196,7 @@ public:
chunkSize = min(pfts.currentFileSize, chunkSize / 4);
else if (pfts.currentFileSize > 20 * chunkSize)
chunkSize = chunkSize * 4;
- return chunkSize ? chunkSize : 1;
+ return chunkSize;
}
void Progress(size_t count)