14 return (StatusCode < 200) | (StatusCode == 204) | (StatusCode == 304);
29#if !defined(WITH_NGHTTP2)
30# define WITH_NGHTTP2 0
31# if defined(__has_include)
32# if __has_include(<nghttp2/nghttp2.h>)
34# define WITH_NGHTTP2 1
39#if !defined(IAS_HTTP_WITH_TWO)
40# define IAS_HTTP_WITH_TWO WITH_NGHTTP2
47# define NGHTTP2_NO_SSIZE_T
49#if PLATFORM_MICROSOFT & !defined(NGHTTP2_STATICLIB)
50# define NGHTTP2_STATICLIB
53#include <nghttp2/nghttp2.h>
55#if PLATFORM_MICROSOFT & !defined(NGHTTP2_STATICLIB)
56# undef NGHTTP2_STATICLIB
59# undef NGHTTP2_NO_SSIZE_T
71 enum class EType :
uint8
100 uint32 GetId()
const {
return (
Id[0] << 24u) | (
Id[1] << 16u) | (
Id[2] << 8u) |
Id[3]; }
103static_assert(
sizeof(
FFrame) == 9);
123 return { (
char*)(Ret.base),
int32(Ret.len) };
150 int32 Num()
const {
return Headers.Num(); }
160 (
uint8*)Key.GetData(),
176 bool IsUsingTls()
const;
177 void GoAway(FTlsPeer& Peer);
178 FOutcome Handshake(FTlsPeer& Peer);
179 FOutcome GetTransactId(FTlsPeer& Peer);
181 FOutcome
Send(FTlsPeer& Peer);
186 FOutcome
Tick(FTlsPeer& Peer);
207FDriverNg::FDriverNg(FTlsPeer& Peer)
220 if (
Statics.Instance ==
nullptr)
238 .mem_user_data =
nullptr,
239 .malloc = [] (
size_t Size,
void*) {
return FMemory::Malloc(
Size); },
240 .free = [] (
void* Ptr,
void*) {
return FMemory::Free(Ptr); },
241 .calloc = [] (
size_t Count,
size_t Size,
void*) {
return FMemory::MallocZeroed(
Count *
Size); },
242 .realloc = [] (
void* Ptr,
size_t Size,
void*) {
return FMemory::Realloc(Ptr,
Size); },
257void FDriverNg::GoAway(FTlsPeer& Peer)
259 if (Session !=
nullptr)
268bool FDriverNg::IsUsingTls()
const
274FOutcome FDriverNg::PumpSend(FTlsPeer& Peer)
280 const uint8* Data =
nullptr;
285 return FOutcome::Error(Message);
290 return FOutcome::Ok(Sent);
317 return FOutcome::Waiting();
322FOutcome FDriverNg::PumpRecv(FTlsPeer& Peer,
FMemoryView Data)
329 return FOutcome::Error(Message);
332 if (Result !=
int32(Data.GetSize()))
334 return FOutcome::Error(
"Not enough data consumed");
344 return FOutcome::Ok();
348FOutcome FDriverNg::Handshake(FTlsPeer& Peer)
356FOutcome FDriverNg::GetTransactId(FTlsPeer& Peer)
361 return FOutcome::Ok(
Id);
368FOutcome FDriverNg::Tick(FTlsPeer& Peer)
381FOutcome FDriverNg::TickInner(FTlsPeer& Peer)
404 Dest = Dest.
Left(Result);
431 return FOutcome::Waiting();
443 return FOutcome::Ok(
Id);
451 return FOutcome::Waiting(1);
458 Headers.Num(),
nullptr,
this);
462FOutcome FDriverNg::Send(FTlsPeer& Peer)
470 if (
RecvFrame.Type == FFrame::EType::RstStream)
472 return FOutcome::Error(
"Received stream reset");
479 ResponseHeaders = Sink;
495 if (
Outcome.GetResult() !=
ThisId)
return FOutcome::WaitStream();
502 if (
RecvFrame.Type == FFrame::EType::RstStream)
504 return FOutcome::Error(
"Received stream reset");
523 return FOutcome::WaitBuffer(
RecvSize);
539 Dest = Dest.
Mid(Result);
571 if (ResponseHeaders ==
nullptr)
619 FTransactId
End(
bool bKeepAlive);
620 FOutcome TrySendRequest(FTlsPeer& Peer);
623 FTransactId GetTransactId()
const;
634 RequestHeaders.Add(
":method", Method);
635 RequestHeaders.Add(
":path", Path);
636 RequestHeaders.Add(
":authority", Host);
637 RequestHeaders.Add(
":scheme",
Scheme);
645#if UE_BUILD_DEVELOPMENT
650 check(
"header keys must be lowercase");
654 RequestHeaders.Add(Key,
Value);
658FTransactId FRequest::GetTransactId()
const
664FTransactId FRequest::End(
bool )
666 Id = GetDriver().Submit(RequestHeaders);
671FOutcome FRequest::TrySendRequest(FTlsPeer& Peer)
673 return GetDriver().Send(Peer);
683 using FRequest::FRequest;
685 FOutcome TryRecvResponse(FTlsPeer& Peer);
686 bool IsKeepAlive()
const;
687 uint32 GetStatusCode()
const;
689 int64 GetContentLength()
const;
690 bool IsChunked()
const;
691 void ReadHeaders(FResponse::FHeaderSink Sink)
const;
695 int64 ContentLength = -1;
700bool FStatusHeaders::IsKeepAlive()
const
706uint32 FStatusHeaders::GetStatusCode()
const
718int64 FStatusHeaders::GetContentLength()
const
720 return ContentLength;
724bool FStatusHeaders::IsChunked()
const
726 return ContentLength < 0;
730void FStatusHeaders::ReadHeaders(FResponse::FHeaderSink Sink)
const
736 if (!Sink(Key,
Value))
744FOutcome FStatusHeaders::TryRecvResponse(FTlsPeer& Peer)
746 FOutcome
Outcome = GetDriver().RecvResponse(Peer, &ResponseHeaders);
775 ContentLength = CrudeToInt(
Value);
782 return FOutcome::Error(
"Invalid status code", StatusCode);
785 if (IsContentless(StatusCode))
790 return FOutcome::Ok();
797 :
public FStatusHeaders
800 using FStatusHeaders::FStatusHeaders;
802 int64 GetRemaining()
const;
806 int64 Remaining = -1;
810int64 FBody::GetRemaining()
const
822 Remaining = GetContentLength();
824 Dest = Dest.
Left(Remaining);
827 FOutcome
Outcome = GetDriver().RecvBody(Peer, Dest);
833 Remaining -=
Outcome.GetResult();
843 :
public DetailTwo::FBody
846 using DetailTwo::FBody::FBody;
856 if (PeerData ==
nullptr)
862 return Driver->Handshake(Peer);
866FOutcome
TickTwo(FTlsPeer& Peer,
void* PeerData)
871 return Driver->GetTransactId(Peer);
875void GoAwayTwo(FTlsPeer& Peer,
void* PeerData)
880 if (Driver ==
nullptr)
885 Driver->GoAway(Peer);
#define check(expr)
Definition AssertionMacros.h:314
#define UE_NONCOPYABLE(TypeName)
Definition CoreMiscDefines.h:457
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
TMemoryView< void > FMutableMemoryView
Definition MemoryFwd.h:14
#define ON_SCOPE_EXIT
Definition ScopeExit.h:73
auto GetData(const TStringConversion< Converter, DefaultConversionSize > &Conversion) -> decltype(Conversion.Get())
Definition StringConv.h:802
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32 Size
Definition VulkanMemory.cpp:4034
Definition AndroidPlatformMisc.h:14
constexpr DataType * GetData() const
Definition MemoryView.h:68
constexpr TMemoryView Left(uint64 InSize) const
Definition MemoryView.h:83
constexpr TMemoryView LeftChop(uint64 InSize) const
Definition MemoryView.h:91
DataType * GetDataEnd() const
Definition MemoryView.h:71
constexpr bool IsEmpty() const
Definition MemoryView.h:77
TMemoryView Right(uint64 InSize) const
Definition MemoryView.h:99
TMemoryView Mid(uint64 InOffset, uint64 InSize=TNumericLimits< uint64 >::Max()) const
Definition MemoryView.h:115
constexpr uint64 GetSize() const
Definition MemoryView.h:74
static FOutcome None()
Definition Misc.inl:80
Definition TransactionTwo.inl:897
void AddHeader(...)
Definition TransactionTwo.inl:900
void Begin(...)
Definition TransactionTwo.inl:899
FTransactId End(...)
Definition TransactionTwo.inl:901
int64 GetRemaining() const
Definition TransactionTwo.inl:909
FOutcome TrySendRequest(FTlsPeer &)
Definition TransactionTwo.inl:902
int64 GetContentLength() const
Definition TransactionTwo.inl:907
uint32 GetStatusCode() const
Definition TransactionTwo.inl:905
FOutcome TryRecv(FMutableMemoryView, FTlsPeer &)
Definition TransactionTwo.inl:911
void ReadHeaders(FResponse::FHeaderSink) const
Definition TransactionTwo.inl:910
bool IsChunked() const
Definition TransactionTwo.inl:908
bool IsKeepAlive() const
Definition TransactionTwo.inl:904
FAnsiStringView GetStatusMessage() const
Definition TransactionTwo.inl:906
FOutcome TryRecvResponse(FTlsPeer &)
Definition TransactionTwo.inl:903
CORE_API UE_STRING_CLASS Mid(int32 Start, int32 Count) const &
Definition String.cpp.inl:863
@ IgnoreCase
Definition CString.h:26
bool IsStatusCodeOk(uint32 StatusCode)
Definition TransactionTwo.inl:18
bool IsContentless(uint32 StatusCode)
Definition TransactionTwo.inl:12
FOutcome TickTwo(FTlsPeer &, void *)
Definition TransactionTwo.inl:914
uint32 FTransactId
Definition TransactionTwo.inl:9
void GoAwayTwo(FTlsPeer &, void *)
Definition TransactionTwo.inl:915
FOutcome HandshakeTwo(FTlsPeer &, void *&)
Definition TransactionTwo.inl:913
static FORCENOINLINE CORE_API void Free(void *Original)
Definition UnrealMemory.cpp:685