Loading ccsrc/Protocols/Http/http_codec.cc +205 −65 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ #include "loggers.hh" #include "LibItsHttp_TypesAndValues.hh" #include "LibItsHttp_MessageBodyTypes.hh" #include "LibItsHttp_XmlMessageBodyTypes.hh" int http_codec::encode (const LibItsHttp__TypesAndValues::HttpMessage& msg, OCTETSTRING& data) { Loading @@ -15,11 +17,13 @@ int http_codec::encode (const LibItsHttp__TypesAndValues::HttpMessage& msg, OCTE TTCN_EncDec::clear_error(); TTCN_Buffer encoding_buffer; _ec.reset(); int result; if (msg.ischosen(LibItsHttp__TypesAndValues::HttpMessage::ALT_request)) { result = encode_request(msg.request(), encoding_buffer); } else if (msg.ischosen(LibItsHttp__TypesAndValues::HttpMessage::ALT_response)) { //result = encode_response(msg.response(), encoding_buffer); result = encode_response(msg.response(), encoding_buffer); } else { loggers::get_instance().warning("http_codec::encode: Unbound HttpMessage"); return -1; Loading @@ -34,9 +38,13 @@ int http_codec::encode (const LibItsHttp__TypesAndValues::HttpMessage& msg, OCTE int http_codec::decode (const OCTETSTRING& data, LibItsHttp__TypesAndValues::HttpMessage& msg, params* params) { loggers::get_instance().log_msg(">>> http_codec::decode: data=", data); TTCN_EncDec::clear_error(); TTCN_Buffer decoding_buffer(data); loggers::get_instance().log_to_hexa("http_codec::decode: decoding_buffer=", decoding_buffer); _dc.reset(); _params = params; // Get the first line (e.g. HTTP/1.1 302 Found or POST / HTTP/1.1) Loading @@ -54,9 +62,10 @@ int http_codec::decode (const OCTETSTRING& data, LibItsHttp__TypesAndValues::Htt loggers::get_instance().log("http_codec::decode: %d - %s", m.size(), m[0].str().c_str()); if (m[0].str().compare("HTTP/") == 0) { // HTTP response LibItsHttp__TypesAndValues::Response response; std::regex rgx ("\\s*HTTP/(\\d)\\.(\\d)\\s+(\\d+)\\s+(\\w+)"); std::regex rgx ("\\s*HTTP/(\\d+)\\.(\\d+)\\s+(\\d+)\\s+(\\w+)*"); std::sregex_iterator begin(str.cbegin(), str.cend(), rgx); std::smatch m = *begin; loggers::get_instance().log("http_codec::decode: Process response: %d", m.size()); if (m.size() != 5) { loggers::get_instance().error("http_codec::decode: Unsupported tag"); return -1; Loading @@ -69,13 +78,11 @@ int http_codec::decode (const OCTETSTRING& data, LibItsHttp__TypesAndValues::Htt decode_headers(decoding_buffer, headers); response.header() = headers; loggers::get_instance().log_to_hexa("Before decoding Body: ", decoding_buffer); CHARSTRING body(""); LibItsHttp__MessageBodyTypes::HttpMessageBody body; if (decode_body(decoding_buffer, body) == -1) { response.body().set_to_omit(); } else if (body.lengthof() == 0) { response.body().set_to_omit(); } else { // TODO response.body() = OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody>(body); } msg.response() = response; } else { // HTTP request Loading @@ -94,14 +101,12 @@ int http_codec::decode (const OCTETSTRING& data, LibItsHttp__TypesAndValues::Htt LibItsHttp__TypesAndValues::HeaderLines headers; decode_headers(decoding_buffer, headers); request.header() = headers; loggers::get_instance().log_to_hexa("Before decoding Body: ", decoding_buffer); CHARSTRING body(""); OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody> body; body.set_to_omit(); if (decode_body(decoding_buffer, body) == -1) { request.body().set_to_omit(); } else if (body.lengthof() == 0) { request.body().set_to_omit(); } else { // TODO request.body() = body; } msg.request() = request; } Loading @@ -119,11 +124,20 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ loggers::get_instance().log_msg(">>> http_codec::encode_request: ", (const Base_Type&)p_request); const OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody>& v = p_request.body(); CHARSTRING body(""); OCTETSTRING os; if (v.ispresent()) { // FIXME body = static_cast<const CHARSTRING&>(*v.get_opt_value()); const LibItsHttp__MessageBodyTypes::HttpMessageBody& body = static_cast<const LibItsHttp__MessageBodyTypes::HttpMessageBody&>(*v.get_opt_value()); loggers::get_instance().log_msg("http_codec::encode_request: body: ", body); if (body.ischosen(LibItsHttp__MessageBodyTypes::HttpMessageBody::ALT_ms__body)) { os = body.ms__body(); } else { LibItsHttp__XmlMessageBodyTypes::XmlBody xml_body = body.xml__body(); if (xml_body.ischosen(LibItsHttp__XmlMessageBodyTypes::XmlBody::ALT_raw)) { os = OCTETSTRING(xml_body.raw().lengthof(), (unsigned char*)static_cast<const char*>(xml_body.raw())); } } } loggers::get_instance().log("http_codec::encode_request: HTTP message lenght: %d ", os.lengthof()); // Encode generic part p_encoding_buffer.put_cs(p_request.method()); Loading @@ -142,8 +156,8 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ p_encoding_buffer.put_cs(header.header__name()); p_encoding_buffer.put_cs(": "); if (std::string(static_cast<const char*>(header.header__name())).compare("Content-Length") == 0) { loggers::get_instance().log("http_codec::encode_request: body length: %d", body.lengthof()); p_encoding_buffer.put_cs(int2str(body.lengthof())); p_encoding_buffer.put_cs(int2str(os.lengthof() + 2/*Stand for the last CRLF*/)); _ec.is_content_length_present = 0x01; } else { const OPTIONAL<LibItsHttp__TypesAndValues::charstring__list>& o = header.header__value(); if (o.ispresent()) { Loading @@ -153,7 +167,7 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ p_encoding_buffer.put_cs(v[0]); int j = 1; while (j < v.size_of()) { p_encoding_buffer.put_cs("; "); p_encoding_buffer.put_cs(", "); loggers::get_instance().log_msg("http_codec::encode_request: Processing value ", v[j]); p_encoding_buffer.put_cs(v[j]); j += 1; Loading @@ -164,16 +178,85 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ p_encoding_buffer.put_cs("\r\n"); } // End of 'for' statement if (body.lengthof() != 0) { p_encoding_buffer.put_cs(body); p_encoding_buffer.put_cs("\r\n"); if (_ec.length != 0) { p_encoding_buffer.put_os(os); p_encoding_buffer.put_cs("\r\n"); } return 0; } int http_codec::encode_response (const LibItsHttp__TypesAndValues::Response& p_response, TTCN_Buffer& p_encoding_buffer) { loggers::get_instance().log_msg(">>> http_codec::encode_response: ", (const Base_Type&)p_response); const OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody>& v = p_response.body(); OCTETSTRING os; if (v.ispresent()) { const LibItsHttp__MessageBodyTypes::HttpMessageBody& body = static_cast<const LibItsHttp__MessageBodyTypes::HttpMessageBody&>(*v.get_opt_value()); loggers::get_instance().log_msg("http_codec::encode_response: body: ", body); if (body.ischosen(LibItsHttp__MessageBodyTypes::HttpMessageBody::ALT_ms__body)) { os = body.ms__body(); } else { LibItsHttp__XmlMessageBodyTypes::XmlBody xml_body = body.xml__body(); if (xml_body.ischosen(LibItsHttp__XmlMessageBodyTypes::XmlBody::ALT_raw)) { os = OCTETSTRING(xml_body.raw().lengthof(), (unsigned char*)static_cast<const char*>(xml_body.raw())); } } } loggers::get_instance().log("http_codec::encode_response: HTTP message lenght: %d ", os.lengthof()); // Encode generic part p_encoding_buffer.put_cs("HTTP/"); p_encoding_buffer.put_cs(int2str(p_response.version__major())); p_encoding_buffer.put_c('.'); p_encoding_buffer.put_cs(int2str(p_response.version__minor())); p_encoding_buffer.put_cs(" "); p_encoding_buffer.put_cs(int2str(p_response.statuscode())); p_encoding_buffer.put_cs(" "); if (p_response.statustext().lengthof() != 0) { p_encoding_buffer.put_cs(p_response.statustext()); } p_encoding_buffer.put_cs("\r\n"); // Encode headers const LibItsHttp__TypesAndValues::HeaderLines& headers = p_response.header(); for (int i = 0; i < headers.size_of(); i++) { const LibItsHttp__TypesAndValues::HeaderLine& header = headers[i]; loggers::get_instance().log_msg("http_codec::encode_response: Processing header ", header.header__name()); p_encoding_buffer.put_cs(header.header__name()); p_encoding_buffer.put_cs(": "); if (std::string(static_cast<const char*>(header.header__name())).compare("Content-Length") == 0) { p_encoding_buffer.put_cs(int2str(os.lengthof() + 2/*Stand for the last CRLF*/)); _ec.is_content_length_present = 0x01; } else { const OPTIONAL<LibItsHttp__TypesAndValues::charstring__list>& o = header.header__value(); if (o.ispresent()) { const LibItsHttp__TypesAndValues::charstring__list& v = dynamic_cast<const OPTIONAL<LibItsHttp__TypesAndValues::charstring__list> &>(o); if (v.size_of() > 0) { loggers::get_instance().log_msg("http_codec::encode_response: Processing value ", v[0]); p_encoding_buffer.put_cs(v[0]); int j = 1; while (j < v.size_of()) { p_encoding_buffer.put_cs(", "); loggers::get_instance().log_msg("http_codec::encode_response: Processing value ", v[j]); p_encoding_buffer.put_cs(v[j]); j += 1; } // End of 'while' statement } } // else, do not include it } p_encoding_buffer.put_cs("\r\n"); } // End of 'for' statement p_encoding_buffer.put_cs("\r\n"); if (_ec.length != 0) { p_encoding_buffer.put_os(os); p_encoding_buffer.put_cs("\r\n"); } return 0; } int http_codec::decode_headers(TTCN_Buffer& decoding_buffer, LibItsHttp__TypesAndValues::HeaderLines& headers) { loggers::get_instance().log(">>> http_codec::decode_headers"); loggers::get_instance().log_to_hexa("http_codec::decode_headers", decoding_buffer); Loading @@ -198,7 +281,6 @@ int http_codec::decode_headers(TTCN_Buffer& decoding_buffer, LibItsHttp__TypesAn case -1: loggers::get_instance().warning("http_codec::decode_headers: Failed to decode headers"); return -1; } // End of 'switch' statement } // End of 'while' statement } Loading @@ -208,12 +290,14 @@ int http_codec::decode_header(CHARSTRING& header_line, LibItsHttp__TypesAndValue try { std::string str(static_cast<const char*>(header_line)); std::regex rgx ("([0-9a-zA-Z-]+)\\:\\s+(.+)(;(.+))*"); std::regex rgx ("([0-9a-zA-Z-]+)\\:\\s+(.+)(,(.+))*"); std::sregex_iterator begin(str.cbegin(), str.cend(), rgx); std::smatch m = *begin; if (m.size() < 5) { loggers::get_instance().warning("http_codec::decode_header: Failed to decode header %s", str.c_str()); return -1; } loggers::get_instance().log("http_codec::decode_header: %d", m.size()); header.header__name() = CHARSTRING(m[1].str().c_str()); LibItsHttp__TypesAndValues::charstring__list v; for (unsigned int j = 0; j < m.size(); j++) { Loading @@ -222,8 +306,13 @@ int http_codec::decode_header(CHARSTRING& header_line, LibItsHttp__TypesAndValue } v[j] = CHARSTRING(m[j + 2].str().c_str()); } // End of 'for' statement header.header__value() = OPTIONAL<LibItsHttp__TypesAndValues::charstring__list>(v); if (m[1].str().compare("Content-Length") == 0) { // Save the the body length loggers::get_instance().log("http_codec::decode_header: decoded Content-Length %s", m[2].str().c_str()); _dc.length = std::stoi(m[2].str()); } return 0; } catch(const std::logic_error& e) { Loading @@ -231,14 +320,65 @@ int http_codec::decode_header(CHARSTRING& header_line, LibItsHttp__TypesAndValue } } int http_codec::decode_body(TTCN_Buffer& decoding_buffer, CHARSTRING& body) { int http_codec::decode_body(TTCN_Buffer& decoding_buffer, LibItsHttp__MessageBodyTypes::HttpMessageBody& message_body) { loggers::get_instance().log(">>> http_codec::decode_body"); loggers::get_instance().log_to_hexa("http_codec::decode_body", decoding_buffer); loggers::get_instance().log_msg("<<< http_codec::decode_body: ", body); // Sanity check if (decoding_buffer.get_len() - decoding_buffer.get_pos() <= 0) { return -1; } OCTETSTRING s(decoding_buffer.get_len() - decoding_buffer.get_pos(), decoding_buffer.get_data() + decoding_buffer.get_pos()); loggers::get_instance().log_msg("http_codec::decode_body: raw body=", s); // Align the payload length with the specified plLenght value loggers::get_instance().log("http_codec::decode_body: _dc.length=%d - body length=%d", _dc.length, s.lengthof()); OCTETSTRING body; if (_dc.length != 0) { const unsigned char* p = static_cast<const unsigned char *>(s); if ((unsigned int)s.lengthof() <= _dc.length) { body = OCTETSTRING(s.lengthof(), p); } else { body = OCTETSTRING(_dc.length, p); } } else { loggers::get_instance().warning("http_codec::decode_body: No Conten-Length header, process all remaining bytes"); body = s; } loggers::get_instance().log_msg("http_codec::decode_body: Aligned body=", body); // Remove CRLF if any int counter = 0; if ((body[body.lengthof() - 1].get_octet() == 0x0d) || (body[body.lengthof() - 1].get_octet() == 0x0a)) { counter += 1; if ((body[body.lengthof() - 2].get_octet() == 0x0d) || (body[body.lengthof() - 2].get_octet() == 0x0a)) { counter += 1; } } loggers::get_instance().log("http_codec::decode_body: Counter=%d", counter); body = OCTETSTRING(body.lengthof() - counter, static_cast<const unsigned char*>(body)); loggers::get_instance().log_msg("http_codec::decode_body: Finalised body=", body); // Check if HTTP message body contains binary characters for (int i = 0; i < body.lengthof(); i++) { unsigned char c = body[i].get_octet(); if (!std::isprint(c) && !std::isspace(c) && !std::ispunct(c)) { loggers::get_instance().log("http_codec::decode_body: Byte #%d is not printable: 0x%02x", i, body[i].get_octet()); _dc.is_binary = 0x01; break; } } // End of 'for' statement loggers::get_instance().log("http_codec::decode_body: Binary mode: %x", _dc.is_binary); LibItsHttp__MessageBodyTypes::HttpMessageBody v; if (_dc.is_binary == 0x01) { message_body.ms__body() = body; } else { LibItsHttp__XmlMessageBodyTypes::XmlBody xml_body; xml_body.raw() = CHARSTRING(body.lengthof(), (char*)static_cast<const unsigned char*>(body)); message_body.xml__body() = xml_body; } return 0; } int http_codec::get_line(TTCN_Buffer& buffer, CHARSTRING& to, const bool concatenate_header_lines) { unsigned int i = 0; const unsigned char *cc_to = buffer.get_read_data(); Loading @@ -249,7 +389,7 @@ int http_codec::get_line(TTCN_Buffer& buffer, CHARSTRING& to, const bool concate } while (true) { // Skip spaces, and emplty lines // Skip spaces, and empty lines for( ; i < buffer.get_read_len() && cc_to[i] != '\0' && cc_to[i] != '\r' && cc_to[i] != '\n'; i++); if(i >= buffer.get_read_len()) { // No more characters to process to = CHARSTRING(""); Loading ccsrc/Protocols/Http/http_codec.hh +24 −3 Original line number Diff line number Diff line Loading @@ -14,13 +14,34 @@ namespace LibItsHttp__TypesAndValues { class HeaderLines; class HeaderLine; } namespace LibItsHttp__MessageBodyTypes { class HttpMessageBody; } struct encoding_context { unsigned int length; unsigned char is_content_length_present; encoding_context() { reset(); }; void reset() { length = -1; is_content_length_present = 0x00; }; }; struct decoding_context { unsigned int length; unsigned char is_binary; decoding_context() { reset(); }; void reset() { length = -1; is_binary = 0x00; }; }; class http_codec: public codec < LibItsHttp__TypesAndValues::HttpMessage, LibItsHttp__TypesAndValues::HttpMessage> { encoding_context _ec; decoding_context _dc; public: explicit http_codec() : codec<LibItsHttp__TypesAndValues::HttpMessage, LibItsHttp__TypesAndValues::HttpMessage>() { }; explicit http_codec() : codec<LibItsHttp__TypesAndValues::HttpMessage, LibItsHttp__TypesAndValues::HttpMessage>(), _ec(), _dc() { }; virtual ~http_codec() { }; virtual int encode (const LibItsHttp__TypesAndValues::HttpMessage&, OCTETSTRING& data); Loading @@ -28,11 +49,11 @@ public: private: int encode_request (const LibItsHttp__TypesAndValues::Request& p_request, TTCN_Buffer& p_encoding_buffer); // int encode_response (const LibItsHttp__TypesAndValues::Request&, TTCN_Buffer& p_encoding_buffer); int encode_response (const LibItsHttp__TypesAndValues::Response& p_response, TTCN_Buffer& p_encoding_buffer); int decode_headers(TTCN_Buffer& decoding_buffer, LibItsHttp__TypesAndValues::HeaderLines& headers); int decode_header(CHARSTRING& header_line, LibItsHttp__TypesAndValues::HeaderLine& header); int decode_body(TTCN_Buffer& decoding_buffer, CHARSTRING& body); int decode_body(TTCN_Buffer& decoding_buffer, LibItsHttp__MessageBodyTypes::HttpMessageBody& message_body); int get_line(TTCN_Buffer& buffer, CHARSTRING& to, const bool concatenate_header_lines = false); }; // End of class http_codec ccsrc/Protocols/Http/http_layer.cc +59 −67 Original line number Diff line number Diff line Loading @@ -10,54 +10,26 @@ using namespace std; // Required for isnan() #include "LibItsHttp_TypesAndValues.hh" #include "LibItsHttp_TestSystem.hh" http_layer::http_layer(const std::string & p_type, const std::string & param) : t_layer<LibItsHttp__TestSystem::HttpPort>(p_type), _params(), _codec(), _headers(new LibItsHttp__TypesAndValues::HeaderLines)//, _device_mode{false} http_layer::http_layer(const std::string & p_type, const std::string & param) : t_layer<LibItsHttp__TestSystem::HttpPort>(p_type), _params()//, _device_mode{false} { loggers::get_instance().log(">>> http_layer::http_layer: %s, %s", to_string().c_str(), param.c_str()); // Setup parameters params::convert(_params, param); } void http_layer::sendMsg(const LibItsHttp__TypesAndValues::HttpMessage& p_http_message, params& p_param) { loggers::get_instance().log_msg(">>> http_layer::sendMsg: ", p_http_message); // Build basic headers int i = 0; LibItsHttp__TypesAndValues::charstring__list values; values[0] = "application/xml"; (*_headers)[i++] = LibItsHttp__TypesAndValues::HeaderLine(CHARSTRING("Accept"), values); values.set_size(0); values[0] = "application/xml"; values[1] = "charset=utf-8"; (*_headers)[i++] = LibItsHttp__TypesAndValues::HeaderLine(CHARSTRING("Content-Type"), values); values.set_size(0); values[0] = "0"; (*_headers)[i++] = LibItsHttp__TypesAndValues::HeaderLine(CHARSTRING("Content-Length"), values); values.set_size(0); values[0] = "www.google.com"; (*_headers)[i++] = LibItsHttp__TypesAndValues::HeaderLine(CHARSTRING("Host"), values); values.set_size(0); // Encode HttpMessage OCTETSTRING data; _codec.encode(p_http_message, data); send_data(data, _params); } void http_layer::send_data(OCTETSTRING& data, params& params) { loggers::get_instance().log_msg(">>> http_layer::send_data: ", data); params::const_iterator it = params.find("HttpMethod"); LibItsHttp__TypesAndValues::HttpMessage msg; if (it != params.cend()) { } else { // Assume it is a GET LibItsHttp__TypesAndValues::Request request; request.method() = "GET"; request.uri() = "/"; request.version__major() = 1; request.version__minor() = 1; request.header() = *_headers.get(); std::vector<uint8_t> buf(static_cast<const unsigned char *>(data), data.lengthof() + static_cast<const unsigned char *>(data)); // FIXME // CHARSTRING c(converter::get_instance().bytes_to_string(buf).c_str()); // request.body() = OPTIONAL<CHARSTRING>(c); msg.request() = request; } loggers::get_instance().log_msg("http_layer::send_data: HttpMessage: ", msg); OCTETSTRING os; _codec.encode(msg, os); send_to_all_layers(os, params); send_to_all_layers(data, params); } void http_layer::receive_data(OCTETSTRING& data, params& params) Loading @@ -65,37 +37,57 @@ void http_layer::receive_data(OCTETSTRING& data, params& params) loggers::get_instance().log_msg(">>> http_layer::receive_data: ", data); // Decode HTTP message LibItsHttp__TypesAndValues::HttpMessage httpMessage; if (_codec.decode(data, httpMessage) == -1) { LibItsHttp__TypesAndValues::HttpMessage http_message; if (_codec.decode(data, http_message) == -1) { loggers::get_instance().warning("http_layer::receive_data: Failed to decode data"); return; } // Extract payload OCTETSTRING payload; if (httpMessage.ischosen(LibItsHttp__TypesAndValues::HttpMessage::ALT_request)) { if (httpMessage.request().body().is_present()) { const CHARSTRING& body = static_cast<OPTIONAL<CHARSTRING>&>(*(httpMessage.request().body().get_opt_value())); std::vector<uint8_t> buf = converter::get_instance().string_to_bytes(static_cast<const char*>(body)); payload = OCTETSTRING(buf.size(), buf.data()); /*OCTETSTRING payload; if (http_message.ischosen(LibItsHttp__TypesAndValues::HttpMessage::ALT_request)) { loggers::get_instance().log("http_layer::receive_data: Process request"); if (http_message.request().body().is_present()) { const OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody>& v = http_message.request().body(); const LibItsHttp__MessageBodyTypes::HttpMessageBody& body = static_cast<const LibItsHttp__MessageBodyTypes::HttpMessageBody&>(*v.get_opt_value()); if (body.ischosen(LibItsHttp__MessageBodyTypes::HttpMessageBody::ALT_ms__body)) { payload = body.ms__body(); } else { LibItsHttp__XmlMessageBodyTypes::XmlBody xml_body = body.xml__body(); if (xml_body.ischosen(LibItsHttp__XmlMessageBodyTypes::XmlBody::ALT_raw)) { payload = OCTETSTRING(xml_body.raw().lengthof(), (unsigned char*)static_cast<const char*>(xml_body.raw())); } else { loggers::get_instance().warning("http_layer::receive_data: No payload in HTTP request"); return; } } else if (httpMessage.ischosen(LibItsHttp__TypesAndValues::HttpMessage::ALT_response)) { if (httpMessage.response().body().is_present()) { const CHARSTRING& body = static_cast<OPTIONAL<CHARSTRING>&>(*(httpMessage.response().body().get_opt_value())); std::vector<uint8_t> buf = converter::get_instance().string_to_bytes(static_cast<const char*>(body)); payload = OCTETSTRING(buf.size(), buf.data()); } } else { loggers::get_instance().warning("http_layer::receive_data: No payload in HTTP request"); return; } } else if (http_message.ischosen(LibItsHttp__TypesAndValues::HttpMessage::ALT_response)) { loggers::get_instance().log("http_layer::receive_data: Process response"); if (http_message.response().body().is_present()) { const OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody>& v = http_message.response().body(); const LibItsHttp__MessageBodyTypes::HttpMessageBody& body = static_cast<const LibItsHttp__MessageBodyTypes::HttpMessageBody&>(*v.get_opt_value()); if (body.ischosen(LibItsHttp__MessageBodyTypes::HttpMessageBody::ALT_ms__body)) { payload = body.ms__body(); } else { LibItsHttp__XmlMessageBodyTypes::XmlBody xml_body = body.xml__body(); if (xml_body.ischosen(LibItsHttp__XmlMessageBodyTypes::XmlBody::ALT_raw)) { payload = OCTETSTRING(xml_body.raw().lengthof(), (unsigned char*)static_cast<const char*>(xml_body.raw())); } else { loggers::get_instance().warning("http_layer::receive_data: No payload in HTTP response"); return; } } } else { loggers::get_instance().warning("http_layer::receive_data: Unexpected HTTP message"); loggers::get_instance().warning("http_layer::receive_data: No payload in HTTP response"); return; } }*/ receive_to_all_layers(payload, params); // Pass it to the ports to_all_upper_ports(http_message/*payload*/, params); } http_layer_factory http_layer_factory::_f; Loading ccsrc/Protocols/Http/http_layer.hh +11 −4 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ namespace LibItsHttp__TestSystem { } namespace LibItsHttp__TypesAndValues { class HeaderLines; //! Forward declaration of TITAN class class HttpMessage; //! Forward declaration of TITAN class } class OCTETSTRING; //! Forward declaration of TITAN class Loading @@ -33,7 +33,6 @@ class OCTETSTRING; //! Forward declaration of TITAN class class http_layer : public t_layer<LibItsHttp__TestSystem::HttpPort> { params _params; http_codec _codec; std::unique_ptr<LibItsHttp__TypesAndValues::HeaderLines> _headers; public: //! \publicsection /*! Loading @@ -42,7 +41,7 @@ public: //! \publicsection * \param[in] p_type \todo * \param[in] p_param \todo */ http_layer() : t_layer(), _params(), _headers(nullptr) {}; http_layer() : t_layer(), _params() { }; /*! * \brief Specialised constructor * Create a new instance of the http_layer class Loading @@ -53,7 +52,15 @@ public: //! \publicsection /*! * \brief Default destructor */ virtual ~http_layer() { _headers.reset(nullptr); }; virtual ~http_layer() { }; /*! * \fn void sendMsg(const LibItsHttp__TypesAndValues::HttpMessage& p_http_message, params& p_param); * \brief Send HTTP message to the lower layers * \param[in] p_http_message The GeoNetworking message to be sent * \param[in] p_params Some parameters to overwrite default value of the lower layers parameters */ void sendMsg(const LibItsHttp__TypesAndValues::HttpMessage& p_http_message, params& p_param); /*! * \virtual Loading Loading
ccsrc/Protocols/Http/http_codec.cc +205 −65 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ #include "loggers.hh" #include "LibItsHttp_TypesAndValues.hh" #include "LibItsHttp_MessageBodyTypes.hh" #include "LibItsHttp_XmlMessageBodyTypes.hh" int http_codec::encode (const LibItsHttp__TypesAndValues::HttpMessage& msg, OCTETSTRING& data) { Loading @@ -15,11 +17,13 @@ int http_codec::encode (const LibItsHttp__TypesAndValues::HttpMessage& msg, OCTE TTCN_EncDec::clear_error(); TTCN_Buffer encoding_buffer; _ec.reset(); int result; if (msg.ischosen(LibItsHttp__TypesAndValues::HttpMessage::ALT_request)) { result = encode_request(msg.request(), encoding_buffer); } else if (msg.ischosen(LibItsHttp__TypesAndValues::HttpMessage::ALT_response)) { //result = encode_response(msg.response(), encoding_buffer); result = encode_response(msg.response(), encoding_buffer); } else { loggers::get_instance().warning("http_codec::encode: Unbound HttpMessage"); return -1; Loading @@ -34,9 +38,13 @@ int http_codec::encode (const LibItsHttp__TypesAndValues::HttpMessage& msg, OCTE int http_codec::decode (const OCTETSTRING& data, LibItsHttp__TypesAndValues::HttpMessage& msg, params* params) { loggers::get_instance().log_msg(">>> http_codec::decode: data=", data); TTCN_EncDec::clear_error(); TTCN_Buffer decoding_buffer(data); loggers::get_instance().log_to_hexa("http_codec::decode: decoding_buffer=", decoding_buffer); _dc.reset(); _params = params; // Get the first line (e.g. HTTP/1.1 302 Found or POST / HTTP/1.1) Loading @@ -54,9 +62,10 @@ int http_codec::decode (const OCTETSTRING& data, LibItsHttp__TypesAndValues::Htt loggers::get_instance().log("http_codec::decode: %d - %s", m.size(), m[0].str().c_str()); if (m[0].str().compare("HTTP/") == 0) { // HTTP response LibItsHttp__TypesAndValues::Response response; std::regex rgx ("\\s*HTTP/(\\d)\\.(\\d)\\s+(\\d+)\\s+(\\w+)"); std::regex rgx ("\\s*HTTP/(\\d+)\\.(\\d+)\\s+(\\d+)\\s+(\\w+)*"); std::sregex_iterator begin(str.cbegin(), str.cend(), rgx); std::smatch m = *begin; loggers::get_instance().log("http_codec::decode: Process response: %d", m.size()); if (m.size() != 5) { loggers::get_instance().error("http_codec::decode: Unsupported tag"); return -1; Loading @@ -69,13 +78,11 @@ int http_codec::decode (const OCTETSTRING& data, LibItsHttp__TypesAndValues::Htt decode_headers(decoding_buffer, headers); response.header() = headers; loggers::get_instance().log_to_hexa("Before decoding Body: ", decoding_buffer); CHARSTRING body(""); LibItsHttp__MessageBodyTypes::HttpMessageBody body; if (decode_body(decoding_buffer, body) == -1) { response.body().set_to_omit(); } else if (body.lengthof() == 0) { response.body().set_to_omit(); } else { // TODO response.body() = OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody>(body); } msg.response() = response; } else { // HTTP request Loading @@ -94,14 +101,12 @@ int http_codec::decode (const OCTETSTRING& data, LibItsHttp__TypesAndValues::Htt LibItsHttp__TypesAndValues::HeaderLines headers; decode_headers(decoding_buffer, headers); request.header() = headers; loggers::get_instance().log_to_hexa("Before decoding Body: ", decoding_buffer); CHARSTRING body(""); OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody> body; body.set_to_omit(); if (decode_body(decoding_buffer, body) == -1) { request.body().set_to_omit(); } else if (body.lengthof() == 0) { request.body().set_to_omit(); } else { // TODO request.body() = body; } msg.request() = request; } Loading @@ -119,11 +124,20 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ loggers::get_instance().log_msg(">>> http_codec::encode_request: ", (const Base_Type&)p_request); const OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody>& v = p_request.body(); CHARSTRING body(""); OCTETSTRING os; if (v.ispresent()) { // FIXME body = static_cast<const CHARSTRING&>(*v.get_opt_value()); const LibItsHttp__MessageBodyTypes::HttpMessageBody& body = static_cast<const LibItsHttp__MessageBodyTypes::HttpMessageBody&>(*v.get_opt_value()); loggers::get_instance().log_msg("http_codec::encode_request: body: ", body); if (body.ischosen(LibItsHttp__MessageBodyTypes::HttpMessageBody::ALT_ms__body)) { os = body.ms__body(); } else { LibItsHttp__XmlMessageBodyTypes::XmlBody xml_body = body.xml__body(); if (xml_body.ischosen(LibItsHttp__XmlMessageBodyTypes::XmlBody::ALT_raw)) { os = OCTETSTRING(xml_body.raw().lengthof(), (unsigned char*)static_cast<const char*>(xml_body.raw())); } } } loggers::get_instance().log("http_codec::encode_request: HTTP message lenght: %d ", os.lengthof()); // Encode generic part p_encoding_buffer.put_cs(p_request.method()); Loading @@ -142,8 +156,8 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ p_encoding_buffer.put_cs(header.header__name()); p_encoding_buffer.put_cs(": "); if (std::string(static_cast<const char*>(header.header__name())).compare("Content-Length") == 0) { loggers::get_instance().log("http_codec::encode_request: body length: %d", body.lengthof()); p_encoding_buffer.put_cs(int2str(body.lengthof())); p_encoding_buffer.put_cs(int2str(os.lengthof() + 2/*Stand for the last CRLF*/)); _ec.is_content_length_present = 0x01; } else { const OPTIONAL<LibItsHttp__TypesAndValues::charstring__list>& o = header.header__value(); if (o.ispresent()) { Loading @@ -153,7 +167,7 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ p_encoding_buffer.put_cs(v[0]); int j = 1; while (j < v.size_of()) { p_encoding_buffer.put_cs("; "); p_encoding_buffer.put_cs(", "); loggers::get_instance().log_msg("http_codec::encode_request: Processing value ", v[j]); p_encoding_buffer.put_cs(v[j]); j += 1; Loading @@ -164,16 +178,85 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ p_encoding_buffer.put_cs("\r\n"); } // End of 'for' statement if (body.lengthof() != 0) { p_encoding_buffer.put_cs(body); p_encoding_buffer.put_cs("\r\n"); if (_ec.length != 0) { p_encoding_buffer.put_os(os); p_encoding_buffer.put_cs("\r\n"); } return 0; } int http_codec::encode_response (const LibItsHttp__TypesAndValues::Response& p_response, TTCN_Buffer& p_encoding_buffer) { loggers::get_instance().log_msg(">>> http_codec::encode_response: ", (const Base_Type&)p_response); const OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody>& v = p_response.body(); OCTETSTRING os; if (v.ispresent()) { const LibItsHttp__MessageBodyTypes::HttpMessageBody& body = static_cast<const LibItsHttp__MessageBodyTypes::HttpMessageBody&>(*v.get_opt_value()); loggers::get_instance().log_msg("http_codec::encode_response: body: ", body); if (body.ischosen(LibItsHttp__MessageBodyTypes::HttpMessageBody::ALT_ms__body)) { os = body.ms__body(); } else { LibItsHttp__XmlMessageBodyTypes::XmlBody xml_body = body.xml__body(); if (xml_body.ischosen(LibItsHttp__XmlMessageBodyTypes::XmlBody::ALT_raw)) { os = OCTETSTRING(xml_body.raw().lengthof(), (unsigned char*)static_cast<const char*>(xml_body.raw())); } } } loggers::get_instance().log("http_codec::encode_response: HTTP message lenght: %d ", os.lengthof()); // Encode generic part p_encoding_buffer.put_cs("HTTP/"); p_encoding_buffer.put_cs(int2str(p_response.version__major())); p_encoding_buffer.put_c('.'); p_encoding_buffer.put_cs(int2str(p_response.version__minor())); p_encoding_buffer.put_cs(" "); p_encoding_buffer.put_cs(int2str(p_response.statuscode())); p_encoding_buffer.put_cs(" "); if (p_response.statustext().lengthof() != 0) { p_encoding_buffer.put_cs(p_response.statustext()); } p_encoding_buffer.put_cs("\r\n"); // Encode headers const LibItsHttp__TypesAndValues::HeaderLines& headers = p_response.header(); for (int i = 0; i < headers.size_of(); i++) { const LibItsHttp__TypesAndValues::HeaderLine& header = headers[i]; loggers::get_instance().log_msg("http_codec::encode_response: Processing header ", header.header__name()); p_encoding_buffer.put_cs(header.header__name()); p_encoding_buffer.put_cs(": "); if (std::string(static_cast<const char*>(header.header__name())).compare("Content-Length") == 0) { p_encoding_buffer.put_cs(int2str(os.lengthof() + 2/*Stand for the last CRLF*/)); _ec.is_content_length_present = 0x01; } else { const OPTIONAL<LibItsHttp__TypesAndValues::charstring__list>& o = header.header__value(); if (o.ispresent()) { const LibItsHttp__TypesAndValues::charstring__list& v = dynamic_cast<const OPTIONAL<LibItsHttp__TypesAndValues::charstring__list> &>(o); if (v.size_of() > 0) { loggers::get_instance().log_msg("http_codec::encode_response: Processing value ", v[0]); p_encoding_buffer.put_cs(v[0]); int j = 1; while (j < v.size_of()) { p_encoding_buffer.put_cs(", "); loggers::get_instance().log_msg("http_codec::encode_response: Processing value ", v[j]); p_encoding_buffer.put_cs(v[j]); j += 1; } // End of 'while' statement } } // else, do not include it } p_encoding_buffer.put_cs("\r\n"); } // End of 'for' statement p_encoding_buffer.put_cs("\r\n"); if (_ec.length != 0) { p_encoding_buffer.put_os(os); p_encoding_buffer.put_cs("\r\n"); } return 0; } int http_codec::decode_headers(TTCN_Buffer& decoding_buffer, LibItsHttp__TypesAndValues::HeaderLines& headers) { loggers::get_instance().log(">>> http_codec::decode_headers"); loggers::get_instance().log_to_hexa("http_codec::decode_headers", decoding_buffer); Loading @@ -198,7 +281,6 @@ int http_codec::decode_headers(TTCN_Buffer& decoding_buffer, LibItsHttp__TypesAn case -1: loggers::get_instance().warning("http_codec::decode_headers: Failed to decode headers"); return -1; } // End of 'switch' statement } // End of 'while' statement } Loading @@ -208,12 +290,14 @@ int http_codec::decode_header(CHARSTRING& header_line, LibItsHttp__TypesAndValue try { std::string str(static_cast<const char*>(header_line)); std::regex rgx ("([0-9a-zA-Z-]+)\\:\\s+(.+)(;(.+))*"); std::regex rgx ("([0-9a-zA-Z-]+)\\:\\s+(.+)(,(.+))*"); std::sregex_iterator begin(str.cbegin(), str.cend(), rgx); std::smatch m = *begin; if (m.size() < 5) { loggers::get_instance().warning("http_codec::decode_header: Failed to decode header %s", str.c_str()); return -1; } loggers::get_instance().log("http_codec::decode_header: %d", m.size()); header.header__name() = CHARSTRING(m[1].str().c_str()); LibItsHttp__TypesAndValues::charstring__list v; for (unsigned int j = 0; j < m.size(); j++) { Loading @@ -222,8 +306,13 @@ int http_codec::decode_header(CHARSTRING& header_line, LibItsHttp__TypesAndValue } v[j] = CHARSTRING(m[j + 2].str().c_str()); } // End of 'for' statement header.header__value() = OPTIONAL<LibItsHttp__TypesAndValues::charstring__list>(v); if (m[1].str().compare("Content-Length") == 0) { // Save the the body length loggers::get_instance().log("http_codec::decode_header: decoded Content-Length %s", m[2].str().c_str()); _dc.length = std::stoi(m[2].str()); } return 0; } catch(const std::logic_error& e) { Loading @@ -231,14 +320,65 @@ int http_codec::decode_header(CHARSTRING& header_line, LibItsHttp__TypesAndValue } } int http_codec::decode_body(TTCN_Buffer& decoding_buffer, CHARSTRING& body) { int http_codec::decode_body(TTCN_Buffer& decoding_buffer, LibItsHttp__MessageBodyTypes::HttpMessageBody& message_body) { loggers::get_instance().log(">>> http_codec::decode_body"); loggers::get_instance().log_to_hexa("http_codec::decode_body", decoding_buffer); loggers::get_instance().log_msg("<<< http_codec::decode_body: ", body); // Sanity check if (decoding_buffer.get_len() - decoding_buffer.get_pos() <= 0) { return -1; } OCTETSTRING s(decoding_buffer.get_len() - decoding_buffer.get_pos(), decoding_buffer.get_data() + decoding_buffer.get_pos()); loggers::get_instance().log_msg("http_codec::decode_body: raw body=", s); // Align the payload length with the specified plLenght value loggers::get_instance().log("http_codec::decode_body: _dc.length=%d - body length=%d", _dc.length, s.lengthof()); OCTETSTRING body; if (_dc.length != 0) { const unsigned char* p = static_cast<const unsigned char *>(s); if ((unsigned int)s.lengthof() <= _dc.length) { body = OCTETSTRING(s.lengthof(), p); } else { body = OCTETSTRING(_dc.length, p); } } else { loggers::get_instance().warning("http_codec::decode_body: No Conten-Length header, process all remaining bytes"); body = s; } loggers::get_instance().log_msg("http_codec::decode_body: Aligned body=", body); // Remove CRLF if any int counter = 0; if ((body[body.lengthof() - 1].get_octet() == 0x0d) || (body[body.lengthof() - 1].get_octet() == 0x0a)) { counter += 1; if ((body[body.lengthof() - 2].get_octet() == 0x0d) || (body[body.lengthof() - 2].get_octet() == 0x0a)) { counter += 1; } } loggers::get_instance().log("http_codec::decode_body: Counter=%d", counter); body = OCTETSTRING(body.lengthof() - counter, static_cast<const unsigned char*>(body)); loggers::get_instance().log_msg("http_codec::decode_body: Finalised body=", body); // Check if HTTP message body contains binary characters for (int i = 0; i < body.lengthof(); i++) { unsigned char c = body[i].get_octet(); if (!std::isprint(c) && !std::isspace(c) && !std::ispunct(c)) { loggers::get_instance().log("http_codec::decode_body: Byte #%d is not printable: 0x%02x", i, body[i].get_octet()); _dc.is_binary = 0x01; break; } } // End of 'for' statement loggers::get_instance().log("http_codec::decode_body: Binary mode: %x", _dc.is_binary); LibItsHttp__MessageBodyTypes::HttpMessageBody v; if (_dc.is_binary == 0x01) { message_body.ms__body() = body; } else { LibItsHttp__XmlMessageBodyTypes::XmlBody xml_body; xml_body.raw() = CHARSTRING(body.lengthof(), (char*)static_cast<const unsigned char*>(body)); message_body.xml__body() = xml_body; } return 0; } int http_codec::get_line(TTCN_Buffer& buffer, CHARSTRING& to, const bool concatenate_header_lines) { unsigned int i = 0; const unsigned char *cc_to = buffer.get_read_data(); Loading @@ -249,7 +389,7 @@ int http_codec::get_line(TTCN_Buffer& buffer, CHARSTRING& to, const bool concate } while (true) { // Skip spaces, and emplty lines // Skip spaces, and empty lines for( ; i < buffer.get_read_len() && cc_to[i] != '\0' && cc_to[i] != '\r' && cc_to[i] != '\n'; i++); if(i >= buffer.get_read_len()) { // No more characters to process to = CHARSTRING(""); Loading
ccsrc/Protocols/Http/http_codec.hh +24 −3 Original line number Diff line number Diff line Loading @@ -14,13 +14,34 @@ namespace LibItsHttp__TypesAndValues { class HeaderLines; class HeaderLine; } namespace LibItsHttp__MessageBodyTypes { class HttpMessageBody; } struct encoding_context { unsigned int length; unsigned char is_content_length_present; encoding_context() { reset(); }; void reset() { length = -1; is_content_length_present = 0x00; }; }; struct decoding_context { unsigned int length; unsigned char is_binary; decoding_context() { reset(); }; void reset() { length = -1; is_binary = 0x00; }; }; class http_codec: public codec < LibItsHttp__TypesAndValues::HttpMessage, LibItsHttp__TypesAndValues::HttpMessage> { encoding_context _ec; decoding_context _dc; public: explicit http_codec() : codec<LibItsHttp__TypesAndValues::HttpMessage, LibItsHttp__TypesAndValues::HttpMessage>() { }; explicit http_codec() : codec<LibItsHttp__TypesAndValues::HttpMessage, LibItsHttp__TypesAndValues::HttpMessage>(), _ec(), _dc() { }; virtual ~http_codec() { }; virtual int encode (const LibItsHttp__TypesAndValues::HttpMessage&, OCTETSTRING& data); Loading @@ -28,11 +49,11 @@ public: private: int encode_request (const LibItsHttp__TypesAndValues::Request& p_request, TTCN_Buffer& p_encoding_buffer); // int encode_response (const LibItsHttp__TypesAndValues::Request&, TTCN_Buffer& p_encoding_buffer); int encode_response (const LibItsHttp__TypesAndValues::Response& p_response, TTCN_Buffer& p_encoding_buffer); int decode_headers(TTCN_Buffer& decoding_buffer, LibItsHttp__TypesAndValues::HeaderLines& headers); int decode_header(CHARSTRING& header_line, LibItsHttp__TypesAndValues::HeaderLine& header); int decode_body(TTCN_Buffer& decoding_buffer, CHARSTRING& body); int decode_body(TTCN_Buffer& decoding_buffer, LibItsHttp__MessageBodyTypes::HttpMessageBody& message_body); int get_line(TTCN_Buffer& buffer, CHARSTRING& to, const bool concatenate_header_lines = false); }; // End of class http_codec
ccsrc/Protocols/Http/http_layer.cc +59 −67 Original line number Diff line number Diff line Loading @@ -10,54 +10,26 @@ using namespace std; // Required for isnan() #include "LibItsHttp_TypesAndValues.hh" #include "LibItsHttp_TestSystem.hh" http_layer::http_layer(const std::string & p_type, const std::string & param) : t_layer<LibItsHttp__TestSystem::HttpPort>(p_type), _params(), _codec(), _headers(new LibItsHttp__TypesAndValues::HeaderLines)//, _device_mode{false} http_layer::http_layer(const std::string & p_type, const std::string & param) : t_layer<LibItsHttp__TestSystem::HttpPort>(p_type), _params()//, _device_mode{false} { loggers::get_instance().log(">>> http_layer::http_layer: %s, %s", to_string().c_str(), param.c_str()); // Setup parameters params::convert(_params, param); } void http_layer::sendMsg(const LibItsHttp__TypesAndValues::HttpMessage& p_http_message, params& p_param) { loggers::get_instance().log_msg(">>> http_layer::sendMsg: ", p_http_message); // Build basic headers int i = 0; LibItsHttp__TypesAndValues::charstring__list values; values[0] = "application/xml"; (*_headers)[i++] = LibItsHttp__TypesAndValues::HeaderLine(CHARSTRING("Accept"), values); values.set_size(0); values[0] = "application/xml"; values[1] = "charset=utf-8"; (*_headers)[i++] = LibItsHttp__TypesAndValues::HeaderLine(CHARSTRING("Content-Type"), values); values.set_size(0); values[0] = "0"; (*_headers)[i++] = LibItsHttp__TypesAndValues::HeaderLine(CHARSTRING("Content-Length"), values); values.set_size(0); values[0] = "www.google.com"; (*_headers)[i++] = LibItsHttp__TypesAndValues::HeaderLine(CHARSTRING("Host"), values); values.set_size(0); // Encode HttpMessage OCTETSTRING data; _codec.encode(p_http_message, data); send_data(data, _params); } void http_layer::send_data(OCTETSTRING& data, params& params) { loggers::get_instance().log_msg(">>> http_layer::send_data: ", data); params::const_iterator it = params.find("HttpMethod"); LibItsHttp__TypesAndValues::HttpMessage msg; if (it != params.cend()) { } else { // Assume it is a GET LibItsHttp__TypesAndValues::Request request; request.method() = "GET"; request.uri() = "/"; request.version__major() = 1; request.version__minor() = 1; request.header() = *_headers.get(); std::vector<uint8_t> buf(static_cast<const unsigned char *>(data), data.lengthof() + static_cast<const unsigned char *>(data)); // FIXME // CHARSTRING c(converter::get_instance().bytes_to_string(buf).c_str()); // request.body() = OPTIONAL<CHARSTRING>(c); msg.request() = request; } loggers::get_instance().log_msg("http_layer::send_data: HttpMessage: ", msg); OCTETSTRING os; _codec.encode(msg, os); send_to_all_layers(os, params); send_to_all_layers(data, params); } void http_layer::receive_data(OCTETSTRING& data, params& params) Loading @@ -65,37 +37,57 @@ void http_layer::receive_data(OCTETSTRING& data, params& params) loggers::get_instance().log_msg(">>> http_layer::receive_data: ", data); // Decode HTTP message LibItsHttp__TypesAndValues::HttpMessage httpMessage; if (_codec.decode(data, httpMessage) == -1) { LibItsHttp__TypesAndValues::HttpMessage http_message; if (_codec.decode(data, http_message) == -1) { loggers::get_instance().warning("http_layer::receive_data: Failed to decode data"); return; } // Extract payload OCTETSTRING payload; if (httpMessage.ischosen(LibItsHttp__TypesAndValues::HttpMessage::ALT_request)) { if (httpMessage.request().body().is_present()) { const CHARSTRING& body = static_cast<OPTIONAL<CHARSTRING>&>(*(httpMessage.request().body().get_opt_value())); std::vector<uint8_t> buf = converter::get_instance().string_to_bytes(static_cast<const char*>(body)); payload = OCTETSTRING(buf.size(), buf.data()); /*OCTETSTRING payload; if (http_message.ischosen(LibItsHttp__TypesAndValues::HttpMessage::ALT_request)) { loggers::get_instance().log("http_layer::receive_data: Process request"); if (http_message.request().body().is_present()) { const OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody>& v = http_message.request().body(); const LibItsHttp__MessageBodyTypes::HttpMessageBody& body = static_cast<const LibItsHttp__MessageBodyTypes::HttpMessageBody&>(*v.get_opt_value()); if (body.ischosen(LibItsHttp__MessageBodyTypes::HttpMessageBody::ALT_ms__body)) { payload = body.ms__body(); } else { LibItsHttp__XmlMessageBodyTypes::XmlBody xml_body = body.xml__body(); if (xml_body.ischosen(LibItsHttp__XmlMessageBodyTypes::XmlBody::ALT_raw)) { payload = OCTETSTRING(xml_body.raw().lengthof(), (unsigned char*)static_cast<const char*>(xml_body.raw())); } else { loggers::get_instance().warning("http_layer::receive_data: No payload in HTTP request"); return; } } else if (httpMessage.ischosen(LibItsHttp__TypesAndValues::HttpMessage::ALT_response)) { if (httpMessage.response().body().is_present()) { const CHARSTRING& body = static_cast<OPTIONAL<CHARSTRING>&>(*(httpMessage.response().body().get_opt_value())); std::vector<uint8_t> buf = converter::get_instance().string_to_bytes(static_cast<const char*>(body)); payload = OCTETSTRING(buf.size(), buf.data()); } } else { loggers::get_instance().warning("http_layer::receive_data: No payload in HTTP request"); return; } } else if (http_message.ischosen(LibItsHttp__TypesAndValues::HttpMessage::ALT_response)) { loggers::get_instance().log("http_layer::receive_data: Process response"); if (http_message.response().body().is_present()) { const OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody>& v = http_message.response().body(); const LibItsHttp__MessageBodyTypes::HttpMessageBody& body = static_cast<const LibItsHttp__MessageBodyTypes::HttpMessageBody&>(*v.get_opt_value()); if (body.ischosen(LibItsHttp__MessageBodyTypes::HttpMessageBody::ALT_ms__body)) { payload = body.ms__body(); } else { LibItsHttp__XmlMessageBodyTypes::XmlBody xml_body = body.xml__body(); if (xml_body.ischosen(LibItsHttp__XmlMessageBodyTypes::XmlBody::ALT_raw)) { payload = OCTETSTRING(xml_body.raw().lengthof(), (unsigned char*)static_cast<const char*>(xml_body.raw())); } else { loggers::get_instance().warning("http_layer::receive_data: No payload in HTTP response"); return; } } } else { loggers::get_instance().warning("http_layer::receive_data: Unexpected HTTP message"); loggers::get_instance().warning("http_layer::receive_data: No payload in HTTP response"); return; } }*/ receive_to_all_layers(payload, params); // Pass it to the ports to_all_upper_ports(http_message/*payload*/, params); } http_layer_factory http_layer_factory::_f; Loading
ccsrc/Protocols/Http/http_layer.hh +11 −4 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ namespace LibItsHttp__TestSystem { } namespace LibItsHttp__TypesAndValues { class HeaderLines; //! Forward declaration of TITAN class class HttpMessage; //! Forward declaration of TITAN class } class OCTETSTRING; //! Forward declaration of TITAN class Loading @@ -33,7 +33,6 @@ class OCTETSTRING; //! Forward declaration of TITAN class class http_layer : public t_layer<LibItsHttp__TestSystem::HttpPort> { params _params; http_codec _codec; std::unique_ptr<LibItsHttp__TypesAndValues::HeaderLines> _headers; public: //! \publicsection /*! Loading @@ -42,7 +41,7 @@ public: //! \publicsection * \param[in] p_type \todo * \param[in] p_param \todo */ http_layer() : t_layer(), _params(), _headers(nullptr) {}; http_layer() : t_layer(), _params() { }; /*! * \brief Specialised constructor * Create a new instance of the http_layer class Loading @@ -53,7 +52,15 @@ public: //! \publicsection /*! * \brief Default destructor */ virtual ~http_layer() { _headers.reset(nullptr); }; virtual ~http_layer() { }; /*! * \fn void sendMsg(const LibItsHttp__TypesAndValues::HttpMessage& p_http_message, params& p_param); * \brief Send HTTP message to the lower layers * \param[in] p_http_message The GeoNetworking message to be sent * \param[in] p_params Some parameters to overwrite default value of the lower layers parameters */ void sendMsg(const LibItsHttp__TypesAndValues::HttpMessage& p_http_message, params& p_param); /*! * \virtual Loading