GCC Code Coverage Report


Directory: ./
File: libs/http_proto/src/server/cors.cpp
Date: 2025-12-22 14:47:58
Exec Total Coverage
Lines: 0 77 0.0%
Functions: 0 11 0.0%
Branches: 0 53 0.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
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/server/cors.hpp>
11 #include <utility>
12
13 namespace boost {
14 namespace http_proto {
15
16 ✗ cors::
17 cors(
18 ✗ cors_options options) noexcept
19 ✗ : options_(std::move(options))
20 {
21 // VFALCO TODO Validate the strings in options against RFC
22 ✗ }
23
24 namespace {
25
26 struct Vary
27 {
28 ✗ Vary(route_params& p)
29 ✗ : p_(p)
30 {
31 ✗ }
32
33 ✗ void set(field f, core::string_view s)
34 {
35 ✗ p_.res.set(f, s);
36 ✗ }
37
38 ✗ void append(field f, core::string_view v)
39 {
40 ✗ auto it = p_.res.find(f);
41 ✗ if (it != p_.res.end())
42 {
43 ✗ std::string s = it->value;
44 ✗ s += ", ";
45 ✗ s += v;
46 ✗ p_.res.set(it, s);
47 ✗ }
48 else
49 {
50 ✗ p_.res.set(f, v);
51 }
52 ✗ }
53
54 private:
55 route_params& p_;
56 std::string v_;
57 };
58
59 } // (anon)
60
61 // Access-Control-Allow-Origin
62 ✗ static void setOrigin(
63 Vary& v,
64 route_params const&,
65 cors_options const& options)
66 {
67 ✗ if( options.origin.empty() ||
68 ✗ options.origin == "*")
69 {
70 ✗ v.set(field::access_control_allow_origin, "*");
71 ✗ return;
72 }
73
74 ✗ v.set(
75 field::access_control_allow_origin,
76 ✗ options.origin);
77 ✗ v.append(field::vary, to_string(field::origin));
78 }
79
80 // Access-Control-Allow-Methods
81 ✗ static void setMethods(
82 Vary& v,
83 cors_options const& options)
84 {
85 ✗ if(! options.methods.empty())
86 {
87 ✗ v.set(
88 field::access_control_allow_methods,
89 ✗ options.methods);
90 ✗ return;
91 }
92 ✗ v.set(
93 field::access_control_allow_methods,
94 "GET,HEAD,PUT,PATCH,POST,DELETE");
95 }
96
97 // Access-Control-Allow-Credentials
98 ✗ static void setCredentials(
99 Vary& v,
100 cors_options const& options)
101 {
102 ✗ if(! options.credentials)
103 ✗ return;
104 ✗ v.set(
105 field::access_control_allow_credentials,
106 "true");
107 }
108
109 // Access-Control-Allowed-Headers
110 ✗ static void setAllowedHeaders(
111 Vary& v,
112 route_params const& p,
113 cors_options const& options)
114 {
115 ✗ if(! options.allowedHeaders.empty())
116 {
117 ✗ v.set(
118 field::access_control_allow_headers,
119 ✗ options.allowedHeaders);
120 ✗ return;
121 }
122 ✗ auto s = p.res.value_or(
123 field::access_control_request_headers, "");
124 ✗ if(! s.empty())
125 {
126 ✗ v.set(field::access_control_allow_headers, s);
127 ✗ v.append(field::vary, s);
128 }
129 }
130
131 // Access-Control-Expose-Headers
132 ✗ static void setExposeHeaders(
133 Vary& v,
134 cors_options const& options)
135 {
136 ✗ if(options.exposedHeaders.empty())
137 ✗ return;
138 ✗ v.set(
139 field::access_control_expose_headers,
140 ✗ options.exposedHeaders);
141 }
142
143 // Access-Control-Max-Age
144 ✗ static void setMaxAge(
145 Vary& v,
146 cors_options const& options)
147 {
148 ✗ if(options.max_age.count() == 0)
149 ✗ return;
150 ✗ v.set(
151 field::access_control_max_age,
152 ✗ std::to_string(
153 options.max_age.count()));
154 }
155
156 route_result
157 ✗ cors::
158 operator()(
159 route_params& p) const
160 {
161 ✗ Vary v(p);
162 ✗ if(p.req.method() ==
163 method::options)
164 {
165 // preflight
166 ✗ setOrigin(v, p, options_);
167 ✗ setMethods(v, options_);
168 ✗ setCredentials(v, options_);
169 ✗ setAllowedHeaders(v, p, options_);
170 ✗ setMaxAge(v, options_);
171 ✗ setExposeHeaders(v, options_);
172
173 ✗ if(options_.preFligthContinue)
174 ✗ return route::next;
175 // Safari and others need this for 204 or may hang
176 ✗ p.res.set_status(options_.result);
177 ✗ p.res.set_content_length(0);
178 ✗ p.serializer.start(p.res);
179 ✗ return route::send;
180 }
181 // actual response
182 ✗ setOrigin(v, p, options_);
183 ✗ setCredentials(v, options_);
184 ✗ setExposeHeaders(v, options_);
185 ✗ return route::next;
186 ✗ }
187
188 } // http_proto
189 } // boost
190