mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
[Common] add network lib
This commit is contained in:
97
Common/Network/FileTransporter/include/FileTransporter.h
Normal file
97
Common/Network/FileTransporter/include/FileTransporter.h
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2021
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "../../../kernel_config.h"
|
||||
|
||||
namespace NSNetwork
|
||||
{
|
||||
namespace NSFileTransport
|
||||
{
|
||||
typedef void (*CFileTransporter_OnComplete)(int error);
|
||||
// <return> cancel: 1, else 0
|
||||
typedef int (*CFileTransporter_OnProgress)(int percent);
|
||||
|
||||
class CFileTransporter_private;
|
||||
class KERNEL_DECL CFileTransporter
|
||||
{
|
||||
protected:
|
||||
// создаем в зависимости от платформы
|
||||
CFileTransporter_private* m_pInternal;
|
||||
|
||||
#ifdef _MAC
|
||||
static bool m_bIsARCEnabled;
|
||||
#endif
|
||||
|
||||
public:
|
||||
CFileTransporter(std::wstring &sDownloadFileUrl, bool bDelete = true); //download constructor
|
||||
CFileTransporter(std::wstring &sUploadPathUrl, unsigned char* cData, const int nSize); //upload constructor
|
||||
virtual ~CFileTransporter();
|
||||
|
||||
void SetDownloadFilePath(const std::wstring& sPath);
|
||||
std::wstring GetDownloadFilePath();
|
||||
bool IsFileDownloaded();
|
||||
void SetDownloadProp(std::wstring &sDownloadFileUrl, bool bDelete = true);
|
||||
bool DownloadSync();
|
||||
void DownloadAsync();
|
||||
|
||||
void SetUploadProp(std::wstring &url, unsigned char* data, const int size);
|
||||
bool UploadSync();
|
||||
void UploadAsync();
|
||||
|
||||
std::wstring& GetResponse();
|
||||
|
||||
void Start(int lPriority);
|
||||
void Suspend();
|
||||
void Resume();
|
||||
void Stop();
|
||||
|
||||
int IsSuspended();
|
||||
int IsRunned();
|
||||
int GetError();
|
||||
|
||||
int GetPriority();
|
||||
|
||||
void CheckSuspend();
|
||||
|
||||
//events
|
||||
void SetEvent_OnProgress(CFileTransporter_OnProgress);
|
||||
void SetEvent_OnComplete(CFileTransporter_OnComplete);
|
||||
|
||||
#ifdef _MAC
|
||||
static void SetARCEnabled(const bool& enabled);
|
||||
static bool GetARCEnabled();
|
||||
#endif
|
||||
};
|
||||
}
|
||||
}
|
||||
177
Common/Network/FileTransporter/src/FileTransporter.cpp
Normal file
177
Common/Network/FileTransporter/src/FileTransporter.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2021
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "./FileTransporter_private.h"
|
||||
#include "../include/FileTransporter.h"
|
||||
|
||||
namespace NSNetwork
|
||||
{
|
||||
namespace NSFileTransport
|
||||
{
|
||||
CFileTransporter::CFileTransporter(std::wstring &sDownloadFileUrl, bool bDelete)
|
||||
{
|
||||
m_pInternal = new CFileTransporter_private(sDownloadFileUrl, bDelete);
|
||||
}
|
||||
|
||||
CFileTransporter::CFileTransporter(std::wstring &sUploadPathUrl, unsigned char* cData, const int nSize)
|
||||
{
|
||||
m_pInternal = new CFileTransporter_private(sUploadPathUrl, cData, nSize);
|
||||
}
|
||||
|
||||
CFileTransporter::~CFileTransporter()
|
||||
{
|
||||
Stop();
|
||||
if (NULL != m_pInternal)
|
||||
delete m_pInternal;
|
||||
}
|
||||
|
||||
void CFileTransporter::SetDownloadFilePath(const std::wstring& sPath)
|
||||
{
|
||||
return m_pInternal->SetDownloadFilePath(sPath);
|
||||
}
|
||||
|
||||
std::wstring CFileTransporter::GetDownloadFilePath()
|
||||
{
|
||||
return m_pInternal->GetDownloadFilePath();
|
||||
}
|
||||
|
||||
bool CFileTransporter::IsFileDownloaded()
|
||||
{
|
||||
return m_pInternal->IsFileDownloaded();
|
||||
}
|
||||
|
||||
void CFileTransporter::SetDownloadProp(std::wstring &sDownloadFileUrl, bool bDelete)
|
||||
{
|
||||
m_pInternal->SetDownloadProp(sDownloadFileUrl, bDelete);
|
||||
}
|
||||
|
||||
bool CFileTransporter::DownloadSync()
|
||||
{
|
||||
return m_pInternal->TransferSync();
|
||||
}
|
||||
|
||||
void CFileTransporter::DownloadAsync()
|
||||
{
|
||||
m_pInternal->TransferAsync();
|
||||
}
|
||||
|
||||
void CFileTransporter::SetUploadProp(std::wstring &sUploadPathUrl, unsigned char* cData, const int nSize)
|
||||
{
|
||||
m_pInternal->SetUploadProp(sUploadPathUrl, cData, nSize);
|
||||
}
|
||||
|
||||
bool CFileTransporter::UploadSync()
|
||||
{
|
||||
return m_pInternal->TransferSync();
|
||||
}
|
||||
|
||||
void CFileTransporter::UploadAsync()
|
||||
{
|
||||
m_pInternal->TransferAsync();
|
||||
}
|
||||
|
||||
std::wstring& CFileTransporter::GetResponse()
|
||||
{
|
||||
return m_pInternal->GetResponse();
|
||||
}
|
||||
|
||||
void CFileTransporter::Start(int lPriority)
|
||||
{
|
||||
return m_pInternal->Start(lPriority);
|
||||
}
|
||||
|
||||
void CFileTransporter::Suspend()
|
||||
{
|
||||
return m_pInternal->Suspend();
|
||||
}
|
||||
|
||||
void CFileTransporter::Resume()
|
||||
{
|
||||
return m_pInternal->Resume();
|
||||
}
|
||||
|
||||
void CFileTransporter::Stop()
|
||||
{
|
||||
return m_pInternal->Stop();
|
||||
}
|
||||
|
||||
int CFileTransporter::IsSuspended()
|
||||
{
|
||||
return m_pInternal->IsSuspended();
|
||||
}
|
||||
|
||||
int CFileTransporter::IsRunned()
|
||||
{
|
||||
return m_pInternal->IsRunned();
|
||||
}
|
||||
|
||||
int CFileTransporter::GetError()
|
||||
{
|
||||
return m_pInternal->GetError();
|
||||
}
|
||||
|
||||
int CFileTransporter::GetPriority()
|
||||
{
|
||||
return m_pInternal->GetPriority();
|
||||
}
|
||||
|
||||
void CFileTransporter::CheckSuspend()
|
||||
{
|
||||
return m_pInternal->CheckSuspend();
|
||||
}
|
||||
|
||||
void CFileTransporter::SetEvent_OnProgress(CFileTransporter_OnProgress func)
|
||||
{
|
||||
m_pInternal->GetInternal()->m_func_onProgress = func;
|
||||
}
|
||||
|
||||
void CFileTransporter::SetEvent_OnComplete(CFileTransporter_OnComplete func)
|
||||
{
|
||||
m_pInternal->GetInternal()->m_func_onComplete = func;
|
||||
}
|
||||
|
||||
#ifdef _MAC
|
||||
bool CFileTransporter::m_bIsARCEnabled = false;
|
||||
|
||||
void CFileTransporter::SetARCEnabled(const bool& enabled)
|
||||
{
|
||||
m_bIsARCEnabled = enabled;
|
||||
}
|
||||
|
||||
bool CFileTransporter::GetARCEnabled()
|
||||
{
|
||||
return m_bIsARCEnabled;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
243
Common/Network/FileTransporter/src/FileTransporter_curl.cpp
Normal file
243
Common/Network/FileTransporter/src/FileTransporter_curl.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2021
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FileTransporter_private.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include "../../DesktopEditor/common/Directory.h"
|
||||
|
||||
#ifndef USE_EXTERNAL_TRANSPORT
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <curl/curl.h>
|
||||
#include <curl/easy.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#else
|
||||
|
||||
#include "transport_external.h"
|
||||
|
||||
#endif
|
||||
|
||||
namespace NSNetwork
|
||||
{
|
||||
namespace NSFileTransport
|
||||
{
|
||||
class CFileTransporterBaseCURL : public CFileTransporterBase
|
||||
{
|
||||
public :
|
||||
CFileTransporterBaseCURL(std::wstring &sDownloadFileUrl, bool bDelete = true)
|
||||
: CFileTransporterBase(sDownloadFileUrl, bDelete)
|
||||
{
|
||||
}
|
||||
CFileTransporterBaseCURL(std::wstring &sUploadPathUrl, unsigned char* cData, const int nSize)
|
||||
: CFileTransporterBase(sUploadPathUrl, cData, nSize)
|
||||
{
|
||||
}
|
||||
virtual ~CFileTransporterBaseCURL()
|
||||
{
|
||||
if (m_bDelete && !m_sFilePath.empty())
|
||||
{
|
||||
std::string sFilePath = U_TO_UTF8(m_sFilePath);
|
||||
unlink(sFilePath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef USE_EXTERNAL_TRANSPORT
|
||||
static size_t write_data(void *ptr, size_t size, size_t nmemb, int fd) {
|
||||
size_t written = write(fd, ptr, size * nmemb);
|
||||
return written;
|
||||
}
|
||||
|
||||
static size_t write_data_to_string(char *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
((std::string*)userp)->append((char*)contents, size * nmemb);
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
virtual int DownloadFile()
|
||||
{
|
||||
CURL *curl;
|
||||
int fp;
|
||||
CURLcode res;
|
||||
std::string sUrl = U_TO_UTF8(m_sFileUrl);
|
||||
std::string sOut;
|
||||
const char *url = sUrl.c_str();
|
||||
curl = curl_easy_init();
|
||||
if (curl)
|
||||
{
|
||||
fp = createUniqueTempFile(sOut);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
|
||||
#if defined(__linux__)
|
||||
//в linux нет встроенных в систему корневых сертификатов, поэтому отключаем проверку
|
||||
//http://curl.haxx.se/docs/sslcerts.html
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
#endif
|
||||
/* tell libcurl to follow redirection(default false) */
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
/* some servers don't like requests that are made without a user-agent field, so we provide one */
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0");
|
||||
res = curl_easy_perform(curl);
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
close(fp);
|
||||
}
|
||||
|
||||
m_bComplete = (CURLE_OK == res);
|
||||
if (m_bComplete)
|
||||
{
|
||||
if (m_sFilePath.empty())
|
||||
m_sFilePath = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sOut.c_str(), sOut.length());
|
||||
else
|
||||
NSFile::CFileBinary::Move(UTF8_TO_U(sOut), m_sFilePath);
|
||||
}
|
||||
//int nRes = execl("/usr/bin/wget", stringWstingToUtf8String (m_sFileUrl).c_str(), "-P", stringWstingToUtf8String (m_sFilePath).c_str(), (char *)NULL);
|
||||
//m_bComplete = nRes >= 0;
|
||||
|
||||
return m_bComplete ? 0 : 1;
|
||||
}
|
||||
|
||||
virtual int UploadFile()
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
std::string sUrl = U_TO_UTF8(m_sUploadUrl);
|
||||
const char *url = sUrl.c_str();
|
||||
struct curl_slist *headerlist = NULL;
|
||||
std::string readBuffer;
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
|
||||
headerlist = curl_slist_append(headerlist, "Content-Type: application/octet-stream");
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_POST, true);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, true);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
|
||||
/* First set the URL that is about to receive our POST. This URL can
|
||||
just as well be a https:// URL if that is what should receive the
|
||||
data. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
/* Now specify the POST data */
|
||||
/* size of the POST data */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, m_nSize);
|
||||
/* binary data */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, m_cData);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data_to_string);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
|
||||
|
||||
#if defined(__linux__)
|
||||
//в linux нет встроенных в систему корневых сертификатов, поэтому отключаем проверку
|
||||
//http://curl.haxx.se/docs/sslcerts.html
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
#endif
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
long http_code = 0;
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
|
||||
|
||||
if (res == CURLE_OK)
|
||||
{
|
||||
if (http_code == 200 || http_code == 1223)
|
||||
{
|
||||
size_t startLenghtPos = readBuffer.find("Content-Length:") + sizeof("Content-Length:");
|
||||
size_t endLenghtPos = readBuffer.substr(startLenghtPos, readBuffer.length()).find("\r");
|
||||
std::string dataSize = readBuffer.substr(startLenghtPos, endLenghtPos);
|
||||
readBuffer = readBuffer.substr(readBuffer.length() - std::stoi(dataSize));
|
||||
NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)readBuffer.c_str(), (LONG)readBuffer.length(), m_sResponse);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = CURLE_HTTP_RETURNED_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
m_bComplete = (CURLE_OK == res);
|
||||
|
||||
return m_bComplete ? 0 : 1;
|
||||
}
|
||||
|
||||
protected:
|
||||
int createUniqueTempFile (std::string &filename)
|
||||
{
|
||||
std::string sTempPath = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(NSDirectory::GetTempPath());
|
||||
sTempPath += "/fileXXXXXX";
|
||||
int fd = mkstemp(const_cast <char *> (sTempPath.c_str()));
|
||||
if (-1 != fd)
|
||||
filename = sTempPath;
|
||||
return fd;
|
||||
}
|
||||
#else
|
||||
virtual int DownloadFile() override
|
||||
{
|
||||
if (m_sFilePath.empty())
|
||||
{
|
||||
m_sFilePath = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSDirectory::GetTempPath(), L"DW");
|
||||
if (NSFile::CFileBinary::Exists(m_sFilePath))
|
||||
NSFile::CFileBinary::Remove(m_sFilePath);
|
||||
}
|
||||
return download_external(m_sDownloadFileUrl, m_sFilePath);
|
||||
}
|
||||
virtual int UploadFile() override
|
||||
{
|
||||
if (!m_sUploadPathUrl.empty() && m_cData != NULL && m_nSize != 0)
|
||||
{
|
||||
return upload_external(m_sUploadPathUrl, m_cData, m_nSize);
|
||||
}
|
||||
|
||||
else return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
CFileTransporter_private::CFileTransporter_private(std::wstring &sDownloadFileUrl, bool bDelete)
|
||||
{
|
||||
m_pInternal = new CFileTransporterBaseCURL(sDownloadFileUrl, bDelete);
|
||||
}
|
||||
|
||||
CFileTransporter_private::CFileTransporter_private(std::wstring &sUploadPathUrl, unsigned char* cData, const int nSize)
|
||||
{
|
||||
m_pInternal = new CFileTransporterBaseCURL(sUploadPathUrl, cData, nSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
136
Common/Network/FileTransporter/src/FileTransporter_mac.mm
Normal file
136
Common/Network/FileTransporter/src/FileTransporter_mac.mm
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2021
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FileTransporter_private.h"
|
||||
#include "FileTransporter.h"
|
||||
|
||||
#ifdef USE_EXTERNAL_DOWNLOAD
|
||||
#include "transport_external.h"
|
||||
#endif
|
||||
|
||||
#if _IOS
|
||||
#import <Foundation/Foundation.h>
|
||||
#else
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
|
||||
namespace NSNetwork
|
||||
{
|
||||
namespace NSFileTransport
|
||||
{
|
||||
static NSString* StringWToNSString ( const std::wstring& Str )
|
||||
{
|
||||
NSString* pString = [ [ NSString alloc ]
|
||||
initWithBytes : (char*)Str.data()
|
||||
length : Str.size() * sizeof(wchar_t)
|
||||
encoding : CFStringConvertEncodingToNSStringEncoding ( kCFStringEncodingUTF32LE ) ];
|
||||
return pString;
|
||||
}
|
||||
class CFileTransporterBaseCocoa : public CFileTransporterBase
|
||||
{
|
||||
public :
|
||||
CFileTransporterBaseCocoa(std::wstring sFileUrl, bool bDelete = true)
|
||||
: CFileTransporterBase(sFileUrl, bDelete)
|
||||
{
|
||||
}
|
||||
virtual ~CFileTransporterBaseCocoa()
|
||||
{
|
||||
}
|
||||
|
||||
virtual int DownloadFile()
|
||||
{
|
||||
if (m_sFilePath.empty())
|
||||
{
|
||||
m_sFilePath = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSFile::CFileBinary::GetTempPath(), L"DWD");
|
||||
if (NSFile::CFileBinary::Exists(m_sFilePath))
|
||||
NSFile::CFileBinary::Remove(m_sFilePath);
|
||||
}
|
||||
|
||||
#ifdef USE_EXTERNAL_DOWNLOAD
|
||||
int nExternalTransport = Transport_external(m_sFileUrl, m_sFilePath);
|
||||
if (0 == nExternalTransport)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
NSString* stringURL = StringWToNSString(m_sFileUrl);
|
||||
NSString *escapedURL = [stringURL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
|
||||
NSURL *url = [NSURL URLWithString:escapedURL];
|
||||
NSData *urlData = [NSData dataWithContentsOfURL:url];
|
||||
if ( urlData )
|
||||
{
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||
|
||||
NSString *filePath = StringWToNSString ( m_sFilePath );
|
||||
[urlData writeToFile:filePath atomically:YES];
|
||||
|
||||
#if defined(_IOS)
|
||||
return 0;
|
||||
#else
|
||||
#ifndef _ASC_USE_ARC_
|
||||
if (!CFileTransporter::GetARCEnabled())
|
||||
{
|
||||
[stringURL release];
|
||||
//[url release];
|
||||
[urlData release];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(_IOS)
|
||||
return 1;
|
||||
#else
|
||||
#ifndef _ASC_USE_ARC_
|
||||
if (!CFileTransporter::GetARCEnabled())
|
||||
{
|
||||
[stringURL release];
|
||||
//[url release];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
CFileTransporter_private::CFileTransporter_private(std::wstring sFileUrl, bool bDelete)
|
||||
{
|
||||
m_pInternal = new CFileTransporterBaseCocoa(sFileUrl, bDelete);
|
||||
}
|
||||
|
||||
CFileTransporter_private::CFileTransporter_private(std::wstring &sUploadPathUrl, unsigned char* cData, const int nSize)
|
||||
{
|
||||
m_pInternal = new CFileTransporterBaseCocoa(sUploadPathUrl, cData, nSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
199
Common/Network/FileTransporter/src/FileTransporter_private.h
Normal file
199
Common/Network/FileTransporter/src/FileTransporter_private.h
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2021
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../../../DesktopEditor/common/File.h"
|
||||
#include "../../../../DesktopEditor/graphics/BaseThread.h"
|
||||
#include "../include/FileTransporter.h"
|
||||
|
||||
namespace NSNetwork
|
||||
{
|
||||
namespace NSFileTransport
|
||||
{
|
||||
class CFileTransporterBase
|
||||
{
|
||||
public :
|
||||
CFileTransporterBase(std::wstring &sDownloadFileUrl, bool bDelete)
|
||||
{
|
||||
m_sFilePath = L"";
|
||||
m_sDownloadFileUrl = sDownloadFileUrl;
|
||||
m_bComplete = false;
|
||||
m_bDelete = bDelete;
|
||||
m_bIsUpload = false;
|
||||
|
||||
m_sUploadPathUrl = L"";
|
||||
m_cData = NULL;
|
||||
m_nSize = 0;
|
||||
m_sResponse = L"";
|
||||
|
||||
|
||||
m_func_onComplete = NULL;
|
||||
m_func_onProgress = NULL;
|
||||
}
|
||||
|
||||
CFileTransporterBase(std::wstring &sUploadPathUrl, unsigned char* cData, const int nSize)
|
||||
{
|
||||
m_sFilePath = L"";
|
||||
m_sDownloadFileUrl = L"";
|
||||
m_bComplete = false;
|
||||
m_bDelete = true;
|
||||
m_bIsUpload = true;
|
||||
|
||||
m_sUploadPathUrl = sUploadPathUrl;
|
||||
m_cData = cData;
|
||||
m_nSize = nSize;
|
||||
m_sResponse = L"";
|
||||
|
||||
|
||||
m_func_onComplete = NULL;
|
||||
m_func_onProgress = NULL;
|
||||
}
|
||||
virtual ~CFileTransporterBase ()
|
||||
{
|
||||
if ( m_sFilePath.length() > 0 && m_bDelete )
|
||||
{
|
||||
NSFile::CFileBinary::Remove(m_sFilePath);
|
||||
m_sFilePath = L"";
|
||||
}
|
||||
}
|
||||
|
||||
virtual int DownloadFile() = 0;
|
||||
virtual int UploadFile() = 0;
|
||||
|
||||
public:
|
||||
std::wstring m_sFilePath; // Путь к сохраненному файлу на диске
|
||||
std::wstring m_sDownloadFileUrl; // Ссылка на скачивание файла
|
||||
|
||||
bool m_bComplete; // Закачался файл или нет
|
||||
bool m_bDelete; // Удалять ли файл в деструкторе
|
||||
bool m_bIsUpload; // Если хотим выгрузку данных
|
||||
|
||||
std::wstring m_sUploadPathUrl; // URL для выгрузки данных
|
||||
unsigned char* m_cData; // Данные в сыром виде
|
||||
int m_nSize; // Размер данных
|
||||
std::wstring m_sResponse; // Ответ сервера
|
||||
|
||||
CFileTransporter_OnComplete m_func_onComplete;
|
||||
CFileTransporter_OnProgress m_func_onProgress;
|
||||
};
|
||||
|
||||
class CFileTransporter_private : public NSThreads::CBaseThread
|
||||
{
|
||||
protected:
|
||||
// создаем в зависимости от платформы
|
||||
CFileTransporterBase* m_pInternal;
|
||||
|
||||
public:
|
||||
CFileTransporterBase* GetInternal()
|
||||
{
|
||||
return m_pInternal;
|
||||
}
|
||||
|
||||
public:
|
||||
CFileTransporter_private(std::wstring &sDownloadFileUrl, bool bDelete = true);
|
||||
CFileTransporter_private(std::wstring &sUploadPathUrl, unsigned char* cData, const int nSize);
|
||||
virtual ~CFileTransporter_private()
|
||||
{
|
||||
Stop();
|
||||
if (NULL != m_pInternal)
|
||||
delete m_pInternal;
|
||||
}
|
||||
|
||||
void SetDownloadProp(std::wstring &sDownloadFileUrl, bool bDelete = true)
|
||||
{
|
||||
m_pInternal->m_sDownloadFileUrl = sDownloadFileUrl;
|
||||
m_pInternal->m_bDelete = bDelete;
|
||||
m_pInternal->m_bIsUpload = false;
|
||||
}
|
||||
|
||||
void SetDownloadFilePath(const std::wstring& sPath)
|
||||
{
|
||||
m_pInternal->m_sFilePath = sPath;
|
||||
}
|
||||
|
||||
std::wstring GetDownloadFilePath()
|
||||
{
|
||||
return m_pInternal->m_sFilePath;
|
||||
}
|
||||
|
||||
bool IsFileDownloaded()
|
||||
{
|
||||
return m_pInternal->m_bComplete;
|
||||
}
|
||||
|
||||
void SetUploadProp(std::wstring &sDownloadFileUrl, unsigned char* cData, const int nSize)
|
||||
{
|
||||
m_pInternal->m_sUploadPathUrl = sDownloadFileUrl;
|
||||
m_pInternal->m_cData = cData;
|
||||
m_pInternal->m_nSize = nSize;
|
||||
m_pInternal->m_bIsUpload = true;
|
||||
}
|
||||
|
||||
std::wstring& GetResponse()
|
||||
{
|
||||
return m_pInternal->m_sResponse;
|
||||
}
|
||||
|
||||
bool TransferSync()
|
||||
{
|
||||
this->Start( 1 );
|
||||
while ( this->IsRunned() )
|
||||
{
|
||||
NSThreads::Sleep( 10 );
|
||||
}
|
||||
return IsFileDownloaded();
|
||||
}
|
||||
|
||||
void TransferAsync()
|
||||
{
|
||||
this->Start( 1 );
|
||||
}
|
||||
|
||||
protected :
|
||||
|
||||
virtual DWORD ThreadProc ()
|
||||
{
|
||||
m_pInternal->m_bComplete = false;
|
||||
|
||||
int hrResultAll = m_pInternal->m_bIsUpload?m_pInternal->UploadFile():m_pInternal->DownloadFile();
|
||||
if (0 == hrResultAll)
|
||||
m_pInternal->m_bComplete = true;
|
||||
|
||||
if (m_pInternal->m_func_onComplete)
|
||||
m_pInternal->m_func_onComplete(hrResultAll);
|
||||
|
||||
m_bRunThread = FALSE;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
424
Common/Network/FileTransporter/src/FileTransporter_win.cpp
Normal file
424
Common/Network/FileTransporter/src/FileTransporter_win.cpp
Normal file
@ -0,0 +1,424 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2021
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FileTransporter_private.h"
|
||||
|
||||
|
||||
#include <wininet.h>
|
||||
#pragma comment(lib, "Wininet")
|
||||
#pragma comment(lib, "Ole32.lib")
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Константа для максимального числа символов в строке
|
||||
#define MAX_SIZE 256
|
||||
// Константа для максимального числа загружаемых байт
|
||||
#define DOWNLOAD_FILE_SIZE 32768
|
||||
#define MAX_SINGLE_DOWNLOAD_FILE_SIZE 524288
|
||||
|
||||
|
||||
// Константа для получения размера файла
|
||||
#define CONTENT_RANGE L"bytes 0-0/"
|
||||
// Константа для колличества символов у CONTENT_RANGE
|
||||
#define CONTENT_RANGE_SIZE ( 11/*sizeof ( CONTENT_RANGE )*/ - 1 )
|
||||
|
||||
namespace NSNetwork
|
||||
{
|
||||
namespace NSFileTransport
|
||||
{
|
||||
class CFileTransporterBaseWin : public CFileTransporterBase
|
||||
{
|
||||
public :
|
||||
CFileTransporterBaseWin(std::wstring &sDownloadFileUrl, bool bDelete = true) :
|
||||
CFileTransporterBase(sDownloadFileUrl, bDelete)
|
||||
{
|
||||
m_pFile = NULL;
|
||||
}
|
||||
|
||||
CFileTransporterBaseWin(std::wstring &sUploadPathUrl, unsigned char* cData, const int nSize) :
|
||||
CFileTransporterBase(sUploadPathUrl, cData, nSize)
|
||||
{
|
||||
m_pFile = NULL;
|
||||
}
|
||||
|
||||
virtual ~CFileTransporterBaseWin()
|
||||
{
|
||||
if ( m_pFile )
|
||||
{
|
||||
::fclose( m_pFile );
|
||||
m_pFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
virtual int DownloadFile() override
|
||||
{
|
||||
CoInitialize ( NULL );
|
||||
if ( /*S_OK != _DownloadFile ( m_sFileUrl )*/TRUE )
|
||||
{
|
||||
HRESULT hrResultAll = DownloadFileAll(m_sDownloadFileUrl, m_sFilePath);
|
||||
|
||||
if (S_OK != hrResultAll)
|
||||
{
|
||||
hrResultAll = (true == DownloadFilePS(m_sDownloadFileUrl, m_sFilePath)) ? S_OK : S_FALSE;
|
||||
CoUninitialize ();
|
||||
return hrResultAll;
|
||||
}
|
||||
}
|
||||
|
||||
CoUninitialize ();
|
||||
m_bComplete = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual int UploadFile() override
|
||||
{
|
||||
//stub
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
FILE *m_pFile; // Хэндл на временный файл
|
||||
unsigned int _DownloadFile(std::wstring sFileUrl)
|
||||
{
|
||||
// Проверяем состояние соединения
|
||||
if ( FALSE == InternetGetConnectedState ( 0, 0 ) )
|
||||
return S_FALSE;
|
||||
|
||||
wchar_t sTempPath[MAX_PATH], sTempFile[MAX_PATH];
|
||||
if ( 0 == GetTempPathW( MAX_PATH, sTempPath ) )
|
||||
return S_FALSE;
|
||||
|
||||
if ( 0 == GetTempFileNameW( sTempPath, L"CSS", 0, sTempFile ) )
|
||||
return S_FALSE;
|
||||
|
||||
m_pFile = ::_wfopen( sTempFile, L"wb" );
|
||||
if ( !m_pFile )
|
||||
return S_FALSE;
|
||||
|
||||
m_sFilePath = std::wstring( sTempFile );
|
||||
|
||||
// Открываем сессию
|
||||
HINTERNET hInternetSession = InternetOpenW ( L"Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
|
||||
if ( NULL == hInternetSession )
|
||||
return S_FALSE;
|
||||
|
||||
// Заголовок запроса ( пока содержит 0 байт ( необходимо для проверки ) )
|
||||
std::wstring sHTTPHdr = L"Range: bytes=0-0";
|
||||
// Открываем ссылку для проверки на ее существование, а также на возможность чтения частями
|
||||
HINTERNET hInternetOpenURL = InternetOpenUrlW ( hInternetSession, sFileUrl.c_str(), sHTTPHdr.c_str(), -1, INTERNET_FLAG_RESYNCHRONIZE, 0 );
|
||||
if ( NULL != hInternetOpenURL )
|
||||
{
|
||||
// Открытие произошло, проверяем ответ
|
||||
if ( TRUE == QueryStatusCode ( hInternetOpenURL, TRUE ) )
|
||||
{
|
||||
// Запрос прошел удачно, проверяем возможность чтения частями и получаем размер данных
|
||||
LONGLONG nFileSize = IsAccept_Ranges ( hInternetOpenURL );
|
||||
// Закрываем хендл
|
||||
InternetCloseHandle ( hInternetOpenURL );
|
||||
if ( -1 == nFileSize )
|
||||
{
|
||||
// Чтение частями недоступно
|
||||
// Закрываем хендл соединения
|
||||
InternetCloseHandle ( hInternetSession );
|
||||
// Закрываем файл (сделается на DownloadAll)
|
||||
// Попробуем записать его целиком
|
||||
return S_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Чтение частями доступно
|
||||
LONGLONG nStartByte = 0;
|
||||
while ( true )
|
||||
{
|
||||
// Если закачали весь файл - то выходим
|
||||
if ( nStartByte == nFileSize - 1 )
|
||||
{
|
||||
// Закрываем хендл соединения
|
||||
InternetCloseHandle ( hInternetSession );
|
||||
return S_OK;
|
||||
}
|
||||
LONGLONG nEndByte = nStartByte + DOWNLOAD_FILE_SIZE;
|
||||
// Если файл заканчивается, то загружаем меньшее колличество байт ( на 1 меньше, чем размер, т.к. начинается с 0 )
|
||||
if ( nEndByte >= nFileSize )
|
||||
nEndByte = nFileSize - 1;
|
||||
|
||||
// Буффер для закачки
|
||||
BYTE arrBuffer [ DOWNLOAD_FILE_SIZE ] = { 0 };
|
||||
DWORD dwBytesDownload = DownloadFilePath ( hInternetSession, arrBuffer, nStartByte, nEndByte, sFileUrl );
|
||||
|
||||
nStartByte = nEndByte;
|
||||
if ( -1 == dwBytesDownload )
|
||||
{
|
||||
// Ничего не прочиталось - это плохо!!!!
|
||||
// Закрываем хендл соединения
|
||||
InternetCloseHandle ( hInternetSession );
|
||||
// Закрываем файл (сделается на DownloadAll)
|
||||
// Попробуем записать его целиком
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
// Пишем в файл
|
||||
::fwrite( (BYTE*)arrBuffer, 1, dwBytesDownload, m_pFile );
|
||||
::fflush( m_pFile );
|
||||
|
||||
NSThreads::Sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Закрываем хендл соединения
|
||||
InternetCloseHandle ( hInternetSession );
|
||||
// Закрываем файл (сделается на DownloadAll)
|
||||
// Попробуем записать его целиком
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Закрываем хендл соединения
|
||||
InternetCloseHandle ( hInternetSession );
|
||||
// Закрываем файл (сделается на DownloadAll)
|
||||
// Попробуем записать его целиком
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
// Закрываем хендл соединения
|
||||
InternetCloseHandle ( hInternetSession );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
DWORD DownloadFilePath ( HINTERNET hInternet, LPBYTE pBuffer, LONGLONG nStartByte, LONGLONG nEndByte, std::wstring sFileURL )
|
||||
{
|
||||
// Неоткрытая сессия
|
||||
if ( NULL == hInternet )
|
||||
return -1;
|
||||
|
||||
// Пришли непонятные параметры
|
||||
if ( nStartByte > nEndByte || !pBuffer )
|
||||
return -1;
|
||||
|
||||
// Заголовок запроса ( содержит nEndByte - nStartByte байт )
|
||||
std::wstring sHTTPHdr = L"Range: bytes=" + std::to_wstring(nStartByte) + L"-" + std::to_wstring(nEndByte);
|
||||
// Открываем ссылку для закачки
|
||||
HINTERNET hInternetOpenURL = InternetOpenUrlW ( hInternet, sFileURL.c_str(), sHTTPHdr.c_str(), -1, INTERNET_FLAG_RESYNCHRONIZE, 0 );
|
||||
if ( NULL == hInternetOpenURL )
|
||||
return -1;
|
||||
// Открытие произошло, проверяем ответ
|
||||
if ( FALSE == QueryStatusCode ( hInternetOpenURL, TRUE ) )
|
||||
{
|
||||
// Закрываем хендл соединения
|
||||
InternetCloseHandle ( hInternetOpenURL );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Какое колличество байт прочитано
|
||||
DWORD dwBytesRead = 0;
|
||||
// Читаем файл
|
||||
if ( FALSE == InternetReadFile ( hInternetOpenURL, pBuffer, DOWNLOAD_FILE_SIZE, &dwBytesRead ) )
|
||||
{
|
||||
// Закрываем хендл соединения
|
||||
InternetCloseHandle ( hInternetOpenURL );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Закрываем хендл соединения
|
||||
InternetCloseHandle ( hInternetOpenURL );
|
||||
|
||||
return dwBytesRead;
|
||||
}
|
||||
|
||||
BOOL QueryStatusCode ( HINTERNET hInternet, BOOL bIsRanges )
|
||||
{
|
||||
// Зачем проверять у неоткрытой сессии что-то
|
||||
if ( NULL == hInternet )
|
||||
return FALSE;
|
||||
|
||||
// Результат ответа
|
||||
INT nResult = 0;
|
||||
// Размер данных ответа ( должно быть = 4 )
|
||||
DWORD dwLengthDataSize = 4;
|
||||
|
||||
// Делаем запрос, если не проходит - то возвращаем FALSE
|
||||
if ( FALSE == HttpQueryInfo ( hInternet, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &nResult, &dwLengthDataSize, NULL ) )
|
||||
return FALSE;
|
||||
|
||||
// Запрос прошел, теперь проверяем код ответа
|
||||
if ( HTTP_STATUS_NOT_FOUND == nResult )
|
||||
{
|
||||
// Объект не найден, плохая ссылка или что-то еще
|
||||
return FALSE;
|
||||
}
|
||||
else if ( ( HTTP_STATUS_OK != nResult && FALSE == bIsRanges ) || ( HTTP_STATUS_PARTIAL_CONTENT != nResult && TRUE == bIsRanges ) )
|
||||
{
|
||||
// Запрос не прошел по какой-то причине
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Все отлично, запрос прошел
|
||||
return TRUE;
|
||||
}
|
||||
// Проверяет, доступно ли для ресурса чтение частями и возвращает -1 если не доступно и размер данных, если доступно
|
||||
LONGLONG IsAccept_Ranges ( HINTERNET hInternet )
|
||||
{
|
||||
// Зачем проверять у неоткрытой сессии что-то
|
||||
if ( NULL == hInternet )
|
||||
return -1;
|
||||
|
||||
// Результат ответа
|
||||
wchar_t arrResult [ MAX_SIZE ] = { 0 };
|
||||
// Размер данных ответа
|
||||
DWORD dwLengthDataSize = sizeof ( arrResult );
|
||||
|
||||
// Делаем запрос, если не проходит - то возвращаем FALSE
|
||||
if ( FALSE == HttpQueryInfoW ( hInternet, HTTP_QUERY_CONTENT_RANGE, &arrResult, &dwLengthDataSize, NULL ) )
|
||||
{
|
||||
// Получаем последнюю ошибку
|
||||
DWORD dwLastError = GetLastError ();
|
||||
if ( dwLastError == ERROR_HTTP_HEADER_NOT_FOUND )
|
||||
{
|
||||
// Не пришел заголовок, значит ресурс не поддерживает чтение частями
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Возникла какая-то другая ошибка - возвращаем FALSE
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Если размер 0, то заголовка нет
|
||||
if ( 0 >= dwLengthDataSize )
|
||||
return -1;
|
||||
|
||||
// Приведем к std::wstring
|
||||
std::wstring strResult ( arrResult );
|
||||
|
||||
// Содержит размер данных
|
||||
LONGLONG nFileSize = 0;
|
||||
|
||||
try
|
||||
{
|
||||
// Ищем индекс размера данных в строке
|
||||
INT nStartIndex = (INT)strResult.find ( CONTENT_RANGE );
|
||||
if ( -1 == nStartIndex )
|
||||
return -1;
|
||||
|
||||
// Оставляем в строке только размер данных
|
||||
strResult = strResult.substr( nStartIndex + CONTENT_RANGE_SIZE );
|
||||
// Теперь получим размер данных, переводя стринг в LONGLONG
|
||||
nFileSize = _wtoi64 ( strResult.c_str() );
|
||||
// Т.к. реально нумерация с 0 ( поэтому добавляем еще 1 байт )
|
||||
if ( 0 < nFileSize )
|
||||
nFileSize += 1;
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
// не нашли возвращаем ошибку
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Все отлично, ресурс поддерживает чтение частями, возвращаем размер
|
||||
return nFileSize;
|
||||
}
|
||||
|
||||
HRESULT DownloadFileAll(std::wstring sFileURL, std::wstring strFileOutput)
|
||||
{
|
||||
if ( m_pFile )
|
||||
{
|
||||
::fclose( m_pFile );
|
||||
m_pFile = NULL;
|
||||
}
|
||||
// Скачиваем файл
|
||||
return URLDownloadToFileW (NULL, sFileURL.c_str(), strFileOutput.c_str(), NULL, NULL);
|
||||
}
|
||||
|
||||
bool DownloadFilePS(const std::wstring& sFileURL, const std::wstring& strFileOutput)
|
||||
{
|
||||
STARTUPINFO sturtupinfo;
|
||||
ZeroMemory(&sturtupinfo,sizeof(STARTUPINFO));
|
||||
sturtupinfo.cb = sizeof(STARTUPINFO);
|
||||
|
||||
std::wstring sFileDst = strFileOutput;
|
||||
size_t posn = 0;
|
||||
while (std::wstring::npos != (posn = sFileDst.find('\\', posn)))
|
||||
{
|
||||
sFileDst.replace(posn, 1, L"/");
|
||||
posn += 1;
|
||||
}
|
||||
|
||||
std::wstring sApp = L"powershell.exe –c \"(new-object System.Net.WebClient).DownloadFile('" + sFileURL + L"','" + sFileDst + L"')\"";
|
||||
wchar_t* pCommandLine = new wchar_t[sApp.length() + 1];
|
||||
memcpy(pCommandLine, sApp.c_str(), sApp.length() * sizeof(wchar_t));
|
||||
pCommandLine[sApp.length()] = (wchar_t)'\0';
|
||||
|
||||
HANDLE ghJob = CreateJobObject(NULL, NULL);
|
||||
|
||||
if (ghJob)
|
||||
{
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
|
||||
|
||||
// Configure all child processes associated with the job to terminate when the
|
||||
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||
if ( 0 == SetInformationJobObject( ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)))
|
||||
{
|
||||
CloseHandle(ghJob);
|
||||
ghJob = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PROCESS_INFORMATION processinfo;
|
||||
ZeroMemory(&processinfo,sizeof(PROCESS_INFORMATION));
|
||||
BOOL bResult = CreateProcessW(NULL, pCommandLine, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &sturtupinfo, &processinfo);
|
||||
|
||||
if (bResult && ghJob)
|
||||
{
|
||||
AssignProcessToJobObject(ghJob, processinfo.hProcess);
|
||||
}
|
||||
|
||||
::WaitForSingleObject(processinfo.hProcess, INFINITE);
|
||||
|
||||
RELEASEARRAYOBJECTS(pCommandLine);
|
||||
|
||||
return NSFile::CFileBinary::Exists(sFileDst);
|
||||
}
|
||||
};
|
||||
|
||||
CFileTransporter_private::CFileTransporter_private(std::wstring &sDownloadFileUrl, bool bDelete)
|
||||
{
|
||||
m_pInternal = new CFileTransporterBaseWin(sDownloadFileUrl, bDelete);
|
||||
}
|
||||
|
||||
CFileTransporter_private::CFileTransporter_private(std::wstring &sUploadPathUrl, unsigned char* cData, const int nSize)
|
||||
{
|
||||
m_pInternal = new CFileTransporterBaseWin(sUploadPathUrl, cData, nSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
168
Common/Network/FileTransporter/src/transport_external.h
Normal file
168
Common/Network/FileTransporter/src/transport_external.h
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2021
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include "../../DesktopEditor/common/Directory.h"
|
||||
|
||||
#ifdef USE_EXTERNAL_TRANSPORT
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
namespace NSNetwork
|
||||
{
|
||||
namespace NSFileTransport
|
||||
{
|
||||
std::string wget_url_validate(const std::string& url)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
const char* url_ptr = url.c_str();
|
||||
while ('-' == *url_ptr++) // '\0' => break
|
||||
++pos;
|
||||
if (*url_ptr == '\0')
|
||||
return "";
|
||||
|
||||
return url.substr(pos);
|
||||
}
|
||||
|
||||
int download_external(const std::wstring& sUrl, const std::wstring& sOutput)
|
||||
{
|
||||
int nReturnCode = -1;
|
||||
|
||||
std::string sUrlA = U_TO_UTF8(sUrl);
|
||||
//sUrlA =("\"" + sUrlA + "\"");
|
||||
std::string sOutputA = U_TO_UTF8(sOutput);
|
||||
//sOutputA =("\"" + sOutputA + "\"");
|
||||
|
||||
if (0 != nReturnCode && NSFile::CFileBinary::Exists(L"/usr/bin/curl"))
|
||||
{
|
||||
pid_t pid = fork(); // create child process
|
||||
int status;
|
||||
|
||||
switch (pid)
|
||||
{
|
||||
case -1: // error
|
||||
break;
|
||||
|
||||
case 0: // child process
|
||||
{
|
||||
const char* nargs[10];
|
||||
nargs[0] = "/usr/bin/curl";
|
||||
nargs[1] = "--url";
|
||||
nargs[2] = sUrlA.c_str();
|
||||
nargs[3] = "--output";
|
||||
nargs[4] = sOutputA.c_str();
|
||||
nargs[5] = "--silent";
|
||||
nargs[6] = "-L";
|
||||
nargs[7] = "--connect-timeout";
|
||||
nargs[8] = "10";
|
||||
nargs[9] = NULL;
|
||||
|
||||
const char* nenv[3];
|
||||
nenv[0] = "LD_PRELOAD=";
|
||||
nenv[1] = "LD_LIBRARY_PATH=";
|
||||
nenv[2] = NULL;
|
||||
|
||||
execve("/usr/bin/curl", (char * const *)nargs, (char * const *)nenv);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
default: // parent process, pid now contains the child pid
|
||||
while (-1 == waitpid(pid, &status, 0)); // wait for child to complete
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
nReturnCode = WEXITSTATUS(status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != nReturnCode && NSFile::CFileBinary::Exists(L"/usr/bin/wget"))
|
||||
{
|
||||
std::string sUrlValidateA = wget_url_validate(sUrlA);
|
||||
|
||||
pid_t pid = fork(); // create child process
|
||||
int status;
|
||||
|
||||
switch (pid)
|
||||
{
|
||||
case -1: // error
|
||||
break;
|
||||
|
||||
case 0: // child process
|
||||
{
|
||||
const char* nargs[8];
|
||||
nargs[0] = "/usr/bin/wget";
|
||||
nargs[1] = sUrlValidateA.c_str();
|
||||
nargs[2] = "-O";
|
||||
nargs[3] = sOutputA.c_str();
|
||||
nargs[4] = "-q";
|
||||
nargs[5] = "--connect-timeout=10";
|
||||
nargs[6] = "--tries=2";
|
||||
nargs[7] = NULL;
|
||||
|
||||
const char* nenv[2];
|
||||
nenv[0] = "LD_PRELOAD=";
|
||||
nenv[1] = NULL;
|
||||
|
||||
execve("/usr/bin/wget", (char * const *)nargs, (char * const *)nenv);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
default: // parent process, pid now contains the child pid
|
||||
while (-1 == waitpid(pid, &status, 0)); // wait for child to complete
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
nReturnCode = WEXITSTATUS(status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == nReturnCode)
|
||||
{
|
||||
if (!NSFile::CFileBinary::Exists(sOutput))
|
||||
nReturnCode = -1;
|
||||
}
|
||||
|
||||
return nReturnCode;
|
||||
}
|
||||
|
||||
int upload_external(std::wstring &sUploadPathUrl, unsigned char* cData, const int nSize)
|
||||
{
|
||||
//stub
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user