1  
//
1  
//
2  
// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/cppalliance/http
7  
// Official repository: https://github.com/cppalliance/http
8  
//
8  
//
9  

9  

10  
#include <boost/http/error.hpp>
10  
#include <boost/http/error.hpp>
11  
#include <boost/url/grammar/error.hpp>
11  
#include <boost/url/grammar/error.hpp>
12  
#include <boost/assert.hpp>
12  
#include <boost/assert.hpp>
13  
#include <cstring>
13  
#include <cstring>
14  

14  

15  
namespace boost {
15  
namespace boost {
16  
namespace http {
16  
namespace http {
17  

17  

18  
namespace detail {
18  
namespace detail {
19  

19  

20  
const char*
20  
const char*
21  
error_cat_type::
21  
error_cat_type::
22  
name() const noexcept
22  
name() const noexcept
23  
{
23  
{
24  
    return "boost.http";
24  
    return "boost.http";
25  
}
25  
}
26  

26  

27  
std::string
27  
std::string
28  
error_cat_type::
28  
error_cat_type::
29  
message(int code) const
29  
message(int code) const
30  
{
30  
{
31  
    return message(code, nullptr, 0);
31  
    return message(code, nullptr, 0);
32  
}
32  
}
33  

33  

34  
char const*
34  
char const*
35  
error_cat_type::
35  
error_cat_type::
36  
message(
36  
message(
37  
    int code,
37  
    int code,
38  
    char*,
38  
    char*,
39  
    std::size_t) const noexcept
39  
    std::size_t) const noexcept
40  
{
40  
{
41  
    switch(static_cast<error>(code))
41  
    switch(static_cast<error>(code))
42  
    {
42  
    {
43  
    case error::expect_100_continue: return "expect 100 continue";
43  
    case error::expect_100_continue: return "expect 100 continue";
44  
    case error::end_of_message: return "end of message";
44  
    case error::end_of_message: return "end of message";
45  
    case error::end_of_stream: return "end of stream";
45  
    case error::end_of_stream: return "end of stream";
46  
    case error::in_place_overflow: return "in place overflow";
46  
    case error::in_place_overflow: return "in place overflow";
47  
    case error::need_data: return "need data";
47  
    case error::need_data: return "need data";
48  

48  

49  
    case error::bad_connection: return "bad Connection";
49  
    case error::bad_connection: return "bad Connection";
50  
    case error::bad_content_length: return "bad Content-Length";
50  
    case error::bad_content_length: return "bad Content-Length";
51  
    case error::bad_expect: return "bad Expect";
51  
    case error::bad_expect: return "bad Expect";
52  
    case error::bad_field_name: return "bad field name";
52  
    case error::bad_field_name: return "bad field name";
53  
    case error::bad_field_value: return "bad field value";
53  
    case error::bad_field_value: return "bad field value";
54  
    case error::bad_field_smuggle: return "bad field smuggle";
54  
    case error::bad_field_smuggle: return "bad field smuggle";
55  
    case error::bad_line_ending: return "bad line ending";
55  
    case error::bad_line_ending: return "bad line ending";
56  
    case error::bad_list: return "bad list";
56  
    case error::bad_list: return "bad list";
57  
    case error::bad_method: return "bad method";
57  
    case error::bad_method: return "bad method";
58  
    case error::bad_number: return "bad number";
58  
    case error::bad_number: return "bad number";
59  
    case error::bad_payload: return "bad payload";
59  
    case error::bad_payload: return "bad payload";
60  
    case error::bad_version: return "bad version";
60  
    case error::bad_version: return "bad version";
61  
    case error::bad_reason: return "bad reason-phrase";
61  
    case error::bad_reason: return "bad reason-phrase";
62  
    case error::bad_request_target: return "bad request-target";
62  
    case error::bad_request_target: return "bad request-target";
63  
    case error::bad_status_code: return "bad status-code";
63  
    case error::bad_status_code: return "bad status-code";
64  
    case error::bad_status_line: return "bad status-line";
64  
    case error::bad_status_line: return "bad status-line";
65  
    case error::bad_transfer_encoding: return "bad Transfer-Encoding";
65  
    case error::bad_transfer_encoding: return "bad Transfer-Encoding";
66  
    case error::bad_upgrade: return "bad Upgrade";
66  
    case error::bad_upgrade: return "bad Upgrade";
67  

67  

68  
    case error::body_too_large: return "body too large";
68  
    case error::body_too_large: return "body too large";
69  
    case error::headers_limit: return "headers limit";
69  
    case error::headers_limit: return "headers limit";
70  
    case error::start_line_limit: return "start line limit";
70  
    case error::start_line_limit: return "start line limit";
71  
    case error::field_size_limit: return "field size limit";
71  
    case error::field_size_limit: return "field size limit";
72  
    case error::fields_limit: return "fields limit";
72  
    case error::fields_limit: return "fields limit";
73  
    case error::incomplete: return "incomplete";
73  
    case error::incomplete: return "incomplete";
74  

74  

75  
    case error::numeric_overflow: return "numeric overflow";
75  
    case error::numeric_overflow: return "numeric overflow";
76  
    case error::multiple_content_length: return "multiple Content-Length";
76  
    case error::multiple_content_length: return "multiple Content-Length";
77  
    case error::buffer_overflow: return "buffer overflow";
77  
    case error::buffer_overflow: return "buffer overflow";
78  
    case error::unhandled_exception: return "unhandled exception";
78  
    case error::unhandled_exception: return "unhandled exception";
79  
    default:
79  
    default:
80  
        return "unknown";
80  
        return "unknown";
81  
    }
81  
    }
82  
}
82  
}
83  

83  

84  
//-----------------------------------------------
84  
//-----------------------------------------------
85  

85  

86  
const char*
86  
const char*
87  
condition_cat_type::
87  
condition_cat_type::
88  
name() const noexcept
88  
name() const noexcept
89  
{
89  
{
90  
    return "boost.http";
90  
    return "boost.http";
91  
}
91  
}
92  

92  

93  
std::string
93  
std::string
94  
condition_cat_type::
94  
condition_cat_type::
95  
message(int code) const
95  
message(int code) const
96  
{
96  
{
97  
    return message(code, nullptr, 0);
97  
    return message(code, nullptr, 0);
98  
}
98  
}
99  

99  

100  
char const*
100  
char const*
101  
condition_cat_type::
101  
condition_cat_type::
102  
message(
102  
message(
103  
    int code,
103  
    int code,
104  
    char*,
104  
    char*,
105  
    std::size_t) const noexcept
105  
    std::size_t) const noexcept
106  
{
106  
{
107  
    switch(static_cast<condition>(code))
107  
    switch(static_cast<condition>(code))
108  
    {
108  
    {
109  
    default:
109  
    default:
110  
    case condition::need_more_input: return "need more input";
110  
    case condition::need_more_input: return "need more input";
111  
    case condition::invalid_payload: return "invalid body octets received";
111  
    case condition::invalid_payload: return "invalid body octets received";
112  
    }
112  
    }
113  
}
113  
}
114  

114  

115  
bool
115  
bool
116  
condition_cat_type::
116  
condition_cat_type::
117  
equivalent(
117  
equivalent(
118  
    system::error_code const& ec,
118  
    system::error_code const& ec,
119  
    int code) const noexcept
119  
    int code) const noexcept
120  
{
120  
{
121  
    switch(static_cast<condition>(code))
121  
    switch(static_cast<condition>(code))
122  
    {
122  
    {
123  
    case condition::invalid_payload:
123  
    case condition::invalid_payload:
124  
        return (ec == error::bad_payload);
124  
        return (ec == error::bad_payload);
125  

125  

126  
    case condition::need_more_input:
126  
    case condition::need_more_input:
127  
        if( ec == urls::grammar::error::need_more ||
127  
        if( ec == urls::grammar::error::need_more ||
128  
            ec == error::need_data )
128  
            ec == error::need_data )
129  
            return true;
129  
            return true;
130  
        break;
130  
        break;
131  

131  

132  
    default:
132  
    default:
133  
        break;
133  
        break;
134  
    }
134  
    }
135  
    return
135  
    return
136  
        *this == ec.category() &&
136  
        *this == ec.category() &&
137  
        ec.value() == code;
137  
        ec.value() == code;
138  
}
138  
}
139  

139  

140  
//-----------------------------------------------
140  
//-----------------------------------------------
141  

141  

142  
// msvc 14.0 has a bug that warns about inability
142  
// msvc 14.0 has a bug that warns about inability
143  
// to use constexpr construction here, even though
143  
// to use constexpr construction here, even though
144  
// there's no constexpr construction
144  
// there's no constexpr construction
145  
#if defined(_MSC_VER) && _MSC_VER <= 1900
145  
#if defined(_MSC_VER) && _MSC_VER <= 1900
146  
# pragma warning( push )
146  
# pragma warning( push )
147  
# pragma warning( disable : 4592 )
147  
# pragma warning( disable : 4592 )
148  
#endif
148  
#endif
149  

149  

150  
#if defined(__cpp_constinit) && __cpp_constinit >= 201907L
150  
#if defined(__cpp_constinit) && __cpp_constinit >= 201907L
151  
constinit error_cat_type error_cat;
151  
constinit error_cat_type error_cat;
152  
constinit condition_cat_type condition_cat;
152  
constinit condition_cat_type condition_cat;
153  
#else
153  
#else
154  
error_cat_type error_cat;
154  
error_cat_type error_cat;
155  
condition_cat_type condition_cat;
155  
condition_cat_type condition_cat;
156  
#endif
156  
#endif
157  

157  

158  
#if defined(_MSC_VER) && _MSC_VER <= 1900
158  
#if defined(_MSC_VER) && _MSC_VER <= 1900
159  
# pragma warning( pop )
159  
# pragma warning( pop )
160  
#endif
160  
#endif
161  

161  

162  
} // detail
162  
} // detail
163  

163  

164  
} // http
164  
} // http
165  
} // boost
165  
} // boost