FastLED 3.9.15
Loading...
Searching...
No Matches
fetch.h
Go to the documentation of this file.
1#pragma once
2
53
54#include "fl/task/promise.h"
55#include "fl/stl/string.h"
56#include "fl/stl/vector.h"
57#include "fl/stl/map.h"
59#include "fl/stl/optional.h"
60#include "fl/stl/function.h"
61#include "fl/stl/shared_ptr.h"
62#include "fl/task/executor.h"
63#include "fl/stl/mutex.h"
64#include "fl/log/log.h"
65#include "fl/stl/json.h" // Add JSON support for response.json() method
66#include "fl/stl/noexcept.h"
67
68namespace fl {
69namespace net {
70namespace http {
71
72// Forward declarations
73class FetchOptions;
74class FetchManager;
75class Response;
76
78class Response {
79public:
81 Response(int status_code) : mStatusCode(status_code), mStatusText(get_default_status_text(status_code)) {}
82 Response(int status_code, const fl::string& status_text)
83 : mStatusCode(status_code), mStatusText(status_text) {}
84
86 int status() const { return mStatusCode; }
87
89 const fl::string& status_text() const { return mStatusText; }
90
92 bool ok() const { return mStatusCode >= 200 && mStatusCode < 300; }
93
95 const fl::string& text() const { return mBody; }
96
99 auto it = mHeaders.find(name);
100 if (it != mHeaders.end()) {
101 return fl::make_optional(it->second);
102 }
103 return fl::nullopt;
104 }
105
108 return get_header("content-type");
109 }
110
112 const fl::string& get_body_text() const { return mBody; }
113
118 fl::json json() const;
119
122 bool is_json() const {
123 auto content_type = get_content_type();
124 if (content_type.has_value()) {
125 fl::string ct = *content_type;
126 // Check for various JSON content types (case-insensitive)
127 return ct.find("json") != fl::string::npos;
128 }
129 return false;
130 }
131
133 void set_status(int status_code) { mStatusCode = status_code; }
135 void set_text(const fl::string& body) { mBody = body; } // Backward compatibility
136 void set_body(const fl::string& body) { mBody = body; }
137 void set_header(const fl::string& name, const fl::string& value) {
138 mHeaders[name] = value;
139 }
140
141private:
146
147 // JSON parsing cache
148 mutable fl::optional<fl::json> mCachedJson; // Lazy-loaded JSON cache
149 mutable bool mJsonParsed = false; // Track parsing attempts
150
154 if (parsed.is_null() && (!mBody.empty())) {
155 // If parsing failed but we have content, return null JSON
156 // This allows safe chaining: resp.json()["key"] | default
157 return fl::json(nullptr);
158 }
159 return parsed;
160 }
161
162 static fl::string get_default_status_text(int status) { // okay static in header
163 switch (status) {
164 case 200: return "OK";
165 case 400: return "Bad Request";
166 case 401: return "Unauthorized";
167 case 403: return "Forbidden";
168 case 404: return "Not Found";
169 case 500: return "Internal Server Error";
170 case 501: return "Not Implemented";
171 case 502: return "Bad Gateway";
172 case 503: return "Service Unavailable";
173 default: return "Unknown";
174 }
175 }
176};
177
178
179
181using FetchCallback = fl::function<void(const Response&)>;
182
188 int timeout_ms = 10000; // 10 second default
189
191 RequestOptions(const fl::string& method_name) : method(method_name) {}
192};
193
196public:
197 explicit FetchOptions(const fl::string& url) : mUrl(url) {}
200
202 FetchOptions& method(const fl::string& http_method) {
203 mOptions.method = http_method;
204 return *this;
205 }
206
209 mOptions.headers[name] = value;
210 return *this;
211 }
212
215 mOptions.body = data;
216 return *this;
217 }
218
220 FetchOptions& json(const fl::string& json_data) {
221 mOptions.body = json_data;
222 mOptions.headers["Content-Type"] = "application/json";
223 return *this;
224 }
225
227 FetchOptions& timeout(int timeout_ms) {
228 mOptions.timeout_ms = timeout_ms;
229 return *this;
230 }
231
233 const fl::string& url() const { return mUrl; }
234
236 const RequestOptions& options() const { return mOptions; }
237
238private:
241
242 friend class FetchManager;
243};
244
246
249public:
250 static FetchManager& instance();
251
253
254 // task::Runner interface
255 void update() override;
256 bool has_active_tasks() const override;
257 size_t active_task_count() const override;
258
259 // Legacy API
260 fl::size active_requests() const;
262
263private:
266};
267
268// ========== Simple Callback API (Backward Compatible) ==========
269
276void fetch(const fl::string& url, const FetchCallback& callback);
277
281inline void fetch(const char* url, const FetchCallback& callback) {
282 fetch(fl::string(url), callback);
283}
284
285// ========== Promise-Based API (JavaScript-like) ==========
286
288fl::task::Promise<Response> fetch_get(const fl::string& url, const FetchOptions& request = FetchOptions(""));
289
291fl::task::Promise<Response> fetch_post(const fl::string& url, const FetchOptions& request = FetchOptions(""));
292
294fl::task::Promise<Response> fetch_put(const fl::string& url, const FetchOptions& request = FetchOptions(""));
295
297fl::task::Promise<Response> fetch_delete(const fl::string& url, const FetchOptions& request = FetchOptions(""));
298
300fl::task::Promise<Response> fetch_head(const fl::string& url, const FetchOptions& request = FetchOptions(""));
301
303fl::task::Promise<Response> fetch_http_options(const fl::string& url, const FetchOptions& request = FetchOptions(""));
304
306fl::task::Promise<Response> fetch_patch(const fl::string& url, const FetchOptions& request = FetchOptions(""));
307
309fl::task::Promise<Response> fetch_request(const fl::string& url, const RequestOptions& options = RequestOptions());
310
313void fetch_update();
314
316fl::size fetch_active_requests();
317
319fl::task::Promise<Response> execute_fetch_request(const fl::string& url, const FetchOptions& request);
320
321} // namespace http
322} // namespace net
323} // namespace fl
fl::size find(const char &value) const FL_NOEXCEPT
bool is_null() const FL_NOEXCEPT
Definition json.h:238
static json parse(const fl::string &txt) FL_NOEXCEPT
Definition json.h:677
bool has_active_tasks() const override
Check if this runner has active tasks.
fl::unique_ptr< FetchEngineListener > mEngineListener
Definition fetch.h:265
size_t active_task_count() const override
Get number of active tasks (for debugging/monitoring)
fl::vector< fl::task::Promise< Response > > mActivePromises
Definition fetch.h:264
static FetchManager & instance()
void register_promise(const fl::task::Promise< Response > &promise)
fl::size active_requests() const
void update() override
Update this runner (called during task pumping)
Internal fetch manager for promise tracking.
Definition fetch.h:248
FetchOptions(const fl::string &url)
Definition fetch.h:197
const fl::string & url() const
Get the URL for this request.
Definition fetch.h:233
FetchOptions & method(const fl::string &http_method)
Set HTTP method.
Definition fetch.h:202
FetchOptions & header(const fl::string &name, const fl::string &value)
Add header.
Definition fetch.h:208
friend class FetchManager
Definition fetch.h:242
FetchOptions & body(const fl::string &data)
Set request body.
Definition fetch.h:214
FetchOptions & json(const fl::string &json_data)
Set JSON body with proper content type.
Definition fetch.h:220
FetchOptions & timeout(int timeout_ms)
Set timeout in milliseconds.
Definition fetch.h:227
RequestOptions mOptions
Definition fetch.h:240
FetchOptions(const fl::string &url, const RequestOptions &options)
Definition fetch.h:198
const RequestOptions & options() const
Get the options for this request.
Definition fetch.h:236
Fetch options builder (fluent interface)
Definition fetch.h:195
Response() FL_NOEXCEPT
Definition fetch.h:80
static fl::string get_default_status_text(int status)
Definition fetch.h:162
const fl::string & text() const
Response body as text (like JavaScript response.text())
Definition fetch.h:95
Response(int status_code, const fl::string &status_text)
Definition fetch.h:82
const fl::string & get_body_text() const
Response body as text (alternative to text())
Definition fetch.h:112
void set_status_text(const fl::string &status_text)
Definition fetch.h:134
fl::optional< fl::string > get_header(const fl::string &name) const
Get header value (like JavaScript response.headers.get())
Definition fetch.h:98
void set_header(const fl::string &name, const fl::string &value)
Definition fetch.h:137
bool is_json() const
Check if response appears to contain JSON content.
Definition fetch.h:122
bool ok() const
Check if response is successful (like JavaScript response.ok)
Definition fetch.h:92
const fl::string & status_text() const
HTTP status text (like JavaScript response.statusText)
Definition fetch.h:89
void set_text(const fl::string &body)
Definition fetch.h:135
fl::string mStatusText
Definition fetch.h:143
int status() const
HTTP status code (like JavaScript response.status)
Definition fetch.h:86
fl::optional< fl::string > get_content_type() const
Get content type convenience method.
Definition fetch.h:107
fl::json parse_json_body() const
Parse JSON from response body with error handling.
Definition fetch.h:152
Response(int status_code)
Definition fetch.h:81
fl::json json() const
Response body parsed as JSON (JavaScript-like API)
void set_status(int status_code)
Set methods (internal use)
Definition fetch.h:133
fl::optional< fl::json > mCachedJson
Definition fetch.h:148
void set_body(const fl::string &body)
Definition fetch.h:136
fl_map< fl::string, fl::string > mHeaders
Definition fetch.h:145
HTTP response class (unified interface)
Definition fetch.h:78
static constexpr fl::size npos
Definition string.h:195
Promise class that provides fluent .then() and .catch_() semantics This is a lightweight wrapper arou...
Definition promise.h:58
Generic task runner interface.
Definition executor.h:88
Definition url.h:15
Task executor — runs registered task runners and manages the run loop.
FastLED's Elegant JSON Library: fl::json
Centralized logging categories for FastLED hardware interfaces and subsystems.
Platform-independent mutex interface.
void fetch_update()
Legacy manual update for fetch promises (use fl::task::run() for new code)
fl::task::Promise< Response > fetch_delete(const fl::string &url, const FetchOptions &request)
HTTP DELETE request.
fl::function< void(const Response &)> FetchCallback
Callback type for simple fetch responses (backward compatible)
Definition fetch.h:181
fl::task::Promise< Response > fetch_http_options(const fl::string &url, const FetchOptions &request)
HTTP OPTIONS request.
fl::task::Promise< Response > fetch_patch(const fl::string &url, const FetchOptions &request)
HTTP PATCH request.
fl::task::Promise< Response > fetch_post(const fl::string &url, const FetchOptions &request)
HTTP POST request.
fl::task::Promise< Response > fetch_head(const fl::string &url, const FetchOptions &request)
HTTP HEAD request.
fl::task::Promise< Response > execute_fetch_request(const fl::string &url, const FetchOptions &request)
Internal helper to execute a fetch request and return a promise.
fl::task::Promise< Response > fetch_get(const fl::string &url, const FetchOptions &request)
HTTP GET request.
fl::task::Promise< Response > fetch_request(const fl::string &url, const RequestOptions &options)
Generic request with options (like fetch(url, options))
void fetch(const fl::string &url, const FetchCallback &callback)
Make an HTTP GET request (cross-platform, backward compatible)
fl::task::Promise< Response > fetch_put(const fl::string &url, const FetchOptions &request)
HTTP PUT request.
fl::size fetch_active_requests()
Get number of active requests.
constexpr int type_rank< T >::value
Optional< T > optional
Definition optional.h:16
optional< T > make_optional(const T &value) FL_NOEXCEPT
Definition optional.h:235
constexpr nullopt_t nullopt
Definition optional.h:13
map< Key, T, Compare > fl_map
Definition map.h:287
Base definition for an LED controller.
Definition crgb.hpp:179
Promise-based fluent API for FastLED - standalone async primitives.
#define FL_NOEXCEPT
fl_map< fl::string, fl::string > headers
Definition fetch.h:186
RequestOptions() FL_NOEXCEPT=default
Request options (matches JavaScript fetch RequestInit)
Definition fetch.h:184