19#include "AUI/IO/AEOFException.h"
20#include "AUI/IO/IInputStream.h"
21#include "AUI/Traits/values.h"
22#include "AFormMultipart.h"
23#include <AUI/IO/APipe.h>
24#include <AUI/Common/AByteBufferView.h>
25#include <AUI/Common/AByteBuffer.h>
26#include <AUI/Common/ASignal.h>
27#include <AUI/Reflect/AEnumerate.h>
28#include <AUI/Thread/AFuture.h>
52 VERSION_2_PRIOR_KNOWLEDGE,
59 enum class ResponseCode {
60 HTTP_100_CONTINUE = 100,
61 HTTP_101_SWITCHING_PROTOCOL = 101,
62 HTTP_102_PROCESSING = 102,
63 HTTP_103_EARLY_HINTS = 103,
65 HTTP_201_CREATED = 201,
66 HTTP_202_ACCEPTED = 202,
67 HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203,
68 HTTP_204_NO_CONTENT = 204,
69 HTTP_205_RESET_CONTENT = 205,
70 HTTP_206_PARTIAL_CONTENT = 206,
71 HTTP_300_MULTIPLE_CHOICE = 300,
72 HTTP_301_MOVED_PERMANENTLY = 301,
74 HTTP_303_SEE_OTHER = 303,
75 HTTP_304_NOT_MODIFIED = 304,
76 HTTP_305_USE_PROXY = 305,
77 HTTP_306_SWITCH_PROXY = 306,
78 HTTP_307_TEMPORARY_REDIRECT = 307,
79 HTTP_308_PERMANENT_REDIRECT = 308,
80 HTTP_400_BAD_REQUEST = 400,
81 HTTP_401_UNAUTHORIZED = 401,
82 HTTP_402_PAYMENT_REQUIRED = 402,
83 HTTP_403_FORBIDDEN = 403,
84 HTTP_404_NOT_FOUND = 404,
85 HTTP_405_METHOD_NOT_ALLOWED = 405,
86 HTTP_406_NOT_ACCEPTABLE = 406,
87 HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407,
88 HTTP_408_REQUEST_TIMEOUT = 408,
89 HTTP_409_CONFLICT = 409,
91 HTTP_411_LENGTH_REQUIRED = 411,
92 HTTP_412_PRECONDITION_FAILED = 412,
93 HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413,
94 HTTP_414_REQUEST_URI_TOO_LONG = 414,
95 HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415,
96 HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416,
97 HTTP_417_EXPECTATION_FAILED = 417,
98 HTTP_500_INTERNAL_SERVER_ERROR = 500,
99 HTTP_501_NOT_IMPLEMENTED = 501,
100 HTTP_502_BAD_GATEWAY = 502,
101 HTTP_503_SERVICE_UNAVAILABLE = 503,
102 HTTP_504_GATEWAY_TIMEOUT = 504,
103 HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505,
129 void throwException()
const;
154 using ReadCallback = std::function<std::size_t(
char* dst,
size_t maxLen)>;
156 using ErrorCallback = std::function<void(
const ErrorDescription& description)>;
161 using AIOException::AIOException;
163 mCurlStatus(errorDescription.curlStatus) {
168 int curlStatus()
const noexcept {
182 ErrorCallback mErrorCallback;
183 HeaderCallback mHeaderCallback;
184 bool mThrowExceptionOnError =
false;
187 Method mMethod = Method::HTTP_GET;
188 std::function<void(
ACurl&)> mOnSuccess;
202 AUI_ASSERTX(mWriteCallback ==
nullptr,
"write callback already set");
203 mWriteCallback = std::move(callback);
214 withInputStream(multipart.makeInputStream());
215 mHeaders.push_back(
"Content-Type: multipart/form-data; boundary={}"_format(multipart.boundary()));
225 AUI_ASSERTX(mReadCallback ==
nullptr,
"write callback already set");
226 mReadCallback = std::move(callback);
236 withBody([inputStream = std::move(inputStream)](
char* dst, std::size_t length) {
237 auto v = inputStream->read(dst, length);
250 Builder& withTimeout(std::chrono::seconds timeout);
256 AUI_ASSERTX(mReadCallback ==
nullptr,
"write callback already set");
259 explicit Body(std::string b) : contents(std::move(b)), i(contents.begin()) {}
261 std::string contents;
262 std::string::iterator i;
264 auto b = _new<Body>(std::move(contents));
266 mReadCallback = [body = std::move(b)](
char* dst, std::size_t length)
mutable {
267 if (body->i == body->contents.end()) {
270 std::size_t remaining = std::distance(body->i, body->contents.end());
271 length = glm::min(length, remaining);
272 std::memcpy(dst, &*body->i, length);
286 mHeaderCallback = std::move(headerCallback);
294 AUI_ASSERTX(mErrorCallback ==
nullptr,
"error callback already set");
295 mErrorCallback = std::move(callback);
313 Builder& throwExceptionOnError(
bool throwExceptionOnError)
noexcept {
314 mThrowExceptionOnError = throwExceptionOnError;
325 Builder& withRanges(
size_t begin,
size_t end);
335 return withRanges(begin, 0);
343 Builder& withLowSpeedLimit(
size_t speed);
350 Builder& withLowSpeedTime(std::chrono::seconds duration);
353 Builder& withHttpVersion(Http version);
354 Builder& withUpload(
bool upload);
356 Builder& withOnSuccess(std::function<
void(
ACurl&)> onSuccess) {
357 mOnSuccess = std::move(onSuccess);
361 template<aui::invocable OnSuccess>
362 Builder& withOnSuccess(OnSuccess&& onSuccess) {
363 mOnSuccess = [onSuccess = std::forward<OnSuccess>(onSuccess)](
ACurl&) {
388 Builder& withParams(
const AVector<std::pair<AString /* key */, AString /* value */>>& params);
398 mParams = std::move(params);
403 mHeaders = std::move(headers);
413 _unique<IInputStream> toInputStream();
421 Response runBlocking();
436 explicit ACurl(Builder& builder):
437 ACurl(std::move(builder))
441 explicit ACurl(Builder&& builder)
noexcept {
442 operator=(std::move(builder));
445 operator=(std::move(o));
450 ACurl& operator=(Builder&& o)
noexcept;
453 int64_t getContentLength()
const;
454 int64_t getNumberOfBytesDownloaded()
const;
455 AString getContentType()
const;
473 virtual void close();
476 void* handle() const noexcept {
481 ResponseCode getResponseCode()
const;
484 AString getErrorString() const noexcept {
485 return AString::fromLatin1(mErrorBuffer);
490 struct curl_slist* mCurlHeaders =
nullptr;
491 char mErrorBuffer[256];
492 bool mCloseRequested =
false;
493 std::string mPostFieldsStorage;
495 static size_t writeCallback(
char* ptr,
size_t size,
size_t nmemb,
void* userdata)
noexcept;
496 static size_t readCallback(
char* ptr,
size_t size,
size_t nmemb,
void* userdata)
noexcept;
497 static size_t headerCallback(
char *buffer,
size_t size,
size_t nitems,
void *userdata)
noexcept;
499 WriteCallback mWriteCallback;
500 ReadCallback mReadCallback;
501 HeaderCallback mHeaderCallback;
503 void reportSuccess() {
507 void reportFail(
int statusCode) {
508 emit fail(ErrorDescription{statusCode, AString::fromLatin1(mErrorBuffer)});
511 template<
typename Ret>
512 Ret getInfo(
int curlInfo)
const;
537 ACurl::ResponseCode::HTTP_100_CONTINUE,
538 ACurl::ResponseCode::HTTP_101_SWITCHING_PROTOCOL,
539 ACurl::ResponseCode::HTTP_102_PROCESSING,
540 ACurl::ResponseCode::HTTP_103_EARLY_HINTS,
541 ACurl::ResponseCode::HTTP_200_OK,
542 ACurl::ResponseCode::HTTP_201_CREATED,
543 ACurl::ResponseCode::HTTP_202_ACCEPTED,
544 ACurl::ResponseCode::HTTP_203_NON_AUTHORITATIVE_INFORMATION,
545 ACurl::ResponseCode::HTTP_204_NO_CONTENT,
546 ACurl::ResponseCode::HTTP_205_RESET_CONTENT,
547 ACurl::ResponseCode::HTTP_206_PARTIAL_CONTENT,
548 ACurl::ResponseCode::HTTP_300_MULTIPLE_CHOICE,
549 ACurl::ResponseCode::HTTP_301_MOVED_PERMANENTLY,
550 ACurl::ResponseCode::HTTP_302_FOUND,
551 ACurl::ResponseCode::HTTP_303_SEE_OTHER,
552 ACurl::ResponseCode::HTTP_304_NOT_MODIFIED,
553 ACurl::ResponseCode::HTTP_305_USE_PROXY,
554 ACurl::ResponseCode::HTTP_306_SWITCH_PROXY,
555 ACurl::ResponseCode::HTTP_307_TEMPORARY_REDIRECT,
556 ACurl::ResponseCode::HTTP_308_PERMANENT_REDIRECT,
557 ACurl::ResponseCode::HTTP_400_BAD_REQUEST,
558 ACurl::ResponseCode::HTTP_401_UNAUTHORIZED,
559 ACurl::ResponseCode::HTTP_402_PAYMENT_REQUIRED,
560 ACurl::ResponseCode::HTTP_403_FORBIDDEN,
561 ACurl::ResponseCode::HTTP_404_NOT_FOUND,
562 ACurl::ResponseCode::HTTP_405_METHOD_NOT_ALLOWED,
563 ACurl::ResponseCode::HTTP_406_NOT_ACCEPTABLE,
564 ACurl::ResponseCode::HTTP_407_PROXY_AUTHENTICATION_REQUIRED,
565 ACurl::ResponseCode::HTTP_408_REQUEST_TIMEOUT,
566 ACurl::ResponseCode::HTTP_409_CONFLICT,
567 ACurl::ResponseCode::HTTP_410_GONE,
568 ACurl::ResponseCode::HTTP_411_LENGTH_REQUIRED,
569 ACurl::ResponseCode::HTTP_412_PRECONDITION_FAILED,
570 ACurl::ResponseCode::HTTP_413_REQUEST_ENTITY_TOO_LARGE,
571 ACurl::ResponseCode::HTTP_414_REQUEST_URI_TOO_LONG,
572 ACurl::ResponseCode::HTTP_415_UNSUPPORTED_MEDIA_TYPE,
573 ACurl::ResponseCode::HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE,
574 ACurl::ResponseCode::HTTP_417_EXPECTATION_FAILED,
575 ACurl::ResponseCode::HTTP_500_INTERNAL_SERVER_ERROR,
576 ACurl::ResponseCode::HTTP_501_NOT_IMPLEMENTED,
577 ACurl::ResponseCode::HTTP_502_BAD_GATEWAY,
578 ACurl::ResponseCode::HTTP_503_SERVICE_UNAVAILABLE,
579 ACurl::ResponseCode::HTTP_504_GATEWAY_TIMEOUT,
580 ACurl::ResponseCode::HTTP_505_HTTP_VERSION_NOT_SUPPORTED)
Acts like std::string_view but for AByteBuffer.
Definition: AByteBufferView.h:24
std::vector-like growing array for byte storage.
Definition: AByteBuffer.h:31
Multi curl instance.
Definition: ACurlMulti.h:44
Builder & withMultipart(const AFormMultipart &multipart)
Add multipart data.
Definition: ACurl.h:213
Builder & withBody(std::string contents)
Like withBody with callback, but wrapped with string.
Definition: ACurl.h:255
Builder & withWriteCallback(WriteCallback callback)
Called on server -> client data received (download).
Definition: ACurl.h:201
Builder & withParams(AString params) noexcept
Sets HTTP params to the query.
Definition: ACurl.h:397
Builder & withErrorCallback(ErrorCallback callback)
Definition: ACurl.h:293
Builder & withHeaderCallback(HeaderCallback headerCallback)
Called on header received.
Definition: ACurl.h:285
Builder & withInputStream(_< IInputStream > inputStream)
Called on client -> server data requested (upload).
Definition: ACurl.h:235
Builder & withBody(ReadCallback callback)
Called on client -> server data requested (upload).
Definition: ACurl.h:224
Builder & withMethod(Method method) noexcept
Sets HTTP method to the query.
Definition: ACurl.h:374
Builder & withRanges(size_t begin)
Sets: Accept-Ranges: begin-end (download part of the file)
Definition: ACurl.h:334
Easy curl instance.
Definition: ACurl.h:41
std::function< size_t(AByteBufferView data)> WriteCallback
A read callback.
Definition: ACurl.h:142
emits success
Emitted on success.
Definition: ACurl.h:529
emits< ErrorDescription > fail
Emitted on network error.
Definition: ACurl.h:522
std::function< std::size_t(char *dst, size_t maxLen)> ReadCallback
A read callback.
Definition: ACurl.h:154
Thrown when stream has reached end (end of file).
Definition: AEOFException.h:20
Represents a value that will be available at some point in the future.
Definition: AFuture.h:620
Exception caused by input/output stream.
Definition: AIOException.h:22
A base object class.
Definition: AObject.h:49
Represents a Unicode character string.
Definition: AString.h:37
An std::weak_ptr with AUI extensions.
Definition: SharedPtrTypes.h:177
Avoids copy of the wrapped value, pointing to a reference.
Definition: values.h:379
#define emit
emits the specified signal in context of this object.
Definition: AObject.h:196
#define AUI_ASSERTX(condition, what)
Asserts that the passed condition evaluates to true. Adds extra message string.
Definition: Assert.h:74
AUI_ENUM_VALUES(ATextOverflow, ATextOverflow::ELLIPSIS, ATextOverflow::CLIP) enum class AOverflowMask
Controls the behaviour of the default AView::drawStencilMask() implementation.
Definition: AOverflow.h:55
Response struct for Builder::runBlocking() and Builder::runAsync()
Definition: ACurl.h:118