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 | 48 | message_base:: | |
52 | set_chunked(bool value) | ||
53 | { | ||
54 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
|
48 | if(value) |
55 | { | ||
56 | // set chunked | ||
57 |
1/2✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
24 | if(! h_.md.transfer_encoding.is_chunked ) |
58 | { | ||
59 |
1/2✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
24 | append( |
60 | field::transfer_encoding, | ||
61 | "chunked"); | ||
62 | 24 | 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 | 6 | [&](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/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | set(it, |
136 | 1 | it->value.substr( | |
137 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | (*itv).data() - |
138 | 1 | 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.
|
4 | 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 |
2/2✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
|
8 | } |
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 |