GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/impl/message_base.ipp
Date: 2023-02-02 18:17:22
Exec Total Coverage
Lines: 98 113 86.7%
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 10 message_base::
189 set_prefix_impl(
190 std::size_t n)
191 {
192
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
10 if( n > h_.prefix ||
193
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 h_.buf == nullptr)
194 {
195 // allocate or grow
196
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 if( n > h_.prefix &&
197 static_cast<std::size_t>(
198 7 n - h_.prefix) >
199 7 static_cast<std::size_t>(
200
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 max_off_t - h_.size))
201 1 detail::throw_length_error();
202
203 7 auto n0 = detail::header::bytes_needed(
204 7 n + h_.size - h_.prefix,
205 7 h_.count);
206 7 auto buf = new char[n0];
207
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if(h_.buf != nullptr)
208 {
209 3 std::memcpy(
210 3 buf + n,
211 3 h_.buf + h_.prefix,
212 3 h_.size - h_.prefix);
213 detail::header::table ft(
214 3 h_.buf + h_.cap);
215 3 h_.copy_table(buf + n0);
216
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 delete[] h_.buf;
217 }
218 else
219 {
220 4 std::memcpy(
221 4 buf + n,
222 4 h_.cbuf + h_.prefix,
223 4 h_.size - h_.prefix);
224 }
225 7 h_.buf = buf;
226 7 h_.cbuf = buf;
227 7 h_.size = static_cast<
228 7 off_t>(h_.size +
229 7 n - h_.prefix);
230 7 h_.prefix = static_cast<
231 off_t>(n);
232 7 h_.cap = n0;
233 7 return h_.buf;
234 }
235
236 // shrink
237 2 std::memmove(
238 2 h_.buf + n,
239 2 h_.buf + h_.prefix,
240 2 h_.size - h_.prefix);
241 2 h_.size = static_cast<
242 2 off_t>(h_.size -
243 2 h_.prefix + n);
244 2 h_.prefix = static_cast<
245 off_t>(n);
246 2 return h_.buf;
247 }
248
249 } // http_proto
250 } // boost
251
252 #endif
253