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