SNode.C
Loading...
Searching...
No Matches
web::http::client::SocketContext Class Reference

#include <SocketContext.h>

Inheritance diagram for web::http::client::SocketContext:
Collaboration diagram for web::http::client::SocketContext:

Public Member Functions

 SocketContext (core::socket::stream::SocketConnection *socketConnection, const std::function< void(const std::shared_ptr< Request > &)> &onRequestBegin, const std::function< void(const std::shared_ptr< Request > &)> &onRequestEnd, bool pipelinedRequests)
 
 ~SocketContext () override
 
- Public Member Functions inherited from core::socket::stream::SocketContext
 SocketContext (core::socket::stream::SocketConnection *socketConnection)
 
void sendToPeer (const char *chunk, std::size_t chunkLen) const final
 
bool streamToPeer (core::pipe::Source *source) const
 
void streamEof ()
 
std::size_t readFromPeer (char *chunk, std::size_t chunklen) const final
 
void setTimeout (const utils::Timeval &timeout) final
 
void shutdownRead ()
 
void shutdownWrite (bool forceClose=false)
 
void close () override
 
std::size_t getTotalSent () const override
 
std::size_t getTotalQueued () const override
 
std::size_t getTotalRead () const override
 
std::size_t getTotalProcessed () const override
 
std::string getOnlineSince () const override
 
std::string getOnlineDuration () const override
 
SocketConnectiongetSocketConnection () const
 
virtual void switchSocketContext (SocketContext *newSocketContext)
 
virtual std::size_t readFromPeer (char *chunk, std::size_t chunklen) const=0
 
void sendToPeer (const std::string &data) const
 
virtual void sendToPeer (const char *chunk, std::size_t chunkLen) const=0
 
- Public Member Functions inherited from core::socket::SocketContext
 SocketContext (const SocketContext &)=delete
 
 SocketContext (SocketContext &&)=delete
 
SocketContextoperator= (const SocketContext &)=delete
 
SocketContextoperator= (SocketContext &&)=delete
 
void sendToPeer (const std::string &data) const
 

Private Types

enum  Flags {
  NONE = 0b00000000 , HTTP10 = 0b00000001 , HTTP11 = 0b00000010 , KEEPALIVE = 0b00000100 ,
  CLOSE = 0b00001000
}
 
using Super = core::socket::stream::SocketContext
 
using Request = web::http::client::Request
 
using Response = web::http::client::Response
 

Private Member Functions

void requestPrepared (Request &&request)
 
void initiateRequest (Request &request)
 
void requestDelivered (Request &&request, bool success)
 
void responseStarted ()
 
void deliverResponse (Response &&response)
 
void deliverResponseParseError (int status, const std::string &reason)
 
void responseDelivered (bool httpClose)
 
void onConnected () override
 
std::size_t onReceivedFromPeer () override
 
void onDisconnected () override
 
bool onSignal (int signum) override
 
void onWriteError (int errnum) override
 

Private Attributes

std::function< void(const std::shared_ptr< Request > &)> onRequestBegin
 
std::function< void(const std::shared_ptr< Request > &)> onRequestEnd
 
std::list< RequestpendingRequests
 
std::list< RequestdeliveredRequests
 
bool pipelinedRequests = false
 
std::shared_ptr< RequestcurrentRequest = nullptr
 
std::shared_ptr< RequestmasterRequest
 
ResponseParser parser
 
int flags = Flags::NONE
 

Friends

class web::http::client::Request
 

Additional Inherited Members

- Protected Member Functions inherited from core::socket::stream::SocketContext
void onReadError (int errnum) override
 
void readFromPeer (std::size_t available)
 
- Protected Member Functions inherited from core::socket::SocketContext
 SocketContext ()=default
 

Detailed Description

Definition at line 65 of file SocketContext.h.

Member Typedef Documentation

◆ Request

◆ Response

◆ Super

Member Enumeration Documentation

◆ Flags

Enumerator
NONE 
HTTP10 
HTTP11 
KEEPALIVE 
CLOSE 

Definition at line 108 of file SocketContext.h.

Constructor & Destructor Documentation

◆ SocketContext()

web::http::client::SocketContext::SocketContext ( core::socket::stream::SocketConnection socketConnection,
const std::function< void(const std::shared_ptr< Request > &)> &  onRequestBegin,
const std::function< void(const std::shared_ptr< Request > &)> &  onRequestEnd,
bool  pipelinedRequests 
)

Definition at line 62 of file SocketContext.cpp.

70 , masterRequest(std::make_shared<Request>(this,
71 getSocketConnection()->getRemoteAddress().toString(false) +
72 getSocketConnection()->getRemoteAddress().getEndpoint(":{}")))
73 , parser(
74 this,
75 [this]() {
77 },
78 [this](web::http::client::Response&& response) {
79 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Response parsed: HTTP/" << response.httpMajor << "."
80 << response.httpMinor << " " << response.statusCode << " " << response.reason;
81
82 deliverResponse(std::move(response));
83 },
84 [this](int status, const std::string& reason) {
85 deliverResponseParseError(status, reason);
86 }) {
87 masterRequest->setMasterRequest(masterRequest);
88 }
const std::string & getConnectionName() const
SocketConnection * getSocketConnection() const
core::socket::stream::SocketConnection * socketConnection
core::socket::stream::SocketContext Super
void deliverResponseParseError(int status, const std::string &reason)
std::function< void(const std::shared_ptr< Request > &)> onRequestBegin
void deliverResponse(Response &&response)
std::function< void(const std::shared_ptr< Request > &)> onRequestEnd
std::shared_ptr< Request > masterRequest
std::string toString(const std::string &method, const std::string &url, const std::string &version, const web::http::CiStringMap< std::string > &queries, const web::http::CiStringMap< std::string > &header, const web::http::CiStringMap< std::string > &cookies, const std::vector< char > &body)

References core::socket::SocketAddress::getEndpoint(), core::socket::stream::SocketConnection::getRemoteAddress(), core::socket::stream::SocketContext::getSocketConnection(), masterRequest, onRequestBegin, onRequestEnd, parser, pipelinedRequests, web::http::client::ResponseParser::ResponseParser(), responseStarted(), core::socket::stream::SocketContext::SocketContext(), and core::socket::SocketAddress::toString().

Referenced by web::http::client::SocketContextFactory::create().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ~SocketContext()

web::http::client::SocketContext::~SocketContext ( )
overridevirtual

Reimplemented from core::socket::stream::SocketContext.

Definition at line 90 of file SocketContext.cpp.

90 {
91 if (!deliveredRequests.empty()) {
92 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Responses missed";
93 for (const Request& request : deliveredRequests) {
94 LOG(DEBUG) << " " << request.method << " " << request.url << " HTTP/" << request.httpMajor << "." << request.httpMinor;
95 }
96 }
97
98 if (!pendingRequests.empty()) {
99 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Requests ignored";
100 for (const Request& request : pendingRequests) {
101 LOG(DEBUG) << " " << request.method << " " << request.url << " HTTP/" << request.httpMajor << "." << request.httpMinor;
102 }
103 }
104 }
web::http::client::Request Request
std::list< Request > deliveredRequests
std::list< Request > pendingRequests

References deliveredRequests, core::socket::stream::SocketConnection::getConnectionName(), core::socket::stream::SocketContext::getSocketConnection(), web::http::client::Request::httpMajor, web::http::client::Request::httpMinor, web::http::client::Request::method, pendingRequests, and web::http::client::Request::url.

Here is the call graph for this function:

Member Function Documentation

◆ deliverResponse()

void web::http::client::SocketContext::deliverResponse ( Response &&  response)
private

Definition at line 227 of file SocketContext.cpp.

227 {
228 const std::shared_ptr<Request> request = std::make_shared<Request>(std::move(deliveredRequests.front()));
229 deliveredRequests.pop_front();
230
231 const std::string requestLine = std::string(request->method)
232 .append(" ")
233 .append(request->url)
234 .append(" HTTP/")
235 .append(std::to_string(request->httpMajor))
236 .append(".")
237 .append(std::to_string(request->httpMinor));
238
239 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Response received: " << requestLine;
240
241 const bool httpClose =
242 response.connectionState == ConnectionState::Close ||
243 (response.connectionState == ConnectionState::Default &&
244 ((response.httpMajor == 0 && response.httpMinor == 9) || (response.httpMajor == 1 && response.httpMinor == 0)));
245
246 request->deliverResponse(request, std::make_shared<Response>(std::move(response)));
247
248 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Response completed: " << requestLine;
249
250 responseDelivered(httpClose);
251 }
void responseDelivered(bool httpClose)

References web::http::Close, web::http::client::Response::connectionState, web::http::Default, deliveredRequests, web::http::client::Request::deliverResponse(), core::socket::stream::SocketConnection::getConnectionName(), core::socket::stream::SocketContext::getSocketConnection(), web::http::client::Request::httpMajor, web::http::client::Response::httpMajor, web::http::client::Request::httpMinor, web::http::client::Response::httpMinor, web::http::client::Request::method, responseDelivered(), and web::http::client::Request::url.

Referenced by onDisconnected().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ deliverResponseParseError()

