October3d55/M/HTTPWebCommunication/Source/WebCommunication/Public/WebCommunicationBPLibrary.h

524 lines
27 KiB
C++

// Copyright 2017-2020 David Romanski(Socke). All Rights Reserved.
#pragma once
#include "WebCommunication.h"
#include "WebCommunicationBPLibrary.generated.h"
class UWebCommunicationRequestCompleteObject;
class FByteToFileThread;
class FWebComTruncateUploadedFileThread;
class UAsyncNodeWebCom;
UCLASS()
class WEBCOMMUNICATION_API UWebCommunicationBPLibrary : public UBlueprintFunctionLibrary
{
GENERATED_UCLASS_BODY()
public:
static UWebCommunicationBPLibrary* webcom;
~UWebCommunicationBPLibrary();
//Delegates
DECLARE_DYNAMIC_MULTICAST_DELEGATE_SixParams(FhttpRequestCompleteDelegate,const FString, dataString, const TArray<FString>&, dataArray, const TArray<FString>&, header, const int32, statusCode, const TArray<uint8>&, byteData, const FString, requestID);
UFUNCTION()
void httpRequestCompleteDelegate(const FString dataString, const TArray<FString>& dataArray, const TArray<FString>& header, const int32 statusCode, const TArray<uint8>& byteData, const FString requestID);
UPROPERTY(BlueprintAssignable, Category = "WebCommunication|Events|RequestComplete")
FhttpRequestCompleteDelegate onhttpRequestCompleteDelegate;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FhttpRequestCompleteGoogleInfoDelegate, const FString, fileName, const int64, fileSizeInBytes, const int32, statusCode, const FString, downloadID, const FString, requestID);
UFUNCTION()
void httpRequestCompleteGoogleInfoDelegate(const FString fileName, const int64 fileSizeInBytes, const int32 statusCode, const FString downloadID, const FString requestID);
UPROPERTY(BlueprintAssignable, Category = "WebCommunication|Events|RequestCompleteGoogleInfo")
FhttpRequestCompleteGoogleInfoDelegate onhttpRequestCompleteGoogleInfoDelegate;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FhttpFileProgressDelegate, const float, size, const int32, bytesSent, const float, percentUpload, const int32, bytesReceived, const float, percentDownload);
/**
* This function is deprecated and will be removed. Please use httpFileDownload or httpFileUpload.
*/
//UFUNCTION()
// void httpFileProgressDelegate(const float size, const int32 bytesSent, const float percentUpload, const int32 bytesReceived, const float percentDownload);
//UPROPERTY(BlueprintAssignable, Category = "WebCommunication|Deprecated|Events|FileProgress")
// FhttpFileProgressDelegate onhttpFileProgressDelegate;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FhttpFileDownloadDelegate, const float, size, const float, megaBytesReceived, const float, percentDownload, const float, megaBit, const FString, requestID);
/**
* @param size Filesize in Megabyte
* @param megaBit Downloadspeed in Megabit/second
*/
UFUNCTION()
void httpFileDownloadDelegate(const float size, const float megaBytesReceived, const float percentDownload, const float megaBit, const FString requestID);
UPROPERTY(BlueprintAssignable, Category = "WebCommunication|Events|Download")
FhttpFileDownloadDelegate onhttpFileDownloadDelegate;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FhttpFileUploadDelegate, const float, size, const int32, bytesSent, const float, percentUpload, const FString, requestID);
/**
* @param size Filesize in Byte
*/
UFUNCTION()
void httpFileUploadDelegate(const float size, const int32 bytesSent, const float percentUpload, const FString requestID);
UPROPERTY(BlueprintAssignable, Category = "WebCommunication|Events|Upload")
FhttpFileUploadDelegate onhttpFileUploadDelegate;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FhttpServerSendEventDelegate, const FString, response, const FString, requestID);
UFUNCTION()
void httpServerSendEventDelegate(const FString response, const FString requestID);
UPROPERTY(BlueprintAssignable, Category = "WebCommunication|Events|ServerSendEvent")
FhttpServerSendEventDelegate onhttpServerSendEventDelegate;
/**
* This function is deprecated and will be removed. Please use getWebCommunicationTarget.
*/
//UFUNCTION(BlueprintCallable, BlueprintPure, Category = "WebCommunication|Deprecated")
// static UWebCommunicationBPLibrary* getTarget();
/**
* Return a Target for the Events
*/
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "WebCommunication")
static UWebCommunicationBPLibrary* getWebCommunicationTarget();
/**
* This function is deprecated and will be removed. Please use httpRequestGET.
*/
//UFUNCTION(BlueprintCallable, Category = "WebCommunication|Deprecated")
// static UWebCommunicationBPLibrary* httpRequestGET(FString url, FString optionalRequestID, FString &requestID);
/**
* Send a GET HTTP Request to Webserver.
* @param optionalRequestID Your own RequestID. It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
* @param requestID It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
* @param bindServerSendEvent Activates the "Server Send Event" for this http request. If you as a client want to get multiple http responses from the server for one http request you can use the http technique "Server Sent Events".
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication|GET", meta = (AutoCreateRefTerm = "otherHttpRequests,header"))
static int32 CreateHttpRequestGET(TArray<struct FhttpRequest> otherHttpRequests, FString url, TMap<FString, FString> header, FString optionalRequestID, bool bindServerSendEvent, TArray<struct FhttpRequest> &httpRequests, FString &requestID);
/**
* For downloads. Data is copied to the hard disk if you cancel the download.
* @param ActionIfFileExists Overwrite = overwrites an existing file otherwise a new one will be created. Cancel Download = If the file already exists, the download will be aborted. Resume = Download continues. If the file is missing, the download is started from the beginning.
* @param optionalRequestID Your own RequestID. It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
* @param requestID It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication|Download", meta = (AutoCreateRefTerm = "otherHttpRequests,header"))
static int32 CreateHttpRequestGETDownload(TArray<struct FhttpRequest>& httpRequests, FString& requestID, TArray<struct FhttpRequest> otherHttpRequests, FString url, TMap<FString, FString> header, EHTTPWebComFileDownloadResumeType ActionIfFileExists, EHTTPWebComFileUpload DirectoryType, FString filePathWithFileName, FString optionalRequestID = "");
/**
* For downloads. The file is downloaded in steps. This significantly reduces RAM consumption. The web server must support resuming aborted downloads.
* @param ActionIfFileExists Overwrite = overwrites an existing file otherwise a new one will be created. Cancel Download = If the file already exists, the download will be aborted. Resume = Download continues. If the file is missing, the download is started from the beginning.
* @param FileSizeStepsInBytes Default = 10 megabytes. Steps in which the download is aborted and restarted. Specified in bytes. You can use the node "MegabyteToByte" for conversion.
* @param optionalRequestID Your own RequestID. It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
* @param requestID It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication|Download", meta = (AutoCreateRefTerm = "otherHttpRequests,header"))
static int32 CreateHttpRequestGETLowRamDownload(TArray<struct FhttpRequest>& httpRequests, FString& requestID, TArray<struct FhttpRequest> otherHttpRequests, FString url, TMap<FString, FString> header, EHTTPWebComFileDownloadResumeType ActionIfFileExists, EHTTPWebComFileUpload DirectoryType, FString filePathWithFileName, int32 FileSizeStepsInBytes = 10485760, FString optionalRequestID ="");
UFUNCTION(BlueprintCallable, Category = "WebCommunication|GET", meta = (AutoCreateRefTerm = "otherHttpRequests"))
static int32 CreateHttpRequestGoogleDrive(TArray<struct FhttpRequest> otherHttpRequests, FString downloadID, FString optionalRequestID, int64 optionalFileSizeInByte, TArray<struct FhttpRequest> &httpRequests, FString &requestID);
UFUNCTION(BlueprintCallable, Category = "WebCommunication|GET", meta = (AutoCreateRefTerm = "otherHttpRequests"))
static int32 CreateHttpRequestGoogleDriveFileInfo(TArray<struct FhttpRequest> otherHttpRequests, FString downloadID, FString optionalRequestID, TArray<struct FhttpRequest>& httpRequests, FString& requestID);
UFUNCTION(BlueprintCallable, Category = "WebCommunication|GET", meta = (AutoCreateRefTerm = "otherHttpRequests"))
static int32 CreateHttpRequestAnonfiles(TArray<struct FhttpRequest> otherHttpRequests, FString url, FString optionalRequestID, TArray<struct FhttpRequest> &httpRequests, FString &requestID);
UFUNCTION(BlueprintCallable, Category = "WebCommunication")
static void executeHttpRequests(TArray<struct FhttpRequest> httpRequests, UWebCommunicationBPLibrary* &WebCommunicationTarget);
/**
* Send a POST HTTP Request to Webserver.
* @param url
* @param POSTData
* @param requestID Optional parameter. It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
* @param bindServerSendEvent Activates the "Server Send Event" for this http request. If you as a client want to get multiple http responses from the server for one http request you can use the http technique "Server Sent Events".
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication|POST", meta = (AutoCreateRefTerm = "otherHttpRequests,header"))
static int32 CreateHttpRequestPOST(TArray<struct FhttpRequest> otherHttpRequests, FString url, TMap<FString, FString> header, TMap<FString, FString> POSTData, FString optionalRequestID, bool bindServerSendEvent, TArray<struct FhttpRequest> &httpRequests, FString &requestID);
/**
* Individual HTTP Request. You have to set all parameters yourself.
*
* @param url Server URL
* @param header User-Agent, Content-Type
* @param verb POST, GET, PUT, PATCH, DELETE
* @param content Request Body or Filepath
* @param requestID Optional parameter. It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
* @param addContentLengthHeader add Content-Length header with the length of the content.
* @param bindServerSendEvent Activates the "Server Send Event" for this http request. If you as a client want to get multiple http responses from the server for one http request you can use the http technique "Server Sent Events".
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication|Individual", meta = (AutoCreateRefTerm = "otherHttpRequests,binaryContent"))
static void CreateHttpRequestIndividual(TArray<struct FhttpRequest> otherHttpRequests, FString url, TMap<FString, FString> header, FString verb,
EHTTPWebComIndividualType contentBodyType, FString contentBody,TArray<uint8> binaryContent, FString optionalRequestID, TArray<struct FhttpRequest> &httpRequests,
FString &requestID, bool addContentLengthHeader = true, bool bindDownloadProgressEvent = false, bool bindUploadProgressEvent = false, bool bindServerSendEvent = false);
/**
* Send a Fila to a Webserver.
*
* @param url Server URL
* @param DirectoryType Absolute or Relative
* @param id name equivalent to <input type="file" name="myFile"> from an html upload
* @param filePath File with path
* @param uploadType Upload progress is only refreshed with type PUT
* @param requestID Optional parameter. It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
*/
/*UFUNCTION(BlueprintCallable, Category = "WebCommunication|Deprecated")
static void httpRequestFileUpload(FString url, EHTTPWebComFileUpload DirectoryType, FString id, FString filePath, EHTTPWebComFileUploadType uploadType, FString optionalRequestID, FString &requestID);*/
/**
* Send a file to a Webserver.
*
* @param otherHttpRequests
* @param url Server URL
* @param DirectoryType Absolute or Relative
* @param filePath path with filename at the end
* @param fileID name equivalent to <input type="file" name="myFile"> from an html upload
* @param requestID Optional parameter. It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication|File Upload", meta = (AutoCreateRefTerm = "otherHttpRequests,header,POSTData"))
static int32 CreateHttpRequestFileUploadPOST(TArray<struct FhttpRequest> otherHttpRequests, FString url, TMap<FString, FString> header, EHTTPWebComFileUpload DirectoryType, FString filePath, FString fileID, TMap<FString, FString> POSTData, FString optionalRequestID, TArray<struct FhttpRequest> &httpRequests, FString &requestID);
/**
* Send multiple files to a Webserver.
*
* @param otherHttpRequests
* @param url Server URL
* @param DirectoryType Absolute or Relative
* @param filePaths paths with filenames at the ends
* @param fileIDs names equivalent to <input type="file" name="myFile"> from an html upload. It is also possible to enter only one file ID for all files.
* @param requestID Optional parameter. It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication|File Upload", meta = (AutoCreateRefTerm = "otherHttpRequests,header,POSTData"))
static int32 CreateHttpRequestFileMultiUploadPOST(TArray<struct FhttpRequest> otherHttpRequests, FString url, TMap<FString, FString> header, EHTTPWebComFileUpload DirectoryType, TArray<FString> filePaths, TArray<FString> fileIDs, TMap<FString, FString> POSTData, FString optionalRequestID, TArray<struct FhttpRequest>& httpRequests, FString& requestID);
/**
* Send a file to a Webserver.
*
* @param otherHttpRequests
* @param url Server URL
* @param DirectoryType Absolute or Relative
* @param filePath path with filename at the end
* @param fileID name equivalent to <input type="file" name="myFile"> from an html upload
* @param requestID Optional parameter. It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
* @param uploadType
PUT Stream (Blank):With this option only the file is written into the http body and nothing else. If your server can handle it then use this option. Additionally headers will be created. fileid, filename, fileformat, mimetype
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PUT Stream (Multiplart):With this option a header is created which goes with a trick into the body and writes the necessary information of the file into the body. Important! The only way to write something at the end of the body is to write this information into the file.
After the upload is finished or canceled the plugin removes this information from the file.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PUT Stream (Copy Multiplart):This option also writes information to the file. But a copy of the file is created before and the info is written into the copy. The copy will be deleted after the upload. Making a copy of a large file can lead to freezing because it is done in the game thread.
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication|File Upload", meta = (AutoCreateRefTerm = "otherHttpRequests,header"))
static int32 CreateHttpRequestFileUploadPUT(TArray<struct FhttpRequest> otherHttpRequests, FString url, TMap<FString, FString> header, EHTTPWebComFileUpload DirectoryType, FString filePath, FString fileID, EHTTPWebComFileUploadType uploadType, FString optionalRequestID, TArray<struct FhttpRequest> &httpRequests, FString &requestID);
/**
* Send multiple files to a Webserver.
*
* @param otherHttpRequests
* @param url Server URL
* @param DirectoryType Absolute or Relative
* @param filePaths paths with filenames at the ends
* @param fileIDs names equivalent to <input type="file" name="myFile"> from an html upload. It is also possible to enter only one file ID for all files.
* @param requestID Optional parameter. It will be output again in the httpRequestComplete event. This allows the request being assigned to the response.
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication|File Upload", meta = (AutoCreateRefTerm = "otherHttpRequests,header"))
static int32 CreateHttpRequestFileMultiUploadPUT(TArray<struct FhttpRequest> otherHttpRequests, FString url, TMap<FString, FString> header, EHTTPWebComFileUpload DirectoryType, TArray<FString> filePaths, TArray<FString> fileIDs, FString optionalRequestID, TArray<struct FhttpRequest>& httpRequests, FString& requestID);
/**
* This function is deprecated and will be removed. Please use httpRequestPOST.
*/
//UFUNCTION(BlueprintCallable, Category = "WebCommunication|Deprecated")
// static TArray<FString> createAndAppendPOSTData(FString id, FString value, TArray<FString> POSTData);
/**
* This function is deprecated and will be removed. Please use httpRequestPOST.
*/
//UFUNCTION(BlueprintCallable, Category = "WebCommunication|Deprecated")
// static TArray<FString> createPOSTData(FString id, FString value);
/**
* Header is added to each request.
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication|Header")
static void addPersistentHTTPRequestHeader(FString id, FString value);
UFUNCTION(BlueprintCallable, Category = "WebCommunication|Header")
static void removePersistentHTTPRequestHeader(FString id);
/**
* Create a File from bytes.
*
* @param byteData from httpRequestCompleteDelegate Event
* @param DirectoryType Absolute or Relative
* @param filePath path with filename c:\myFile.zip or content\myFile.zip
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication")
static void byteDataToFile(EHTTPWebComFileBytesToFileActionType fileAction,TArray<uint8> byteData, EHTTPWebComFileUpload DirectoryType, FString filePath);
/**
* Returns a percent-encoded version of the passed in string. Do not use with strings with http::// but for the parameters.
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication")
static FString urlEncode(FString urlParameter);
/**
* Returns a percent-encoded version of the passed in string. Do not use with strings with http::// but for the parameters.
*/
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "WebCommunication")
static FString urlEncodePure(FString urlParameter);
/**
* Cancel Request
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication")
static void cancelRequest(FString requestID);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "WebCommunication")
static int32 megabyteToByte(int32 mb);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "WebCommunication")
static float byteToMegabyte(int32 byte);
/**
* With a multipart PUT STREAM upload something must be written at the end of the file. With this function you can check if the part is still in the file.
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication")
static void searchUploadLeftovers(EHTTPWebComFileUpload DirectoryType, FString filePath, bool& foundLeftovers, int64& originalFileSize);
/**
* With a multipart PUT STREAM upload something must be written at the end of the file. With this function the part can be removed. In this function the function searchUploadLeftovers is called.
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication")
static bool repairFileAfterUpload(EHTTPWebComFileUpload DirectoryType, FString filePath);
/**
* Determines the mime type based on the file extension.
*/
UFUNCTION(BlueprintCallable, Category = "WebCommunication")
static void getMimeTypeByFile(EHTTPWebComFileUpload DirectoryType, FString filePath, FString& mimeType, bool& success);
UFUNCTION(BlueprintCallable, Category = "WebCommunication")
static TMap<FString,FString> getMimeTypeMap();
void addRequestToTruncateThread(FhttpRequest& httpRequest);
bool isFileBlocked(FString filePath);
TMap<FString, FString> additionalHeader;
bool removeHeaders;
FString getMimeTypeInternal(FString fileType);
TMap<FString, FString> mimeTypes;
TMap<FString, FString> toCancelRequests;
TMap<FString, TSharedRef<IHttpRequest, ESPMode::ThreadSafe>> startedRequests;
FByteToFileThread* getByteToFileThread();
static FString Int64ToFString(int64 Num);
void startRequests(TArray<struct FhttpRequest>& httpRequests);
void registerUAsyncNodeHttpRequest(FString requestID, UAsyncNodeWebCom* asyncNodeHttpRequest);
void unregisterUAsyncNodeHttpRequest(FString requestID);
UAsyncNodeWebCom* getUAsyncNodeHttpRequest(FString requestID);
//void registerUAsyncNodeGoogleInfoRequest(FString requestID, UAsyncNodeHttpGoogleFileInfoRequest* asyncNodeHttpRequest);
//void unregisterUAsyncNodeGoogleInfoRequest(FString requestID);
//UAsyncNodeHttpGoogleFileInfoRequest* getUAsyncNodeGoogleInfoRequest(FString requestID);
private:
TMap<FString, UAsyncNodeWebCom*> asyncNodeHttpRequests;
static void fireErrorMessageInGameThread(UAsyncNodeWebCom* asyncNodeHttpRequest, int32 errorCode, FString requestID);
void fillRequestGET(struct FhttpRequest& requestStruct, TSharedRef<IHttpRequest, ESPMode::ThreadSafe> request);
void fillRequestPOST(struct FhttpRequest& requestStruct, TSharedRef<IHttpRequest, ESPMode::ThreadSafe> request);
void fillHeader(FhttpRequest& requestStruct, TSharedRef<IHttpRequest, ESPMode::ThreadSafe> request);
bool fillRequestUPLOAD(struct FhttpRequest& requestStruct, TSharedRef<IHttpRequest, ESPMode::ThreadSafe> request);
TArray<uint8> fstringToByteArray(FString data);
FString postMapToString(TMap<FString, FString> POSTData);
class FByteToFileThread* byteToFileThread = nullptr;
class FWebComTruncateUploadedFileThread* truncateUploadedFileThread = nullptr;
};
class FByteToFileThread : public FRunnable {
public:
FByteToFileThread(){
FString threadName = "FByteToFileThread" + FGuid::NewGuid().ToString();
thread = FRunnableThread::Create(this, *threadName, 0, EThreadPriority::TPri_Normal);
}
virtual uint32 Run() override {
while (true) {
while (fileQueue.IsEmpty() == false) {
FfileToByteStruct fileToByteStruct;
fileQueue.Dequeue(fileToByteStruct);
if (fileToByteStruct.byteData.Num() <= 0) {
UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: Empty byteData Array."));
break;
}
if (fileToByteStruct.filePath.IsEmpty()) {
UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: FilePath not set."));
break;
}
FString dir;
if (fileToByteStruct.DirectoryType == EHTTPWebComFileUpload::E_ad) {
dir = FPaths::ConvertRelativePathToFull(fileToByteStruct.filePath);
}
else {
FString gameDir = FPaths::ProjectDir();
dir = FPaths::ConvertRelativePathToFull(gameDir + fileToByteStruct.filePath);
}
switch (fileToByteStruct.fileAction)
{
case EHTTPWebComFileBytesToFileActionType::E_NOT_OVERWRITE:
if (FPaths::FileExists(dir)) {
UE_LOG(LogTemp, Warning, TEXT("UWebCommunicationBPLibrary: File exist. Cancel write to file."));
break;
}
break;
case EHTTPWebComFileBytesToFileActionType::E_OVERWRITE:
FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*dir);
}
FArchive* writer = IFileManager::Get().CreateFileWriter(*dir, EFileWrite::FILEWRITE_Append);
if (!writer) {
UE_LOG(LogTemp, Error, TEXT("ByteDataToFile: Can't write into %s "), *dir);
}
else {
writer->Seek(writer->TotalSize());
writer->Serialize(fileToByteStruct.byteData.GetData(), fileToByteStruct.byteData.Num());
writer->Flush();
writer->Close();
fileToByteStruct.byteData.Empty();
fileToByteStruct.filePath.Empty();
}
delete writer;
}
pauseThread(true);
//workaround. suspend do not work on all platforms(IOS,Android). lets sleep
while (paused) {
FPlatformProcess::Sleep(0.01);
}
}
thread = nullptr;
return 0;
}
void saveFile(FfileToByteStruct& fileToByteStruct) {
fileQueue.Enqueue(fileToByteStruct);
pauseThread(false);
}
void pauseThread(bool pause) {
paused = pause;
if (thread != nullptr)
thread->Suspend(pause);
}
protected:
TQueue<FfileToByteStruct> fileQueue;
FRunnableThread* thread = nullptr;
bool paused;
};
class FWebComTruncateUploadedFileThread : public FRunnable {
public:
FWebComTruncateUploadedFileThread() {
FString threadName = "FWebComTruncateUploadedFileThread" + FGuid::NewGuid().ToString();
thread = FRunnableThread::Create(this, *threadName, 0, EThreadPriority::TPri_Normal);
}
virtual uint32 Run() override {
while (true) {
while (httpRequestQueue.IsEmpty() == false) {
FhttpRequest httpRequest;
httpRequestQueue.Dequeue(httpRequest);
//Wait until the file has been released.
FPlatformProcess::Sleep(2);
if (httpRequest.requestType == EHTTPWebComRequestType::PUT_STREAM_MP && !httpRequest.filePath.IsEmpty() && httpRequest.originalFileSize > 0) {
IFileHandle* f = FPlatformFileManager::Get().GetPlatformFile().OpenWrite(*httpRequest.filePath, true, true);
if (f != nullptr) {
bool truncate = f->Truncate(httpRequest.originalFileSize);
f->Flush();
if (truncate) {
UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: truncate okay: %s"),*httpRequest.filePath);
}
else {
UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: truncate fail: %s"), *httpRequest.filePath);
}
delete f;
}
blockedFiles.Remove(httpRequest.filePath);
}
if (httpRequest.requestType == EHTTPWebComRequestType::PUT_STREAM_COPY && !httpRequest.filePath.IsEmpty()) {
if (FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*httpRequest.filePath)) {
UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: upload copy has been deleted: %s"), *httpRequest.filePath);
}
else {
UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: upload copy could not be deleted: %s"), *httpRequest.filePath);
}
blockedFiles.Remove(httpRequest.filePath);
}
}
pauseThread(true);
//workaround. suspend do not work on all platforms(IOS,Android). lets sleep
while (paused) {
FPlatformProcess::Sleep(1);
}
}
thread = nullptr;
return 0;
}
void addRequest(FhttpRequest& httpRequestP) {
httpRequestQueue.Enqueue(httpRequestP);
blockedFiles.Add(httpRequestP.filePath);
pauseThread(false);
}
void pauseThread(bool pause) {
paused = pause;
if (thread != nullptr)
thread->Suspend(pause);
}
TArray<FString> blockedFiles;
protected:
TQueue<FhttpRequest> httpRequestQueue;
FRunnableThread* thread = nullptr;
bool paused;
};