GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/impl/message_base.ipp
Date: 2023-12-11 14:11:20
Exec Total Coverage
Lines: 98 115 85.2%
Functions: 3 6 50.0%
Branches: 56 90 62.2%

Line Branch Exec Source
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 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 set_content_length(n);
29
30 set_chunked(false);
31 }
32 else
33 {
34 // VFALCO ?
35 }
36 }
37
38 void
39 message_base::
40 set_content_length(
41 std::uint64_t n)
42 {
43 set(field::content_length,
44 detail::number_string(n));
45 }
46
47 void
48 message_base::
49 set_chunked(bool value)
50 {
51 if(value)
52 {
53 // set chunked
54 if(! h_.md.transfer_encoding.is_chunked )
55 {
56 append(
57 field::transfer_encoding,
58 "chunked");
59 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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
12 if(ph_->md.connection.ec.failed())
74 {
75 // throw? return false?
76 5 return;
77 }
78
79
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 7 times.
12 if(ph_->md.connection.count == 0)
80 {
81 // no Connection field
82
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 switch(ph_->version)
83 {
84 3 default:
85 case version::http_1_1:
86
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if(! value)
87
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 set(field::connection, "close");
88 3 break;
89
90 2 case version::http_1_0:
91
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(value)
92
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
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
2/2
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 6 times.
14 while(it != end())
108 {
109
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
8 if(it->id != field::connection)
110 {
111 ++it;
112 4 continue;
113 }
114 auto rv = grammar::parse(
115 8 it->value,
116
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
16 list_rule(token_rule, 1));
117
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 BOOST_ASSERT(! rv.has_error());
118
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
8 BOOST_ASSERT(! rv->empty());
119 8 auto itv = rv->begin();
120
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 if(urls::grammar::ci_is_equal(
121 8 *itv, token))
122 {
123
2/2
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
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/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 set(it,
133 1 it->value.substr(
134
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
2 (*itv).data() -
135 1 it->value.data()));
136 1 ++it;
137 }
138 4 continue;
139 }
140 // search remaining tokens
141
1/2
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
8 std::string s = *itv++;
142
2/2
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 4 times.
7 while(itv != rv->end())
143 {
144
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
3 if(! urls::grammar::ci_is_equal(
145 3 *itv, token))
146
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);
147 3 ++itv;
148 }
149
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 set(it, s);
150 4 ++it;
151 }
152 6 };
153
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 if(value)
154 {
155
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 if(ph_->md.connection.close)
156
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 erase_token("close");
157 }
158 else
159 {
160
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(ph_->md.connection.keep_alive)
161
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 erase_token("keep-alive");
162 }
163
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
7 switch(ph_->version)
164 {
165 5 default:
166 case version::http_1_1:
167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if(! value)
168 {
169 // add one "close" token if needed
170 if(! ph_->md.connection.close)
171 append(field::connection, "close");
172 }
173 5 break;
174
175 2 case version::http_1_0:
176
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(value)
177 {
178 // add one "keep-alive" token if needed
179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(! ph_->md.connection.keep_alive)
180 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
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
10 if( n > h_.prefix ||
194
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 h_.buf == nullptr)
195 {
196 // allocate or grow
197
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 if( n > h_.prefix &&
198 static_cast<std::size_t>(
199 7 n - h_.prefix) >
200 7 static_cast<std::size_t>(
201
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
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
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
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
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
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
254