UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ConnectionPool.inl
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5namespace UE::IoStore::HTTP
6{
7
9class FHost
10{
11public:
12 enum class EDirection : uint8 { Send, Recv };
13 static const uint32 InvalidIp = 0x00ff'ffff;
14
25
26 FHost(const FParams& Params);
29 FOutcome Connect(FSocket& Socket);
30 int32 IsResolved() const;
32 FCertRootsRef GetVerifyCert() const { return VerifyCert; }
33 uint32 GetMaxConnections() const { return MaxConnections; }
34 uint32 GetMaxInflight() const { return MaxInflight; }
36 bool IsPooled() const { return bPooled; }
37 uint32 GetIpAddress() const { return IpAddresses[0]; }
38 FAnsiStringView GetHostName() const { return HostName; }
39 uint32 GetPort() const { return Port; }
40
41private:
42 FCertRootsRef VerifyCert;
43 const ANSICHAR* HostName;
44 uint32 IpAddresses[4] = {};
45 int16 SendBufKb = -1;
46 int16 RecvBufKb = -1;
47 uint16 Port;
48 uint8 MaxConnections;
49 uint8 MaxInflight;
51 bool bPooled;
52};
53
55FHost::FHost(const FParams& Params)
56: VerifyCert(Params.VerifyCert)
57, HostName(Params.HostName)
58, Port(uint16(Params.Port))
59, MaxConnections(uint8(Params.MaxConnections))
60, MaxInflight(Params.MaxInflight)
62, bPooled(Params.bPooled)
63{
64 check(MaxConnections && MaxConnections == Params.MaxConnections);
65
66 if (Port == 0)
67 {
68 Port = (VerifyCert == ECertRootsRefType::None) ? 80 : 443;
69 }
70}
71
74{
75 (Dir == EDirection::Send) ? SendBufKb : RecvBufKb = uint16(Size >> 10);
76}
77
80{
81 return int32((Dir == EDirection::Send) ? SendBufKb : RecvBufKb) << 10;
82}
83
86{
87 // todo: GetAddrInfoW() for async resolve on Windows
88
89 TRACE_CPUPROFILER_EVENT_SCOPE(IasHttp::PoolResolve);
90
91 IpAddresses[0] = 1;
92
93 addrinfo* Info = nullptr;
94 ON_SCOPE_EXIT { if (Info != nullptr) Socket_FreeAddrInfo(Info); };
95
96 addrinfo Hints = {};
97 Hints.ai_family = AF_INET;
98 Hints.ai_socktype = SOCK_STREAM;
99 Hints.ai_protocol = IPPROTO_TCP;
100 auto Result = Socket_GetAddrInfo(HostName, nullptr, &Hints, &Info);
101 if (uint32(Result) || Info == nullptr)
102 {
103 return FOutcome::Error("Error encountered resolving");
104 }
105
106 if (Info->ai_family != AF_INET)
107 {
108 return FOutcome::Error("Unexpected address family during resolve");
109 }
110
112 for (const addrinfo* Cursor = Info; Cursor != nullptr; Cursor = Cursor->ai_next)
113 {
114 const auto* AddrInet = (sockaddr_in*)(Cursor->ai_addr);
115 if (AddrInet->sin_family != AF_INET)
116 {
117 continue;
118 }
119
120 uint32 IpAddress = 0;
121 memcpy(&IpAddress, &(AddrInet->sin_addr), sizeof(uint32));
122
123 if (IpAddress == 0)
124 {
125 break;
126 }
127
128 IpAddresses[AddressCount] = Socket_HtoNl(IpAddress);
129 if (++AddressCount >= UE_ARRAY_COUNT(IpAddresses))
130 {
131 break;
132 }
133 }
134
135 if (AddressCount > 0)
136 {
138 }
139
140 return FOutcome::Error("Unable to resolve host");
141}
142
145{
146 switch (IpAddresses[0])
147 {
148 case 0: return 0;
149 case 1: return -1;
150 default: return 1;
151 }
152}
153
156{
157 check(Socket.IsValid());
158
160
161 if (IsResolved() <= 0)
162 {
164 {
165 return Outcome;
166 }
167 }
168
169 check(IsResolved() > 0);
170
172
173 // Attempt a SOCKS connect
174 Outcome = MaybeConnectSocks(Socket, IpAddress, Port);
175 if (Outcome.IsError())
176 {
177 return Outcome;
178 }
179 check(Outcome.IsOk());
180 bool bSocksConnected = (Outcome.GetResult() == 1);
181
182 // Condition the socket
183 if (!Socket.SetBlocking(false))
184 {
185 return FOutcome::Error("Unable to set socket non-blocking");
186 }
187
189 {
190 Socket.SetSendBufSize(OptValue);
191 }
192
194 {
195 Socket.SetRecvBufSize(OptValue);
196 }
197
198 // Socks connect in a blocking fashion so we're all set (ret=1)
199 if (bSocksConnected)
200 {
201 return FOutcome::Ok();
202 }
203
204 // Issue the connect - this is done non-blocking so we need to wait (ret=0)
205 if (Outcome = Socket.Connect(IpAddress, Port); Outcome.IsError())
206 {
207 return Outcome;
208 }
209
210 return Outcome;
211}
212
213
214
217{
218 FUrlOffsets Offsets;
219 if (ParseUrl(Url, Offsets) < 0)
220 {
221 return -1;
222 }
223
224 HostName = Offsets.HostName.Get(Url);
225
227 if (Offsets.SchemeLength == 5)
228 {
230 }
231
232 if (Offsets.Port)
233 {
234 FAnsiStringView PortView = Offsets.Port.Get(Url);
235 Port = uint16(CrudeToInt(PortView));
236 }
237
238 return Offsets.Path;
239}
240
243{
244 check(Params.ConnectionCount - 1u <= 63u);
245 check(Params.Port <= 0xffffu);
246 check(Params.HttpVersion != EHttpVersion::Two || Params.ConnectionCount == 1); // only one as per rfc9113
247
248 // Alloc a new internal object
249 uint32 HostNameLen = Params.HostName.Len();
250 uint32 AllocSize = sizeof(FHost) + (HostNameLen + 1);
251 auto* Internal = (FHost*)FMemory::Malloc(AllocSize, alignof(FHost));
252
253 // Copy host
254 char* HostDest = (char*)(Internal + 1);
255 memcpy(HostDest, Params.HostName.GetData(), HostNameLen);
256 HostDest[HostNameLen] = '\0';
257
258 // Init internal object
259 new (Internal) FHost({
260 .HostName = HostDest,
261 .Port = Params.Port,
262 .MaxConnections = Params.ConnectionCount,
263 .bPooled = true,
264 .MaxInflight = Params.MaxInflight,
265 .HttpVersion = Params.HttpVersion,
266 .VerifyCert = Params.VerifyCert,
267 });
268 Internal->SetBufferSize(FHost::EDirection::Send, Params.SendBufSize);
269 Internal->SetBufferSize(FHost::EDirection::Recv, Params.RecvBufSize);
270
271 Ptr = Internal;
272}
273
276{
277 if (Ptr != nullptr)
278 {
279 FMemory::Free(Ptr);
280 }
281}
282
285{
286 return Ptr->ResolveHostName().IsOk();
287}
288
291{
292 const FAnsiStringView HostName = Ptr->GetHostName();
293 OutString.Appendf("%.*s", HostName.Len(), HostName.GetData());
294 if (!!Ptr->IsResolved())
295 {
296 const auto IpAddress = Ptr->GetIpAddress();
297 OutString.Appendf(" (%u.%u.%u.%u)",
298 (IpAddress >> 24) & 0xff,
299 (IpAddress >> 16) & 0xff,
300 (IpAddress >> 8) & 0xff,
301 IpAddress & 0xff
302 );
303 }
304 else
305 {
306 OutString.Append(" (unresolved)");
307 }
308}
309
312{
313 FUrlOffsets Tmp;
314 return ParseUrl(Url, Tmp) >= 0;
315}
316
317} // namespace UE::IoStore::HTTP
318
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int16 int16
A 16-bit signed integer.
Definition Platform.h:1123
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::ANSICHAR ANSICHAR
An ANSI character. Normally a signed type.
Definition Platform.h:1131
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define TRACE_CPUPROFILER_EVENT_SCOPE(Name)
Definition CpuProfilerTrace.h:528
#define ON_SCOPE_EXIT
Definition ScopeExit.h:73
#define UE_ARRAY_COUNT(array)
Definition UnrealTemplate.h:212
uint32 Size
Definition VulkanMemory.cpp:4034
memcpy(InputBufferBase, BinkBlocksData, BinkBlocksSize)
uint8_t uint8
Definition binka_ue_file_header.h:8
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition StringBuilder.h:79
BuilderType & Appendf(const FmtType &Fmt, Types... Args)
Definition StringBuilder.h:419
BuilderType & Append(const OtherCharType *const String, const int32 Length)
Definition StringBuilder.h:238
constexpr int32 Len() const
Definition StringView.h:174
constexpr const CharType * GetData() const
Definition StringView.h:160
static UE_API FCertRootsRef NoTls()
Definition Peer.inl:400
static UE_API FCertRootsRef Default()
Definition Peer.inl:406
UE_API bool Resolve()
Definition ConnectionPool.inl:284
static UE_API bool IsValidHostUrl(FAnsiStringView Url)
Definition ConnectionPool.inl:311
UE_API void Describe(FAnsiStringBuilderBase &) const
Definition ConnectionPool.inl:290
UE_API ~FConnectionPool()
Definition ConnectionPool.inl:275
Definition ConnectionPool.inl:10
EDirection
Definition ConnectionPool.inl:12
int32 GetBufferSize(EDirection Dir) const
Definition ConnectionPool.inl:79
void SetBufferSize(EDirection Dir, int32 Size)
Definition ConnectionPool.inl:73
uint32 GetMaxConnections() const
Definition ConnectionPool.inl:33
uint32 GetMaxInflight() const
Definition ConnectionPool.inl:34
FOutcome Connect(FSocket &Socket)
Definition ConnectionPool.inl:155
int32 IsResolved() const
Definition ConnectionPool.inl:144
uint32 GetPort() const
Definition ConnectionPool.inl:39
FCertRootsRef GetVerifyCert() const
Definition ConnectionPool.inl:32
EHttpVersion GetHttpVersion() const
Definition ConnectionPool.inl:35
uint32 GetIpAddress() const
Definition ConnectionPool.inl:37
bool IsPooled() const
Definition ConnectionPool.inl:36
FOutcome ResolveHostName()
Definition ConnectionPool.inl:85
static const uint32 InvalidIp
Definition ConnectionPool.inl:13
FHost(const FParams &Params)
Definition ConnectionPool.inl:55
FAnsiStringView GetHostName() const
Definition ConnectionPool.inl:38
Definition Misc.inl:73
static FOutcome Ok(int32 Result=0)
Definition Misc.inl:113
bool IsError() const
Definition Misc.inl:81
bool IsOk() const
Definition Misc.inl:86
static FOutcome Error(const char *Message, int32 Code=-1)
Definition Misc.inl:151
static FOutcome None()
Definition Misc.inl:80
Definition Socket.inl:367
Definition HttpServerHttpVersion.h:7
Definition ByteSwap.h:14
Definition Client.h:20
EHttpVersion
Definition Client.h:24
UPTRINT FCertRootsRef
Definition Client.h:56
uint32 Socket_HtoNl(uint32 v)
Definition Socket.inl:116
static FORCENOINLINE CORE_API void Free(void *Original)
Definition UnrealMemory.cpp:685
static const FCertRootsRef None
Definition Peer.inl:30
UE_API int32 SetHostFromUrl(FAnsiStringView Url)
Definition ConnectionPool.inl:216
FCertRootsRef VerifyCert
Definition Client.h:92
FAnsiStringView HostName
Definition Client.h:91
uint32 Port
Definition Client.h:95
Definition ConnectionPool.inl:16
uint8 MaxInflight
Definition ConnectionPool.inl:21
FCertRootsRef VerifyCert
Definition ConnectionPool.inl:23
uint32 Port
Definition ConnectionPool.inl:18
bool bPooled
Definition ConnectionPool.inl:20
uint16 MaxConnections
Definition ConnectionPool.inl:19
const ANSICHAR * HostName
Definition ConnectionPool.inl:17
FAnsiStringView Get(FAnsiStringView Url) const
Definition Misc.inl:208
Definition Misc.inl:203
Slice Port
Definition Misc.inl:216
Slice HostName
Definition Misc.inl:215
uint8 SchemeLength
Definition Misc.inl:218
uint8 Path
Definition Misc.inl:217