userver: userver/server/middlewares/cors.hpp Source File
Loading...
Searching...
No Matches
cors.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/server/middlewares/cors.hpp
4/// @brief CORS (Cross-Origin Resource Sharing) middleware
5
6#include <string>
7#include <vector>
8
9#include <userver/formats/parse/to.hpp>
10#include <userver/http/common_headers.hpp>
11#include <userver/server/http/http_method.hpp>
12#include <userver/server/middlewares/builtin.hpp>
13#include <userver/server/middlewares/http_middleware_base.hpp>
14#include <userver/yaml_config/schema.hpp>
15
16USERVER_NAMESPACE_BEGIN
17
18namespace server::middlewares {
19
20/// @brief CORS (Cross-Origin Resource Sharing) middleware
21///
22/// This middleware handles CORS preflight requests and adds appropriate CORS headers
23/// to responses to allow cross-origin requests from web browsers.
24///
25/// @note The middleware is usually created by @ref server::middlewares::CorsFactory
26class Cors final : public HttpMiddlewareBase {
27public:
28 struct Config {
29 /// Allowed origins. Use "*" to allow all origins (not recommended for production)
30 std::vector<std::string> allowed_origins;
31
32 /// Allowed HTTP methods
33 std::vector<std::string> allowed_methods = {
34 ToString(http::HttpMethod::kGet),
35 ToString(http::HttpMethod::kPost),
36 ToString(http::HttpMethod::kPut),
37 ToString(http::HttpMethod::kPatch),
38 ToString(http::HttpMethod::kDelete),
39 ToString(http::HttpMethod::kHead),
40 ToString(http::HttpMethod::kOptions),
41 };
42
43 /// Allowed headers
44 std::vector<std::string> allowed_headers = {
45 std::string(USERVER_NAMESPACE::http::headers::kAccept),
46 std::string(USERVER_NAMESPACE::http::headers::kAcceptLanguage),
47 std::string(USERVER_NAMESPACE::http::headers::kContentLanguage),
48 std::string(USERVER_NAMESPACE::http::headers::kContentType),
49 };
50
51 /// Headers that can be exposed to the browser
52 std::vector<std::string> exposed_headers;
53
54 /// Whether to allow credentials (cookies, authorization headers)
55 bool allow_credentials{false};
56
57 /// Maximum age for preflight cache
58 std::chrono::seconds max_age{std::chrono::hours(24)};
59 };
60
61 explicit Cors(const Config& config);
62
63private:
64 void HandleRequest(http::HttpRequest& request, request::RequestContext& context) const override;
65
66 bool IsPreflightRequest(const http::HttpRequest& request) const;
67 void HandlePreflightRequest(http::HttpRequest& request) const;
68 void AddCorsHeaders(http::HttpRequest& request, const std::string& origin) const;
69 bool IsOriginAllowed(const std::string& origin) const;
70 const std::string& GetOriginHeader(const http::HttpRequest& request) const;
71
72 const Config config_;
73};
74
75/// @ingroup userver_components
76///
77/// @brief Factory for @ref server::middlewares::Cors
78///
79/// The middleware handles CORS preflight requests and adds appropriate CORS headers
80/// to responses to allow cross-origin requests from web browsers.
81/// For additional information about CORS please see https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS.
82///
83/// ## Static options of `CorsFactory`:
84///
85/// @include{doc} scripts/docs/en/components_schema/core/src/server/middlewares/cors.md
86///
87/// Options inherited from @ref components::RawComponentBase :
88/// @include{doc} scripts/docs/en/components_schema/core/src/components/impl/component_base.md
89///
90/// @see @ref server::middlewares::Cors
91class CorsFactory final : public HttpMiddlewareFactoryBase {
92public:
93 /// @ingroup userver_component_names
94 /// @brief The default name of @ref server::middlewares::CorsFactory component
95 static constexpr std::string_view kName = "cors-middleware";
96
97 CorsFactory(const components::ComponentConfig&, const components::ComponentContext&);
98
99 static yaml_config::Schema GetStaticConfigSchema();
100
101 yaml_config::Schema GetMiddlewareConfigSchema() const override;
102
103private:
104 std::unique_ptr<HttpMiddlewareBase> Create(
105 const handlers::HttpHandlerBase& handler,
106 yaml_config::YamlConfig middleware_config
107 ) const override;
108
109 const yaml_config::YamlConfig global_config_;
110};
111
112/// Parse CORS configuration from YAML
113Cors::Config Parse(const yaml_config::YamlConfig& value, formats::parse::To<Cors::Config>);
114
115} // namespace server::middlewares
116
117template <>
118inline constexpr bool components::kHasValidate<server::middlewares::CorsFactory> = true;
119
120template <>
121inline constexpr auto components::kConfigFileMode<server::middlewares::CorsFactory> = ConfigFileMode::kRequired;
122
123USERVER_NAMESPACE_END