Loading ccsrc/Framework/include/layer.hh +19 −3 Original line number Diff line number Diff line Loading @@ -109,13 +109,28 @@ public: //! \publicsection * \todo Remove the logs * \virtual */ virtual void receive_data(OCTETSTRING &p_data, params &p_params) {} virtual void receive_data(OCTETSTRING &p_data, params &p_params) {}; /*! * \virtual * \fn void close_connection(); * \brief Request the transport layer(s) below to close the current * connection (e.g. after an HTTP "Connection: close" header). * The next send_data() on the transport layer re-establishes it. */ virtual void close_connection() { printf(">>> close_connection: lowerLayers size=%d\n", (int)lowerLayers.size()); for (std::vector<layer *>::const_iterator it = lowerLayers.cbegin(); it != lowerLayers.cend(); ++it) { (*it)->close_connection(); } printf("<<< close_connection\n"); }; /*! * \inline * \fn const std::string& to_string(); * \brief Remove the specified upper layer protocol from the list of the upper layer * \param[in] The layer protocol to be removed * \brief Return the string representation of the layer * \return The string representation of the layer */ inline const std::string& to_string() const { return type; }; Loading Loading @@ -144,3 +159,4 @@ protected: //! \protectedsection } // End of 'for' statement }; }; // End of class layer ccsrc/Protocols/Http/http_layer.cc +24 −1 Original line number Diff line number Diff line Loading @@ -220,8 +220,31 @@ void http_layer::receive_data(OCTETSTRING &p_data, params ¶ms) { return; } // "Connection: close" in a response means the server will close this connection after the response. // Tear the TCP connection down now so the next request is sent on a fresh connection instead of being RST by the server (see RFC 9112 §9.6). if (http_message.ischosen(LibHttp__TypesAndValues::HttpMessage::ALT_response)) { for (int i = 0; i < http_message.response().header().lengthof(); i++) { const CHARSTRING& hname = http_message.response().header()[i].header__name(); if (strcasecmp(static_cast<const char*>(hname), "Connection") != 0) { continue; } const OPTIONAL<LibHttp__TypesAndValues::charstring__list> &o = http_message.response().header()[i].header__value(); if (!o.ispresent()) { continue; } const LibHttp__TypesAndValues::charstring__list &v = dynamic_cast<const OPTIONAL<LibHttp__TypesAndValues::charstring__list> &>(o); for (int j = 0; j < v.lengthof(); j++) { if (strcasestr(static_cast<const char*>(v[j]), "close") != nullptr) { loggers::get_instance().log("http_layer::receive_data: 'Connection: close' received, closing transport connection"); close_connection(); // Propagates down to tcp_layer break; } } // End of 'for' statement } // End of 'for' statement } loggers::get_instance().log("http_layer::receive_data: Device mode: %d", _device_mode); if (_device_mode) { loggers::get_instance().log("http_layer::receive_data: Device mode set"); OCTETSTRING os(0, nullptr); if (http_message.ischosen(LibHttp__TypesAndValues::HttpMessage::ALT_response)) { if (http_message.response().body().ispresent()) { Loading ccsrc/Protocols/Tcp/tcp_layer.cc +21 −0 Original line number Diff line number Diff line Loading @@ -286,5 +286,26 @@ void tcp_layer::peer_disconnected(int p_client_id) _client_id = -1; } void tcp_layer::peer_half_closed(int p_client_id) { loggers::get_instance().log(">>> tcp_layer::peer_half_closed: %d", p_client_id); // The server sent a FIN (e.g. after "Connection: close"): the connection // cannot carry a new request. Drop it from the peer list so that // send_data() re-establishes a fresh connection on the next request. remove_client(p_client_id); peer_disconnected(p_client_id); } void tcp_layer::close_connection() { loggers::get_instance().log(">>> tcp_layer::close_connection: _client_id: %d", _client_id); if ((_params[params::server_mode].compare("0") == 0) && (_client_id != -1)) { remove_client(_client_id); _client_id = -1; } } tcp_layer_factory tcp_layer_factory::_f; ccsrc/Protocols/Tcp/tcp_layer.hh +6 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,11 @@ public: //! \publicsection */ virtual void receive_data(OCTETSTRING &p_data, params &info); /*! * \brief Close the active client connection so the next send_data() reconnects. */ virtual void close_connection(); /*! * \virtual * \fn void message_incoming(const uint8_t* message_buffer, int length, int client_id = -1); Loading Loading @@ -101,6 +106,7 @@ protected: //! \protectedsection int send_message_on_nonblocking_fd(int client_id, const uint8_t *message_buffer, int length_of_message); int receive_message_on_fd(int p_client_id); void peer_disconnected(int p_client_id); void peer_half_closed(int p_client_id); private: //! \privatesection void Handle_Fd_Event(int fd, boolean is_readable, boolean is_writable, boolean is_error); Loading Loading
ccsrc/Framework/include/layer.hh +19 −3 Original line number Diff line number Diff line Loading @@ -109,13 +109,28 @@ public: //! \publicsection * \todo Remove the logs * \virtual */ virtual void receive_data(OCTETSTRING &p_data, params &p_params) {} virtual void receive_data(OCTETSTRING &p_data, params &p_params) {}; /*! * \virtual * \fn void close_connection(); * \brief Request the transport layer(s) below to close the current * connection (e.g. after an HTTP "Connection: close" header). * The next send_data() on the transport layer re-establishes it. */ virtual void close_connection() { printf(">>> close_connection: lowerLayers size=%d\n", (int)lowerLayers.size()); for (std::vector<layer *>::const_iterator it = lowerLayers.cbegin(); it != lowerLayers.cend(); ++it) { (*it)->close_connection(); } printf("<<< close_connection\n"); }; /*! * \inline * \fn const std::string& to_string(); * \brief Remove the specified upper layer protocol from the list of the upper layer * \param[in] The layer protocol to be removed * \brief Return the string representation of the layer * \return The string representation of the layer */ inline const std::string& to_string() const { return type; }; Loading Loading @@ -144,3 +159,4 @@ protected: //! \protectedsection } // End of 'for' statement }; }; // End of class layer
ccsrc/Protocols/Http/http_layer.cc +24 −1 Original line number Diff line number Diff line Loading @@ -220,8 +220,31 @@ void http_layer::receive_data(OCTETSTRING &p_data, params ¶ms) { return; } // "Connection: close" in a response means the server will close this connection after the response. // Tear the TCP connection down now so the next request is sent on a fresh connection instead of being RST by the server (see RFC 9112 §9.6). if (http_message.ischosen(LibHttp__TypesAndValues::HttpMessage::ALT_response)) { for (int i = 0; i < http_message.response().header().lengthof(); i++) { const CHARSTRING& hname = http_message.response().header()[i].header__name(); if (strcasecmp(static_cast<const char*>(hname), "Connection") != 0) { continue; } const OPTIONAL<LibHttp__TypesAndValues::charstring__list> &o = http_message.response().header()[i].header__value(); if (!o.ispresent()) { continue; } const LibHttp__TypesAndValues::charstring__list &v = dynamic_cast<const OPTIONAL<LibHttp__TypesAndValues::charstring__list> &>(o); for (int j = 0; j < v.lengthof(); j++) { if (strcasestr(static_cast<const char*>(v[j]), "close") != nullptr) { loggers::get_instance().log("http_layer::receive_data: 'Connection: close' received, closing transport connection"); close_connection(); // Propagates down to tcp_layer break; } } // End of 'for' statement } // End of 'for' statement } loggers::get_instance().log("http_layer::receive_data: Device mode: %d", _device_mode); if (_device_mode) { loggers::get_instance().log("http_layer::receive_data: Device mode set"); OCTETSTRING os(0, nullptr); if (http_message.ischosen(LibHttp__TypesAndValues::HttpMessage::ALT_response)) { if (http_message.response().body().ispresent()) { Loading
ccsrc/Protocols/Tcp/tcp_layer.cc +21 −0 Original line number Diff line number Diff line Loading @@ -286,5 +286,26 @@ void tcp_layer::peer_disconnected(int p_client_id) _client_id = -1; } void tcp_layer::peer_half_closed(int p_client_id) { loggers::get_instance().log(">>> tcp_layer::peer_half_closed: %d", p_client_id); // The server sent a FIN (e.g. after "Connection: close"): the connection // cannot carry a new request. Drop it from the peer list so that // send_data() re-establishes a fresh connection on the next request. remove_client(p_client_id); peer_disconnected(p_client_id); } void tcp_layer::close_connection() { loggers::get_instance().log(">>> tcp_layer::close_connection: _client_id: %d", _client_id); if ((_params[params::server_mode].compare("0") == 0) && (_client_id != -1)) { remove_client(_client_id); _client_id = -1; } } tcp_layer_factory tcp_layer_factory::_f;
ccsrc/Protocols/Tcp/tcp_layer.hh +6 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,11 @@ public: //! \publicsection */ virtual void receive_data(OCTETSTRING &p_data, params &info); /*! * \brief Close the active client connection so the next send_data() reconnects. */ virtual void close_connection(); /*! * \virtual * \fn void message_incoming(const uint8_t* message_buffer, int length, int client_id = -1); Loading Loading @@ -101,6 +106,7 @@ protected: //! \protectedsection int send_message_on_nonblocking_fd(int client_id, const uint8_t *message_buffer, int length_of_message); int receive_message_on_fd(int p_client_id); void peer_disconnected(int p_client_id); void peer_half_closed(int p_client_id); private: //! \privatesection void Handle_Fd_Event(int fd, boolean is_readable, boolean is_writable, boolean is_error); Loading