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
 
- 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 43 of file SocketContext.h.

Member Typedef Documentation

◆ Request

◆ Response

◆ Super

Member Enumeration Documentation

◆ Flags

Enumerator
NONE 
HTTP10 
HTTP11 
KEEPALIVE 
CLOSE 

Definition at line 86 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 39 of file SocketContext.cpp.

47 , masterRequest(std::make_shared<Request>(this, getSocketConnection()->getConfiguredServer()))
48 , parser(
49 this,
50 [this]() {
52 },
53 [this](web::http::client::Response&& response) {
54 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Response parsed: HTTP/" << response.httpMajor << "."
55 << response.httpMinor << " " << response.statusCode << " " << response.reason;
56
57 deliverResponse(std::move(response));
58 },
59 [this](int status, const std::string& reason) {
60 deliverResponseParseError(status, reason);
61 }) {
62 masterRequest->setMasterRequest(masterRequest);
63 }
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 pipelinedRequests, and SocketContext().

Referenced by SocketContext().

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

65 {
66 if (!deliveredRequests.empty()) {
67 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Responses missed";
68 for (const Request& request : deliveredRequests) {
69 LOG(DEBUG) << " " << request.method << " " << request.url << " HTTP/" << request.httpMajor << "." << request.httpMinor;
70 }
71 }
72
73 if (!pendingRequests.empty()) {
74 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Requests ignored";
75 for (const Request& request : pendingRequests) {
76 LOG(DEBUG) << " " << request.method << " " << request.url << " HTTP/" << request.httpMajor << "." << request.httpMinor;
77 }
78 }
79 }
web::http::client::Request Request
std::list< Request > deliveredRequests
std::list< Request > pendingRequests

Member Function Documentation

◆ deliverResponse()

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

Definition at line 201 of file SocketContext.cpp.

201 {
202 const std::shared_ptr<Request> request = std::make_shared<Request>(std::move(deliveredRequests.front()));
203 deliveredRequests.pop_front();
204
205 const std::string requestLine = std::string(request->method)
206 .append(" ")
207 .append(request->url)
208 .append(" HTTP/")
209 .append(std::to_string(request->httpMajor))
210 .append(".")
211 .append(std::to_string(request->httpMinor));
212
213 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Response ready: " << requestLine;
214
215 const bool httpClose =
216 response.connectionState == ConnectionState::Close ||
217 (response.connectionState == ConnectionState::Default &&
218 ((response.httpMajor == 0 && response.httpMinor == 9) || (response.httpMajor == 1 && response.httpMinor == 0)));
219
220 request->deliverResponse(request, std::make_shared<Response>(std::move(response)));
221
222 responseDelivered(httpClose);
223
224 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Response completed: " << requestLine;
225 }
void responseDelivered(bool httpClose)

References responseDelivered().

Here is the call graph for this function:

◆ deliverResponseParseError()

void web::http::client::SocketContext::deliverResponseParseError ( int status,
const std::string & reason )
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 LOG(WARNING) << getSocketConnection()->getConnectionName() << " HTTP: Response parse error: " << reason << " (" << status << ") "
232 << std::string(request->method)
233 .append(" ")
234 .append(request->url)
235 .append(" HTTP/")
236 .append(std::to_string(request->httpMajor))
237 .append(".")
238 .append(std::to_string(request->httpMinor));
239
240 request->deliverResponseParseError(request, reason);
241
242 shutdownWrite(true);
243 }
void shutdownWrite(bool forceClose=false)

◆ initiateRequest()

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

Definition at line 112 of file SocketContext.cpp.

