Commit 999abd07 authored by Denis Filatov's avatar Denis Filatov
Browse files

Merge branch 'STF525' of https://forge.etsi.org/gitlab/ITS/ITS into STF525

parents 1489a789 9b425776
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -7,9 +7,17 @@

namespace LibItsHttp__EncdecDeclarations {

    BITSTRING fx__enc__http__message(const LibItsHttp__TypesAndValues::HttpMessage& p) { return BITSTRING(); }
  BITSTRING fx__enc__http__message(const LibItsHttp__TypesAndValues::HttpMessage& p) {
    loggers::get_instance().log_msg(">>> fx__enc__http__message: ", (const Base_Type&)p);

    OCTETSTRING os;
    http_codec codec;
    codec.encode(p, os);

    return oct2bit(os);
  }
  INTEGER fx__dec__http__message(BITSTRING& pdu, LibItsHttp__TypesAndValues::HttpMessage& p) {
        loggers::get_instance().log_msg(">>> fx__dec__http__response: ", pdu);
    loggers::get_instance().log_msg(">>> fx__dec__http__message: ", pdu);

    OCTETSTRING os = bit2oct(pdu);
    http_codec codec;
+139 −64
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
int http_codec::encode (const LibItsHttp__TypesAndValues::HttpMessage& msg, OCTETSTRING& data)
{
  loggers::get_instance().log_msg(">>> http_codec::encode: ", (const Base_Type&)msg);
  loggers::get_instance().log(">>> http_codec::encode: %p", this);

  TTCN_EncDec::clear_error();
  TTCN_Buffer encoding_buffer;
@@ -125,26 +126,6 @@ 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();
  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_request: body: ", body);
    if (encode_body(body, os) == -1) {
      loggers::get_instance().warning("http_codec::encode_request: Failed to encode HTTP body");
      _ec.length = 0;
      _ec.is_content_length_present = 0x00;
    } else {
      _ec.length = os.lengthof();
      _ec.is_content_length_present = 0x01;
    }
    loggers::get_instance().log("http_codec::encode_request: length=%d", _ec.length);
  } else {
    loggers::get_instance().log("http_codec::encode_request: HTTP body field not present");
    _ec.length = 0;
    _ec.is_content_length_present = 0x00;
  }

  // Encode generic part
  p_encoding_buffer.put_cs(p_request.method());
  p_encoding_buffer.put_c(' ');
@@ -154,35 +135,36 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ
  p_encoding_buffer.put_c('.');
  p_encoding_buffer.put_cs(int2str(p_request.version__minor()));
  p_encoding_buffer.put_cs("\r\n");
  // Encode headers
  
  // Encode headers excepeted the Content-length
  const LibItsHttp__TypesAndValues::HeaderLines& headers = p_request.header();
  std::string content_type;
  for (int i = 0; i < headers.size_of(); i++) {
    const LibItsHttp__TypesAndValues::HeaderLine& header = headers[i];
    loggers::get_instance().log_msg("http_codec::encode_request: 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) {
      if (_ec.length != 0) {
        p_encoding_buffer.put_cs(int2str(_ec.length + 2/*Stand for the last CRLF*/));
        _ec.is_content_length_present = 0x01;
      } else {
        p_encoding_buffer.put_cs("0");
        _ec.is_content_length_present = 0x00;
      }
      loggers::get_instance().log("http_codec::encode_request: Content-length: %d - %x", _ec.length, _ec.is_content_length_present);
    if (std::string(static_cast<const char*>(header.header__name())).compare("Content-length") == 0) { // Skip it, processed later
      continue;
    } 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_request: Processing value ", v[0]);
          if (std::string(static_cast<const char*>(header.header__name())).compare("Content-type") == 0) { // Store it for HTTP body payload encoding
            loggers::get_instance().log("http_codec::encode_request: Storing Content-type");
            int j = 0;
            while (j < v.size_of()) {
              content_type += v[j++];
            } // End of 'while' statement
          }
          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_request: Processing value ", v[j]);
                p_encoding_buffer.put_cs(v[j]);
                j += 1;
            p_encoding_buffer.put_cs(v[j++]);
          } // End of 'while' statement
        }
      } // else, do not include it
@@ -190,6 +172,38 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ
    p_encoding_buffer.put_cs("\r\n");
  } // End of 'for' statement
  
  // Encode message body
  const OPTIONAL<LibItsHttp__MessageBodyTypes::HttpMessageBody>& v = p_request.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_request: body: ", body);
    if (encode_body(body, os, content_type) == -1) {
      loggers::get_instance().warning("http_codec::encode_request: Failed to encode HTTP body");
      _ec.length = 0;
      _ec.is_content_length_present = 0x00;
    } else {
      _ec.length = os.lengthof();
      _ec.is_content_length_present = 0x01;
    }
    loggers::get_instance().log("http_codec::encode_request: length=%d", _ec.length);
  } else {
    loggers::get_instance().log("http_codec::encode_request: HTTP body field not present");
    _ec.length = 0;
    _ec.is_content_length_present = 0x00;
  }

  // Encode Content-length header
  if (_ec.length != 0) {
    p_encoding_buffer.put_cs(int2str(_ec.length + 2/*Stand for the last CRLF*/));
    _ec.is_content_length_present = 0x01;
  } else {
    p_encoding_buffer.put_cs("0");
    _ec.is_content_length_present = 0x00;
  }
  loggers::get_instance().log("http_codec::encode_request: Content-length: %d - %x", _ec.length, _ec.is_content_length_present);
  p_encoding_buffer.put_cs("\r\n");

  p_encoding_buffer.put_cs("\r\n");
  if (_ec.is_content_length_present == 0x01) {
    loggers::get_instance().log_msg("http_codec::encode_request: Add body ", os);
@@ -203,16 +217,6 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ
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 (encode_body(body, os) == -1) {
      _ec.length = 0;
    }
  }

  // Encode generic part
  p_encoding_buffer.put_cs("HTTP/");
  p_encoding_buffer.put_cs(int2str(p_response.version__major()));
