GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/impl/message_base.ipp
Date: 2023-01-09 16:11:13
Exec Total Coverage
Lines: 99 114 86.8%
Functions: 3 6 50.0%
Branches: 56 90 62.2%

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