server: add --cors-* options (#25655)
* server: add --cors-* options * add special "localhost" value * add tests * fix test * add link to PR
This commit is contained in:
@@ -47,6 +47,16 @@ static void log_server_request(const httplib::Request & req, const httplib::Resp
|
||||
SRV_DBG("response: %s\n", res.body.c_str());
|
||||
}
|
||||
|
||||
// returns true if the Origin header value's host is localhost / 127.0.0.1 / ::1 (any port)
|
||||
static bool origin_is_localhost(const std::string & origin) {
|
||||
try {
|
||||
const std::string host = common_http_parse_url(origin).host;
|
||||
return host == "localhost" || host == "127.0.0.1" || host == "::1";
|
||||
} catch (const std::exception &) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// For Google Cloud Platform deployment compatibility
|
||||
struct gcp_params {
|
||||
bool enabled;
|
||||
@@ -266,13 +276,26 @@ bool server_http_context::init(const common_params & params) {
|
||||
};
|
||||
|
||||
// register server middlewares
|
||||
srv->set_pre_routing_handler([middleware_validate_api_key, middleware_server_state](const httplib::Request & req, httplib::Response & res) {
|
||||
res.set_header("Access-Control-Allow-Origin", req.get_header_value("Origin"));
|
||||
srv->set_pre_routing_handler([¶ms, middleware_validate_api_key, middleware_server_state](const httplib::Request & req, httplib::Response & res) {
|
||||
if (params.cors_credentials && params.cors_origins == "*") {
|
||||
// special case: echo back the Origin header to allow any origin to access the server with credentials
|
||||
res.set_header("Access-Control-Allow-Origin", req.get_header_value("Origin"));
|
||||
} else if (params.cors_origins == "localhost") {
|
||||
// special case: only reflect the Origin header if it is a localhost origin
|
||||
std::string origin = req.get_header_value("Origin");
|
||||
if (origin_is_localhost(origin)) {
|
||||
res.set_header("Access-Control-Allow-Origin", origin);
|
||||
} else {
|
||||
SRV_WRN("(CORS) skip non-localhost origin: %s\n", origin.c_str());
|
||||
}
|
||||
} else {
|
||||
res.set_header("Access-Control-Allow-Origin", params.cors_origins);
|
||||
}
|
||||
// If this is OPTIONS request, skip validation because browsers don't include Authorization header
|
||||
if (req.method == "OPTIONS") {
|
||||
res.set_header("Access-Control-Allow-Credentials", "true");
|
||||
res.set_header("Access-Control-Allow-Methods", "GET, POST");
|
||||
res.set_header("Access-Control-Allow-Headers", "*");
|
||||
res.set_header("Access-Control-Allow-Credentials", params.cors_credentials ? "true" : "false");
|
||||
res.set_header("Access-Control-Allow-Methods", params.cors_methods);
|
||||
res.set_header("Access-Control-Allow-Headers", params.cors_headers);
|
||||
res.set_content("", "text/html"); // blank response, no data
|
||||
return httplib::Server::HandlerResponse::Handled; // skip further processing
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user