Files
UnrealEngineUWP/Engine/Source/Programs/Unsync/Private/UnsyncHttp.h
Yuriy ODonnell b5709042fb Import Unsync into the main source tree
This is a binary patching and incremental downloading tool, similar to rsync or zsync. It aims to improve the large binary download processes that previously were served by robocopy (i.e. full packages produced by the build farm).

The original code can be found in `//depot/usr/yuriy.odonnell/unsync`. This commit is a branch from the original location to preserve history.

While the codebase is designed to be self-contained and does not depend on any engine libraries, it mostly follows the UE coding guidelines and can be built with UBT.

Currently only Windows is supported, however the tool is expected to also work on Mac and Linux in the future.

#rb Martin.Ridgers
#preflight skip

[CL 18993571 by Yuriy ODonnell in ue5-main branch]
2022-02-15 04:30:27 -05:00

135 lines
3.1 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "UnsyncBuffer.h"
#include "UnsyncCommon.h"
#include "UnsyncSocket.h"
#include "UnsyncUtil.h"
#include <deque>
#include <memory>
#include <string>
namespace unsync {
enum class EHttpContentType
{
Unknown,
Text_Html,
Text_Plain,
Application_OctetStream,
Application_Json,
Application_UECB, // Unreal Engine Compact Binary
};
enum class EHttpMethod
{
GET,
// HEAD, // < TODO: support requests that don't return a body
POST,
PUT,
};
struct FHttpRequest
{
EHttpMethod Method = EHttpMethod::GET;
std::string_view Url = {};
std::string_view CustomHeaders = {};
EHttpContentType PayloadContentType = EHttpContentType::Unknown;
FBufferView Payload = {};
EHttpContentType AcceptContentType = EHttpContentType::Unknown;
};
struct FHttpResponse
{
FBuffer Buffer; // TODO: use pooled IOBuffer
int32 Code = 0;
EHttpContentType ContentType = EHttpContentType::Unknown;
bool Success() const { return Code >= 200 && Code < 300; }
std::string_view AsStringView() const { return std::string_view((const char*)Buffer.Data(), Buffer.Size()); }
};
struct FHttpConnection
{
FHttpConnection(const std::string& InHostAddress, uint16 InPort, const FTlsClientSettings* TlsSettings = nullptr);
FHttpConnection(const FHttpConnection& Other);
bool Open();
void Close();
const std::string HostAddress; // NOLINT
const uint16 HostPort = 80; // NOLINT
const bool bUseTls = false; // NOLINT
bool bKeepAlive = true;
std::string TlsSubject;
bool bTlsVerifyCertificate = true;
std::shared_ptr<FBuffer> TlsCacert;
uint64 NumActiveRequests = 0;
// TODO: use single memory allocation for multiple reponse objects (perhaps a ring buffer)
std::deque<FHttpResponse> ResponseQueue; // Contains HTTP responses for pipelined requests
FTimePoint LastUsed = {};
FSocketBase& GetSocket()
{
LastUsed = TimePointNow();
return *Socket;
}
protected:
std::unique_ptr<FSocketBase> Socket;
};
const char* HttpStatusToString(int32 Code);
// Synchronous HTTP request API
FHttpResponse HttpRequest(FHttpConnection& Connection, const FHttpRequest& Request);
inline FHttpResponse
HttpRequest(FHttpConnection& Connection,
EHttpMethod Method,
std::string_view Url,
EHttpContentType ContentType,
FBufferView Payload,
std::string_view CustomHeaders = {})
{
FHttpRequest Request;
Request.Method = Method;
Request.Url = Url;
Request.PayloadContentType = ContentType;
Request.Payload = Payload;
Request.CustomHeaders = CustomHeaders;
return HttpRequest(Connection, Request);
}
inline FHttpResponse
HttpRequest(FHttpConnection& Connection, EHttpMethod Method, std::string_view Url, std::string_view CustomHeaders = {})
{
FHttpRequest Request;
Request.Method = Method;
Request.Url = Url;
Request.CustomHeaders = CustomHeaders;
return HttpRequest(Connection, Request);
}
// Pipelined HTTP request API
bool HttpRequestBegin(FHttpConnection& Connection, const FHttpRequest& Request);
FHttpResponse HttpRequestEnd(FHttpConnection& Connection);
} // namespace unsync