112 {
113 currentRequest = std::make_shared<Request>(std::move(request));
114
115 const std::string requestLine = std::string(currentRequest->method)
116 .append(" ")
117 .append(currentRequest->url)
118 .append(" HTTP/")
119 .append(std::to_string(currentRequest->httpMajor))
120 .append(".")
121 .append(std::to_string(currentRequest->httpMinor));
122
123 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Request delivering: " << requestLine;
124
125 if (!currentRequest->initiate()) {
126 LOG(WARNING) << getSocketConnection()->getConnectionName() << " HTTP: Request delivering failed: " << requestLine;
127
128 core::EventReceiver::atNextTick([this, masterRequest = static_cast<std::weak_ptr<Request>>(masterRequest)]() {
129 if (!masterRequest.expired()) {
130 if (!pendingRequests.empty()) {
131 Request& request = pendingRequests.front();
132
133 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Request dequeued: " << request.method << " "
134 << request.url << " HTTP/" << request.httpMajor << "." << request.httpMinor;
135
136 initiateRequest(request);
137 pendingRequests.pop_front();
138 } else {
139 currentRequest = nullptr;
140 }
141 }
142 });
143 }
144 }
static void atNextTick(const std::function< void(void)> &callBack)
std::shared_ptr< Request > currentRequest

Referenced by requestPrepared().

Here is the caller graph for this function:

◆ onConnected()

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

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

Definition at line 271 of file SocketContext.cpp.

271 {
272 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: connected";
273
275 }

◆ onDisconnected()

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

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

Definition at line 287 of file SocketContext.cpp.

287 {
288 if (!deliveredRequests.empty()) {
289 const Request& request = deliveredRequests.front();
290 if (request.httpMajor == 1 && request.httpMinor == 0) {
292 }
293 }
294
296
297 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: disconnected";
298 }

References web::http::client::Request::httpMajor, and web::http::client::Request::httpMinor.

◆ onReceivedFromPeer()

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

Implements core::socket::SocketContext.

Definition at line 277 of file SocketContext.cpp.

277 {
278 std::size_t consumed = 0;
279
280 if (!deliveredRequests.empty()) {
281 consumed = parser.parse();
282 }
283
284 return consumed;
285 }
std::size_t parse()
Definition Parser.cpp:70

◆ onSignal()

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

Implements core::socket::SocketContext.

Definition at line 300 of file SocketContext.cpp.

300 {
301 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: received signal " << signum;
302
303 return true;
304 }

◆ onWriteError()

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

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

Definition at line 306 of file SocketContext.cpp.

306 {
307 // Do nothing in case of an write error
308 }

◆ requestDelivered()

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

Definition at line 146 of file SocketContext.cpp.

146 {
147 const std::string requestLine = std::string(request.method)
148 .append(" ")
149 .append(request.url)
150 .append(" HTTP/")
151 .append(std::to_string(request.httpMajor))
152 .append(".")
153 .append(std::to_string(request.httpMinor));
154
155 if (success) {
156 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Request delivered: " << requestLine;
157
158 deliveredRequests.emplace_back(std::move(request));
159
160 if (pipelinedRequests) {
161 core::EventReceiver::atNextTick([this, masterRequest = static_cast<std::weak_ptr<Request>>(masterRequest)]() {
162 if (!masterRequest.expired()) {
163 if (!pendingRequests.empty()) {
164 Request& request = pendingRequests.front();
165
166 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Request dequeued: " << request.method << " "
167 << request.url << " HTTP/" << request.httpMajor << "." << request.httpMinor;
168
169 initiateRequest(request);
170 pendingRequests.pop_front();
171 } else {
172 currentRequest = nullptr;
173 }
174 }
175 });
176 }
177 } else {
178 LOG(WARNING) << getSocketConnection()->getConnectionName() << " HTTP: Request delivering failed: " << requestLine;
179
181 }
182 }

References pipelinedRequests.

◆ requestPrepared()

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

Definition at line 81 of file SocketContext.cpp.

