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
 
SocketConnectiongetSocketConnection () const
 
virtual void switchSocketContext (SocketContext *newSocketContext)
 
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
 
- 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 61 of file SocketContext.cpp.

69 , masterRequest(std::make_shared<Request>(this, getSocketConnection()->getConfiguredServer()))
70 , parser(
71 this,
72 [this]() {
74 },
75 [this](web::http::client::Response&& response) {
76 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Response parsed: HTTP/" << response.httpMajor << "."
77 << response.httpMinor << " " << response.statusCode << " " << response.reason;
78
79 deliverResponse(std::move(response));
80 },
81 [this](int status, const std::string& reason) {
82 deliverResponseParseError(status, reason);
83 }) {
84 masterRequest->setMasterRequest(masterRequest);
85 }
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

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

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::SocketContext.

Definition at line 87 of file SocketContext.cpp.

87 {
88 if (!deliveredRequests.empty()) {
89 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Responses missed";
90 for (const Request& request : deliveredRequests) {
91 LOG(DEBUG) << " " << request.method << " " << request.url << " HTTP/" << request.httpMajor << "." << request.httpMinor;
92 }
93 }
94
95 if (!pendingRequests.empty()) {
96 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Requests ignored";
97 for (const Request& request : pendingRequests) {
98 LOG(DEBUG) << " " << request.method << " " << request.url << " HTTP/" << request.httpMajor << "." << request.httpMinor;
99 }
100 }
101 }
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 223 of file SocketContext.cpp.

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

249 {
250 const std::shared_ptr<Request> request = std::make_shared<Request>(std::move(deliveredRequests.front()));
251 deliveredRequests.pop_front();
252
253 LOG(WARNING) << getSocketConnection()->getConnectionName() << " HTTP: Response parse error: " << reason << " (" << status << ") "
254 << std::string(request->method)
255 .append(" ")
256 .append(request->url)
257 .append(" HTTP/")
258 .append(std::to_string(request->httpMajor))
259 .append(".")
260 .append(std::to_string(request->httpMinor));
261
262 request->deliverResponseParseError(request, reason);
263
264 shutdownWrite(true);
265 }
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 134 of file SocketContext.cpp.

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

293 {
294 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: connected";
295
297 }

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 309 of file SocketContext.cpp.

309 {
310 if (!deliveredRequests.empty()) {
311 const Request& request = deliveredRequests.front();
312 if (request.httpMajor == 1 && request.httpMinor == 0) {
314 }
315 }
316
318
319 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: disconnected";
320 }

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 299 of file SocketContext.cpp.

299 {
300 std::size_t consumed = 0;
301
302 if (!deliveredRequests.empty()) {
303 consumed = parser.parse();
304 }
305
306 return consumed;
307 }
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 322 of file SocketContext.cpp.

322 {
323 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: received signal " << signum;
324
325 return true;
326 }

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 328 of file SocketContext.cpp.

328 {
329 // Do nothing in case of an write error
330 }

◆ requestDelivered()

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

Definition at line 168 of file SocketContext.cpp.

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

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 103 of file SocketContext.cpp.

103 {
104 const std::string requestLine = std::string(request.method)
105 .append(" ")
106 .append(request.url)
107 .append(" HTTP/")
108 .append(std::to_string(request.httpMajor))
109 .append(".")
110 .append(std::to_string(request.httpMinor));
111
114 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Request accepted: " << requestLine;
115
116 flags = (flags & ~Flags::HTTP11) | ((request.httpMajor == 1 && request.httpMinor == 1) ? Flags::HTTP11 : Flags::NONE);
117 flags = (flags & ~Flags::HTTP10) | ((request.httpMajor == 1 && request.httpMinor == 0) ? Flags::HTTP10 : Flags::NONE);
118 flags = (flags & ~Flags::KEEPALIVE) |
119 (web::http::ciContains(request.header("Connection"), "keep-alive") ? Flags::KEEPALIVE : Flags::NONE);
120 flags = (flags & ~Flags::CLOSE) | (web::http::ciContains(request.header("Connection"), "close") ? Flags::CLOSE : Flags::NONE);
121
122 if (!currentRequest) {
123 initiateRequest(request);
124 } else {
125 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Request queued: " << requestLine;
126
127 pendingRequests.emplace_back(std::move(request));
128 }
129 } else {
130 LOG(WARNING) << getSocketConnection()->getConnectionName() << " HTTP: Request rejected: " << requestLine;
131 }
132 }
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 267 of file SocketContext.cpp.

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

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 206 of file SocketContext.cpp.

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

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: