@@ -21,14 +21,10 @@ HttpRequest::HttpRequest(Method aMethod, const std::string &aUrl, const std::str
2121// HttpFuture implementation
2222HttpFuture::HttpFuture (std::future<HttpResponse> aFuture)
2323 : mFuture(std::move(aFuture)),
24- mResponseCallback(nullptr ),
25- mErrorCallback(nullptr ),
26- mIsBlocking(false ),
2724 mReturnCodeDefaultCallback(nullptr ) {}
2825
2926std::shared_ptr<HttpFuture> HttpFuture::onReturnCode (int aCode, ResponseCallback aCallback) {
3027 mReturnCodeCallbacks [aCode] = aCallback;
31- checkAndInvoke ();
3228 return shared_from_this ();
3329}
3430
@@ -37,88 +33,14 @@ std::shared_ptr<HttpFuture> HttpFuture::onReturnCode(const std::vector<int> &aCo
3733 for (int aCode : aCodes) {
3834 mReturnCodeCallbacks [aCode] = aCallback;
3935 }
40- checkAndInvoke ();
4136 return shared_from_this ();
4237}
4338
4439std::shared_ptr<HttpFuture> HttpFuture::onOtherReturnCode (ResponseCallback aCallback) {
4540 mReturnCodeDefaultCallback = aCallback;
46- checkAndInvoke ();
4741 return shared_from_this ();
4842}
4943
50- std::shared_ptr<HttpFuture> HttpFuture::onResponse (ResponseCallback aCallback) {
51- mResponseCallback = aCallback;
52- checkAndInvoke ();
53- return shared_from_this ();
54- }
55-
56- std::shared_ptr<HttpFuture> HttpFuture::onError (ErrorCallback aCallback) {
57- mErrorCallback = aCallback;
58- checkAndInvoke ();
59- return shared_from_this ();
60- }
61-
62- std::shared_ptr<HttpFuture> HttpFuture::then (ResponseCallback aOnResponse, ErrorCallback aOnError) {
63- mResponseCallback = aOnResponse;
64- mErrorCallback = aOnError;
65- checkAndInvoke ();
66- return shared_from_this ();
67- }
68-
69- std::shared_ptr<HttpFuture> HttpFuture::flatMap (TransformCallback aTransform) {
70- // If future is ready, transform immediately
71- if (mFuture .valid () &&
72- mFuture .wait_for (std::chrono::seconds (0 )) == std::future_status::ready) {
73- // Note: exceptions are not used here. If the transform callable throws
74- // and exceptions are disabled, the program will terminate. Callers
75- // should avoid throwing from transform when building without
76- // exceptions (ESP builds).
77- HttpResponse aResp = mFuture .get ();
78- return aTransform (aResp);
79- }
80-
81- // Otherwise, chain the transformation
82- std::shared_ptr<HttpFuture> aSelf = shared_from_this ();
83- onResponse ([aSelf, aTransform](const HttpResponse &aResp) {
84- auto aNextFuture = aTransform (aResp);
85- if (aNextFuture) {
86- // Propagate callbacks to next future if needed
87- // (callbacks are already set on the returned future)
88- }
89- });
90-
91- return shared_from_this ();
92- }
93-
94- std::shared_ptr<HttpFuture> HttpFuture::map (
95- std::function<HttpResponse(const HttpResponse &)> aTransform) {
96- if (mFuture .valid () &&
97- mFuture .wait_for (std::chrono::seconds (0 )) == std::future_status::ready) {
98- // Note: do not throw in transform when building without exceptions.
99- HttpResponse aResp = mFuture .get ();
100- HttpResponse aTransformed = aTransform (aResp);
101- auto aNewFuture = std::make_shared<HttpFuture>(
102- std::async (std::launch::deferred, [aTransformed]() { return aTransformed; }));
103- return aNewFuture;
104- }
105-
106- std::shared_ptr<HttpFuture> aSelf = shared_from_this ();
107- auto aMappedPromise = std::make_shared<std::promise<HttpResponse>>();
108-
109- onResponse ([aSelf, aTransform, aMappedPromise](const HttpResponse &aResp) {
110- // If transform throws and exceptions are disabled the program will
111- // terminate. Prefer not to throw in callbacks when building for ESP.
112- HttpResponse aTransformed = aTransform (aResp);
113- aMappedPromise->set_value (aTransformed);
114- });
115-
116- onError ([aMappedPromise](const HttpResponse &aErr) { aMappedPromise->set_value (aErr); });
117-
118- auto aNewFuture = std::make_shared<HttpFuture>(aMappedPromise->get_future ());
119- return aNewFuture;
120- }
121-
12244HttpResponse HttpFuture::get () {
12345 if (mFuture .valid ()) {
12446 return mFuture .get ();
@@ -130,72 +52,31 @@ HttpResponse HttpFuture::get() {
13052 return aError;
13153}
13254
133- bool HttpFuture::ready () const {
55+ bool HttpFuture::IsReady () const {
13456 if (!mFuture .valid ())
13557 return false ;
13658 return mFuture .wait_for (std::chrono::seconds (0 )) == std::future_status::ready;
13759}
13860
139- std::shared_ptr<HttpFuture> HttpFuture::always (std::function<void (const HttpResponse &)> aCallback) {
140- auto aCb = [aCallback](const HttpResponse &aResp) { aCallback (aResp); };
141-
142- // Register for both success and error
143- if (!mResponseCallback ) {
144- mResponseCallback = aCb;
145- } else {
146- auto aExisting = mResponseCallback ;
147- mResponseCallback = [aExisting, aCb](const HttpResponse &aResp) {
148- aExisting (aResp);
149- aCb (aResp);
150- };
61+ void HttpFuture::checkAndInvoke () {
62+ if (!IsReady ()) {
63+ return ;
15164 }
15265
153- if (!mErrorCallback ) {
154- mErrorCallback = aCb;
155- } else {
156- auto aExisting = mErrorCallback ;
157- mErrorCallback = [aExisting, aCb](const HttpResponse &aResp) {
158- aExisting (aResp);
159- aCb (aResp);
160- };
161- }
66+ HttpResponse aResponse = mFuture .get ();
16267
163- checkAndInvoke ();
164- return shared_from_this ();
165- }
68+ std::lock_guard<std::mutex> aLock (mCallbackMutex );
16669
167- void HttpFuture::checkAndInvoke () {
168- if (!mFuture .valid ())
70+ // Check for specific return code handler
71+ auto aIt = mReturnCodeCallbacks .find (aResponse.status_code );
72+ if (aIt != mReturnCodeCallbacks .end ()) {
73+ aIt->second (aResponse);
16974 return ;
75+ }
17076
171- if (mFuture .wait_for (std::chrono::seconds (0 )) == std::future_status::ready) {
172- // Note: avoid throwing inside futures/callbacks when building without
173- // exceptions. mFuture.get() should return a valid HttpResponse value
174- // (implementations should set an error HttpResponse instead of
175- // throwing). If an exception does escape and exceptions are disabled,
176- // the program will terminate.
177- HttpResponse aResponse = mFuture .get ();
178-
179- std::lock_guard<std::mutex> aLock (mCallbackMutex );
180-
181- // Check for specific return code handler
182- auto aIt = mReturnCodeCallbacks .find (aResponse.status_code );
183- if (aIt != mReturnCodeCallbacks .end ()) {
184- aIt->second (aResponse);
185- return ;
186- }
187-
188- // Check for default return code handler
189- if (mReturnCodeDefaultCallback ) {
190- mReturnCodeDefaultCallback (aResponse);
191- return ;
192- }
193-
194- // Fall back to success/error handlers
195- if (aResponse.success && mResponseCallback ) {
196- mResponseCallback (aResponse);
197- } else if (!aResponse.success && mErrorCallback ) {
198- mErrorCallback (aResponse);
199- }
77+ // Check for default return code handler
78+ if (mReturnCodeDefaultCallback ) {
79+ mReturnCodeDefaultCallback (aResponse);
80+ return ;
20081 }
20182}
0 commit comments