81 {
82 const std::string requestLine = std::string(request.method)
83 .append(" ")
84 .append(request.url)
85 .append(" HTTP/")
86 .append(std::to_string(request.httpMajor))
87 .append(".")
88 .append(std::to_string(request.httpMinor));
89
92 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Request accepted: " << requestLine;
93
94 flags = (flags & ~Flags::HTTP11) | ((request.httpMajor == 1 && request.httpMinor == 1) ? Flags::HTTP11 : Flags::NONE);
95 flags = (flags & ~Flags::HTTP10) | ((request.httpMajor == 1 && request.httpMinor == 0) ? Flags::HTTP10 : Flags::NONE);
96 flags = (flags & ~Flags::KEEPALIVE) |
97 (web::http::ciContains(request.header("Connection"), "keep-alive") ? Flags::KEEPALIVE : Flags::NONE);
98 flags = (flags & ~Flags::CLOSE) | (web::http::ciContains(request.header("Connection"), "close") ? Flags::CLOSE : Flags::NONE);
99
100 if (!currentRequest) {
101 initiateRequest(request);
102 } else {
103 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Request queued: " << requestLine;
104
105 pendingRequests.emplace_back(std::move(request));
106 }
107 } else {
108 LOG(WARNING) << getSocketConnection()->getConnectionName() << " HTTP: Request rejected: " << requestLine;
109 }
110 }
void initiateRequest(Request &request)
bool ciContains(const std::string &str1, const std::string &str2)

References CLOSE, flags, HTTP10, HTTP11, web::http::client::Request::httpMajor, web::http::client::Request::httpMinor, initiateRequest(), KEEPALIVE, and NONE.

Here is the call graph for this function:

◆ responseDelivered()

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

Definition at line 245 of file SocketContext.cpp.

245 {
246 if (httpClose) {
247 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Connection = Close";
248 } else {
249 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Connection = Keep-Alive";
250
251 if (!pipelinedRequests) {
252 core::EventReceiver::atNextTick([this, masterRequest = static_cast<std::weak_ptr<Request>>(masterRequest)]() {
253 if (!masterRequest.expired()) {
254 if (!pendingRequests.empty()) {
255 Request& request = pendingRequests.front();
256
257 LOG(DEBUG) << getSocketConnection()->getConnectionName() << " HTTP: Request dequeued: " << request.method << " "
258 << request.url << " HTTP/" << request.httpMajor << "." << request.httpMinor;
259
260 initiateRequest(request);
261 pendingRequests.pop_front();
262 } else {
263 currentRequest = nullptr;
264 }
265 }
266 });
267 }
268 }
269 }

References pipelinedRequests.

Referenced by deliverResponse().

Here is the caller graph for this function:

◆ responseStarted()

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

Definition at line 184 of file SocketContext.cpp.

184 {
185 if (!deliveredRequests.empty()) {
186 const std::string requestLine = std::string(deliveredRequests.front().method)
187 .append(" ")
188 .append(deliveredRequests.front().url)
189 .append(" HTTP/")
190 .append(std::to_string(deliveredRequests.front().httpMajor))
191 .append(".")
192 .append(std::to_string(deliveredRequests.front().httpMinor));
193
194 LOG(INFO) << getSocketConnection()->getConnectionName() << " HTTP: Response started: " << requestLine;
195 } else {
196 LOG(ERROR) << getSocketConnection()->getConnectionName() << " HTTP: Response without delivered request";
197 shutdownWrite(true);
198 }
199 }

Friends And Related Symbol Documentation

◆ web::http::client::Request

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

Definition at line 95 of file SocketContext.h.

Member Data Documentation

◆ currentRequest

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

Definition at line 81 of file SocketContext.h.

◆ deliveredRequests

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

Definition at line 77 of file SocketContext.h.

◆ flags

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

Definition at line 93 of file SocketContext.h.

Referenced by requestPrepared().

◆ masterRequest

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

Definition at line 82 of file SocketContext.h.

◆ onRequestBegin

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

Definition at line 67 of file SocketContext.h.

◆ onRequestEnd

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

Definition at line 68 of file SocketContext.h.

◆ parser

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

Definition at line 84 of file SocketContext.h.

◆ pendingRequests

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

Definition at line 76 of file SocketContext.h.

◆ pipelinedRequests

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

Definition at line 79 of file SocketContext.h.

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


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