SW Task Event Loop Framework v1.0.0
High-performance C++ asynchronous event loop framework with timer management and promise-based programming
Loading...
Searching...
No Matches
HttpService.h
Go to the documentation of this file.
1#pragma once
2#include <string>
3#include <vector>
4#include <functional>
5#include <memory>
6#include <atomic>
7#include <unordered_map>
8#include <mutex>
9#include <condition_variable>
10#include <thread>
11#include <optional>
12#include <cstdint>
13#include <chrono>
14#include <curl/curl.h> // Quan trọng để tránh xung đột typedef
15
16namespace sw_task::net {
17
19
20enum class HttpErrorCode {
21 Network,
22 Timeout,
24 Resolve,
25 SSL,
28};
29
30struct HttpError {
32 std::string message;
33};
34
36 long statusCode{0};
37 std::string body;
38 std::string effectiveUrl;
39 std::unordered_map<std::string,std::string> headers;
40 std::optional<HttpError> error;
41 double elapsedMs{0.0};
42
43 bool ok() const {
44 return !error.has_value() && statusCode >= 200 && statusCode < 300;
45 }
46};
47
49 using CompleteFn = std::function<void(const HttpResponse&)>;
50 using ProgressFn = std::function<void(std::size_t, std::size_t)>;
51
53 std::string url;
54 std::vector<std::pair<std::string,std::string>> headers;
55 std::string body;
56 uint32_t timeoutMs{0};
59
60 void addHeader(std::string name, std::string value) {
61 headers.emplace_back(std::move(name), std::move(value));
62 }
63};
64
66public:
67 using RequestId = std::uint64_t;
68
71
73 bool cancel(RequestId id);
74
75 void setMaxConcurrent(std::size_t n);
76 std::size_t pending() const;
77 std::size_t activeCount() const;
78 std::size_t queuedCount() const;
79
80 void shutdown();
81
82private:
83 struct RequestCtx {
84 RequestId id;
85 HttpRequest req;
86 CURL* easy{nullptr};
87 bool canceled{false};
88 std::string responseBody;
89 std::unordered_map<std::string,std::string> respHeaders;
90 std::chrono::steady_clock::time_point startTime;
91 curl_slist* headerList{nullptr}; // để cleanup
92 };
93
94 CURLM* multi_{nullptr};
95 std::atomic<bool> running_{true};
96 std::thread worker_;
97
98 mutable std::mutex mtx_;
99 std::condition_variable cv_;
100
101 std::vector<RequestCtx> newQueue_;
102 std::unordered_map<RequestId, RequestCtx> active_;
103 std::unordered_map<CURL*, RequestId> easyToId_;
104
105 std::size_t maxConcurrent_{16};
106 RequestId nextId_{1};
107
108 void runLoop();
109 void addNewRequestsLocked();
110 void performOnce(int waitTimeoutMs);
111 void collectCompletions();
112 void finishRequest(RequestCtx& ctx, CURLcode result);
113 void cleanupEasy(RequestCtx& ctx);
114 void setupEasy(RequestCtx& ctx);
115
116 static size_t writeCallback(char* ptr, size_t size, size_t nmemb, void* userdata);
117 static size_t headerCallback(char* buffer, size_t size, size_t nitems, void* userdata);
118};
119
120} // namespace sw_task::net
void setMaxConcurrent(std::size_t n)
bool cancel(RequestId id)
std::size_t pending() const
RequestId submit(HttpRequest req)
std::size_t queuedCount() const
std::size_t activeCount() const
std::vector< std::pair< std::string, std::string > > headers
Definition HttpService.h:54
void addHeader(std::string name, std::string value)
Definition HttpService.h:60
std::function< void(std::size_t, std::size_t)> ProgressFn
Definition HttpService.h:50
std::function< void(const HttpResponse &)> CompleteFn
Definition HttpService.h:49
std::optional< HttpError > error
Definition HttpService.h:40
std::unordered_map< std::string, std::string > headers
Definition HttpService.h:39