LCOV - code coverage report
Current view: top level - libs/http_proto/src/message_base.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 84.0 % 75 63
Test Date: 2024-07-25 21:11:03 Functions: 60.0 % 5 3

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
       3              : // Copyright (c) 2024 Christian Mazakas
       4              : //
       5              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7              : //
       8              : // Official repository: https://github.com/cppalliance/http_proto
       9              : //
      10              : 
      11              : #include <boost/http_proto/message_base.hpp>
      12              : #include <boost/http_proto/rfc/list_rule.hpp>
      13              : #include <boost/http_proto/rfc/token_rule.hpp>
      14              : #include <boost/http_proto/detail/except.hpp>
      15              : #include "detail/number_string.hpp"
      16              : #include <boost/url/grammar/parse.hpp>
      17              : #include <boost/url/grammar/ci_string.hpp>
      18              : 
      19              : namespace boost {
      20              : namespace http_proto {
      21              : 
      22              : void
      23            0 : message_base::
      24              : set_payload_size(
      25              :     std::uint64_t n)
      26              : {
      27              :     //if(! is_head_response())
      28              :     if(true)
      29              :     {
      30              :         // comes first for exception safety
      31            0 :         set_content_length(n);
      32              : 
      33            0 :         set_chunked(false);
      34              :     }
      35              :     else
      36              :     {
      37              :         // VFALCO ?
      38              :     }
      39            0 : }
      40              : 
      41              : void
      42            0 : message_base::
      43              : set_content_length(
      44              :     std::uint64_t n)
      45              : {
      46            0 :     set(field::content_length,
      47            0 :         detail::number_string(n));
      48            0 : }
      49              : 
      50              : void
      51           48 : message_base::
      52              : set_chunked(bool value)
      53              : {
      54           48 :     if(value)
      55              :     {
      56              :         // set chunked
      57           24 :         if(! h_.md.transfer_encoding.is_chunked )
      58              :         {
      59           24 :             append(
      60              :                 field::transfer_encoding,
      61              :                 "chunked");
      62           24 :             return;
      63              :         }
      64              :     }
      65              :     else
      66              :     {
      67              :         // clear chunked
      68              :         // VFALCO ?
      69              :     }
      70              : }
      71              : 
      72              : void
      73           12 : message_base::
      74              : set_keep_alive(bool value)
      75              : {
      76           12 :     if(ph_->md.connection.ec.failed())
      77              :     {
      78              :         // throw? return false?
      79            5 :         return;
      80              :     }
      81              : 
      82           12 :     if(ph_->md.connection.count == 0)
      83              :     {
      84              :         // no Connection field
      85            5 :         switch(ph_->version)
      86              :         {
      87            3 :         default:
      88              :         case version::http_1_1:
      89            3 :             if(! value)
      90            2 :                 set(field::connection, "close");
      91            3 :             break;
      92              : 
      93            2 :         case version::http_1_0:
      94            2 :             if(value)
      95            1 :                 set(field::connection, "keep-alive");
      96            2 :             break;
      97              :         }
      98            5 :         return;
      99              :     }
     100              : 
     101              :     // VFALCO TODO iterate in reverse order,
     102              :     // and cache the last iterator to use
     103              :     // for appending
     104              : 
     105              :     // one or more Connection fields
     106            7 :     auto it = begin();
     107              :     auto const erase_token =
     108            6 :         [&](core::string_view token)
     109              :         {
     110           14 :             while(it != end())
     111              :             {
     112            8 :                 if(it->id != field::connection)
     113              :                 {
     114            0 :                     ++it;
     115            4 :                     continue;
     116              :                 }
     117              :                 auto rv = grammar::parse(
     118            8 :                     it->value,
     119           16 :                     list_rule(token_rule, 1));
     120            8 :                 BOOST_ASSERT(! rv.has_error());
     121            8 :                 BOOST_ASSERT(! rv->empty());
     122            8 :                 auto itv = rv->begin();
     123            8 :                 if(urls::grammar::ci_is_equal(
     124            8 :                     *itv, token))
     125              :                 {
     126            4 :                     if(rv->size() == 1)
     127              :                     {
     128              :                         // only one token
     129            3 :                         it = erase(it);
     130              :                     }
     131              :                     else
     132              :                     {
     133              :                         // first token matches
     134            1 :                         ++itv;
     135            1 :                         set(it,
     136            1 :                             it->value.substr(
     137            2 :                                 (*itv).data() -
     138            1 :                                 it->value.data()));
     139            1 :                         ++it;
     140              :                     }
     141            4 :                     continue;
     142              :                 }
     143              :                 // search remaining tokens
     144            4 :                 std::string s = *itv++;
     145            7 :                 while(itv != rv->end())
     146              :                 {
     147            3 :                     if(! urls::grammar::ci_is_equal(
     148            3 :                         *itv, token))
     149            1 :                         s += ", " + std::string(*itv);
     150            3 :                     ++itv;
     151              :                 }
     152            4 :                 set(it, s);
     153            4 :                 ++it;
     154            8 :             }
     155            6 :         };
     156            7 :     if(value)
     157              :     {
     158            6 :         if(ph_->md.connection.close)
     159            5 :             erase_token("close");
     160              :     }
     161              :     else
     162              :     {
     163            1 :         if(ph_->md.connection.keep_alive)
     164            1 :             erase_token("keep-alive");
     165              :     }
     166            7 :     switch(ph_->version)
     167              :     {
     168            5 :     default:
     169              :     case version::http_1_1:
     170            5 :         if(! value)
     171              :         {
     172              :             // add one "close" token if needed
     173            0 :             if(! ph_->md.connection.close)
     174            0 :                 append(field::connection, "close");
     175              :         }
     176            5 :         break;
     177              : 
     178            2 :     case version::http_1_0:
     179            2 :         if(value)
     180              :         {
     181              :             // add one "keep-alive" token if needed
     182            1 :             if(! ph_->md.connection.keep_alive)
     183            0 :                 append(field::connection, "keep-alive");
     184              :         }
     185            2 :         break;
     186              :     }
     187              : }
     188              : 
     189              : } // http_proto
     190              : } // boost
        

Generated by: LCOV version 2.1