CppServer 1.0.6.0
C++ Server Library
Loading...
Searching...
No Matches
http_client.cpp
Go to the documentation of this file.
1
8
10
11namespace CppServer {
12namespace HTTP {
13
14void HTTPClient::onReceived(const void* buffer, size_t size)
15{
16 // Receive HTTP response header
17 if (_response.IsPendingHeader())
18 {
19 if (_response.ReceiveHeader(buffer, size))
21
22 size = 0;
23 }
24
25 // Check for HTTP response error
26 if (_response.error())
27 {
28 onReceivedResponseError(_response, "Invalid HTTP response!");
29 _response.Clear();
31 return;
32 }
33
34 // Receive HTTP response body
35 if (_response.ReceiveBody(buffer, size))
36 {
38 _response.Clear();
39 return;
40 }
41
42 // Check for HTTP response error
43 if (_response.error())
44 {
45 onReceivedResponseError(_response, "Invalid HTTP response!");
46 _response.Clear();
48 return;
49 }
50}
51
53{
54 // Receive HTTP response body
55 if (_response.IsPendingBody())
56 {
58 _response.Clear();
59 return;
60 }
61}
62
63std::future<HTTPResponse> HTTPClientEx::SendRequest(const HTTPRequest& request, const CppCommon::Timespan& timeout)
64{
65 // Create TCP resolver if the current one is empty
66 if (!_resolver)
67 _resolver = std::make_shared<Asio::TCPResolver>(service());
68 // Create timeout check timer if the current one is empty
69 if (!_timeout)
70 _timeout = std::make_shared<Asio::Timer>(service());
71
72 _promise = std::promise<HTTPResponse>();
74
75 // Check if the HTTP request is valid
76 if (_request.empty() || _request.error())
77 {
78 SetResponseError("Invalid HTTP request!");
79 return _promise.get_future();
80 }
81
82 if (!IsConnected())
83 {
84 // Connect to the Web server
85 if (!ConnectAsync(_resolver))
86 {
87 SetResponseError("Connection failed!");
88 return _promise.get_future();
89 }
90 }
91 else
92 {
93 // Send prepared HTTP request
94 if (!SendRequestAsync())
95 {
96 SetResponseError("Failed to send HTTP request!");
97 return _promise.get_future();
98 }
99 }
100
101 // Setup timeout check timer
102 auto self(this->shared_from_this());
103 auto timeout_handler = [this, self](bool canceled)
104 {
105 if (canceled)
106 return;
107
109
110 // Disconnect on timeout
112 };
113 if (!_timeout->Setup(timeout_handler, timeout) || !_timeout->WaitAsync())
114 {
115 SetResponseError("Failed to setup timeout timer!");
116 return _promise.get_future();
117 }
118
119 return _promise.get_future();
120}
121
123{
125
126 // Send prepared HTTP request on connect
127 if (!_request.empty() && !_request.error())
128 if (!SendRequestAsync())
129 SetResponseError("Failed to send HTTP request!");
130}
131
133{
134 // Cancel timeout check timer
135 if (_timeout)
136 _timeout->Cancel();
137
138 if (!_request.empty())
139 SetResponseError("Disconnected!");
140
142}
143
144void HTTPClientEx::onError(int error, const std::string& category, const std::string& message)
145{
146 // Cancel timeout check timer
147 if (_timeout)
148 _timeout->Cancel();
149
150 if (!_request.empty())
151 SetResponseError(message.empty() ? "Socket error!" : message);
152
153 HTTPClient::onError(error, category, message);
154}
155
157{
158 // Cancel timeout check timer
159 if (_timeout)
160 _timeout->Cancel();
161
162 SetResponseValue(response);
163}
164
165void HTTPClientEx::onReceivedResponseError(const HTTPResponse& response, const std::string& error)
166{
167 // Cancel timeout check timer
168 if (_timeout)
169 _timeout->Cancel();
170
171 SetResponseError(error);
172}
173
174void HTTPClientEx::SetResponseValue(const HTTPResponse& response)
175{
176 // Guard try/catch block against promise double-resolution races
177 try
178 {
179 _promise.set_value(response);
180 } catch (...) {}
181
182 // Clear HTTP request
183 _request.Clear();
184}
185
186void HTTPClientEx::SetResponseError(const std::string& error)
187{
188 // Guard try/catch block against promise double-resolution races
189 try
190 {
191 _promise.set_exception(std::make_exception_ptr(std::runtime_error(error)));
192 } catch (...) {}
193
194 // Clear HTTP request
195 _request.Clear();
196}
197
198} // namespace HTTP
199} // namespace CppServer
bool IsConnected() const noexcept
Is the client connected?
Definition tcp_client.h:101
virtual void onConnected()
Handle client connected notification.
Definition tcp_client.h:281
virtual void onError(int error, const std::string &category, const std::string &message)
Handle error notification.
Definition tcp_client.h:324
std::shared_ptr< Service > & service() noexcept
Get the Asio service.
Definition tcp_client.h:63
virtual bool ConnectAsync()
Connect the client (asynchronous).
virtual bool DisconnectAsync()
Disconnect the client (asynchronous).
Definition tcp_client.h:146
void onReceivedResponse(const HTTPResponse &response) override
Handle HTTP response received notification.
void onError(int error, const std::string &category, const std::string &message) override
Handle error notification.
std::shared_ptr< Asio::Timer > & timeout() noexcept
Get the timeout check timer.
void onDisconnected() override
Handle client disconnected notification.
void onConnected() override
Handle client connected notification.
void onReceivedResponseError(const HTTPResponse &response, const std::string &error) override
Handle HTTP response error notification.
void onReceived(const void *buffer, size_t size) override
Handle buffer received notification.
HTTPResponse _response
HTTP response.
HTTPRequest _request
HTTP request.
size_t SendRequest()
Send the current HTTP request (synchronous).
Definition http_client.h:51
HTTPRequest & request() noexcept
Get the HTTP request.
Definition http_client.h:44
bool SendRequestAsync()
Send the current HTTP request (asynchronous).
virtual void onReceivedResponse(const HTTPResponse &response)
Handle HTTP response received notification.
virtual void onReceivedResponseHeader(const HTTPResponse &response)
Handle HTTP response header received notification.
virtual void onReceivedResponseError(const HTTPResponse &response, const std::string &error)
Handle HTTP response error notification.
void onDisconnected() override
Handle client disconnected notification.
HTTPRequest & Clear()
Clear the HTTP request cache.
HTTP client definition.
HTTP definitions.
C++ Server project definitions.
Definition asio.h:56