1 | #ifndef CPR_SESSION_H |
---|---|
2 | #define CPR_SESSION_H |
3 | |
4 | #include <cstdint> |
5 | #include <fstream> |
6 | #include <functional> |
7 | #include <future> |
8 | #include <memory> |
9 | #include <queue> |
10 | |
11 | #include "cpr/accept_encoding.h" |
12 | #include "cpr/async_wrapper.h" |
13 | #include "cpr/auth.h" |
14 | #include "cpr/bearer.h" |
15 | #include "cpr/body.h" |
16 | #include "cpr/callback.h" |
17 | #include "cpr/connect_timeout.h" |
18 | #include "cpr/cookies.h" |
19 | #include "cpr/cprtypes.h" |
20 | #include "cpr/curlholder.h" |
21 | #include "cpr/http_version.h" |
22 | #include "cpr/interface.h" |
23 | #include "cpr/limit_rate.h" |
24 | #include "cpr/local_port.h" |
25 | #include "cpr/local_port_range.h" |
26 | #include "cpr/low_speed.h" |
27 | #include "cpr/multipart.h" |
28 | #include "cpr/parameters.h" |
29 | #include "cpr/payload.h" |
30 | #include "cpr/proxies.h" |
31 | #include "cpr/proxyauth.h" |
32 | #include "cpr/range.h" |
33 | #include "cpr/redirect.h" |
34 | #include "cpr/reserve_size.h" |
35 | #include "cpr/resolve.h" |
36 | #include "cpr/response.h" |
37 | #include "cpr/ssl_options.h" |
38 | #include "cpr/timeout.h" |
39 | #include "cpr/unix_socket.h" |
40 | #include "cpr/user_agent.h" |
41 | #include "cpr/util.h" |
42 | #include "cpr/verbose.h" |
43 | |
44 | namespace cpr { |
45 | |
46 | using AsyncResponse = AsyncWrapper<Response>; |
47 | |
48 | class Interceptor; |
49 | class MultiPerform; |
50 | |
51 | class Session : public std::enable_shared_from_this<Session> { |
52 | public: |
53 | Session(); |
54 | Session(const Session& other) = delete; |
55 | Session(Session&& old) = default; |
56 | |
57 | ~Session() = default; |
58 | |
59 | Session& operator=(Session&& old) noexcept = default; |
60 | Session& operator=(const Session& other) = delete; |
61 | |
62 | void SetUrl(const Url& url); |
63 | void SetParameters(const Parameters& parameters); |
64 | void SetParameters(Parameters&& parameters); |
65 | void SetHeader(const Header& header); |
66 | void UpdateHeader(const Header& header); |
67 | void SetTimeout(const Timeout& timeout); |
68 | void SetConnectTimeout(const ConnectTimeout& timeout); |
69 | void SetAuth(const Authentication& auth); |
70 | // Only supported with libcurl >= 7.61.0. |
71 | // As an alternative use SetHeader and add the token manually. |
72 | #if LIBCURL_VERSION_NUM >= 0x073D00 |
73 | void SetBearer(const Bearer& token); |
74 | #endif |
75 | void SetUserAgent(const UserAgent& ua); |
76 | void SetPayload(Payload&& payload); |
77 | void SetPayload(const Payload& payload); |
78 | void SetProxies(Proxies&& proxies); |
79 | void SetProxies(const Proxies& proxies); |
80 | void SetProxyAuth(ProxyAuthentication&& proxy_auth); |
81 | void SetProxyAuth(const ProxyAuthentication& proxy_auth); |
82 | void SetMultipart(Multipart&& multipart); |
83 | void SetMultipart(const Multipart& multipart); |
84 | void SetRedirect(const Redirect& redirect); |
85 | void SetCookies(const Cookies& cookies); |
86 | void SetBody(Body&& body); |
87 | void SetBody(const Body& body); |
88 | void SetLowSpeed(const LowSpeed& low_speed); |
89 | void SetVerifySsl(const VerifySsl& verify); |
90 | void SetUnixSocket(const UnixSocket& unix_socket); |
91 | void SetSslOptions(const SslOptions& options); |
92 | void SetReadCallback(const ReadCallback& read); |
93 | void SetHeaderCallback(const HeaderCallback& header); |
94 | void SetWriteCallback(const WriteCallback& write); |
95 | void SetProgressCallback(const ProgressCallback& progress); |
96 | void SetDebugCallback(const DebugCallback& debug); |
97 | void SetVerbose(const Verbose& verbose); |
98 | void SetInterface(const Interface& iface); |
99 | void SetLocalPort(const LocalPort& local_port); |
100 | void SetLocalPortRange(const LocalPortRange& local_port_range); |
101 | void SetHttpVersion(const HttpVersion& version); |
102 | void SetRange(const Range& range); |
103 | void SetResolve(const Resolve& resolve); |
104 | void SetResolves(const std::vector<Resolve>& resolves); |
105 | void SetMultiRange(const MultiRange& multi_range); |
106 | void SetReserveSize(const ReserveSize& reserve_size); |
107 | void SetAcceptEncoding(const AcceptEncoding& accept_encoding); |
108 | void SetAcceptEncoding(AcceptEncoding&& accept_encoding); |
109 | void SetLimitRate(const LimitRate& limit_rate); |
110 | |
111 | // For cancellable requests |
112 | void SetCancellationParam(std::shared_ptr<std::atomic_bool> param); |
113 | |
114 | // Used in templated functions |
115 | void SetOption(const Url& url); |
116 | void SetOption(const Parameters& parameters); |
117 | void SetOption(Parameters&& parameters); |
118 | void SetOption(const Header& header); |
119 | void SetOption(const Timeout& timeout); |
120 | void SetOption(const ConnectTimeout& timeout); |
121 | void SetOption(const Authentication& auth); |
122 | // Only supported with libcurl >= 7.61.0. |
123 | // As an alternative use SetHeader and add the token manually. |
124 | #if LIBCURL_VERSION_NUM >= 0x073D00 |
125 | void SetOption(const Bearer& auth); |
126 | #endif |
127 | void SetOption(const UserAgent& ua); |
128 | void SetOption(Payload&& payload); |
129 | void SetOption(const Payload& payload); |
130 | void SetOption(const LimitRate& limit_rate); |
131 | void SetOption(Proxies&& proxies); |
132 | void SetOption(const Proxies& proxies); |
133 | void SetOption(ProxyAuthentication&& proxy_auth); |
134 | void SetOption(const ProxyAuthentication& proxy_auth); |
135 | void SetOption(Multipart&& multipart); |
136 | void SetOption(const Multipart& multipart); |
137 | void SetOption(const Redirect& redirect); |
138 | void SetOption(const Cookies& cookies); |
139 | void SetOption(Body&& body); |
140 | void SetOption(const Body& body); |
141 | void SetOption(const ReadCallback& read); |
142 | void SetOption(const HeaderCallback& header); |
143 | void SetOption(const WriteCallback& write); |
144 | void SetOption(const ProgressCallback& progress); |
145 | void SetOption(const DebugCallback& debug); |
146 | void SetOption(const LowSpeed& low_speed); |
147 | void SetOption(const VerifySsl& verify); |
148 | void SetOption(const Verbose& verbose); |
149 | void SetOption(const UnixSocket& unix_socket); |
150 | void SetOption(const SslOptions& options); |
151 | void SetOption(const Interface& iface); |
152 | void SetOption(const LocalPort& local_port); |
153 | void SetOption(const LocalPortRange& local_port_range); |
154 | void SetOption(const HttpVersion& version); |
155 | void SetOption(const Range& range); |
156 | void SetOption(const MultiRange& multi_range); |
157 | void SetOption(const ReserveSize& reserve_size); |
158 | void SetOption(const AcceptEncoding& accept_encoding); |
159 | void SetOption(AcceptEncoding&& accept_encoding); |
160 | void SetOption(const Resolve& resolve); |
161 | void SetOption(const std::vector<Resolve>& resolves); |
162 | |
163 | cpr_off_t GetDownloadFileLength(); |
164 | /** |
165 | * Attempt to preallocate enough memory for specified number of characters in the response string. |
166 | * Pass 0 to disable this behavior and let the response string be allocated dynamically on demand. |
167 | * |
168 | * Example: |
169 | * cpr::Session session; |
170 | * session.SetUrl(cpr::Url{"http://xxx/file"}); |
171 | * session.ResponseStringReserve(1024 * 512); // Reserve space for at least 1024 * 512 characters |
172 | * cpr::Response r = session.Get(); |
173 | **/ |
174 | void ResponseStringReserve(size_t size); |
175 | Response Delete(); |
176 | Response Download(const WriteCallback& write); |
177 | Response Download(std::ofstream& file); |
178 | Response Get(); |
179 | Response Head(); |
180 | Response Options(); |
181 | Response Patch(); |
182 | Response Post(); |
183 | Response Put(); |
184 | |
185 | AsyncResponse GetAsync(); |
186 | AsyncResponse DeleteAsync(); |
187 | AsyncResponse DownloadAsync(const WriteCallback& write); |
188 | AsyncResponse DownloadAsync(std::ofstream& file); |
189 | AsyncResponse HeadAsync(); |
190 | AsyncResponse OptionsAsync(); |
191 | AsyncResponse PatchAsync(); |
192 | AsyncResponse PostAsync(); |
193 | AsyncResponse PutAsync(); |
194 | |
195 | template <typename Then> |
196 | auto GetCallback(Then then); |
197 | template <typename Then> |
198 | auto PostCallback(Then then); |
199 | template <typename Then> |
200 | auto PutCallback(Then then); |
201 | template <typename Then> |
202 | auto HeadCallback(Then then); |
203 | template <typename Then> |
204 | auto DeleteCallback(Then then); |
205 | template <typename Then> |
206 | auto OptionsCallback(Then then); |
207 | template <typename Then> |
208 | auto PatchCallback(Then then); |
209 | |
210 | std::shared_ptr<CurlHolder> GetCurlHolder(); |
211 | std::string GetFullRequestUrl(); |
212 | |
213 | void PrepareDelete(); |
214 | void PrepareGet(); |
215 | void PrepareHead(); |
216 | void PrepareOptions(); |
217 | void PreparePatch(); |
218 | void PreparePost(); |
219 | void PreparePut(); |
220 | void PrepareDownload(const WriteCallback& write); |
221 | void PrepareDownload(std::ofstream& file); |
222 | Response Complete(CURLcode curl_error); |
223 | Response CompleteDownload(CURLcode curl_error); |
224 | |
225 | void AddInterceptor(const std::shared_ptr<Interceptor>& pinterceptor); |
226 | |
227 | private: |
228 | // Interceptors should be able to call the private proceed() function |
229 | friend Interceptor; |
230 | friend MultiPerform; |
231 | |
232 | |
233 | bool hasBodyOrPayload_{false}; |
234 | bool chunkedTransferEncoding_{false}; |
235 | std::shared_ptr<CurlHolder> curl_; |
236 | Url url_; |
237 | Parameters parameters_; |
238 | Proxies proxies_; |
239 | ProxyAuthentication proxyAuth_; |
240 | Header header_; |
241 | AcceptEncoding acceptEncoding_; |
242 | /** |
243 | * Will be set by the read callback. |
244 | * Ensures that the "Transfer-Encoding" is set to "chunked", if not overriden in header_. |
245 | **/ |
246 | ReadCallback readcb_; |
247 | HeaderCallback headercb_; |
248 | WriteCallback writecb_; |
249 | ProgressCallback progresscb_; |
250 | DebugCallback debugcb_; |
251 | CancellationCallback cancellationcb_; |
252 | |
253 | size_t response_string_reserve_size_{0}; |
254 | std::string response_string_; |
255 | std::string header_string_; |
256 | std::queue<std::shared_ptr<Interceptor>> interceptors_; |
257 | bool isUsedInMultiPerform{false}; |
258 | bool isCancellable{false}; |
259 | |
260 | Response makeDownloadRequest(); |
261 | Response makeRequest(); |
262 | Response proceed(); |
263 | Response intercept(); |
264 | void prepareCommon(); |
265 | void prepareCommonDownload(); |
266 | void SetHeaderInternal(); |
267 | std::shared_ptr<Session> GetSharedPtrFromThis(); |
268 | CURLcode DoEasyPerform(); |
269 | }; |
270 | |
271 | template <typename Then> |
272 | auto Session::GetCallback(Then then) { |
273 | return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Get()); }, std::move(then)); |
274 | } |
275 | |
276 | template <typename Then> |
277 | auto Session::PostCallback(Then then) { |
278 | return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Post()); }, std::move(then)); |
279 | } |
280 | |
281 | template <typename Then> |
282 | auto Session::PutCallback(Then then) { |
283 | return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Put()); }, std::move(then)); |
284 | } |
285 | |
286 | template <typename Then> |
287 | auto Session::HeadCallback(Then then) { |
288 | return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Head()); }, std::move(then)); |
289 | } |
290 | |
291 | template <typename Then> |
292 | auto Session::DeleteCallback(Then then) { |
293 | return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Delete()); }, std::move(then)); |
294 | } |
295 | |
296 | template <typename Then> |
297 | auto Session::OptionsCallback(Then then) { |
298 | return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Options()); }, std::move(then)); |
299 | } |
300 | |
301 | template <typename Then> |
302 | auto Session::PatchCallback(Then then) { |
303 | return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Patch()); }, std::move(then)); |
304 | } |
305 | |
306 | } // namespace cpr |
307 | |
308 | #endif |
309 |