Commit eb652d4f authored by Yann Garcia's avatar Yann Garcia
Browse files

Add support of unzip BFK AT download

parent f69933a7
Loading
Loading
Loading
Loading
+56 −9
Original line number Diff line number Diff line
@@ -41,20 +41,47 @@ int http_codec::encode(const LibHttp__TypesAndValues::HttpMessage &msg, OCTETSTR
int http_codec::decode(const OCTETSTRING &data, LibHttp__TypesAndValues::HttpMessage &msg, params *params) {
  loggers::get_instance().log_msg(">>> http_codec::decode: data=", data);

  // Sanity checks
  if ((data[0].get_octet() & 0x80) == 0x80) {
    loggers::get_instance().warning("http_codec::decode: Unicode format not supported");
    return -1;
  }

  TTCN_EncDec::clear_error();
  TTCN_Buffer decoding_buffer(data);
  loggers::get_instance().log_to_hexa("http_codec::decode: decoding_buffer=", decoding_buffer);
  TTCN_Buffer decoding_buffer;

  if (_initial_content_length != 0) { // Check if the data is a new fragment of the response 
    loggers::get_instance().warning("http_codec::decode: Need to bufferize and wait for all fragments received");
    _bufferized_buffers.push_back(data);
    _current_content_length += data.lengthof(); // FIXME Need to calculate the size of the header buffer, do not assume th first fragmwnt is the header buffer
    loggers::get_instance().log("http_codec::decode: _bufferized_buffers size: %d - _current_content_length: %d - _initial_content_length: %d", _bufferized_buffers.size(), _current_content_length, _initial_content_length);
    if (_current_content_length < _initial_content_length) { // Wait for the next fragment
      loggers::get_instance().warning("http_codec::decode: Wait for the next fragment");
      return -2;
    } else { // Rebuild the wall message and continue the decoding
      loggers::get_instance().log("http_codec::decode: All the fragments were received, rebuild message");
      // Concatenate the fragments
      loggers::get_instance().log("http_codec::decode: Concatenate bufferized datas");
      for (size_t i = 0; i < _bufferized_buffers.size(); i++) {
        decoding_buffer.put_string(_bufferized_buffers[i]);
      } // End of 'for' statement
      _bufferized_buffers.clear();
      loggers::get_instance().log("http_codec::decode: _bufferized_buffers cleared: %d", _bufferized_buffers.size());
      // Reset counters
      loggers::get_instance().log("http_codec::decode: Reset bufferization counters");
      _initial_content_length = 0;
      _current_content_length = 0;
      // Continue the decoding
    }
  } else { // It can be a full HTTP response or the first gragment of the HTTP response
    decoding_buffer.put_string(data);
  }
  loggers::get_instance().log("http_codec::decode: decoding_buffer size: %d", decoding_buffer.get_len());
  loggers::get_instance().log_to_hexa("http_codec::decode: Before decoding_buffer Body: ", decoding_buffer);

  _dc.reset();

  _params = params;

  if ((*decoding_buffer.get_data() & 0x80) == 0x80) {
    loggers::get_instance().warning("http_codec::decode: Unicode format not supported");
    return -1;
  }

  // Get the first line (e.g. HTTP/1.1 302 Found or POST / HTTP/1.1)
  CHARSTRING message_id;
  if (get_line(decoding_buffer, message_id) == -1) {
@@ -86,8 +113,28 @@ int http_codec::decode(const OCTETSTRING &data, LibHttp__TypesAndValues::HttpMes
      LibHttp__TypesAndValues::Headers headers;
      std::string                      content_type;
      decode_headers(decoding_buffer, headers, content_type);
      if (_dc.length > decoding_buffer.get_len()) { // HTTP response is fragmented
        // Need to bufferize the first packet and wait for the other fragments tp be received
        loggers::get_instance().warning("http_codec::decode: Need to bufferize the first packet and wait for the other fragments tp be received");
        // Set counters
        loggers::get_instance().log("http_codec::decode: Set bufferization counters");
        _initial_content_length = _dc.length;
        _current_content_length = 0;
        _bufferized_buffers.push_back(data);
        _current_content_length += data.lengthof();
        loggers::get_instance().log("http_codec::decode: _bufferized_buffers size: %d - _current_content_length: %d", _bufferized_buffers.size(), _current_content_length);
        return -2;
      } else {
        // Force reset counters
        loggers::get_instance().log("http_codec::decode: Force reset bufferization counters");
        _initial_content_length = 0;
        _current_content_length = 0;
      }

      response.header() = headers;
      loggers::get_instance().log_to_hexa("Before decoding Body: ", decoding_buffer);
      loggers::get_instance().log("http_codec::decode: _initial_content_length = %d", _initial_content_length);
      loggers::get_instance().log("http_codec::decode: headers().content_length (_dc.length) = %d - decoding_buffer.get_len() = %d", _dc.length, decoding_buffer.get_len());
      LibHttp__MessageBodyTypes::HttpMessageBody body;
      if (decode_body(decoding_buffer, body, content_type) == -1) {
        response.body().set_to_omit();
+5 −1
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ class Base_Type;
class Record_Type;
class TTCN_Typedescriptor_t;
class TTCN_Buffer;
class OCTETSTRING;

namespace LibHttp__TypesAndValues {
  class HttpMessage;
@@ -60,9 +61,12 @@ class http_codec : public codec_gen<LibHttp__TypesAndValues::HttpMessage, LibHtt

protected:
  std::map<std::string, std::unique_ptr<codec_gen<Record_Type, Record_Type>>> _codecs;
  std::vector<OCTETSTRING> _bufferized_buffers;
  unsigned int             _initial_content_length;
  unsigned int             _current_content_length;

public:
  explicit http_codec() : codec_gen<LibHttp__TypesAndValues::HttpMessage, LibHttp__TypesAndValues::HttpMessage>(), _ec(), _dc(), _codecs(){};
  explicit http_codec() : codec_gen<LibHttp__TypesAndValues::HttpMessage, LibHttp__TypesAndValues::HttpMessage>(), _ec(), _dc(), _codecs(), _bufferized_buffers(), _initial_content_length{0}, _current_content_length{0} {};
  virtual ~http_codec(){};

  virtual int encode(const LibHttp__TypesAndValues::HttpMessage &, OCTETSTRING &data);
+6 −1
Original line number Diff line number Diff line
@@ -95,9 +95,14 @@ void http_layer::receive_data(OCTETSTRING &data, params &params) {

  // Decode HTTP message
  LibHttp__TypesAndValues::HttpMessage http_message;
  if (_codec->decode(data, http_message, &params) == -1) {
  int ret_code = _codec->decode(data, http_message, &params);
  if (ret_code == -1) {
    loggers::get_instance().warning("http_layer::receive_data: Failed to decode data");
    return;
  } else if (ret_code == -2) { // Need to wait for next data
    loggers::get_instance().log("http_layer::receive_data: Set Buffurizing to 1");
    params.insert(std::make_pair<std::string, std::string>("Buffurizing", "1"));
    return;
  }
  if (_device_mode) {
    OCTETSTRING os;
+4 −0
Original line number Diff line number Diff line
@@ -210,6 +210,10 @@ void tcp_layer::message_incoming(const unsigned char* message_buffer, int length
    std::string("timestamp"),
    std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count())));
  this->receive_data(data, params); // TODO Check execution time for decoding operation
  params::const_iterator it = params.find(std::string("Buffurizing"));
  if (it != params.end()) {
    loggers::get_instance().log("tcp_layer::message_incoming: Buffurizing requested");
  }
  loggers::get_instance().set_stop_time(_time_key, duration);
}