LCOV - code coverage report
Current view: top level - model - DataPart.cpp (source / functions) Coverage Total Hit
Test: final-coverage.info Lines: 100.0 % 61 61
Test Date: 2025-02-14 17:40:40 Functions: 100.0 % 7 7

            Line data    Source code
       1              : /*
       2              :  ___________________________________________
       3              : |    _     ___                        _     |
       4              : |   | |   |__ \                      | |    |
       5              : |   | |__    ) |__ _  __ _  ___ _ __ | |_   |
       6              : |   | '_ \  / // _` |/ _` |/ _ \ '_ \| __|  |  HTTP/2 AGENT FOR MOCK TESTING
       7              : |   | | | |/ /| (_| | (_| |  __/ | | | |_   |  Version 0.0.z
       8              : |   |_| |_|____\__,_|\__, |\___|_| |_|\__|  |  https://github.com/testillano/h2agent
       9              : |                     __/ |                 |
      10              : |                    |___/                  |
      11              : |___________________________________________|
      12              : 
      13              : Licensed under the MIT License <http://opensource.org/licenses/MIT>.
      14              : SPDX-License-Identifier: MIT
      15              : Copyright (c) 2021 Eduardo Ramos
      16              : 
      17              : Permission is hereby  granted, free of charge, to any  person obtaining a copy
      18              : of this software and associated  documentation files (the "Software"), to deal
      19              : in the Software  without restriction, including without  limitation the rights
      20              : to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
      21              : copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
      22              : furnished to do so, subject to the following conditions:
      23              : 
      24              : The above copyright notice and this permission notice shall be included in all
      25              : copies or substantial portions of the Software.
      26              : 
      27              : THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
      28              : IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
      29              : FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
      30              : AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
      31              : LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      32              : OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
      33              : SOFTWARE.
      34              : */
      35              : 
      36              : #include <ert/tracing/Logger.hpp>
      37              : #include <ert/http2comm/Http2Headers.hpp>
      38              : 
      39              : #include <functions.hpp>
      40              : 
      41              : #include <DataPart.hpp>
      42              : 
      43              : 
      44              : namespace h2agent
      45              : {
      46              : namespace model
      47              : {
      48              : 
      49              : // MyMultipartConsumer
      50              : 
      51              : // {
      52              : //   "multipart.1": {
      53              : //     "content": "<h2 class=\"fg-white\">",
      54              : //     "headers": { "content-type": "text/html" }
      55              : //   },
      56              : //   "multipart.2": {
      57              : //     "content": "0xc0a80100",
      58              : //     "headers": { "content-type": "application/octet-stream" }
      59              : //   },
      60              : //   "multipart.3": {
      61              : //     "content": { "foo": "bar" },
      62              : //     "headers": { "content-type": "application/json" }
      63              : //   }
      64              : // }
      65              : 
      66            2 : void MyMultipartConsumer::receiveHeader(const std::string &name, const std::string &value) {
      67              : 
      68            2 :     std::string n = name;
      69            2 :     std::transform(n.begin(), n.end(), n.begin(), [](unsigned char c) {
      70           24 :         return std::tolower(c);
      71              :     });
      72            2 :     if (n == "content-type") content_type_ = value;
      73            2 :     data_part_->json_["multipart." + std::to_string(data_count_)]["headers"][name] = value;
      74            2 : }
      75              : 
      76            2 : void MyMultipartConsumer::receiveData(const std::string &data) {
      77            2 :     nlohmann::json content;
      78            2 :     data_part_->decodeContent(data, content_type_, content);
      79            2 :     data_part_->json_["multipart." + std::to_string(data_count_)]["content"] = std::move(content);
      80            2 :     data_count_++;
      81            2 : }
      82              : 
      83              : // DataPart
      84              : 
      85            2 : std::string DataPart::asAsciiString() const {
      86            2 :     std::string result;
      87            2 :     h2agent::model::asAsciiString(str_, result);
      88            2 :     return result;
      89              : } // LCOV_EXCL_LINE
      90              : 
      91           16 : bool DataPart::assignFromHex(const std::string &strAsHex) {
      92           16 :     decoded_ = false;
      93           16 :     return h2agent::model::fromHexString(strAsHex, str_);
      94              : }
      95              : 
      96          441 : void DataPart::decodeContent(const std::string &content, const std::string &contentType, nlohmann::json &jsonRepresentation) {
      97              : 
      98          441 :     LOGDEBUG(
      99              :         std::string output;
     100              :         bool printable = h2agent::model::asHexString(content, output);
     101              :         ert::tracing::Logger::debug(ert::tracing::Logger::asString("Content (which is %sprintable) as hex: %s", (printable ? "":"non-"), output.c_str()), ERT_FILE_LOCATION);
     102              :     );
     103              : 
     104              :     //// Normalize content-type:
     105              :     //std::string ct = contentType;
     106              :     //std::transform(ct.begin(), ct.end(), ct.begin(), [](unsigned char c) {
     107              :     //    return std::tolower(c);
     108              :     //});
     109              : 
     110          441 :     if (contentType == "application/json") {
     111          325 :         /*is_json_ = */h2agent::model::parseJsonContent(content, jsonRepresentation, true /* write exception message */);
     112          325 :         is_json_ = true; // even if json is invalid, we prefer to show the error description, but obey the content-type
     113              :     }
     114          116 :     else if (contentType.rfind("text/", 0) == 0) {
     115            2 :         jsonRepresentation = content;
     116              :     }
     117          114 :     else if (contentType.rfind("multipart/", 0) == 0) { // i.e.: multipart/related; boundary=abcdef12345
     118            2 :         size_t pos = contentType.find("boundary=");
     119            2 :         std::string boundary = (pos != std::string::npos) ? contentType.substr(pos + 9) : "";
     120              : 
     121            2 :         if (boundary.empty()) {
     122            1 :             ert::tracing::Logger::error(ert::tracing::Logger::asString("Invalid multipart boundary received: '%s'", boundary.c_str()), ERT_FILE_LOCATION);
     123              :         }
     124              :         else {
     125            1 :             is_json_ = true; // multipart decoded will always be represented by h2agent proprietary json:
     126            1 :             MyMultipartConsumer mpConsumer(boundary, this);
     127            1 :             mpConsumer.decode(content);
     128            1 :         }
     129            2 :     }
     130              :     else {
     131          112 :         LOGINFORMATIONAL(ert::tracing::Logger::informational(ert::tracing::Logger::asString("Unsupported content-type '%s' decoding for json representation. Generic procedure will be applied (hex string for non printable data received)", contentType.c_str()), ERT_FILE_LOCATION));
     132          112 :         std::string output;
     133          112 :         if (h2agent::model::asHexString(content, output)) {
     134          109 :             jsonRepresentation = content;
     135              :         }
     136              :         else {
     137            3 :             jsonRepresentation = std::move(output);
     138              :         }
     139          112 :     }
     140          441 : }
     141              : 
     142          558 : void DataPart::decode(const nghttp2::asio_http2::header_map &headers) {
     143              : 
     144          558 :     if (decoded_) {
     145          103 :         LOGDEBUG(ert::tracing::Logger::debug(ert::tracing::Logger::asString("Data part already decoded (%s). Skipping operation !", ert::http2comm::headersAsString(headers).c_str()), ERT_FILE_LOCATION));
     146          119 :         return;
     147              :     }
     148              : 
     149          455 :     if (str_.empty()) {
     150           16 :         decoded_ = true;
     151           16 :         is_json_ = false;
     152           16 :         return;
     153              :     }
     154              : 
     155          439 :     std::string contentType;
     156          439 :     auto ct_it = headers.find("content-type");
     157          439 :     if (ct_it != headers.end()) {
     158          331 :         contentType = ct_it->second.value;
     159          331 :         LOGDEBUG(ert::tracing::Logger::debug(ert::tracing::Logger::asString("content-type: %s", contentType.c_str()), ERT_FILE_LOCATION));
     160              :     }
     161              : 
     162          439 :     decodeContent(str_, contentType, json_);
     163              : 
     164          439 :     decoded_ = true;
     165              : 
     166          439 :     LOGDEBUG(
     167              :         std::string msg;
     168              :     try {
     169              :         msg = json_.dump();
     170              :     }
     171              :     catch (const std::exception& e)
     172              :     {
     173              :         msg = e.what();
     174              :     }
     175              :     ert::tracing::Logger::debug(ert::tracing::Logger::asString("DataPart json representation: %s", msg.c_str()), ERT_FILE_LOCATION);
     176              :     );
     177          439 : }
     178              : 
     179              : }
     180              : }
     181              : 
        

Generated by: LCOV version 2.0-1