void web::http::client::SocketContext::deliverResponseParseError ( int  status,
const std::string &  reason 
)
private

Definition at line 253 of file SocketContext.cpp.

253 {
254 const std::shared_ptr<Request> request = std::make_shared<Request>(std::move(deliveredRequests.front()));
255 deliveredRequests.pop_front();
256
257 LOG(WARNING) << getSocketConnection()->getConnectionName() << " HTTP: Response parse error: " << reason << " (" << status << ") "
258 << std::string(request->method)
259 .append(" ")
260 .append(request->url)
261 .append(" HTTP/")
262 .append(std::to_string(request->httpMajor))
263 .append(".")
264 .append(std::to_string(request->httpMinor));
265
266 request->deliverResponseParseError(request, reason);
267
268 shutdownWrite(true);
269 }
void shutdownWrite(bool forceClose=false)

References deliveredRequests, web::http::client::Request::deliverResponseParseError(), core::socket::stream::SocketConnection::getConnectionName(), core::socket::stream::SocketContext::getSocketConnection(), web::http::client::Request::httpMajor, web::http::client::Request::httpMinor, web::http::client::Request::method, core::socket::stream::SocketContext::shutdownWrite(), and web::http::client::Request::url.

Here is the call graph for this function:

◆ initiateRequest()

void web::http::client::SocketContext::initiateRequest ( Request request)
private

Definition at line 137 of file SocketContext.cpp.

137 {
138 currentRequest = std::make_shared<Request>(std::move(request));
139
140 const std::string requestLine = std::string(currentRequest->method)
141 .append(" ")
142 .append(currentRequest->url)
143 .append(" HTTP/")
144 .append(std::to_string(currentRequest->httpMajor))
145 .append(".")
146 .append(std::to_string(currentRequest->httpMinor));
147
148 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Request start: " << requestLine;
149
150 if (!currentRequest->initiate(currentRequest)) {
151 LOG(WARNING) << getSocketConnection()->getConnectionName() << " HTTP: Request delivering failed: " << requestLine;
152
153 core::EventReceiver::atNextTick([this, masterRequest = static_cast<std::weak_ptr<Request>>(masterRequest)]() {
154 if (!masterRequest.expired()) {
155 if (!pendingRequests.empty()) {
156 Request& request = pendingRequests.front();
157
158 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Request dequeued: " << request.method << " "
159 << request.url << " HTTP/" << request.httpMajor << "." << request.httpMinor;
160
161 initiateRequest(request);
162 pendingRequests.pop_front();
163 } else {
164 currentRequest = nullptr;
165 }
166 }
167 });
168 }
169 }
static void atNextTick(const std::function< void(void)> &callBack)
std::shared_ptr< Request > currentRequest

References core::EventReceiver::atNextTick(), currentRequest, core::socket::stream::SocketConnection::getConnectionName(), core::socket::stream::SocketContext::getSocketConnection(), web::http::client::Request::httpMajor, web::http::client::Request::httpMinor, web::http::client::Request::initiate(), initiateRequest(), masterRequest, web::http::client::Request::method, pendingRequests, and web::http::client::Request::url.

Referenced by initiateRequest(), requestDelivered(), requestPrepared(), and responseDelivered().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ onConnected()

void web::http::client::SocketContext::onConnected ( )
overrideprivatevirtual

Implements core::socket::stream::SocketContext.

Definition at line 298 of file SocketContext.cpp.

298 {
299 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Connected";
300
302 }

References core::socket::stream::SocketConnection::getConnectionName(), core::socket::stream::SocketContext::getSocketConnection(), masterRequest, and onRequestBegin.

Here is the call graph for this function:

◆ onDisconnected()

void web::http::client::SocketContext::onDisconnected ( )
overrideprivatevirtual

Implements core::socket::stream::SocketContext.

Definition at line 314 of file SocketContext.cpp.

314 {
315 if (!deliveredRequests.empty()) {
316 const Request& request = deliveredRequests.front();
317 if (request.httpMajor == 1 && request.httpMinor == 0) {
319 }
320 }
321
323
324 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Disconnected";
325 }

References deliveredRequests, deliverResponse(), core::socket::stream::SocketConnection::getConnectionName(), web::http::client::ResponseParser::getResponse(), core::socket::stream::SocketContext::getSocketConnection(), web::http::client::Request::httpMajor, web::http::client::Request::httpMinor, masterRequest, onRequestEnd, and parser.

Here is the call graph for this function:

◆ onReceivedFromPeer()

std::size_t web::http::client::SocketContext::onReceivedFromPeer ( )
overrideprivatevirtual

