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