LCOV - code coverage report
Current view: top level - libs/http_proto/src - message_base.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 57 75 76.0 %
Date: 2024-03-22 19:51:41 Functions: 2 5 40.0 %

          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           0 : message_base::
      52             : set_chunked(bool value)
      53             : {
      54           0 :     if(value)
      55             :     {
      56             :         // set chunked
      57           0 :         if(! h_.md.transfer_encoding.is_chunked )
      58             :         {
      59           0 :             append(
      60             :                 field::transfer_encoding,
      61           0 :                 "chunked");
      62           0 :             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          14 :         [&](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           1 :                                 (*itv).data() -
     138           3 :                                 it->value.data()));
     139           1 :                         ++it;
     140             :                     }
     141           4 :                     continue;
     142             :                 }
     143             :                 // search remaining tokens
     144           8 :                 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             :             }
     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 1.15