@@ -225,26 +229,29 @@ int http_codec::encode_response (const LibItsHttp__TypesAndValues::Response& p_r
    p_encoding_buffer.put_cs(p_response.statustext());
  }
  p_encoding_buffer.put_cs("\r\n");
  // Encode headers
  
  // Encode headers excepeted the Content-length
  const LibItsHttp__TypesAndValues::HeaderLines& headers = p_response.header();
  std::string content_type;
  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) {
      if (_ec.length != 0) {
        p_encoding_buffer.put_cs(int2str(_ec.length + 2/*Stand for the last CRLF*/));
      } else {
        p_encoding_buffer.put_cs("0");
      }
      _ec.is_content_length_present = 0x01;
      continue;
    } 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]);
          if (std::string(static_cast<const char*>(header.header__name())).compare("Content-type") == 0) { // Store it for HTTP body payload encoding
            int j = 1;
            while (j < v.size_of()) {
              content_type += v[j++];
            } // End of 'while' statement
          }
          p_encoding_buffer.put_cs(v[0]);
          int j = 1;
          while (j < v.size_of()) {
@@ -259,6 +266,37 @@ int http_codec::encode_response (const LibItsHttp__TypesAndValues::Response& p_r
    p_encoding_buffer.put_cs("\r\n");
  } // End of 'for' statement

  // Encode message body
  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 (encode_body(body, os, content_type) == -1) {
      _ec.length = 0;
      _ec.is_content_length_present = 0x00;
    } else {
      _ec.length = os.lengthof();
      _ec.is_content_length_present = 0x01;
    }
    loggers::get_instance().log("http_codec::encode_request: length=%d", _ec.length);
  } else {
    loggers::get_instance().log("http_codec::encode_request: HTTP body field not present");
    _ec.length = 0;
    _ec.is_content_length_present = 0x00;
  }

  // Encode Content-length header
  if (_ec.length != 0) {
    p_encoding_buffer.put_cs(int2str(_ec.length + 2/*Stand for the last CRLF*/));
    _ec.is_content_length_present = 0x01;
  } else {
    p_encoding_buffer.put_cs("0");
    _ec.is_content_length_present = 0x00;
  }
  loggers::get_instance().log("http_codec::encode_response: Content-length: %d - %x", _ec.length, _ec.is_content_length_present);
  p_encoding_buffer.put_cs("\r\n");
  
  p_encoding_buffer.put_cs("\r\n");
  if (_ec.length != 0) {
    p_encoding_buffer.put_os(os);
@@ -331,12 +369,36 @@ int http_codec::decode_header(CHARSTRING& header_line, LibItsHttp__TypesAndValue
  }
}

