src/request_base.cpp

100.0% Lines (56/56) 100.0% List of functions (2/2)
request_base.cpp
f(x) Functions (2)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2024 Christian Mazakas
4 // Copyright (c) 2025 Mohammad Nejati
5 //
6 // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // Official repository: https://github.com/cppalliance/http
10 //
11
12 #include <boost/http/request_base.hpp>
13
14 #include <cstring>
15
16 namespace boost {
17 namespace http {
18
19 void
20 10x request_base::
21 set_expect_100_continue(bool b)
22 {
23 10x if(h_.md.expect.count == 0)
24 {
25 3x BOOST_ASSERT(
26 ! h_.md.expect.ec);
27 3x BOOST_ASSERT(
28 ! h_.md.expect.is_100_continue);
29 3x if( b )
30 {
31 2x append(
32 field::expect,
33 "100-continue");
34 2x return;
35 }
36 1x return;
37 }
38
39 7x if(h_.md.expect.count == 1)
40 {
41 3x if(b)
42 {
43 2x if(! h_.md.expect.ec)
44 {
45 1x BOOST_ASSERT(
46 h_.md.expect.is_100_continue);
47 1x return;
48 }
49 1x BOOST_ASSERT(
50 ! h_.md.expect.is_100_continue);
51 1x auto it = find(field::expect);
52 1x BOOST_ASSERT(it != end());
53 1x set(it, "100-continue");
54 1x return;
55 }
56
57 1x auto it = find(field::expect);
58 1x BOOST_ASSERT(it != end());
59 1x erase(it);
60 1x return;
61 }
62
63 4x BOOST_ASSERT(h_.md.expect.ec);
64
65 4x auto nc = (b ? 1 : 0);
66 4x auto ne = h_.md.expect.count - nc;
67 4x if( b )
68 3x set(find(field::expect), "100-continue");
69
70 4x raw_erase_n(field::expect, ne);
71 4x h_.md.expect.count = nc;
72 4x h_.md.expect.ec = {};
73 4x h_.md.expect.is_100_continue = b;
74 }
75
76 //------------------------------------------------
77
78 void
79 44x request_base::
80 set_start_line_impl(
81 http::method m,
82 core::string_view ms,
83 core::string_view t,
84 http::version v)
85 {
86 // TODO: check validity
87 44x auto const vs = to_string(v);
88 auto const new_prefix =
89 44x ms.size() + 1 + // method SP
90 44x t.size() + 1 + // request-target SP
91 44x vs.size() + 2; // HTTP-version CRLF
92
93 // Introduce a new scope so that prefix_op's
94 // destructor runs before h_.on_start_line().
95 {
96 auto op = prefix_op_t(
97 44x *this, new_prefix, &ms, &t);
98
99 42x h_.version = v;
100 42x h_.req.method = m;
101 42x h_.req.method_len = static_cast<
102 42x offset_type>(ms.size());
103 42x h_.req.target_len = static_cast<
104 42x offset_type>(t.size());
105
106 42x char* m_dest = h_.buf;
107 42x char* t_dest = h_.buf + ms.size() + 1;
108 42x char* v_dest = t_dest + t.size() + 1;
109
110 42x std::memmove(t_dest, t.data(), t.size());
111 42x t_dest[t.size()] = ' ';
112
113 // memmove after target because could overlap
114 42x std::memmove(m_dest, ms.data(), ms.size());
115 42x m_dest[ms.size()] = ' ';
116
117 42x std::memcpy(v_dest, vs.data(), vs.size());
118 42x v_dest[vs.size() + 0] = '\r';
119 42x v_dest[vs.size() + 1] = '\n';
120 42x }
121
122 42x h_.on_start_line();
123 42x }
124
125 } // http
126 } // boost
127