Implements core::socket::SocketContext.

Definition at line 304 of file SocketContext.cpp.

304 {
305 std::size_t consumed = 0;
306
307 if (!deliveredRequests.empty()) {
308 consumed = parser.parse();
309 }
310
311 return consumed;
312 }
std::size_t parse()
Definition Parser.cpp:92

References deliveredRequests, web::http::Parser::parse(), and parser.

Here is the call graph for this function:

◆ onSignal()

bool web::http::client::SocketContext::onSignal ( int  signum)
overrideprivatevirtual

Implements core::socket::SocketContext.

Definition at line 327 of file SocketContext.cpp.

327 {
328 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Received signal " << signum;
329
330 return true;
331 }

References core::socket::stream::SocketConnection::getConnectionName(), and core::socket::stream::SocketContext::getSocketConnection().

Here is the call graph for this function:

◆ onWriteError()

void web::http::client::SocketContext::onWriteError ( int  errnum)
overrideprivatevirtual

Reimplemented from core::socket::stream::SocketContext.

Definition at line 333 of file SocketContext.cpp.

333 {
334 // Do nothing in case of an write error
335 }

◆ requestDelivered()

void web::http::client::SocketContext::requestDelivered ( Request &&  request,
bool  success 
)
private

Definition at line 171 of file SocketContext.cpp.

171 {
172 const std::string requestLine = std::string(request.method)
173 .append(" ")
174 .append(request.url)
175 .append(" HTTP/")
176 .append(std::to_string(request.httpMajor))
177 .append(".")
178 .append(std::to_string(request.httpMinor));
179
180 if (success) {
181 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Request delivered: " << requestLine;
182
183 deliveredRequests.emplace_back(std::move(request));
184
185 if (pipelinedRequests) {
186 core::EventReceiver::atNextTick([this, masterRequest = static_cast<std::weak_ptr<Request>>(masterRequest)]() {
187 if (!masterRequest.expired()) {
188 if (!pendingRequests.empty()) {
189 Request& request = pendingRequests.front();
190
191 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Request dequeued: " << request.method << " "
192 << request.url << " HTTP/" << request.httpMajor << "." << request.httpMinor;
193
194 initiateRequest(request);
195 pendingRequests.pop_front();
196 } else {
197 currentRequest = nullptr;
198 }
199 }
200 });
201 }
202 } else {
203 LOG(WARNING) << getSocketConnection()->getConnectionName() << " HTTP: Request deliver failed: " << requestLine;
204
206 }
207 }

References core::EventReceiver::atNextTick(), currentRequest, deliveredRequests, core::socket::stream::SocketConnection::getConnectionName(), core::socket::stream::SocketContext::getSocketConnection(), web::http::client::Request::httpMajor, web::http::client::Request::httpMinor, initiateRequest(), masterRequest, web::http::client::Request::method, pendingRequests, pipelinedRequests, core::socket::stream::SocketContext::shutdownWrite(), and web::http::client::Request::url.

Referenced by web::http::client::Request::requestDelivered().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ requestPrepared()

void web::http::client::SocketContext::requestPrepared ( Request &&  request)
private

Definition at line 106 of file SocketContext.cpp.

106 {
107 const std::string requestLine = std::string(request.method)
108 .append(" ")
109 .append(request.url)
110 .append(" HTTP/")
111 .append(std::to_string(request.httpMajor))
112 .append(".")
113 .append(std::to_string(request.httpMinor));
114
117 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Request accepted: " << requestLine;
118
119 flags = (flags & ~Flags::HTTP11) | ((request.httpMajor == 1 && request.httpMinor == 1) ? Flags::HTTP11 : Flags::NONE);
120 flags = (flags & ~Flags::HTTP10) | ((request.httpMajor == 1 && request.httpMinor == 0) ? Flags::HTTP10 : Flags::NONE);
121 flags = (flags & ~Flags::KEEPALIVE) |
122 (web::http::ciContains(request.header("Connection"), "keep-alive") ? Flags::KEEPALIVE : Flags::NONE);
123 flags = (flags & ~Flags::CLOSE) | (web::http::ciContains(request.header("Connection"), "close") ? Flags::CLOSE : Flags::NONE);
124
125 if (!currentRequest) {
126 initiateRequest(request);
127 } else {
128 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Request queued: " << requestLine;
129
130 pendingRequests.emplace_back(std::move(request));
131 }
132 } else {
133 LOG(WARNING) << getSocketConnection()->getConnectionName() << " HTTP: Request rejected: " << requestLine;
134 }
135 }
void initiateRequest(Request &request)
bool ciContains(const std::string &str1, const std::string &str2)