int http_codec::encode_body(const LibItsHttp__MessageBodyTypes::HttpMessageBody& p_message_body, OCTETSTRING& p_encoding_buffer) {
int http_codec::encode_body(const LibItsHttp__MessageBodyTypes::HttpMessageBody& p_message_body, OCTETSTRING& p_encoding_buffer, const std::string& p_content_type) {
  loggers::get_instance().log_msg(">>> http_codec::encode_body: ", (const Base_Type&)p_message_body);
  loggers::get_instance().log("http_codec::encode_body: # of codecs=%d", _codecs.size());
  loggers::get_instance().log("http_codec::encode_body: # of codecs=%d - %p", _codecs.size(), this);
  loggers::get_instance().log("http_codec::encode_body: Content-type:'%s'", p_content_type.c_str());

  // Sanity check
  if (p_content_type.empty()) {
    loggers::get_instance().warning("http_codec::encode_body: Failed to select a codec for  HTTP body payload");
    return -1;
  }

  if (p_message_body.ischosen(LibItsHttp__MessageBodyTypes::HttpMessageBody::ALT_binary__body)) {
    p_encoding_buffer = p_message_body.binary__body().raw();
    const LibItsHttp__BinaryMessageBodyTypes::BinaryBody& binary_body = p_message_body.binary__body();
    if (binary_body.ischosen(LibItsHttp__BinaryMessageBodyTypes::BinaryBody::ALT_raw)) {
      p_encoding_buffer = OCTETSTRING(binary_body.raw().lengthof(), (unsigned char*)static_cast<const unsigned char*>(binary_body.raw()));
    } else {
      std::map<std::string, std::unique_ptr<codec<Record_Type, Record_Type> > >::const_iterator it;
      bool processed = false;
      if (p_content_type.find_first_of("x-its") != std::string::npos) {
        it = _codecs.find("etsi_ieee1609dot2");
        if (it != _codecs.cend()) {
          loggers::get_instance().log("http_codec::encode_body: Call 'etsi_ts103097_data_codec'");
          _codecs["etsi_ieee1609dot2"]->encode((Record_Type&)binary_body, p_encoding_buffer);
        }
      } // TODO Add new HTTP message codec here
      if (!processed) {
        loggers::get_instance().warning("http_codec::encode_body: Unsupported HTTP codec, use raw field as default");
        p_encoding_buffer = OCTETSTRING(binary_body.raw().lengthof(), (unsigned char*)static_cast<const unsigned char*>(binary_body.raw()));
      }
    }
  } else if (p_message_body.ischosen(LibItsHttp__MessageBodyTypes::HttpMessageBody::ALT_html__body)) {
    p_encoding_buffer = OCTETSTRING(p_message_body.html__body().lengthof(), (unsigned char*)static_cast<const char*>(p_message_body.html__body()));
  } else if (p_message_body.ischosen(LibItsHttp__MessageBodyTypes::HttpMessageBody::ALT_text__body)) {
@@ -346,14 +408,24 @@ int http_codec::encode_body(const LibItsHttp__MessageBodyTypes::HttpMessageBody&
    if (xml_body.ischosen(LibItsHttp__XmlMessageBodyTypes::XmlBody::ALT_raw)) {
      p_encoding_buffer = OCTETSTRING(xml_body.raw().lengthof(), (unsigned char*)static_cast<const char*>(xml_body.raw()));
    } else {
      std::map<std::string, std::unique_ptr<codec<Record_Type, Record_Type> > >::const_iterator it = _codecs.find("held");
      std::map<std::string, std::unique_ptr<codec<Record_Type, Record_Type> > >::const_iterator it;
      bool processed = false;
      if (p_content_type.find_first_of("held") != std::string::npos) {
        it = _codecs.find("held");
        if (it != _codecs.cend()) {
          loggers::get_instance().log("http_codec::encode_body: Call 'held_codec'");
          _codecs["held"]->encode((Record_Type&)xml_body, p_encoding_buffer);
      } else {
        }
      } else if (p_content_type.find_first_of("lost") != std::string::npos) {
        it = _codecs.find("lost");
        if (it != _codecs.cend()) {
          loggers::get_instance().log("http_codec::encode_body: Call 'lost_codec'");
          _codecs["lost"]->encode((Record_Type&)xml_body, p_encoding_buffer);
        }
      } // TODO Add new HTTP message codec here
      if (!processed) {
        loggers::get_instance().warning("http_codec::encode_body: Unsupported HTTP codec, use raw field as default");
        p_encoding_buffer = OCTETSTRING(xml_body.raw().lengthof(), (unsigned char*)static_cast<const char*>(xml_body.raw()));
        // TODO Add new HTTP message codec here
      }
    }
  } else {
@@ -532,11 +604,14 @@ void http_codec::set_payload_codecs(const std::string& p_codecs) {
      loggers::get_instance().log("http_codec::set_payload_codecs: %d - %s - %s - %s - %s - %s - %s - %s - %s", m.size(), m[1].str().c_str(), m[2].str().c_str(), m[3].str().c_str(), m[4].str().c_str(), m[5].str().c_str(), m[6].str().c_str(), m[7].str().c_str(), m[8].str().c_str());
      for (unsigned int j = 1; j < m.size() - 1; j += 3) { // Exclude m[0]
        loggers::get_instance().log("http_codec::set_payload_codecs: insert (%s, %s), j = %d", m[j].str().c_str(), m[j + 1].str().c_str(), j);
        if (m[j].str().empty()) {
          break;
        }
        std::string key(m[j].str());
        _codecs.insert(std::make_pair(key, std::unique_ptr<codec<Record_Type, Record_Type> >(codec_stack_builder::get_instance()->get_codec(m[j + 1].str().c_str()))));
      } // End of 'for' statement
    } // End of 'for' statement
    //loggers::get_instance().log("http_codec::set_payload_codecs: _codecs length=%d", _codecs.size());
    loggers::get_instance().log("http_codec::set_payload_codecs: _codecs length=%d - %p", _codecs.size(), this);
  }
  catch(const std::logic_error& e){
    loggers::get_instance().warning("http_codec::set_payload_codecs: std::logic_error: %s", e.what());
+1 −1
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ public:
private:
  int encode_request (const LibItsHttp__TypesAndValues::Request& p_request, TTCN_Buffer& p_encoding_buffer);
  int encode_response (const LibItsHttp__TypesAndValues::Response& p_response, TTCN_Buffer& p_encoding_buffer);
  int encode_body(const LibItsHttp__MessageBodyTypes::HttpMessageBody& p_message_body, OCTETSTRING& p_encoding_buffer);
  int encode_body(const LibItsHttp__MessageBodyTypes::HttpMessageBody& p_message_body, OCTETSTRING& p_encoding_buffer, const std::string& p_content_type);

  int decode_headers(TTCN_Buffer& decoding_buffer, LibItsHttp__TypesAndValues::HeaderLines& headers);
  int decode_header(CHARSTRING& header_line, LibItsHttp__TypesAndValues::HeaderLine& header);
+1 −1
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ RUN echo "docker-titan-STF525" > /etc/hostname \
      xsltproc \
    && DEBIAN_FRONTEND=noninteractive apt-get autoremove --purge -y \
    && DEBIAN_FRONTEND=noninteractive apt-get autoclean \
    && useradd --create-home --shell /bin/bash etsi --groups sudo username \
    && useradd --create-home --shell /bin/bash --groups sudo,etsi etsi \
    && echo "etsi:etsi" | chpasswd \
    && adduser etsi sudo \
    && cd /home/etsi \
+1 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ LogEventTypes:= Yes
#   latitude               : Latitude of the Test System
#   longitude              : Longitude of the Test System
#   beaconing              : Set to 1 if GnLayer shall start beaconing
#   expiry                 : Beaconning timer expiry (ms)
#   expiry                 : Beaconing timer expiry (ms)
#   device_mode            : Set to 1 if the layer shall encapsulate upper layer PDU
#   secured_mode           : Set to 1 if message exchanges shall be signed
#   encrypted_mode         : Set to 1 if message exchanges shall be encrypted
Loading