Line data Source code
1 : //
2 : // Copyright (c) 2025 Mohammad Nejati
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 : #include <boost/http_proto/response.hpp>
11 :
12 : #include <cstring>
13 :
14 : namespace boost {
15 : namespace http_proto {
16 :
17 : void
18 23 : response::
19 : set_start_line_impl(
20 : http_proto::status sc,
21 : unsigned short si,
22 : core::string_view rs,
23 : http_proto::version v)
24 : {
25 23 : clone_if_needed();
26 :
27 : // TODO: check validity
28 23 : auto const vs = to_string(v);
29 : auto const new_prefix =
30 23 : vs.size() + 1 + // HTTP-version SP
31 23 : 3 + 1 + // status-code SP
32 23 : rs.size() + 2; // reason-phrase CRLF
33 :
34 : // Introduce a new scope so that prefix_op's
35 : // destructor runs before h_.on_start_line().
36 : {
37 23 : auto op = prefix_op_t(*this, new_prefix, &rs);
38 22 : char* dest = h_.buf;
39 :
40 22 : h_.version = v;
41 22 : vs.copy(dest, vs.size());
42 22 : dest += vs.size();
43 22 : *dest++ = ' ';
44 :
45 22 : h_.res.status = sc;
46 22 : h_.res.status_int = si;
47 22 : dest[0] = '0' + ((h_.res.status_int / 100) % 10);
48 22 : dest[1] = '0' + ((h_.res.status_int / 10) % 10);
49 22 : dest[2] = '0' + ((h_.res.status_int / 1) % 10);
50 22 : dest[3] = ' ';
51 22 : dest += 4;
52 :
53 22 : std::memmove(dest, rs.data(), rs.size());
54 22 : dest += rs.size();
55 22 : dest[0] = '\r';
56 22 : dest[1] = '\n';
57 22 : }
58 :
59 22 : h_.on_start_line();
60 22 : }
61 :
62 : void
63 3 : response::
64 : set_version(
65 : http_proto::version v)
66 : {
67 3 : clone_if_needed();
68 :
69 3 : if(v == h_.version)
70 1 : return;
71 2 : if(h_.is_default())
72 : {
73 1 : auto def = h_.get_default(detail::kind::response);
74 0 : return set_start_line_impl(
75 1 : def->res.status, def->res.status_int,
76 : core::string_view(
77 2 : def->cbuf + 13, def->prefix - 15), v);
78 : }
79 :
80 : // Introduce a new scope so that prefix_op's
81 : // destructor runs before h_.on_start_line().
82 : {
83 : auto op = prefix_op_t(
84 1 : *this, h_.prefix, nullptr);
85 1 : char* dest = h_.buf;
86 1 : if(v == http_proto::version::http_1_1)
87 1 : dest[7] = '1';
88 : else
89 0 : dest[7] = '0';
90 1 : h_.version = v;
91 1 : }
92 :
93 1 : h_.on_start_line();
94 : }
95 :
96 : } // http_proto
97 : } // boost
|