References web::http::ciContains(), CLOSE, currentRequest, flags, core::socket::stream::SocketConnection::getConnectionName(), core::socket::stream::SocketContext::getSocketConnection(), web::http::client::Request::header(), HTTP10, HTTP11, web::http::client::Request::httpMajor, web::http::client::Request::httpMinor, initiateRequest(), KEEPALIVE, web::http::client::Request::method, NONE, pendingRequests, and web::http::client::Request::url.

Referenced by web::http::client::Request::requestPrepared().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ responseDelivered()

void web::http::client::SocketContext::responseDelivered ( bool  httpClose)
private

Definition at line 271 of file SocketContext.cpp.

271 {
272 if (httpClose) {
273 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Connection = Close";
274 } else {
275 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Connection = Keep-Alive";
276
277 if (!pipelinedRequests) {
278 core::EventReceiver::atNextTick([this, masterRequest = static_cast<std::weak_ptr<Request>>(masterRequest)]() {
279 if (!masterRequest.expired()) {
280 if (!pendingRequests.empty()) {
281 Request& request = pendingRequests.front();
282
283 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Initiating request: " << request.method
284 << " " << request.url << " HTTP/" << request.httpMajor << "." << request.httpMinor;
285
286 initiateRequest(request);
287
288 pendingRequests.pop_front();
289 } else {
290 currentRequest = nullptr;
291 }
292 }
293 });
294 }
295 }
296 }

References core::EventReceiver::atNextTick(), currentRequest, core::socket::stream::SocketConnection::getConnectionName(), core::socket::stream::SocketContext::getSocketConnection(), web::http::client::Request::httpMajor, web::http::client::Request::httpMinor, initiateRequest(), masterRequest, web::http::client::Request::method, pendingRequests, pipelinedRequests, and web::http::client::Request::url.

Referenced by deliverResponse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ responseStarted()

void web::http::client::SocketContext::responseStarted ( )
private

Definition at line 209 of file SocketContext.cpp.

209 {
210 if (!deliveredRequests.empty()) {
211 const std::string requestLine = std::string(deliveredRequests.front().method)
212 .append(" ")
213 .append(deliveredRequests.front().url)
214 .append(" HTTP/")
215 .append(std::to_string(deliveredRequests.front().httpMajor))
216 .append(".")
217 .append(std::to_string(deliveredRequests.front().httpMinor));
218
219 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Response start: " << requestLine;
220 } else {
221 LOG(ERROR) << getSocketConnection()->getConnectionName() << " HTTP: Response without delivered request";
222
223 shutdownWrite(true);
224 }
225 }

References deliveredRequests, core::socket::stream::SocketConnection::getConnectionName(), core::socket::stream::SocketContext::getSocketConnection(), web::http::client::Request::httpMajor, web::http::client::Request::httpMinor, web::http::client::Request::method, core::socket::stream::SocketContext::shutdownWrite(), and web::http::client::Request::url.

Referenced by SocketContext().

Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Symbol Documentation

◆ web::http::client::Request

friend class web::http::client::Request
friend

Definition at line 117 of file SocketContext.h.

Member Data Documentation

◆ currentRequest

std::shared_ptr<Request> web::http::client::SocketContext::currentRequest = nullptr
private

◆ deliveredRequests

std::list<Request> web::http::client::SocketContext::deliveredRequests
private

◆ flags

int web::http::client::SocketContext::flags = Flags::NONE
private

Definition at line 115 of file SocketContext.h.

Referenced by requestPrepared().

◆ masterRequest

std::shared_ptr<Request> web::http::client::SocketContext::masterRequest
private

◆ onRequestBegin

std::function<void(const std::shared_ptr<Request>&)> web::http::client::SocketContext::onRequestBegin
private

Definition at line 89 of file SocketContext.h.

Referenced by onConnected(), and SocketContext().

◆ onRequestEnd

std::function<void(const std::shared_ptr<Request>&)> web::http::client::SocketContext::onRequestEnd
private

Definition at line 90 of file SocketContext.h.

Referenced by onDisconnected(), and SocketContext().

◆ parser

ResponseParser web::http::client::SocketContext::parser
private

Definition at line 106 of file SocketContext.h.

Referenced by onDisconnected(), onReceivedFromPeer(), and SocketContext().

◆ pendingRequests

std::list<Request> web::http::client::SocketContext::pendingRequests
private

◆ pipelinedRequests

bool web::http::client::SocketContext::pipelinedRequests = false
private

Definition at line 101 of file SocketContext.h.

Referenced by requestDelivered(), responseDelivered(), and SocketContext().


The documentation for this class was generated from the following files: