1174 lines
42 KiB
C++
1174 lines
42 KiB
C++
|
|
// Copyright 2017-2020 David Romanski(Socke). All Rights Reserved.
|
||
|
|
#include "WebCommunicationRequestCompleteObject.h"
|
||
|
|
|
||
|
|
|
||
|
|
UWebCommunicationRequestCompleteObject::UWebCommunicationRequestCompleteObject(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) {
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
UWebCommunicationRequestCompleteObject::~UWebCommunicationRequestCompleteObject() {
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::BeginDestroy(){
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: BeginDestroy "));
|
||
|
|
if (thread != nullptr) {
|
||
|
|
thread->Stop();
|
||
|
|
delete thread;
|
||
|
|
thread = nullptr;
|
||
|
|
}
|
||
|
|
Super::BeginDestroy();
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::initWebCom(){
|
||
|
|
this->AddToRoot();
|
||
|
|
thread = new FWebcomThread(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestComplete(FHttpRequestPtr request, FHttpResponsePtr response, bool bWasSuccessful) {
|
||
|
|
FWebcomTheadJob* job = new FWebcomTheadJob();
|
||
|
|
job->request = request;
|
||
|
|
job->response = response;
|
||
|
|
job->bWasSuccessful = bWasSuccessful;
|
||
|
|
job->type = 0;
|
||
|
|
thread->addJob(job);
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestCompleteInternal(FHttpRequestPtr Request, FHttpResponsePtr response, bool bWasSuccessful){
|
||
|
|
if (webCommunicationBPLibrary == nullptr) {
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: Missing Object instance (12)."));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if ((httpRequest.requestType == EHTTPWebComRequestType::PUT_STREAM_MP || httpRequest.requestType == EHTTPWebComRequestType::PUT_STREAM_COPY)
|
||
|
|
&& !httpRequest.filePath.IsEmpty() && httpRequest.originalFileSize > 0) {
|
||
|
|
webCommunicationBPLibrary->addRequestToTruncateThread(httpRequest);
|
||
|
|
}
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: RequestID %s"), *requestID);
|
||
|
|
|
||
|
|
UWebCommunicationBPLibrary* webcom = webCommunicationBPLibrary;
|
||
|
|
FString requestIDP = requestID;
|
||
|
|
if (webcom->removeHeaders) {
|
||
|
|
webcom->additionalHeader.Empty();
|
||
|
|
}
|
||
|
|
|
||
|
|
UAsyncNodeWebCom* asyncNodeHttpRequest = webcom->getUAsyncNodeHttpRequest(requestID);
|
||
|
|
|
||
|
|
EMultiStepType multistepGlobal = multiStepDownloadType;
|
||
|
|
FString downloadIDGlobal = downloadID;
|
||
|
|
|
||
|
|
if (!bWasSuccessful || !response.IsValid()) {
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("Request unsuccessful, check the url. %i"),response->GetResponseCode());
|
||
|
|
TArray<FString> dataArray;
|
||
|
|
TArray<uint8> byteArray;
|
||
|
|
FString dataString = "No Response";
|
||
|
|
int32 statusCode = 500;
|
||
|
|
if (response.IsValid()) {
|
||
|
|
dataString = response->GetContentAsString();
|
||
|
|
dataString.ParseIntoArray(dataArray, TEXT("\r\n"), true);
|
||
|
|
statusCode = response->GetResponseCode();
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
dataArray.Add(dataString);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//switch to gamethread
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest, webcom, dataString, dataArray, statusCode, byteArray, downloadIDGlobal, requestIDP, multistepGlobal]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
if (multistepGlobal == EMultiStepType::GOOGLE_INFO) {
|
||
|
|
UAsyncNodeHttpGoogleFileInfoRequest* asyncNodeGoogleInfoRequest = dynamic_cast<UAsyncNodeHttpGoogleFileInfoRequest*>(asyncNodeHttpRequest);
|
||
|
|
if (asyncNodeGoogleInfoRequest) {
|
||
|
|
asyncNodeGoogleInfoRequest->httpRequestCompleteGoogleFileInfo("", 0, statusCode, downloadIDGlobal, requestIDP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
UAsyncNodeHttpDownloadUpload* asyncNodeDownloadUpload = dynamic_cast<UAsyncNodeHttpDownloadUpload*>(asyncNodeHttpRequest);
|
||
|
|
if (asyncNodeDownloadUpload) {
|
||
|
|
asyncNodeDownloadUpload->httpRequestDownloadUploadComplete(dataString,dataArray,TArray<FString>(), statusCode, requestIDP);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
asyncNodeHttpRequest->httpRequestComplete(dataString,dataArray, TArray<FString>(), statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (multistepGlobal == EMultiStepType::GOOGLE_INFO) {
|
||
|
|
webcom->onhttpRequestCompleteGoogleInfoDelegate.Broadcast("", 0, statusCode, downloadIDGlobal, requestIDP);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteDelegate.Broadcast(dataString, dataArray, TArray<FString>(), statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
});
|
||
|
|
|
||
|
|
|
||
|
|
//write download to file
|
||
|
|
if (fileCancelResumeDownloadDir.IsEmpty() == false && downloadDataCopy.Num() > 0) {
|
||
|
|
FArchive* writer = IFileManager::Get().CreateFileWriter(*fileCancelResumeDownloadDir, EFileWrite::FILEWRITE_Append);
|
||
|
|
if (writer) {
|
||
|
|
writer->Seek(writer->TotalSize());
|
||
|
|
writer->Serialize(downloadDataCopy.GetData(), downloadDataCopy.Num());
|
||
|
|
downloadDataCopy.Empty();
|
||
|
|
writer->Close();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
TArray<uint8> byteArray = response->GetContent();
|
||
|
|
FString dataString = response->GetContentAsString();
|
||
|
|
TArray<FString> dataArray;
|
||
|
|
dataString.ParseIntoArray(dataArray, TEXT("\r\n"), true);
|
||
|
|
|
||
|
|
if (multiStepDownloadType == EMultiStepType::GOOGLE_INFO) {
|
||
|
|
//UE_LOG(LogTemp, Warning, TEXT("UWebCommunicationBPLibrary: %s"),*dataString);
|
||
|
|
|
||
|
|
//read fileinfos from google drive html/javascript view page
|
||
|
|
FString left;
|
||
|
|
FString right;
|
||
|
|
dataString.Split("itemJson:", &left, &right);
|
||
|
|
|
||
|
|
TArray<FString> lines;
|
||
|
|
int32 lineCount = right.ParseIntoArray(lines, TEXT(","), true);
|
||
|
|
|
||
|
|
if (lineCount > 27) {
|
||
|
|
FString fileName = lines[1];
|
||
|
|
fileName = fileName.Replace(TEXT("\""), TEXT(""));
|
||
|
|
|
||
|
|
FString fileSizeString = lines[27];
|
||
|
|
fileSizeString = fileSizeString.Replace(TEXT("\""), TEXT(""));
|
||
|
|
fileSizeString = fileSizeString.Replace(TEXT("]"), TEXT(""));
|
||
|
|
|
||
|
|
int64 fileSize = FCString::Atoi64(*fileSizeString);
|
||
|
|
|
||
|
|
int32 statusCode = response->GetResponseCode();
|
||
|
|
|
||
|
|
/*UE_LOG(LogTemp, Warning, TEXT("FileName: %s"),*fileName);
|
||
|
|
UE_LOG(LogTemp, Warning, TEXT("FileSize: %i"),fileSize);*/
|
||
|
|
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest,webcom, fileName, fileSize,statusCode, downloadIDGlobal, requestIDP, multistepGlobal]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
UAsyncNodeHttpGoogleFileInfoRequest* asyncNodeGoogleInfoRequest = dynamic_cast<UAsyncNodeHttpGoogleFileInfoRequest*>(asyncNodeHttpRequest);
|
||
|
|
if (asyncNodeGoogleInfoRequest) {
|
||
|
|
asyncNodeGoogleInfoRequest->httpRequestCompleteGoogleFileInfo(fileName, fileSize, statusCode, downloadIDGlobal, requestIDP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteGoogleInfoDelegate.Broadcast(fileName, fileSize, statusCode, downloadIDGlobal, requestIDP);
|
||
|
|
}
|
||
|
|
|
||
|
|
});
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest, webcom, downloadIDGlobal, requestIDP, multistepGlobal]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
UAsyncNodeHttpGoogleFileInfoRequest* asyncNodeGoogleInfoRequest = dynamic_cast<UAsyncNodeHttpGoogleFileInfoRequest*>(asyncNodeHttpRequest);
|
||
|
|
if (asyncNodeGoogleInfoRequest) {
|
||
|
|
asyncNodeGoogleInfoRequest->httpRequestCompleteGoogleFileInfo("", 0, 452, downloadIDGlobal, requestIDP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteGoogleInfoDelegate.Broadcast("", 0, 452, downloadIDGlobal, requestIDP);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
//if its a resume download and the existing file is => then the file on server then empty data
|
||
|
|
if (fileCancelResumeDownloadDir.IsEmpty() == false) {
|
||
|
|
|
||
|
|
//Content-Range: bytes 0-0/104857600
|
||
|
|
FString responseSize = response->GetHeader("Content-Range");
|
||
|
|
|
||
|
|
if (responseSize.IsEmpty()) {
|
||
|
|
responseSize = response->GetHeader("content-range");
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (responseSize.IsEmpty()) {
|
||
|
|
responseSize = response->GetHeader("Content-range");
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (responseSize.IsEmpty()) {
|
||
|
|
responseSize = response->GetHeader("content-Range");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (responseSize.IsEmpty() == false) {
|
||
|
|
FString left;
|
||
|
|
FString right;
|
||
|
|
responseSize.Split("/", &left, &right);
|
||
|
|
responseSize = right;
|
||
|
|
|
||
|
|
int32 fullSize = FCString::Atoi(*responseSize);
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary filesize: %i"), FPlatformFileManager::Get().GetPlatformFile().FileSize(*fileCancelResumeDownloadDir));
|
||
|
|
if (FPlatformFileManager::Get().GetPlatformFile().FileSize(*fileCancelResumeDownloadDir) >= fullSize) {
|
||
|
|
byteArray.Empty();
|
||
|
|
dataArray.Empty();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (byteArray.Num() > 0) {
|
||
|
|
FArchive* writer = IFileManager::Get().CreateFileWriter(*fileCancelResumeDownloadDir, EFileWrite::FILEWRITE_Append);
|
||
|
|
if (writer) {
|
||
|
|
writer->Seek(writer->TotalSize());
|
||
|
|
writer->Serialize(byteArray.GetData(), byteArray.Num());
|
||
|
|
writer->Close();
|
||
|
|
}
|
||
|
|
delete writer;
|
||
|
|
byteArray.Empty();
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int32 statusCode = response->GetResponseCode();
|
||
|
|
|
||
|
|
TArray<FString> headerData = response->GetAllHeaders();
|
||
|
|
|
||
|
|
//switch to gamethread
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest,webcom, dataString, dataArray, headerData, statusCode, byteArray, requestIDP]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
UAsyncNodeHttpDownloadUpload* asyncNodeDownloadUpload = dynamic_cast<UAsyncNodeHttpDownloadUpload*>(asyncNodeHttpRequest);
|
||
|
|
if (asyncNodeDownloadUpload) {
|
||
|
|
asyncNodeDownloadUpload->httpRequestDownloadUploadComplete(dataString, dataArray, headerData, statusCode, requestIDP);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
asyncNodeHttpRequest->httpRequestComplete(dataString, dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteDelegate.Broadcast(dataString, dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
byteArray.Empty();
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestCompleteLowRam(FHttpRequestPtr request, FHttpResponsePtr response, bool bWasSuccessful) {
|
||
|
|
FWebcomTheadJob* job = new FWebcomTheadJob();
|
||
|
|
job->request = request;
|
||
|
|
job->response = response;
|
||
|
|
job->bWasSuccessful = bWasSuccessful;
|
||
|
|
job->type = 1;
|
||
|
|
thread->addJob(job);
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestCompleteLowRamInternal(FHttpRequestPtr request, FHttpResponsePtr response, bool bWasSuccessful){
|
||
|
|
if (webCommunicationBPLibrary == nullptr) {
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: Missing Object instance (12)."));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: RequestID %s"), *requestID);
|
||
|
|
|
||
|
|
UWebCommunicationBPLibrary* webcom = webCommunicationBPLibrary;
|
||
|
|
FString requestIDP = requestID;
|
||
|
|
if (webcom->removeHeaders) {
|
||
|
|
webcom->additionalHeader.Empty();
|
||
|
|
}
|
||
|
|
|
||
|
|
UAsyncNodeWebCom* asyncNodeHttpRequest = webcom->getUAsyncNodeHttpRequest(requestID);
|
||
|
|
|
||
|
|
if (!bWasSuccessful || !response.IsValid()) {
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("Request unsuccessful, check the url"));
|
||
|
|
TArray<FString> dataArray;
|
||
|
|
TArray<uint8> byteArray;
|
||
|
|
FString dataString = "No Response";
|
||
|
|
int32 statusCode = 500;
|
||
|
|
if (response.IsValid()) {
|
||
|
|
dataString = response->GetContentAsString();
|
||
|
|
dataString.ParseIntoArray(dataArray, TEXT("\r\n"), true);
|
||
|
|
statusCode = response->GetResponseCode();
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
dataArray.Add(dataString);
|
||
|
|
}
|
||
|
|
//switch to gamethread
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest, webcom, dataString, dataArray, statusCode, byteArray, requestIDP]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
UAsyncNodeHttpDownloadUpload* asyncNodeDownloadUpload = dynamic_cast<UAsyncNodeHttpDownloadUpload*>(asyncNodeHttpRequest);
|
||
|
|
if (asyncNodeDownloadUpload) {
|
||
|
|
asyncNodeDownloadUpload->httpRequestDownloadUploadComplete(dataString, dataArray, TArray<FString>(), statusCode, requestIDP);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
asyncNodeHttpRequest->httpRequestComplete(dataString, dataArray, TArray<FString>(), statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteDelegate.Broadcast(dataString, dataArray, TArray<FString>(), statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//Content-Range: bytes 0-0/104857600
|
||
|
|
|
||
|
|
FString responseSize = response->GetHeader("Content-Range");
|
||
|
|
|
||
|
|
if (responseSize.IsEmpty()) {
|
||
|
|
responseSize = response->GetHeader("content-range");
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (responseSize.IsEmpty()) {
|
||
|
|
responseSize = response->GetHeader("Content-range");
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (responseSize.IsEmpty()) {
|
||
|
|
responseSize = response->GetHeader("content-Range");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
TArray<uint8> byteArray;
|
||
|
|
TArray<FString> dataArray;
|
||
|
|
TArray<FString> headerData = response->GetAllHeaders();
|
||
|
|
int32 statusCode = response->GetResponseCode();
|
||
|
|
|
||
|
|
if (responseSize.IsEmpty()) {
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest,webcom, dataArray, headerData, statusCode, byteArray, requestIDP]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
UAsyncNodeHttpDownloadUpload* asyncNodeDownloadUpload = dynamic_cast<UAsyncNodeHttpDownloadUpload*>(asyncNodeHttpRequest);
|
||
|
|
if (asyncNodeDownloadUpload) {
|
||
|
|
asyncNodeDownloadUpload->httpRequestDownloadUploadComplete("", dataArray,headerData, statusCode, requestIDP);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
asyncNodeHttpRequest->httpRequestComplete("", dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteDelegate.Broadcast("", dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("File Download: Server does not suport download range or wrong url. Cancel Download"));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
FString left;
|
||
|
|
FString right;
|
||
|
|
responseSize.Split("/", &left, &right);
|
||
|
|
responseSize = right;
|
||
|
|
|
||
|
|
int64 fullSize = FCString::Atoi64(*responseSize);
|
||
|
|
|
||
|
|
if (responseSize.IsEmpty() || fullSize < 1 || fileCancelResumeDownloadBytePartSize < 1) {
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest, webcom, dataArray, headerData, statusCode, byteArray, requestIDP]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
UAsyncNodeHttpDownloadUpload* asyncNodeDownloadUpload = dynamic_cast<UAsyncNodeHttpDownloadUpload*>(asyncNodeHttpRequest);
|
||
|
|
if (asyncNodeDownloadUpload) {
|
||
|
|
asyncNodeDownloadUpload->httpRequestDownloadUploadComplete("", dataArray,headerData, statusCode, requestIDP);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
asyncNodeHttpRequest->httpRequestComplete("", dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteDelegate.Broadcast("", dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("File Download: Server does not suport download range or wrong url. Cancel Download"));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (FPlatformFileManager::Get().GetPlatformFile().FileSize(*fileCancelResumeDownloadDir) >= fullSize) {
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest, webcom, dataArray, headerData, statusCode, byteArray, requestIDP]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
UAsyncNodeHttpDownloadUpload* asyncNodeDownloadUpload = dynamic_cast<UAsyncNodeHttpDownloadUpload*>(asyncNodeHttpRequest);
|
||
|
|
if (asyncNodeDownloadUpload) {
|
||
|
|
asyncNodeDownloadUpload->httpRequestDownloadUploadComplete("", dataArray, headerData, statusCode, requestIDP);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
asyncNodeHttpRequest->httpRequestComplete("", dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteDelegate.Broadcast("", dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("File Download: File size equal to or larger than on the server. Cancel Download"));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if (fileCancelResumeDownloadByteFullSize == 0) {
|
||
|
|
|
||
|
|
if (fileCancelResumeDownloadBytePartSize > fullSize)
|
||
|
|
fullSize = fileCancelResumeDownloadBytePartSize;
|
||
|
|
|
||
|
|
TArray<struct FhttpRequest> httpRequestsBack;
|
||
|
|
FString requestIDBack;
|
||
|
|
TArray<struct FhttpRequest> otherHttpRequests;
|
||
|
|
webcom->CreateHttpRequestGETLowRamDownload(httpRequestsBack, requestIDBack, otherHttpRequests, request->GetURL(), httpRequest.header, EHTTPWebComFileDownloadResumeType::E_RESUME, EHTTPWebComFileUpload::E_ad, fileCancelResumeDownloadDir, (fileCancelResumeDownloadBytePartSize), requestID);
|
||
|
|
|
||
|
|
if (httpRequestsBack.Num() > 0) {
|
||
|
|
FhttpRequest createdRequest = httpRequestsBack.Last();
|
||
|
|
createdRequest.request->setFileCancelResumeDownloadByteFullSize(fullSize);
|
||
|
|
webcom->executeHttpRequests(httpRequestsBack, webcom);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest, webcom, dataArray, headerData, statusCode, byteArray, requestIDP]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
UAsyncNodeHttpDownloadUpload* asyncNodeDownloadUpload = dynamic_cast<UAsyncNodeHttpDownloadUpload*>(asyncNodeHttpRequest);
|
||
|
|
if (asyncNodeDownloadUpload) {
|
||
|
|
asyncNodeDownloadUpload->httpRequestDownloadUploadComplete("", dataArray, headerData, statusCode, requestIDP);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
asyncNodeHttpRequest->httpRequestComplete("", dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteDelegate.Broadcast("", dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("Something's went wrong. download is aborted "));
|
||
|
|
}
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
FArchive* writer = IFileManager::Get().CreateFileWriter(*fileCancelResumeDownloadDir, EFileWrite::FILEWRITE_Append);
|
||
|
|
if (!writer) {
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("File Download: Can't write into %s "), *fileCancelResumeDownloadDir);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (response.IsValid()) {
|
||
|
|
|
||
|
|
TArray<uint8> data = response->GetContent();
|
||
|
|
bool finish = false;
|
||
|
|
if ((writer->TotalSize() + data.Num()) >= fullSize)
|
||
|
|
finish = true;
|
||
|
|
|
||
|
|
writer->Seek(writer->TotalSize());
|
||
|
|
writer->Serialize(data.GetData(), data.Num());
|
||
|
|
|
||
|
|
if (!finish) {
|
||
|
|
TArray<struct FhttpRequest> httpRequestsBack;
|
||
|
|
FString requestIDBack;
|
||
|
|
TArray<struct FhttpRequest> otherHttpRequests;
|
||
|
|
|
||
|
|
/*if ((writer->TotalSize() + fileCancelResumeDownloadBytePartSize) > fileCancelResumeDownloadByteFullSize) {
|
||
|
|
fileCancelResumeDownloadBytePartSize = fileCancelResumeDownloadByteFullSize - writer->TotalSize();
|
||
|
|
}*/
|
||
|
|
|
||
|
|
|
||
|
|
webcom->CreateHttpRequestGETLowRamDownload(httpRequestsBack, requestIDBack, otherHttpRequests, request->GetURL(), httpRequest.header, EHTTPWebComFileDownloadResumeType::E_RESUME, EHTTPWebComFileUpload::E_ad, fileCancelResumeDownloadDir, (fileCancelResumeDownloadBytePartSize), requestID);
|
||
|
|
|
||
|
|
if (httpRequestsBack.Num() > 0) {
|
||
|
|
FhttpRequest createdRequest = httpRequestsBack.Last();
|
||
|
|
//httpRequestsBack.RemoveAt(httpRequestsBack.Num()-1);
|
||
|
|
createdRequest.request->setFileCancelResumeDownloadByteFullSize(fileCancelResumeDownloadByteFullSize);
|
||
|
|
createdRequest.request->setFileCancelResumeDownloadByteStart(fileCancelResumeDownloadByteStart + data.Num());
|
||
|
|
//httpRequestsBack.Add(createdRequest);
|
||
|
|
|
||
|
|
webcom->executeHttpRequests(httpRequestsBack, webcom);
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("Something's went wrong. download is aborted "));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
//switch to gamethread
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest,webcom, dataArray, headerData, statusCode, byteArray, requestIDP]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
UAsyncNodeHttpDownloadUpload* asyncNodeDownloadUpload = dynamic_cast<UAsyncNodeHttpDownloadUpload*>(asyncNodeHttpRequest);
|
||
|
|
if (asyncNodeDownloadUpload) {
|
||
|
|
asyncNodeDownloadUpload->httpRequestDownloadUploadComplete("", dataArray, headerData, statusCode, requestIDP);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
asyncNodeHttpRequest->httpRequestComplete("", dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteDelegate.Broadcast("", dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("Cancel1: %i | %i"), fileCancelResumeDownloadByteStart+data.Num(), writer->TotalSize());
|
||
|
|
|
||
|
|
data.Empty();
|
||
|
|
|
||
|
|
}
|
||
|
|
/* else {
|
||
|
|
UE_LOG(LogTemp, Display, TEXT("Cancel3: Request successful"));
|
||
|
|
}*/
|
||
|
|
writer->Close();
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#if ENGINE_MAJOR_VERSION >= 5 & ENGINE_MINOR_VERSION >= 4
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestProgressUpload(FHttpRequestPtr request, uint64 bytesSent, uint64 bytesReceived) {
|
||
|
|
#else
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestProgressUpload(FHttpRequestPtr request, int32 bytesSent, int32 bytesReceived) {
|
||
|
|
#endif
|
||
|
|
FWebcomTheadJob* job = new FWebcomTheadJob();
|
||
|
|
job->request = request;
|
||
|
|
job->bytesSent = bytesSent;
|
||
|
|
job->bytesReceived = bytesReceived;
|
||
|
|
job->type = 3;
|
||
|
|
thread->addJob(job);
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestProgressUploadInternal(FHttpRequestPtr request, uint64 bytesSent, uint64 bytesReceived){
|
||
|
|
if (webCommunicationBPLibrary == nullptr) {
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: Missing Object instance (53)."));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: RequestID %s"), *requestID);
|
||
|
|
|
||
|
|
UWebCommunicationBPLibrary* webcom = webCommunicationBPLibrary;
|
||
|
|
FString requestIDP = requestID;
|
||
|
|
|
||
|
|
if (request.IsValid()) {
|
||
|
|
if (webCommunicationBPLibrary->toCancelRequests.Find(requestID) != nullptr) {
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [request]() {
|
||
|
|
request->CancelRequest();
|
||
|
|
});
|
||
|
|
webCommunicationBPLibrary->toCancelRequests.Remove(requestID);
|
||
|
|
|
||
|
|
UE_LOG(LogTemp, Warning, TEXT("Request has been canceled. %s"),*requestID);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
float size = (float)request->GetContentLength();
|
||
|
|
if (size <= 0)
|
||
|
|
size = 1;
|
||
|
|
float percentUpload = ((float)bytesSent / size) * 100;
|
||
|
|
float percentDownload = 0;
|
||
|
|
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [webcom,size, bytesSent, percentUpload, bytesReceived, percentDownload, requestIDP]() {
|
||
|
|
webcom->onhttpFileUploadDelegate.Broadcast(size, bytesSent, percentUpload, requestIDP);
|
||
|
|
});
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("size:%f | bytesSent:%i | percentUpload:%f | bytesReceived:%i | percentDownload:%f"), size, bytesSent, percentUpload, bytesReceived, percentDownload);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#if ENGINE_MAJOR_VERSION >= 5 & ENGINE_MINOR_VERSION >= 4
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestProgressDownload(FHttpRequestPtr request, uint64 bytesSent, uint64 bytesReceived) {
|
||
|
|
#else
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestProgressDownload(FHttpRequestPtr request, int32 bytesSent, int32 bytesReceived) {
|
||
|
|
#endif
|
||
|
|
FWebcomTheadJob* job = new FWebcomTheadJob();
|
||
|
|
job->request = request;
|
||
|
|
job->bytesSent = bytesSent;
|
||
|
|
job->bytesReceived = bytesReceived;
|
||
|
|
job->type = 4;
|
||
|
|
thread->addJob(job);
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestProgressDownloadInternal(FHttpRequestPtr request, uint64 bytesSent, uint64 bytesReceived){
|
||
|
|
if (webCommunicationBPLibrary == nullptr) {
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: Missing Object instance (83)."));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: Response %s"), *res);
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: RequestID %s"), *requestID);
|
||
|
|
|
||
|
|
UWebCommunicationBPLibrary* webcom = webCommunicationBPLibrary;
|
||
|
|
FString requestIDP = requestID;
|
||
|
|
|
||
|
|
if (request.IsValid()) {
|
||
|
|
if (webCommunicationBPLibrary->toCancelRequests.Find(requestID) != nullptr) {
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [request]() {
|
||
|
|
request->CancelRequest();
|
||
|
|
});
|
||
|
|
webCommunicationBPLibrary->toCancelRequests.Remove(requestID);
|
||
|
|
|
||
|
|
UE_LOG(LogTemp, Warning, TEXT("Request has been canceled. %s"), *requestID);
|
||
|
|
downloadDataCopy.Append(request->GetResponse()->GetContent());
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
FHttpResponsePtr response = request->GetResponse();
|
||
|
|
if (response.IsValid()) {
|
||
|
|
bytesReceived = bytesReceived + fileCancelResumeDownloadByteStart;
|
||
|
|
float size = (float)(response->GetContentLength() + fileCancelResumeDownloadByteStart);
|
||
|
|
if (size <= 0)
|
||
|
|
size = 1;
|
||
|
|
float percentUpload = 0;
|
||
|
|
float percentDownload = ((float)bytesReceived / size) * 100;
|
||
|
|
|
||
|
|
|
||
|
|
//downloadspeed
|
||
|
|
if (lastTimeTicks == 0) {
|
||
|
|
lastTimeTicks = FDateTime::Now().GetTicks();
|
||
|
|
bytesCurrent = bytesReceived;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
//one second = 10000000 ticks
|
||
|
|
if (((FDateTime::Now().GetTicks()) - lastTimeTicks) >= 10000000) {
|
||
|
|
mbit = ((float)bytesReceived - (float)bytesCurrent) / 1024 / 1024 * 8;
|
||
|
|
lastTimeTicks = FDateTime::Now().GetTicks();
|
||
|
|
bytesCurrent = bytesReceived;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
float mbitGlobal = mbit;
|
||
|
|
|
||
|
|
float sizeMB = size / 1024 / 1024;
|
||
|
|
float bytesReceivedMB = (float)bytesReceived / 1024 / 1024;
|
||
|
|
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [webcom, size, bytesSent, percentUpload, bytesReceived, percentDownload, requestIDP, mbitGlobal, sizeMB, bytesReceivedMB]() {
|
||
|
|
//webcom->onhttpFileProgressDelegate.Broadcast(size, bytesSent, percentUpload, bytesReceived, percentDownload);
|
||
|
|
webcom->onhttpFileDownloadDelegate.Broadcast(sizeMB, bytesReceivedMB, percentDownload, mbitGlobal, requestIDP);
|
||
|
|
});
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("size:%f | bytesSent:%i | percentUpload:%f | bytesReceived:%i | percentDownload:%f"), size, bytesSent, percentUpload, bytesReceived, percentDownload);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
#if ENGINE_MAJOR_VERSION >= 5 & ENGINE_MINOR_VERSION >= 4
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestProgressServerSendEvent(FHttpRequestPtr request, uint64 bytesSent, uint64 bytesReceived){
|
||
|
|
#else
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestProgressServerSendEvent(FHttpRequestPtr request, int32 bytesSent, int32 bytesReceived){
|
||
|
|
#endif
|
||
|
|
FWebcomTheadJob* job = new FWebcomTheadJob();
|
||
|
|
job->request = request;
|
||
|
|
job->bytesSent = bytesSent;
|
||
|
|
job->bytesReceived = bytesReceived;
|
||
|
|
job->type = 5;
|
||
|
|
thread->addJob(job);
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestProgressServerSendEventInternal(FHttpRequestPtr request, uint64 bytesSent, uint64 bytesReceived){
|
||
|
|
UWebCommunicationBPLibrary* webcom = webCommunicationBPLibrary;
|
||
|
|
FString requestIDP = requestID;
|
||
|
|
FHttpResponsePtr response = request->GetResponse();
|
||
|
|
if (response.IsValid()) {
|
||
|
|
TArray<uint8> responseBytes;
|
||
|
|
FString responseContent = FString();
|
||
|
|
int32 size = (bytesReceived - bytesReceivedLastTime);
|
||
|
|
|
||
|
|
responseBytes.AddZeroed(size+1);
|
||
|
|
FMemory::Memcpy(responseBytes.GetData(), response->GetContent().GetData() + bytesReceivedLastTime, size);
|
||
|
|
responseContent = UTF8_TO_TCHAR(responseBytes.GetData());
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Warning, TEXT("UWebCommunicationRequestCompleteObject::requestProgressServerSendEvent: %i %i %i %i %s"),
|
||
|
|
// response->GetContent().Num(), bytesReceivedLastTime, bytesReceived, size, *responseContent);
|
||
|
|
|
||
|
|
bytesReceivedLastTime = bytesReceived;
|
||
|
|
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [webcom, responseContent, requestIDP]() {
|
||
|
|
webcom->onhttpServerSendEventDelegate.Broadcast(responseContent, requestIDP);;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#if ENGINE_MAJOR_VERSION >= 5 & ENGINE_MINOR_VERSION >= 4
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestProgressDownloadLowRam(FHttpRequestPtr request, uint64 bytesSent, uint64 bytesReceived){
|
||
|
|
#else
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestProgressDownloadLowRam(FHttpRequestPtr request, int32 bytesSent, int32 bytesReceived){
|
||
|
|
#endif
|
||
|
|
FWebcomTheadJob* job = new FWebcomTheadJob();
|
||
|
|
job->request = request;
|
||
|
|
job->bytesSent = bytesSent;
|
||
|
|
job->bytesReceived = bytesReceived;
|
||
|
|
job->type = 6;
|
||
|
|
thread->addJob(job);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestProgressDownloadLowRamInternal(FHttpRequestPtr request, uint64 bytesSent, uint64 bytesReceived){
|
||
|
|
if (webCommunicationBPLibrary == nullptr) {
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: Missing Object instance (127)."));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: RequestID %s"), *requestID);
|
||
|
|
|
||
|
|
UWebCommunicationBPLibrary* webcom = webCommunicationBPLibrary;
|
||
|
|
FString requestIDP = requestID;
|
||
|
|
|
||
|
|
if (request.IsValid()) {
|
||
|
|
if (webCommunicationBPLibrary->toCancelRequests.Find(requestID) != nullptr) {
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [request]() {
|
||
|
|
request->CancelRequest();
|
||
|
|
});
|
||
|
|
webCommunicationBPLibrary->toCancelRequests.Remove(requestID);
|
||
|
|
|
||
|
|
|
||
|
|
UE_LOG(LogTemp, Warning, TEXT("Request has been canceled. %s"), *requestID);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
FHttpResponsePtr response = request->GetResponse();
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if (response.IsValid()) {
|
||
|
|
double size = (double)fileCancelResumeDownloadByteFullSize;
|
||
|
|
if (size <= 0)
|
||
|
|
size = 1;
|
||
|
|
double percentUpload = 0;
|
||
|
|
int64 bytesReceived64 = bytesReceived + fileCancelResumeDownloadByteStart;
|
||
|
|
double percentDownload = ((double)bytesReceived64 / size) * 100;
|
||
|
|
|
||
|
|
//downloadspeed
|
||
|
|
if (lastTimeTicks == 0) {
|
||
|
|
lastTimeTicks = FDateTime::Now().GetTicks();
|
||
|
|
bytesCurrent = bytesReceived;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
//one second = 10000000 ticks
|
||
|
|
if (((FDateTime::Now().GetTicks()) - lastTimeTicks) >= 10000000) {
|
||
|
|
mbit = ((float)bytesReceived - (float)bytesCurrent) / 1024 / 1024 * 8;
|
||
|
|
lastTimeTicks = FDateTime::Now().GetTicks();
|
||
|
|
bytesCurrent = bytesReceived;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
float mbitGlobal = mbit;
|
||
|
|
|
||
|
|
double sizeMB = size / 1024 / 1024;
|
||
|
|
double bytesReceivedMB = (double)bytesReceived64 / 1024 / 1024;
|
||
|
|
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [webcom, size, bytesSent, percentUpload, bytesReceived, percentDownload, requestIDP, mbitGlobal, sizeMB, bytesReceivedMB]() {
|
||
|
|
//webcom->onhttpFileProgressDelegate.Broadcast(size, bytesSent, (float)percentUpload, (int64)bytesReceived, (float)percentDownload);
|
||
|
|
webcom->onhttpFileDownloadDelegate.Broadcast((float)sizeMB, (float)bytesReceivedMB, (float)percentDownload, mbitGlobal, requestIDP);
|
||
|
|
});
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestMultiStepComplete(FHttpRequestPtr Request, FHttpResponsePtr response, bool bWasSuccessful){
|
||
|
|
|
||
|
|
if (webCommunicationBPLibrary == nullptr) {
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: Missing Object instance (12)."));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: RequestID %s"), *requestID);
|
||
|
|
|
||
|
|
UWebCommunicationBPLibrary* webcom = webCommunicationBPLibrary;
|
||
|
|
FString requestIDP = requestID;
|
||
|
|
if (webcom->removeHeaders) {
|
||
|
|
webcom->additionalHeader.Empty();
|
||
|
|
}
|
||
|
|
|
||
|
|
UAsyncNodeWebCom* asyncNodeHttpRequest = webcom->getUAsyncNodeHttpRequest(requestID);
|
||
|
|
|
||
|
|
if (!bWasSuccessful || !response.IsValid()) {
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("Request unsuccessful, check the url"));
|
||
|
|
TArray<FString> dataArray;
|
||
|
|
TArray<uint8> byteArray;
|
||
|
|
FString dataString = "No Response";
|
||
|
|
int32 statusCode = 500;
|
||
|
|
if (response.IsValid()) {
|
||
|
|
dataString = response->GetContentAsString();
|
||
|
|
dataString.ParseIntoArray(dataArray, TEXT("\r\n"), true);
|
||
|
|
statusCode = response->GetResponseCode();
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
dataArray.Add(dataString);
|
||
|
|
}
|
||
|
|
//switch to gamethread
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest, webcom, dataString, dataArray, statusCode, byteArray, requestIDP]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
asyncNodeHttpRequest->httpRequestComplete(dataString, dataArray, TArray<FString>(), statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteDelegate.Broadcast(dataString, dataArray, TArray<FString>(), statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
|
||
|
|
});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
TArray<uint8> byteArray = response->GetContent();
|
||
|
|
FString dataString = response->GetContentAsString();
|
||
|
|
TArray<FString> dataArray;
|
||
|
|
dataString.ParseIntoArray(dataArray, TEXT("\r\n"), true);
|
||
|
|
|
||
|
|
int32 statusCode = response->GetResponseCode();
|
||
|
|
TArray<FString> headerData = response->GetAllHeaders();
|
||
|
|
|
||
|
|
//gooledrive has a virus check for big files. read the confirm code from the html code and start a regluar get download request
|
||
|
|
if (multiStepDownload == 1 && dataArray.Num() > 0) {
|
||
|
|
FString dataStringTmp = dataArray.Last();
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Error, TEXT("filesize: %s"),*sizeStr);
|
||
|
|
|
||
|
|
FString newUrl = generateURLFromHTML(dataStringTmp, Request.Get()->GetURL());
|
||
|
|
|
||
|
|
//no virus message
|
||
|
|
if (newUrl.EndsWith("confirm=")) {
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest,webcom, dataString, dataArray, headerData, statusCode, byteArray, requestIDP]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
asyncNodeHttpRequest->httpRequestComplete(dataString, dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteDelegate.Broadcast(dataString, dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
TArray<struct FhttpRequest> otherHttpRequests;
|
||
|
|
TArray<struct FhttpRequest> httpRequests;
|
||
|
|
|
||
|
|
UWebCommunicationRequestCompleteObject* requestObject = NewObject<UWebCommunicationRequestCompleteObject>(UWebCommunicationRequestCompleteObject::StaticClass());
|
||
|
|
requestObject->setRequestID(requestID, httpRequest, UWebCommunicationBPLibrary::getWebCommunicationTarget());
|
||
|
|
requestObject->setDownloadID(downloadID);
|
||
|
|
requestObject->setMultiStepDownload(2);
|
||
|
|
|
||
|
|
|
||
|
|
FhttpRequest temphttpRequest;
|
||
|
|
temphttpRequest.requestType = EHTTPWebComRequestType::GET;
|
||
|
|
temphttpRequest.url = newUrl;
|
||
|
|
requestObject->setHTMLFileSize(HTMLFileSize);
|
||
|
|
temphttpRequest.request = requestObject;
|
||
|
|
|
||
|
|
otherHttpRequests.Add(temphttpRequest);
|
||
|
|
httpRequests = otherHttpRequests;
|
||
|
|
|
||
|
|
webCommunicationBPLibrary->executeHttpRequests(httpRequests, webCommunicationBPLibrary);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//switch to gamethread
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest, webcom, dataString, dataArray, headerData, statusCode, byteArray, requestIDP]() {
|
||
|
|
if (asyncNodeHttpRequest != nullptr && asyncNodeHttpRequest->IsValidLowLevel()) {
|
||
|
|
asyncNodeHttpRequest->httpRequestComplete(dataString, dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
webcom->onhttpRequestCompleteDelegate.Broadcast(dataString, dataArray, headerData, statusCode, byteArray, requestIDP);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
}
|
||
|
|
#if ENGINE_MAJOR_VERSION >= 5 & ENGINE_MINOR_VERSION >= 4
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestMultiStepDownload(FHttpRequestPtr request, uint64 bytesSent, uint64 bytesReceived){
|
||
|
|
#else
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestMultiStepDownload(FHttpRequestPtr request, int32 bytesSent, int32 bytesReceived){
|
||
|
|
#endif
|
||
|
|
FWebcomTheadJob* job = new FWebcomTheadJob();
|
||
|
|
job->request = request;
|
||
|
|
job->bytesSent = bytesSent;
|
||
|
|
job->bytesReceived = bytesReceived;
|
||
|
|
job->type = 2;
|
||
|
|
thread->addJob(job);
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::requestMultiStepDownloadInternal(FHttpRequestPtr request, uint64 bytesSent, uint64 bytesReceived){
|
||
|
|
if (webCommunicationBPLibrary == nullptr) {
|
||
|
|
UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: Missing Object instance (83)."));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (multiStepDownload != 2 && HTMLFileSize <= 0)
|
||
|
|
return;
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: RequestID %s"), *requestID);
|
||
|
|
|
||
|
|
UWebCommunicationBPLibrary* webcom = webCommunicationBPLibrary;
|
||
|
|
FString requestIDP = requestID;
|
||
|
|
|
||
|
|
if (request.IsValid()) {
|
||
|
|
if (webCommunicationBPLibrary->toCancelRequests.Find(requestID) != nullptr) {
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [request]() {
|
||
|
|
request->CancelRequest();
|
||
|
|
});
|
||
|
|
|
||
|
|
|
||
|
|
UE_LOG(LogTemp, Warning, TEXT("Request has been canceled. %s"), *requestID);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
FHttpResponsePtr response = request->GetResponse();
|
||
|
|
/*UE_LOG(LogTemp, Warning, TEXT("bytesReceived: %i"), response->GetContentLength());
|
||
|
|
UE_LOG(LogTemp, Warning, TEXT("GetContent: %i"), response->GetContent().Num());
|
||
|
|
UE_LOG(LogTemp, Warning, TEXT("x3x: %i"), (int32)HTMLFileSize);*/
|
||
|
|
|
||
|
|
if (response.IsValid()) {
|
||
|
|
float size = (HTMLFileSize == 0) ? response->GetContentLength() : (float)HTMLFileSize;
|
||
|
|
if (size <= 0)
|
||
|
|
size = 1;
|
||
|
|
float percentUpload = 0;
|
||
|
|
float percentDownload = ((float)bytesReceived / size) * 100;
|
||
|
|
if (percentDownload > 100) {
|
||
|
|
percentDownload = 100;
|
||
|
|
//multiStepDownload = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
//for the mbit thread
|
||
|
|
bytesCurrent = bytesReceived;
|
||
|
|
|
||
|
|
float mbitGlobal = mbit;
|
||
|
|
float sizeMB = size / 1024 / 1024;
|
||
|
|
float bytesReceivedMB = (float)bytesReceived / 1024 / 1024;
|
||
|
|
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [webcom, size, bytesSent, percentUpload, bytesReceived, percentDownload, requestIDP, mbitGlobal, sizeMB, bytesReceivedMB]() {
|
||
|
|
//webcom->onhttpFileProgressDelegate.Broadcast(size, bytesSent, percentUpload, bytesReceived, percentDownload);
|
||
|
|
webcom->onhttpFileDownloadDelegate.Broadcast(sizeMB, bytesReceivedMB, percentDownload, mbitGlobal, requestIDP);
|
||
|
|
});
|
||
|
|
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("size:%f | bytesSent:%i | percentUpload:%f | bytesReceived:%i | percentDownload:%f"), size, bytesSent, percentUpload, bytesReceived, percentDownload);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::setRequestID(FString requestIDP, struct FhttpRequest& httpRequestP, UWebCommunicationBPLibrary* webCommunicationBPLibraryP) {
|
||
|
|
httpRequest = httpRequestP;
|
||
|
|
requestID = requestIDP;
|
||
|
|
webCommunicationBPLibrary = webCommunicationBPLibraryP;
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::setRequestStruct(struct FhttpRequest& httpRequestP) {
|
||
|
|
httpRequest = httpRequestP;
|
||
|
|
}
|
||
|
|
|
||
|
|
FString UWebCommunicationRequestCompleteObject::getRequestID() {
|
||
|
|
return requestID;
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::setDownloadID(FString downloadIDP){
|
||
|
|
downloadID = downloadIDP;
|
||
|
|
}
|
||
|
|
|
||
|
|
FString UWebCommunicationRequestCompleteObject::getDownloadID(){
|
||
|
|
return downloadID;
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::setMultiStepDownload(int32 stepP) {
|
||
|
|
multiStepDownload = stepP;
|
||
|
|
//UE_LOG(LogTemp, Warning, TEXT("UWebCommunicationBPLibrary: %i."), multiStepDownload);
|
||
|
|
}
|
||
|
|
|
||
|
|
int32 UWebCommunicationRequestCompleteObject::getMultiStepDownload() {
|
||
|
|
return multiStepDownload;
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::setMultiStepDownloadType(EMultiStepType multiStepDownloadTypeP){
|
||
|
|
multiStepDownloadType = multiStepDownloadTypeP;
|
||
|
|
}
|
||
|
|
|
||
|
|
EMultiStepType UWebCommunicationRequestCompleteObject::getMultiStepDownloadType(){
|
||
|
|
return multiStepDownloadType;
|
||
|
|
}
|
||
|
|
|
||
|
|
FString UWebCommunicationRequestCompleteObject::generateURLFromHTML(FString html, FString oldURL){
|
||
|
|
FString newURL;
|
||
|
|
if (multiStepDownloadType == EMultiStepType::GOOGLE) {
|
||
|
|
//get confirm id from html
|
||
|
|
FString left;
|
||
|
|
FString right;
|
||
|
|
html.Split(";confirm=", &left, &right);
|
||
|
|
right.Split("&", &left, &right);
|
||
|
|
FString linkParam = "download&confirm=" + left + "&";
|
||
|
|
newURL = oldURL + "&confirm=" + left;//oldURL.Replace(TEXT("download&"), *linkParam);
|
||
|
|
|
||
|
|
//get file size from html
|
||
|
|
if (HTMLFileSize == 0) {
|
||
|
|
html.Split("uc-name-size", &left, &right);
|
||
|
|
right.Split("</span>", &left, &right);
|
||
|
|
FString sizeStr = left;
|
||
|
|
FString left2;
|
||
|
|
FString right2;
|
||
|
|
sizeStr.Split("</a>", &left2, &right2, ESearchCase::CaseSensitive, ESearchDir::FromEnd);
|
||
|
|
sizeStr = right2.Replace(TEXT("("), TEXT("")).Replace(TEXT(")"), TEXT("")).Replace(TEXT(" "), TEXT("")).Replace(TEXT(","), TEXT("."));
|
||
|
|
if (sizeStr.Contains("M")) {
|
||
|
|
sizeStr = sizeStr.Replace(TEXT("M"), TEXT(""));
|
||
|
|
HTMLFileSize = FCString::Atof(*sizeStr) * 1024 * 1024;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
sizeStr = sizeStr.Replace(TEXT("G"), TEXT(""));
|
||
|
|
HTMLFileSize = ((double)FCString::Atof(*sizeStr)) * 1024 * 1024 * 1024;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return newURL;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if (multiStepDownloadType == EMultiStepType::ANONFILE) {
|
||
|
|
//get confirm id from html
|
||
|
|
FString left;
|
||
|
|
FString right;
|
||
|
|
html.Split("id=\"download-url\"", &left, &right);
|
||
|
|
right.Split("</a>", &left, &right);
|
||
|
|
FString left2;
|
||
|
|
FString right2;
|
||
|
|
left.Split("href=", &left2, &right2);
|
||
|
|
right2.Split("><", &newURL, &right);
|
||
|
|
newURL = newURL.Replace(TEXT("\""), TEXT(""));
|
||
|
|
}
|
||
|
|
|
||
|
|
return newURL;
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::setFileCancelResumeDownloadByteFullSize(int64 size) {
|
||
|
|
fileCancelResumeDownloadByteFullSize = size;
|
||
|
|
}
|
||
|
|
|
||
|
|
int64 UWebCommunicationRequestCompleteObject::getFileCancelResumeDownloadByteFullSize() {
|
||
|
|
return fileCancelResumeDownloadByteFullSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::setFileCancelResumeDownloadBytePartSize(int64 size){
|
||
|
|
fileCancelResumeDownloadBytePartSize = size;
|
||
|
|
}
|
||
|
|
|
||
|
|
int64 UWebCommunicationRequestCompleteObject::getFileCancelResumeDownloadBytePartSize(){
|
||
|
|
return fileCancelResumeDownloadBytePartSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::setFileCancelResumeDownloadByteStart(int64 size){
|
||
|
|
if (size < 0) {
|
||
|
|
fileCancelResumeDownloadByteStart = 0;;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
fileCancelResumeDownloadByteStart = size;
|
||
|
|
}
|
||
|
|
|
||
|
|
int64 UWebCommunicationRequestCompleteObject::getFileCancelResumeDownloadByteStart(){
|
||
|
|
return fileCancelResumeDownloadByteStart;
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::setFileCancelResumeDownloadDir(FString dir){
|
||
|
|
fileCancelResumeDownloadDir = dir;
|
||
|
|
}
|
||
|
|
|
||
|
|
FString UWebCommunicationRequestCompleteObject::getFileCancelResumeDownloadDir(){
|
||
|
|
return fileCancelResumeDownloadDir;
|
||
|
|
}
|
||
|
|
|
||
|
|
void UWebCommunicationRequestCompleteObject::setHTMLFileSize(int64 size) {
|
||
|
|
HTMLFileSize = size;
|
||
|
|
}
|
||
|
|
|
||
|
|
int64 UWebCommunicationRequestCompleteObject::getHTMLFileSize() {
|
||
|
|
return HTMLFileSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/***************************************************************/
|
||
|
|
FWebcomThread::FWebcomThread(UWebCommunicationRequestCompleteObject* parentObjectP) :
|
||
|
|
parentObject(parentObjectP){
|
||
|
|
FString threadName = "FWebcomThread" + FGuid::NewGuid().ToString();
|
||
|
|
thread = FRunnableThread::Create(this, *threadName, 0, EThreadPriority::TPri_Normal);
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: new Thead "));
|
||
|
|
}
|
||
|
|
|
||
|
|
FWebcomThread::~FWebcomThread(){
|
||
|
|
delete thread;
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: delete Thead "));
|
||
|
|
}
|
||
|
|
|
||
|
|
uint32 FWebcomThread::Run(){
|
||
|
|
|
||
|
|
while (run) {
|
||
|
|
|
||
|
|
while (jobQueue.IsEmpty() == false) {
|
||
|
|
FWebcomTheadJob* job = nullptr;
|
||
|
|
jobQueue.Dequeue(job);
|
||
|
|
if (job == nullptr || parentObject == nullptr) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
switch (job->type)
|
||
|
|
{
|
||
|
|
case 0:
|
||
|
|
parentObject->requestCompleteInternal(job->request, job->response, job->bWasSuccessful);
|
||
|
|
run = false;
|
||
|
|
break;
|
||
|
|
case 1:
|
||
|
|
parentObject->requestCompleteLowRamInternal(job->request, job->response, job->bWasSuccessful);
|
||
|
|
run = false;
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
parentObject->requestMultiStepDownloadInternal(job->request, job->bytesSent, job->bytesReceived);
|
||
|
|
break;
|
||
|
|
case 3:
|
||
|
|
parentObject->requestProgressUploadInternal(job->request, job->bytesSent, job->bytesReceived);
|
||
|
|
break;
|
||
|
|
case 4:
|
||
|
|
parentObject->requestProgressDownloadInternal(job->request, job->bytesSent, job->bytesReceived);
|
||
|
|
break;
|
||
|
|
case 5:
|
||
|
|
parentObject->requestProgressServerSendEventInternal(job->request, job->bytesSent, job->bytesReceived);
|
||
|
|
break;
|
||
|
|
case 6:
|
||
|
|
parentObject->requestProgressDownloadLowRamInternal(job->request, job->bytesSent, job->bytesReceived);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (job != nullptr) {
|
||
|
|
delete job;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (run) {
|
||
|
|
pauseThread(true);
|
||
|
|
//workaround. suspend do not work on all platforms. lets sleep
|
||
|
|
while (paused && run) {
|
||
|
|
FPlatformProcess::Sleep(0.01);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
UWebCommunicationRequestCompleteObject* parentObjectCopy = parentObject;
|
||
|
|
AsyncTask(ENamedThreads::GameThread, [parentObjectCopy]() {
|
||
|
|
if (parentObjectCopy != nullptr) {
|
||
|
|
parentObjectCopy->RemoveFromRoot();
|
||
|
|
//UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: RemoveFromRoot "));
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
void FWebcomThread::stopThread(){
|
||
|
|
run = false;
|
||
|
|
if (thread != nullptr) {
|
||
|
|
pauseThread(false);
|
||
|
|
}
|
||
|
|
Stop();
|
||
|
|
}
|
||
|
|
|
||
|
|
void FWebcomThread::pauseThread(bool pause){
|
||
|
|
paused = pause;
|
||
|
|
//thread->Suspend(pause);
|
||
|
|
}
|
||
|
|
|
||
|
|
void FWebcomThread::addJob(FWebcomTheadJob* job){
|
||
|
|
jobQueue.Enqueue(job);
|
||
|
|
pauseThread(false);
|
||
|
|
}
|