446 lines
16 KiB
C++
446 lines
16 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Interfaces/IHttpBase.h"
|
|
|
|
class IHttpRequest;
|
|
class IHttpResponse;
|
|
|
|
/**
|
|
* Enumerates thread policy about which thread to complete the http request
|
|
*/
|
|
enum class EHttpRequestDelegateThreadPolicy : uint8
|
|
{
|
|
CompleteOnGameThread = 0,
|
|
CompleteOnHttpThread,
|
|
};
|
|
|
|
class IHttpRequest;
|
|
class IHttpResponse;
|
|
|
|
typedef TSharedPtr<IHttpRequest, ESPMode::ThreadSafe> FHttpRequestPtr;
|
|
typedef TSharedPtr<IHttpResponse, ESPMode::ThreadSafe> FHttpResponsePtr;
|
|
|
|
typedef TSharedRef<IHttpRequest, ESPMode::ThreadSafe> FHttpRequestRef;
|
|
typedef TSharedRef<IHttpResponse, ESPMode::ThreadSafe> FHttpResponseRef;
|
|
|
|
/**
|
|
* Delegate called when an Http request completes
|
|
*
|
|
* @param Request original Http request that started things
|
|
* @param Response response received from the server if a successful connection was established. Note that
|
|
* even if response is not null, it doesn't mean the request was processed successfully. Use
|
|
* Response->GetStatus(), Response->GetFailureReason() and Response->GetResponseCode() to decide
|
|
* how to handle it
|
|
* @param bProcessedSuccessfully this flag indicates whether or not the request was able to be processed successfully.
|
|
* It could be connect error, timeout error or platform http error. Note that when this flag is true
|
|
* doesn't mean the http request get 2xx success status code, it just means this request got response
|
|
* from http server and completed the processing
|
|
*/
|
|
using FHttpRequestCompleteDelegate = TTSDelegate<void(FHttpRequestPtr /*Request*/, FHttpResponsePtr /*Response*/, bool /*bProcessedSuccessfully*/)>;
|
|
|
|
/**
|
|
* Delegate called when an Http request receives status code
|
|
*
|
|
* @param Request original Http request that started things
|
|
* @param status code
|
|
*/
|
|
using FHttpRequestStatusCodeReceivedDelegate = TTSDelegate<void(FHttpRequestPtr /*Request*/, int32 /*StatusCode*/)>;
|
|
|
|
/**
|
|
* Delegate called when an Http request receives a header
|
|
*
|
|
* @param Request original Http request that started things
|
|
* @param HeaderName the name of the header
|
|
* @param NewHeaderValue the value of the header
|
|
*/
|
|
using FHttpRequestHeaderReceivedDelegate = TTSDelegate<void(FHttpRequestPtr /*Request*/, const FString& /*HeaderName*/, const FString& /*NewHeaderValue*/)>;
|
|
|
|
/**
|
|
* Delegate called per tick to update an Http request upload or download size progress
|
|
*
|
|
* @param Request original Http request that started things
|
|
* @param BytesSent the number of bytes sent / uploaded in the request so far.
|
|
* @param BytesReceived the number of bytes received / downloaded in the response so far.
|
|
*/
|
|
using FHttpRequestProgressDelegate = TTSDelegate<void(FHttpRequestPtr /*Request*/, int32 /*BytesSent*/, int32 /*BytesReceived*/)>;
|
|
|
|
/**
|
|
* Delegate called per tick to update an Http request upload or download size progress
|
|
*
|
|
* @param Request original Http request that started things
|
|
* @param BytesSent the number of bytes sent / uploaded in the request so far.
|
|
* @param BytesReceived the number of bytes received / downloaded in the response so far.
|
|
*/
|
|
using FHttpRequestProgressDelegate64 = TTSDelegate<void(FHttpRequestPtr /*Request*/, uint64 /*BytesSent*/, uint64 /*BytesReceived*/)>;
|
|
|
|
/**
|
|
* Delegate called when an Http request will be retried in the future
|
|
*
|
|
* @param Request - original Http request that started things
|
|
* @param Response - response received from the server if a successful connection was established
|
|
* @param SecondsToRetry - seconds in the future when the response will be retried
|
|
*/
|
|
using FHttpRequestWillRetryDelegate = TTSDelegate<void(FHttpRequestPtr /*Request*/, FHttpResponsePtr /*Response*/, float /*SecondsToRetry*/)>;
|
|
|
|
/**
|
|
* Delegate called when an Http request will send/recv data through stream
|
|
*
|
|
* @param Ptr - The buffer ptr to read/write
|
|
* @param Length - The length of buffer to read/write
|
|
* @return true if succeed, false if failed to read/write data
|
|
*/
|
|
using FHttpRequestStreamDelegate = TTSDelegate<bool(void*/*Ptr*/, int64/*Length*/)>;
|
|
|
|
/**
|
|
* Delegate called when an Http request will send/recv data through stream
|
|
*
|
|
* @param Ptr - The buffer ptr to read/write
|
|
* @param InOutLength - The int64 reference length of buffer to read/write, if there is any error when serialize set it to 0
|
|
*/
|
|
using FHttpRequestStreamDelegateV2 = TTSDelegate<void(void*/*Ptr*/, int64&/*InOutLength*/)>;
|
|
|
|
/**
|
|
* Delegate version of FArchive, for streaming interface
|
|
*/
|
|
class UE_DEPRECATED(5.5, "FArchiveWithDelegate is deprecated and will be moved to internal") FArchiveWithDelegate final : public FArchive
|
|
{
|
|
public:
|
|
FArchiveWithDelegate(FHttpRequestStreamDelegate InStreamDelegate)
|
|
: StreamDelegate(InStreamDelegate)
|
|
{
|
|
}
|
|
|
|
virtual void Serialize(void* V, int64 Length) override
|
|
{
|
|
if (!StreamDelegate.IsBound() || !StreamDelegate.Execute(V, Length))
|
|
{
|
|
SetError();
|
|
}
|
|
}
|
|
|
|
private:
|
|
FHttpRequestStreamDelegate StreamDelegate;
|
|
};
|
|
|
|
/**
|
|
* Options that can be specified on a Http Request
|
|
*/
|
|
namespace HttpRequestOptions
|
|
{
|
|
static const FName HttpVersion("HttpVersion");
|
|
#if UE_HTTP_SUPPORT_UNIX_SOCKET
|
|
static const FName UnixSocketPath("UnixSocketPath");
|
|
#endif //UE_HTTP_SUPPORT_UNIX_SOCKET
|
|
}
|
|
|
|
/**
|
|
* Interface for Http requests (created using FHttpFactory)
|
|
*/
|
|
class IHttpRequest :
|
|
public IHttpBase, public TSharedFromThis<IHttpRequest, ESPMode::ThreadSafe>
|
|
{
|
|
public:
|
|
|
|
/**
|
|
* Gets the verb (GET, PUT, POST) used by the request.
|
|
*
|
|
* @return the verb string
|
|
*/
|
|
virtual FString GetVerb() const = 0;
|
|
|
|
/**
|
|
* Sets the verb used by the request.
|
|
* Eg. (GET, PUT, POST)
|
|
* Should be set before calling ProcessRequest.
|
|
* If not specified then a GET is assumed.
|
|
*
|
|
* @param Verb - verb to use.
|
|
*/
|
|
virtual void SetVerb(const FString& Verb) = 0;
|
|
|
|
/**
|
|
* Sets the URL for the request
|
|
* Eg. (http://my.domain.com/something.ext?key=value&key2=value).
|
|
* Must be set before calling ProcessRequest.
|
|
*
|
|
* @param URL - URL to use.
|
|
*/
|
|
virtual void SetURL(const FString& URL) = 0;
|
|
|
|
/**
|
|
* Get the current value for the given option
|
|
*
|
|
* @return the current value set for this option or an empty string if no value has been specified
|
|
*/
|
|
virtual FString GetOption(const FName Option) const = 0;
|
|
|
|
/**
|
|
* Sets the given option for this Request
|
|
* Must be set before calling ProcessRequest.
|
|
*
|
|
* @param Option - The option to set, see 'HttpRequestOptions' for supported options
|
|
* @param OptionValue - The value of the option to set
|
|
*/
|
|
virtual void SetOption(const FName Option, const FString& OptionValue) = 0;
|
|
|
|
/**
|
|
* Sets the content of the request (optional data).
|
|
* Usually only set for POST requests.
|
|
*
|
|
* @param ContentPayload - payload to set.
|
|
*/
|
|
virtual void SetContent(const TArray<uint8>& ContentPayload) = 0;
|
|
|
|
/**
|
|
* Sets the content of the request (optional data).
|
|
* Usually only set for POST requests.
|
|
*
|
|
* This version lets the API take ownership of the payload directly, helpful for larger payloads.
|
|
*
|
|
* @param ContentPayload - payload to set.
|
|
*/
|
|
virtual void SetContent(TArray<uint8>&& ContentPayload) = 0;
|
|
|
|
/**
|
|
* Sets the content of the request as a string encoded as UTF8.
|
|
*
|
|
* @param ContentString - payload to set.
|
|
*/
|
|
virtual void SetContentAsString(const FString& ContentString) = 0;
|
|
|
|
/**
|
|
* Sets the content of the request to stream from a file.
|
|
*
|
|
* @param FileName - filename from which to stream the body.
|
|
* @return True if the file is valid and will be used to stream the request. False otherwise.
|
|
*/
|
|
virtual bool SetContentAsStreamedFile(const FString& Filename) = 0;
|
|
|
|
/**
|
|
* Sets the content of the request to stream directly from an archive.
|
|
* NOTE: The Stream->Serialize will be called from another thread other than the game thread
|
|
*
|
|
* @param Stream - archive from which the payload should be streamed.
|
|
* @return True if the archive can be used to stream the request. False otherwise.
|
|
*/
|
|
virtual bool SetContentFromStream(TSharedRef<FArchive, ESPMode::ThreadSafe> Stream) = 0;
|
|
|
|
/**
|
|
* Sets the content of the request to stream directly from an delegate.
|
|
* NOTE:
|
|
* - The delegate will be called from another thread other than the game thread, make sure
|
|
* it's thread-safe in there
|
|
* - Make sure the delegate is safe to be called until receiving the process complete callback
|
|
* or after canceling the request
|
|
* @param StreamDelegate - delegate from which the payload should be streamed.
|
|
* @return True if the delegate can be used to stream the request. False otherwise.
|
|
*/
|
|
UE_DEPRECATED(5.5, "SetContentFromStreamDelegate has been deprecated and will not be supported because there is no seek support through delegate. Implement your own FArchive instead.")
|
|
bool SetContentFromStreamDelegate(FHttpRequestStreamDelegate StreamDelegate);
|
|
|
|
/**
|
|
* Sets the stream to receive the response body. Make sure to handle the cleanup of stream when
|
|
* Serialize generated error(Stream->GetError returns true after Stream->Serialize call), this
|
|
* http request will fail and quit.
|
|
*
|
|
* NOTE: Once set, the data will no longer be cached in response, IHttpResponse::GetContent() and
|
|
* IHttpResponse::GetContentAsString() will return empty result. The Stream->Serialize will be called
|
|
* from another thread other than the game thread
|
|
*
|
|
* @param Stream - will be used to receive the response body
|
|
* @return True if the stream can be used. False otherwise.
|
|
*/
|
|
virtual bool SetResponseBodyReceiveStream(TSharedRef<FArchive> Stream) = 0;
|
|
|
|
/**
|
|
* Sets the delegate to receive the response body. Make sure to handle the cleanup of received data when
|
|
* failed to process the data(StreamDelegate return false), this http request will fail and quit.
|
|
*
|
|
* NOTE: Once set, the data will no longer be cached in response, IHttpResponse::GetContent() and
|
|
* IHttpResponse::GetContentAsString() will return empty result. The delegate will be called from
|
|
* another thread other than the game thread
|
|
*
|
|
* @param StreamDelegate - will be used to receive the response body
|
|
* @return True if the delegate can be used. False otherwise.
|
|
*/
|
|
UE_DEPRECATED(5.5, "SetResponseBodyReceiveStreamDelegate has been deprecated, use SetResponseBodyReceiveStreamDelegateV2 instead")
|
|
HTTP_API bool SetResponseBodyReceiveStreamDelegate(FHttpRequestStreamDelegate StreamDelegate);
|
|
|
|
/**
|
|
* Sets the delegate to receive the response body. Make sure to handle the cleanup of received data when
|
|
* failed to process the data(StreamDelegate return false), this http request will fail and quit.
|
|
*
|
|
* NOTE: Once set, the data will no longer be cached in response, IHttpResponse::GetContent() and
|
|
* IHttpResponse::GetContentAsString() will return empty result. The delegate will be called from
|
|
* another thread other than the game thread
|
|
*
|
|
* @param StreamDelegate - will be used to receive the response body
|
|
* @return True if the delegate can be used. False otherwise.
|
|
*/
|
|
HTTP_API bool SetResponseBodyReceiveStreamDelegateV2(FHttpRequestStreamDelegateV2 StreamDelegate);
|
|
|
|
/**
|
|
* Sets optional header info.
|
|
* SetHeader for a given HeaderName will overwrite any previous values
|
|
* Use AppendToHeader to append more values for the same header
|
|
* Content-Length is the only header set for you.
|
|
* Required headers depends on the request itself.
|
|
* Eg. "multipart/form-data" needed for a form post
|
|
*
|
|
* @param HeaderName - Name of the header (ie, Content-Type)
|
|
* @param HeaderValue - Value of the header
|
|
*/
|
|
virtual void SetHeader(const FString& HeaderName, const FString& HeaderValue) = 0;
|
|
|
|
/**
|
|
* Appends to the value already set in the header.
|
|
* If there is already content in that header, a comma delimiter is used.
|
|
* If the header is as of yet unset, the result is the same as calling SetHeader
|
|
* Content-Length is the only header set for you.
|
|
* Also see: SetHeader()
|
|
*
|
|
* @param HeaderName - Name of the header (ie, Content-Type)
|
|
* @param AdditionalHeaderValue - Value to add to the existing contents of the specified header.
|
|
* comma is inserted between old value and new value, per HTTP specifications
|
|
*/
|
|
virtual void AppendToHeader(const FString& HeaderName, const FString& AdditionalHeaderValue) = 0;
|
|
|
|
/**
|
|
* Sets an optional timeout in seconds for this entire HTTP request to complete.
|
|
* If set, this value overrides the default HTTP timeout set via FHttpModule::SetTimeout().
|
|
*
|
|
* @param InTimeoutSecs - Timeout for this HTTP request instance, in seconds
|
|
*/
|
|
virtual void SetTimeout(float InTimeoutSecs) = 0;
|
|
|
|
/**
|
|
* Sets an optional activity timeout in seconds for this HTTP request. After connecting to
|
|
* web server, if there is no activity(send or receive) happen for this time period, it will
|
|
* trigger activity timeout
|
|
* If set, this value overrides the default HTTP activity timeout
|
|
*
|
|
* @param InTimeoutSecs - Timeout for this HTTP request instance, in seconds
|
|
*/
|
|
virtual void SetActivityTimeout(float InTimeoutSecs) = 0;
|
|
|
|
/**
|
|
* Clears the optional timeout in seconds for this HTTP request, causing the default value
|
|
* from FHttpModule::GetTimeout() to be used.
|
|
*/
|
|
virtual void ClearTimeout() = 0;
|
|
|
|
/**
|
|
* Reset the elapsed timeout duration and flag, after the request completed and need to be reused
|
|
*/
|
|
virtual void ResetTimeoutStatus() = 0;
|
|
|
|
/**
|
|
* Gets the optional timeout in seconds for this entire HTTP request to complete.
|
|
* If valid, this value overrides the default HTTP timeout set via FHttpModule::SetTimeout().
|
|
*
|
|
* @return the timeout for this HTTP request instance, in seconds
|
|
*/
|
|
virtual TOptional<float> GetTimeout() const = 0;
|
|
|
|
/**
|
|
* Called to begin processing the request.
|
|
* OnProcessRequestComplete delegate is always called when the request completes or on error if it is bound.
|
|
* A request can be re-used but not while still being processed.
|
|
*
|
|
* @return if the request was successfully started.
|
|
*/
|
|
virtual bool ProcessRequest() = 0;
|
|
|
|
/**
|
|
* Delegate called when the request is complete. See FHttpRequestCompleteDelegate
|
|
*/
|
|
virtual FHttpRequestCompleteDelegate& OnProcessRequestComplete() = 0;
|
|
|
|
/**
|
|
* Delegate called to update the request/response progress. See FHttpRequestProgressDelegate64
|
|
*/
|
|
virtual FHttpRequestProgressDelegate64& OnRequestProgress64() = 0;
|
|
|
|
/**
|
|
* Delegate called when the request will be retried
|
|
*/
|
|
virtual FHttpRequestWillRetryDelegate& OnRequestWillRetry() = 0;
|
|
|
|
/**
|
|
* Delegate called to signal the receipt of a header. See FHttpRequestHeaderReceivedDelegate
|
|
*/
|
|
virtual FHttpRequestHeaderReceivedDelegate& OnHeaderReceived() = 0;
|
|
|
|
/**
|
|
* Delegate called to signal the receipt of a header. See FHttpRequestStatusCodeReceivedDelegate
|
|
*/
|
|
virtual FHttpRequestStatusCodeReceivedDelegate& OnStatusCodeReceived() = 0;
|
|
|
|
/**
|
|
* Called to cancel a request that is still being processed
|
|
*/
|
|
virtual void CancelRequest() = 0;
|
|
|
|
/**
|
|
* Get the associated Response
|
|
*
|
|
* @return the response
|
|
*/
|
|
virtual const FHttpResponsePtr GetResponse() const = 0;
|
|
|
|
/**
|
|
* Used to tick the request
|
|
*
|
|
* @param DeltaSeconds - seconds since last ticked
|
|
*/
|
|
virtual void Tick(float DeltaSeconds) = 0;
|
|
|
|
/**
|
|
* Gets the time that it took for the server to fully respond to the request.
|
|
*
|
|
* @return elapsed time in seconds.
|
|
*/
|
|
virtual float GetElapsedTime() const = 0;
|
|
|
|
/**
|
|
* Set thread policy about which thread to trigger the delegates, set by FHttpManager::SetRequestCompletedDelegate,
|
|
* IHttpRequest::OnStatusCodeReceived, IHttpRequest::OnHeaderReceived, IHttpRequest::OnRequestProgress64 and IHttpRequest::OnProcessRequestComplete.
|
|
*
|
|
* Note that when set it as CompleteOnHttpThread, the thread to trigger delegates could be any thread
|
|
* depends on the implementation. User code should make the delegate thread-safe and shouldn't assume
|
|
* it's triggered by the thread where this request get created.
|
|
*
|
|
* @param InThreadPolicy - The thread policy to indicate which thread to trigger the delegates
|
|
*/
|
|
virtual void SetDelegateThreadPolicy(EHttpRequestDelegateThreadPolicy InThreadPolicy) = 0;
|
|
|
|
/**
|
|
* Get thread policy about which thread to complete this request
|
|
*
|
|
* @return The thread policy
|
|
*/
|
|
virtual EHttpRequestDelegateThreadPolicy GetDelegateThreadPolicy() const = 0;
|
|
|
|
/**
|
|
* Blocking call to wait the request until it's completed
|
|
*
|
|
* WARNINGS:
|
|
*
|
|
* - This is a blocking call, DON'T use this in a time-sensitive context
|
|
* - Complete delegate will be used in this function so customized complete delegate is not supported
|
|
* - This will force the usage of EHttpRequestDelegateThreadPolicy::CompleteOnHttpThread to make sure the
|
|
* request can complete, when this function get called from main thread. So if any other delegate is
|
|
* bound, make sure the bound delegate can handle the custom logic in a thread-safe way
|
|
*/
|
|
virtual void ProcessRequestUntilComplete() = 0;
|
|
|
|
/**
|
|
* Destructor for overrides
|
|
*/
|
|
virtual ~IHttpRequest() = default;
|
|
};
|
|
|