GCC Code Coverage Report


Directory: libs/http_proto/
File: libs/http_proto/src/message_base.cpp
Date: 2024-03-18 23:12:48
Exec Total Coverage
Lines: 57 75 76.0%
Functions: 2 5 40.0%
Branches: 45 78 57.7%

Line Branch Exec Source
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 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 set_content_length(n);
32
33 set_chunked(false);
34 }
35 else
36 {
37 // VFALCO ?
38 }
39 }
40
41 void
42 message_base::
43 set_content_length(
44 std::uint64_t n)
45 {
46 set(field::content_length,
47 detail::number_string(n));
48 }
49
50 void
51 message_base::
52 set_chunked(bool value)
53 {
54 if(value)
55 {
56 // set chunked
57 if(! h_.md.transfer_encoding.is_chunked )
58 {
59 append(
60 field::transfer_encoding,
61 "chunked");
62 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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
12 if(ph_->md.connection.ec.failed())
77 {
78 // throw? return false?
79 5 return;
80 }
81
82
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 7 times.
12 if(ph_->md.connection.count == 0)
83 {
84 // no Connection field
85
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 switch(ph_->version)
86 {
87 3 default:
88 case version::http_1_1:
89
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if(! value)
90
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 set(field::connection, "close");
91 3 break;
92
93 2 case version::http_1_0:
94
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(value)
95
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
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
2/2
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 6 times.
14 while(it != end())
111 {
112
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
8 if(it->id != field::connection)
113 {
114 ++it;
115 4 continue;
116 }
117 auto rv = grammar::parse(
118 8 it->value,
119
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
16 list_rule(token_rule, 1));
120
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 BOOST_ASSERT(! rv.has_error());
121
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
8 BOOST_ASSERT(! rv->empty());
122 8 auto itv = rv->begin();
123
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 if(urls::grammar::ci_is_equal(
124 8 *itv, token))
125 {
126
2/2
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
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
2/4
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
3 it->value.data()));
139 1 ++it;
140 }
141 4 continue;
142 }
143 // search remaining tokens
144
1/2
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
8 std::string s = *itv++;
145
2/2
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 4 times.
7 while(itv != rv->end())
146 {
147
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
3 if(! urls::grammar::ci_is_equal(
148 3 *itv, token))
149
3/6
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
1 s += ", " + std::string(*itv);
150 3 ++itv;
151 }
152
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 set(it, s);
153 4 ++it;
154 }
155 6 };
156
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 if(value)
157 {
158
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 if(ph_->md.connection.close)
159
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 erase_token("close");
160 }
161 else
162 {
163
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(ph_->md.connection.keep_alive)
164
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 erase_token("keep-alive");
165 }
166
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
7 switch(ph_->version)
167 {
168 5 default:
169 case version::http_1_1:
170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if(! value)
171 {
172 // add one "close" token if needed
173 if(! ph_->md.connection.close)
174 append(field::connection, "close");
175 }
176 5 break;
177
178 2 case version::http_1_0:
179
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(value)
180 {
181 // add one "keep-alive" token if needed
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(! ph_->md.connection.keep_alive)
183 append(field::connection, "keep-alive");
184 }
185 2 break;
186 }
187 }
188
189 } // http_proto
190 } // boost
191