LCOV - code coverage report
Current view: top level - http_proto/impl - message_base.ipp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 98 115 85.2 %
Date: 2023-12-22 17:54:30 Functions: 3 6 50.0 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
       3             : //
       4             : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5             : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6             : //
       7             : // Official repository: https://github.com/CPPAlliance/http_proto
       8             : //
       9             : 
      10             : #ifndef BOOST_HTTP_PROTO_IMPL_MESSAGE_BASE_IPP
      11             : #define BOOST_HTTP_PROTO_IMPL_MESSAGE_BASE_IPP
      12             : 
      13             : #include <boost/http_proto/message_base.hpp>
      14             : #include <boost/core/detail/string_view.hpp>
      15             : 
      16             : namespace boost {
      17             : namespace http_proto {
      18             : 
      19             : void
      20           0 : message_base::
      21             : set_payload_size(
      22             :     std::uint64_t n)
      23             : {
      24             :     //if(! is_head_response())
      25             :     if(true)
      26             :     {
      27             :         // comes first for exception safety
      28           0 :         set_content_length(n);
      29             : 
      30           0 :         set_chunked(false);
      31             :     }
      32             :     else
      33             :     {
      34             :         // VFALCO ?
      35             :     }
      36           0 : }
      37             : 
      38             : void
      39           0 : message_base::
      40             : set_content_length(
      41             :     std::uint64_t n)
      42             : {
      43           0 :     set(field::content_length,
      44           0 :         detail::number_string(n));
      45           0 : }
      46             : 
      47             : void
      48           0 : message_base::
      49             : set_chunked(bool value)
      50             : {
      51           0 :     if(value)
      52             :     {
      53             :         // set chunked
      54           0 :         if(! h_.md.transfer_encoding.is_chunked )
      55             :         {
      56           0 :             append(
      57             :                 field::transfer_encoding,
      58             :                 "chunked");
      59           0 :             return;
      60             :         }
      61             :     }
      62             :     else
      63             :     {
      64             :         // clear chunked
      65             :         // VFALCO ?
      66             :     }
      67             : }
      68             : 
      69             : void
      70          12 : message_base::
      71             : set_keep_alive(bool value)
      72             : {
      73          12 :     if(ph_->md.connection.ec.failed())
      74             :     {
      75             :         // throw? return false?
      76           5 :         return;
      77             :     }
      78             : 
      79          12 :     if(ph_->md.connection.count == 0)
      80             :     {
      81             :         // no Connection field
      82           5 :         switch(ph_->version)
      83             :         {
      84           3 :         default:
      85             :         case version::http_1_1:
      86           3 :             if(! value)
      87           2 :                 set(field::connection, "close");
      88           3 :             break;
      89             : 
      90           2 :         case version::http_1_0:
      91           2 :             if(value)
      92           1 :                 set(field::connection, "keep-alive");
      93           2 :             break;
      94             :         }
      95           5 :         return;
      96             :     }
      97             : 
      98             :     // VFALCO TODO iterate in reverse order,
      99             :     // and cache the last iterator to use
     100             :     // for appending
     101             : 
     102             :     // one or more Connection fields
     103           7 :     auto it = begin();
     104             :     auto const erase_token =
     105          14 :         [&](core::string_view token)
     106             :         {
     107          14 :             while(it != end())
     108             :             {
     109           8 :                 if(it->id != field::connection)
     110             :                 {
     111           0 :                     ++it;
     112           4 :                     continue;
     113             :                 }
     114             :                 auto rv = grammar::parse(
     115           8 :                     it->value,
     116          16 :                     list_rule(token_rule, 1));
     117           8 :                 BOOST_ASSERT(! rv.has_error());
     118           8 :                 BOOST_ASSERT(! rv->empty());
     119           8 :                 auto itv = rv->begin();
     120           8 :                 if(urls::grammar::ci_is_equal(
     121           8 :                     *itv, token))
     122             :                 {
     123           4 :                     if(rv->size() == 1)
     124             :                     {
     125             :                         // only one token
     126           3 :                         it = erase(it);
     127             :                     }
     128             :                     else
     129             :                     {
     130             :                         // first token matches
     131           1 :                         ++itv;
     132           1 :                         set(it,
     133           1 :                             it->value.substr(
     134           2 :                                 (*itv).data() -
     135           1 :                                 it->value.data()));
     136           1 :                         ++it;
     137             :                     }
     138           4 :                     continue;
     139             :                 }
     140             :                 // search remaining tokens
     141           8 :                 std::string s = *itv++;
     142           7 :                 while(itv != rv->end())
     143             :                 {
     144           3 :                     if(! urls::grammar::ci_is_equal(
     145           3 :                         *itv, token))
     146           1 :                         s += ", " + std::string(*itv);
     147           3 :                     ++itv;
     148             :                 }
     149           4 :                 set(it, s);
     150           4 :                 ++it;
     151             :             }
     152           6 :         };
     153           7 :     if(value)
     154             :     {
     155           6 :         if(ph_->md.connection.close)
     156           5 :             erase_token("close");
     157             :     }
     158             :     else
     159             :     {
     160           1 :         if(ph_->md.connection.keep_alive)
     161           1 :             erase_token("keep-alive");
     162             :     }
     163           7 :     switch(ph_->version)
     164             :     {
     165           5 :     default:
     166             :     case version::http_1_1:
     167           5 :         if(! value)
     168             :         {
     169             :             // add one "close" token if needed
     170           0 :             if(! ph_->md.connection.close)
     171           0 :                 append(field::connection, "close");
     172             :         }
     173           5 :         break;
     174             : 
     175           2 :     case version::http_1_0:
     176           2 :         if(value)
     177             :         {
     178             :             // add one "keep-alive" token if needed
     179           1 :             if(! ph_->md.connection.keep_alive)
     180           0 :                 append(field::connection, "keep-alive");
     181             :         }
     182           2 :         break;
     183             :     }
     184             : }
     185             : 
     186             : //------------------------------------------------
     187             : 
     188             : char*
     189          10 : message_base::
     190             : set_prefix_impl(
     191             :     std::size_t n)
     192             : {
     193          10 :     if( n > h_.prefix ||
     194           3 :         h_.buf == nullptr)
     195             :     {
     196             :         // allocate or grow
     197           8 :         if( n > h_.prefix &&
     198             :             static_cast<std::size_t>(
     199           7 :                 n - h_.prefix) >
     200           7 :             static_cast<std::size_t>(
     201           7 :                 max_off_t - h_.size))
     202           1 :             detail::throw_length_error();
     203             : 
     204           7 :         auto n0 = detail::header::bytes_needed(
     205           7 :             n + h_.size - h_.prefix,
     206           7 :             h_.count);
     207           7 :         auto buf = new char[n0];
     208           7 :         if(h_.buf != nullptr)
     209             :         {
     210           3 :             std::memcpy(
     211           3 :                 buf + n,
     212           3 :                 h_.buf + h_.prefix,
     213           3 :                 h_.size - h_.prefix);
     214             :             detail::header::table ft(
     215           3 :                 h_.buf + h_.cap);
     216           3 :             h_.copy_table(buf + n0);
     217           3 :             delete[] h_.buf;
     218             :         }
     219             :         else
     220             :         {
     221           4 :             std::memcpy(
     222           4 :                 buf + n,
     223           4 :                 h_.cbuf + h_.prefix,
     224           4 :                 h_.size - h_.prefix);
     225             :         }
     226           7 :         h_.buf = buf;
     227           7 :         h_.cbuf = buf;
     228           7 :         h_.size = static_cast<
     229           7 :             off_t>(h_.size +
     230           7 :                 n - h_.prefix);
     231           7 :         h_.prefix = static_cast<
     232             :             off_t>(n);
     233           7 :         h_.cap = n0;
     234           7 :         return h_.buf;
     235             :     }
     236             : 
     237             :     // shrink
     238           2 :     std::memmove(
     239           2 :         h_.buf + n,
     240           2 :         h_.buf + h_.prefix,
     241           2 :         h_.size - h_.prefix);
     242           2 :     h_.size = static_cast<
     243           2 :         off_t>(h_.size -
     244           2 :             h_.prefix + n);
     245           2 :     h_.prefix = static_cast<
     246             :         off_t>(n);
     247           2 :     return h_.buf;
     248             : }
     249             : 
     250             : } // http_proto
     251             : } // boost
     252             : 
     253             : #endif

Generated by: LCOV version 1.15