5#include "../Foundation/Compiler.h"
6#ifndef SC_EXPORT_LIBRARY_HTTP_CLIENT
7#define SC_EXPORT_LIBRARY_HTTP_CLIENT 0
9#define SC_HTTP_CLIENT_EXPORT SC_COMPILER_LIBRARY_EXPORT(SC_EXPORT_LIBRARY_HTTP_CLIENT)
11#include "../Foundation/Result.h"
12#include "../Foundation/Span.h"
13#include "../Foundation/StringSpan.h"
14#include "Internal/HttpClientThreading.h"
21struct SC_HTTP_CLIENT_EXPORT HttpClientRequestBodyProvider;
22struct SC_HTTP_CLIENT_EXPORT HttpClientRequestOptions;
53 [[nodiscard]]
bool isIdentity()
const {
return type == Identity; }
54 [[nodiscard]]
static Type parseName(
StringSpan name);
55 [[nodiscard]]
static const char* getName(Type type);
64 size_t valueOffset = 0;
65 bool hasHeaderValue =
false;
83 [[nodiscard]]
bool isChunked()
const {
return type == Chunked; }
84 [[nodiscard]]
static Type parseName(
StringSpan name);
85 [[nodiscard]]
static const char* getName(Type type);
93 size_t valueOffset = 0;
94 bool hasHeaderValue =
false;
110 MultipleOperationsPerClient,
112 SizedStreamRequestBody,
113 ChunkedStreamRequestBody,
116 ProtocolHttp2Preferred,
117 ProtocolHttp2Required,
118 TlsDisablePeerVerification,
127 Backend backend = Unsupported;
129 bool multipleOperationsPerClient =
false;
130 bool fixedRequestBody =
false;
131 bool sizedStreamRequestBody =
false;
132 bool chunkedStreamRequestBody =
false;
133 bool redirectPolicy =
false;
134 bool protocolHttp11Only =
false;
135 bool protocolHttp2Preferred =
false;
136 bool protocolHttp2Required =
false;
137 bool tlsDisablePeerVerification =
false;
138 bool tlsCustomCaPath =
false;
139 bool proxyNoProxy =
false;
140 bool proxyHttp =
false;
141 bool proxyAuthorization =
false;
142 bool proxyBypassList =
false;
143 bool contentCodingPolicy =
false;
145 [[nodiscard]]
bool hasBackend(Backend requiredBackend)
const;
146 [[nodiscard]]
bool supports(Feature feature)
const;
149 [[nodiscard]]
Result requireBackend(Backend requiredBackend)
const;
152 [[nodiscard]]
const char* getBackendName()
const;
153 [[nodiscard]]
static const char* getBackendName(Backend backend);
154 [[nodiscard]]
static const char* getFeatureName(Feature feature);
175 bool canReplay =
false;
179 [[nodiscard]]
bool isStreamed()
const {
return framing == SizedStream or framing == ChunkedStream; }
180 [[nodiscard]]
bool isChunkedStream()
const {
return framing == ChunkedStream; }
181 [[nodiscard]]
const char* getFramingName()
const {
return getFramingName(framing); }
182 [[nodiscard]]
static const char* getFramingName(Framing framing);
183 [[nodiscard]]
uint64_t getDeclaredSizeInBytes()
const
185 if (framing == FixedSize)
187 return static_cast<uint64_t>(bytes.sizeInBytes());
189 return framing == SizedStream ? sizeInBytes : 0;
203 Mode mode = NoRedirects;
206 [[nodiscard]]
const char* getModeName()
const {
return getModeName(mode); }
207 [[nodiscard]]
static const char* getModeName(Mode mode);
219 bool verifyPeer =
true;
234 Preference preference = Default;
236 [[nodiscard]]
const char* getPreferenceName()
const {
return getPreferenceName(preference); }
237 [[nodiscard]]
static const char* getPreferenceName(Preference preference);
255 [[nodiscard]]
const char* getModeName()
const {
return getModeName(mode); }
256 [[nodiscard]]
static const char* getModeName(Mode mode);
286 Method method = HttpGET;
294 [[nodiscard]]
const char* getMethodName()
const {
return getMethodName(method); }
295 [[nodiscard]]
static const char* getMethodName(Method method);
296 [[nodiscard]]
Result validate()
const;
315 size_t headersLength = 0;
316 Protocol negotiatedProtocol = Protocol::Unknown;
321 [[nodiscard]]
bool hasHeader(
StringSpan name)
const;
325 [[nodiscard]]
bool getContentLength(
uint64_t& value)
const;
326 [[nodiscard]]
bool getContentType(
StringSpan& value)
const;
327 [[nodiscard]]
bool getContentEncoding(
StringSpan& value)
const;
328 [[nodiscard]]
bool getTransferEncoding(
StringSpan& value)
const;
329 [[nodiscard]]
bool getLocation(
StringSpan& value)
const;
330 [[nodiscard]]
bool getWwwAuthenticate(
StringSpan& value)
const;
331 [[nodiscard]]
bool getProxyAuthenticate(
StringSpan& value)
const;
336 [[nodiscard]]
bool hasContentCoding(HttpClientContentCoding::Type type)
const;
337 [[nodiscard]]
bool hasTransferCoding(HttpClientTransferCoding::Type type)
const;
338 [[nodiscard]]
bool isHttp11()
const {
return negotiatedProtocol == Protocol::Http11; }
339 [[nodiscard]]
bool isHttp2()
const {
return negotiatedProtocol == Protocol::Http2; }
340 [[nodiscard]]
bool isInformationalStatus()
const {
return statusCode >= 100 and statusCode < 200; }
341 [[nodiscard]]
bool isSuccessfulStatus()
const {
return statusCode >= 200 and statusCode < 300; }
342 [[nodiscard]]
bool isRedirectStatus()
const {
return statusCode >= 300 and statusCode < 400; }
343 [[nodiscard]]
bool isClientErrorStatus()
const {
return statusCode >= 400 and statusCode < 500; }
344 [[nodiscard]]
bool isServerErrorStatus()
const {
return statusCode >= 500 and statusCode < 600; }
345 [[nodiscard]]
bool isErrorStatus()
const {
return statusCode >= 400; }
346 [[nodiscard]]
const char* getProtocolName()
const {
return getProtocolName(negotiatedProtocol); }
347 [[nodiscard]]
static const char* getProtocolName(Protocol protocol);
384struct SC_HTTP_CLIENT_EXPORT HttpClientOperation;
417 Type type = Type::ResponseHead;
419 size_t bufferIndex = 0;
444#pragma warning(disable : 4324)
456 [[nodiscard]]
Result init();
457 [[nodiscard]]
Result init(HttpClientCapabilities::Backend requiredBackend);
459 [[nodiscard]]
Result init(HttpClientCapabilities::Backend requiredBackend,
461 [[nodiscard]]
Result close();
464 [[nodiscard]]
bool isInitialized()
const {
return initialized; }
480 friend struct Internal;
481 friend struct HttpClientLinuxCallbacks;
487 bool initialized =
false;
490 alignas(
uint64_t)
char storage[128];
491#elif SC_PLATFORM_WINDOWS
492 alignas(
uint64_t)
char storage[128];
493#elif SC_PLATFORM_LINUX
494 alignas(
uint64_t)
char storage[512];
512 [[nodiscard]]
Result close();
513 [[nodiscard]]
Result cancel();
532 [[nodiscard]]
bool isInitialized()
const {
return initialized; }
533 [[nodiscard]]
bool isRequestInFlight()
const {
return requestInFlight; }
535 friend struct Internal;
539 friend struct HttpClientAppleCallbacks;
540 friend struct HttpClientLinuxCallbacks;
541 friend struct HttpClientWindowsCallbacks;
543 Result platformInit();
544 Result platformClose();
545 Result platformStart();
546 Result platformCancel();
548 Result enqueueEvent(
const HttpClientOperationEvent& event);
549 bool dequeueEvent(HttpClientOperationEvent& event);
551 Result allocateResponseBuffer(
size_t minimumSizeInBytes,
size_t& bufferIndex, Span<char>& data);
552 void releaseResponseBuffer(
size_t bufferIndex);
553 Result enqueueResponseDataCopy(Span<const char> data);
555 void enqueueResponseHead();
556 void enqueueResponseBuffer(
size_t bufferIndex,
size_t size);
557 void enqueueResponseComplete();
558 void enqueueError(Result error);
560 void resetResponseState(HttpClientResponse& response);
561 void resetRequestBodyState();
562 bool isAutomaticRedirectEnabled()
const;
563 bool canAutomaticRedirectRequestReplay()
const;
564 Result copyResponseEffectiveUrl(StringSpan url);
566 size_t readRequestBodyChunk(Span<char> dest, Result& outError,
bool& outEnd);
567 bool hasPendingEvents()
const;
568 Result processPendingEvents();
570 HttpClient* client =
nullptr;
571 HttpClientResponse* currentResponse =
nullptr;
572 HttpClientOperationListener* currentListener =
nullptr;
573 HttpClientOperationNotifier* notifier =
nullptr;
574 HttpClientRequest currentRequest;
576 Span<HttpClientResponseBuffer> responseBuffers;
577 Span<HttpClientOperationEvent> eventQueue;
579 Span<char> responseHeaders;
580 Span<char> responseMetadata;
581 Span<char> backendScratch;
583 mutable HttpClientLocalMutex eventMutex;
584 HttpClientLocalConditionVariable eventCV;
585 HttpClientOperationEvent dequeuedEvent;
587 size_t eventHead = 0;
588 size_t eventTail = 0;
589 size_t eventCount = 0;
590 bool requestBodyFinished =
false;
591 Result requestBodyError = Result(
true);
593 bool initialized =
false;
594 bool requestInFlight =
false;
597 alignas(
uint64_t)
char storage[512];
598#elif SC_PLATFORM_WINDOWS
599 alignas(
uint64_t)
char storage[256];
600#elif SC_PLATFORM_LINUX
601 alignas(
uint64_t)
char storage[512];
#define SC_COMPILER_UNUSED(param)
Silence an unused variable or unused parameter warning.
Definition Compiler.h:169
unsigned char uint8_t
Platform independent (1) byte unsigned int.
Definition PrimitiveTypes.h:27
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition PrimitiveTypes.h:33
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:29
Compile-time backend capability report for the active HttpClient backend.
Definition HttpClient.h:99
Caller-owned cursor for iterating comma-separated Content-Encoding values.
Definition HttpClient.h:61
Parsed response content-coding token view.
Definition HttpClient.h:39
Event slot storage used by HttpClientOperation to hand off backend notifications.
Definition HttpClient.h:408
Listener receiving response notifications during HttpClientOperation::poll.
Definition HttpClient.h:365
virtual void onError(Result error)
Called when the request fails.
Definition HttpClient.h:381
virtual void onResponseComplete()
Called when the response body completed successfully.
Definition HttpClient.h:377
virtual void onResponseHead(HttpClientResponse &response)
Called once the response status code and headers are available.
Definition HttpClient.h:370
virtual void onResponseBody(Span< const char > data)
Called for each response body chunk delivered by poll()
Definition HttpClient.h:374
Caller-owned memory for one HttpClientOperation.
Definition HttpClient.h:431
Span< char > responseBufferMemory
Optional; split equally into responseBuffers if non-empty.
Definition HttpClient.h:435
Optional notifier used by external adapters to wake up their own event loop.
Definition HttpClient.h:388
virtual void notifyHttpClientOperation(HttpClientOperation &operation)=0
Notifies an external adapter that the operation has queued new events.
One in-flight HTTP request/response operation.
Definition HttpClient.h:502
void setNotifier(HttpClientOperationNotifier *notifierValue)
Registers an optional notifier used by adapters such as HttpClientAsyncT.
Definition HttpClient.h:530
Result start(const HttpClientRequest &request, HttpClientResponse &response, HttpClientOperationListener *listener=nullptr)
Starts a new request on this operation.
Result poll(uint32_t timeoutMilliseconds=0)
Processes queued backend events and optionally waits for more work.
Pull-based provider for streamed request bodies.
Definition HttpClient.h:352
virtual Result pullRequestBody(Span< char > dest, size_t &bytesWritten, bool &endReached)=0
Writes the next request body chunk in dest.
Outgoing request body description.
Definition HttpClient.h:159
Framing
Transfer framing requested for the outgoing body.
Definition HttpClient.h:165
Extended request options grouped by transport concern.
Definition HttpClient.h:261
HTTP protocol preference for one request.
Definition HttpClient.h:225
Proxy policy for one request.
Definition HttpClient.h:242
StringSpan authorization
Optional exact Proxy-Authorization header value for Http
Definition HttpClient.h:252
StringSpan url
Required for Http, must use the http:// scheme.
Definition HttpClient.h:251
Mode
Definition HttpClient.h:244
@ NoProxy
Bypass proxies for this request.
Definition HttpClient.h:246
@ Default
Use the backend default proxy configuration.
Definition HttpClient.h:245
@ Http
Use url as an explicit HTTP proxy URL.
Definition HttpClient.h:247
StringSpan bypassList
Optional comma-separated proxy bypass list for Http
Definition HttpClient.h:253
Redirect handling policy for one request.
Definition HttpClient.h:195
Timeout policy for one request.
Definition HttpClient.h:212
TLS policy for one request.
Definition HttpClient.h:218
Configuration for an outgoing HTTP request.
Definition HttpClient.h:274
StringSpan url
Full URL including scheme (e.g. "https://example.com/path")
Definition HttpClient.h:288
Caller-owned response buffer descriptor for one HttpClientOperation.
Definition HttpClient.h:398
Parsed response metadata filled when headers arrive.
Definition HttpClient.h:303
Caller-owned cursor for iterating comma-separated Transfer-Encoding values.
Definition HttpClient.h:90
Parsed response transfer-coding token view.
Definition HttpClient.h:70
Reusable HTTP backend/session owner.
Definition HttpClient.h:447
static Result executeBlocking(const HttpClientRequest &request, HttpClientResponse &response, Span< char > bodyBuffer, size_t &bodyLength, const HttpClientOperationMemory &memory)
Convenience helper executing a request synchronously on top of HttpClientOperation::poll.
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition Result.h:13
View over a contiguous sequence of items (pointer + size in elements).
Definition Span.h:29
An read-only view over a string (to avoid including Strings library when parsing is not needed).
Definition StringSpan.h:37