drogon
C++14/17-based HTTP application framework
Loading...
Searching...
No Matches
HttpClient.h
Go to the documentation of this file.
1
15#pragma once
16
17#include <drogon/exports.h>
18#include <drogon/HttpTypes.h>
19#include <drogon/drogon_callbacks.h>
20#include <drogon/HttpResponse.h>
21#include <drogon/HttpRequest.h>
22#include <trantor/utils/NonCopyable.h>
23#include <trantor/net/EventLoop.h>
24#include <cstddef>
25#include <functional>
26#include <memory>
27#include <future>
28#include "drogon/HttpBinder.h"
29
30#ifdef __cpp_impl_coroutine
32#endif
33
34namespace drogon
35{
36class HttpClient;
37using HttpClientPtr = std::shared_ptr<HttpClient>;
38#ifdef __cpp_impl_coroutine
39namespace internal
40{
41struct HttpRespAwaiter : public CallbackAwaiter<HttpResponsePtr>
42{
43 HttpRespAwaiter(HttpClient *client, HttpRequestPtr req, double timeout)
44 : client_(client), req_(std::move(req)), timeout_(timeout)
45 {
46 }
47
48 void await_suspend(std::coroutine_handle<> handle);
49
50 private:
51 HttpClient *client_;
52 HttpRequestPtr req_;
53 double timeout_;
54};
55
56} // namespace internal
57#endif
58
60
72class DROGON_EXPORT HttpClient : public trantor::NonCopyable
73{
74 public:
91 virtual void sendRequest(const HttpRequestPtr &req,
92 const HttpReqCallback &callback,
93 double timeout = 0) = 0;
94
111 virtual void sendRequest(const HttpRequestPtr &req,
112 HttpReqCallback &&callback,
113 double timeout = 0) = 0;
114
130 std::pair<ReqResult, HttpResponsePtr> sendRequest(const HttpRequestPtr &req,
131 double timeout = 0)
132 {
133 assert(!getLoop()->isInLoopThread() &&
134 "Deadlock detected! Calling a sync API from the same loop as "
135 "the HTTP client processes on will deadlock the event loop");
136 std::promise<std::pair<ReqResult, HttpResponsePtr>> prom;
137 auto f = prom.get_future();
139 req,
140 [&prom](ReqResult r, const HttpResponsePtr &resp) {
141 prom.set_value({r, resp});
142 },
143 timeout);
144 return f.get();
145 }
146
147#ifdef __cpp_impl_coroutine
160 internal::HttpRespAwaiter sendRequestCoro(HttpRequestPtr req,
161 double timeout = 0)
162 {
163 return internal::HttpRespAwaiter(this, std::move(req), timeout);
164 }
165#endif
166
168
180 virtual void setSockOptCallback(std::function<void(int)> cb) = 0;
181
186 virtual std::size_t requestsBufferSize() = 0;
187
190
195 virtual void setPipeliningDepth(size_t depth) = 0;
196
198
203 virtual void enableCookies(bool flag = true) = 0;
204
206
212 virtual void addCookie(const std::string &key,
213 const std::string &value) = 0;
214
216
222 virtual void addCookie(const Cookie &cookie) = 0;
223
231 virtual void setUserAgent(const std::string &userAgent) = 0;
232
251 static HttpClientPtr newHttpClient(const std::string &ip,
252 uint16_t port,
253 bool useSSL = false,
254 trantor::EventLoop *loop = nullptr,
255 bool useOldTLS = false,
256 bool validateCert = true);
257
259 virtual trantor::EventLoop *getLoop() = 0;
260
262 virtual size_t bytesSent() const = 0;
263 virtual size_t bytesReceived() const = 0;
264
265 virtual std::string host() const = 0;
266
267 std::string getHost() const
268 {
269 return host();
270 }
271
272 virtual uint16_t port() const = 0;
273
274 uint16_t getPort() const
275 {
276 return port();
277 }
278
279 virtual bool secure() const = 0;
280
281 bool onDefaultPort() const
282 {
283 if (secure())
284 return port() == 443;
285 return port() == 80;
286 }
287
296 virtual void setCertPath(const std::string &cert,
297 const std::string &key) = 0;
298
309 virtual void addSSLConfigs(
310 const std::vector<std::pair<std::string, std::string>>
311 &sslConfCmds) = 0;
312
314
344 static HttpClientPtr newHttpClient(const std::string &hostString,
345 trantor::EventLoop *loop = nullptr,
346 bool useOldTLS = false,
347 bool validateCert = true);
348
349 virtual ~HttpClient()
350 {
351 }
352
353 protected:
354 HttpClient() = default;
355};
356
357#ifdef __cpp_impl_coroutine
358
359class HttpException : public std::exception
360{
361 public:
362 HttpException() = delete;
363
364 explicit HttpException(ReqResult res)
365 : resultCode_(res), message_(to_string_view(res))
366 {
367 }
368
369 const char *what() const noexcept override
370 {
371 return message_.data();
372 }
373
374 ReqResult code() const
375 {
376 return resultCode_;
377 }
378
379 private:
380 ReqResult resultCode_;
381 std::string_view message_;
382};
383
384inline void internal::HttpRespAwaiter::await_suspend(
385 std::coroutine_handle<> handle)
386{
387 assert(client_ != nullptr);
388 assert(req_ != nullptr);
389 client_->sendRequest(
390 req_,
391 [handle, this](ReqResult result, const HttpResponsePtr &resp) {
392 if (result == ReqResult::Ok)
393 setValue(resp);
394 else
395 setException(std::make_exception_ptr(HttpException(result)));
396 handle.resume();
397 },
398 timeout_);
399}
400#endif
401
402} // namespace drogon
this class represents a cookie entity.
Definition Cookie.h:32
Asynchronous http client.
Definition HttpClient.h:73
static HttpClientPtr newHttpClient(const std::string &hostString, trantor::EventLoop *loop=nullptr, bool useOldTLS=false, bool validateCert=true)
Create a Http client using the hostString to connect to server.
virtual void setSockOptCallback(std::function< void(int)> cb)=0
Set socket options(before connecting).
virtual void sendRequest(const HttpRequestPtr &req, HttpReqCallback &&callback, double timeout=0)=0
Send a request asynchronously to the server.
virtual trantor::EventLoop * getLoop()=0
Get the event loop of the client;.
virtual void addCookie(const std::string &key, const std::string &value)=0
Add a cookie to the client.
virtual void setUserAgent(const std::string &userAgent)=0
Set the user_agent header, the default value is 'DrogonClient' if this method is not used.
static HttpClientPtr newHttpClient(const std::string &ip, uint16_t port, bool useSSL=false, trantor::EventLoop *loop=nullptr, bool useOldTLS=false, bool validateCert=true)
Create a new HTTP client which use ip and port to connect to server.
virtual void sendRequest(const HttpRequestPtr &req, const HttpReqCallback &callback, double timeout=0)=0
Send a request asynchronously to the server.
virtual size_t bytesSent() const =0
Get the number of bytes sent or received.
std::pair< ReqResult, HttpResponsePtr > sendRequest(const HttpRequestPtr &req, double timeout=0)
Send a request synchronously to the server and return the response.
Definition HttpClient.h:130
virtual void setCertPath(const std::string &cert, const std::string &key)=0
Set the client certificate used by the HTTP connection.
virtual void addCookie(const Cookie &cookie)=0
Add a cookie to the client.
virtual void enableCookies(bool flag=true)=0
Enable cookies for the client.
virtual void setPipeliningDepth(size_t depth)=0
virtual void addSSLConfigs(const std::vector< std::pair< std::string, std::string > > &sslConfCmds)=0
Supplies command style options for SSL_CONF_cmd.
virtual std::size_t requestsBufferSize()=0
Return the number of unsent http requests in the current http client cache buffer.
Drogon Test is a minimal effort test framework developed because the major C++ test frameworks doesn'...
Definition Attribute.h:23