@@ -64,7 +64,7 @@ void RunServer(std::optional<std::string> host, std::optional<int> port,
64
64
bool ignore_cout) {
65
65
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
66
66
auto signal_handler = +[](int sig) -> void {
67
- std::cout << " \r Caught interrupt signal:" << sig << " , shutting down\n " ;;
67
+ std::cout << " \r Caught interrupt signal:" << sig << " , shutting down\n " ;
68
68
shutdown_signal = true ;
69
69
};
70
70
signal (SIGINT, signal_handler);
@@ -288,54 +288,105 @@ void RunServer(std::optional<std::string> host, std::optional<int> port,
288
288
return false ;
289
289
};
290
290
291
+ auto handle_cors = [config_service](const drogon::HttpRequestPtr& req,
292
+ const drogon::HttpResponsePtr& resp) {
293
+ const std::string& origin = req->getHeader (" Origin" );
294
+ CTL_INF (" Origin: " << origin);
295
+
296
+ auto allowed_origins =
297
+ config_service->GetApiServerConfiguration ()->allowed_origins ;
298
+
299
+ auto is_contains_asterisk =
300
+ std::find (allowed_origins.begin (), allowed_origins.end (), " *" );
301
+ if (is_contains_asterisk != allowed_origins.end ()) {
302
+ resp->addHeader (" Access-Control-Allow-Origin" , " *" );
303
+ resp->addHeader (" Access-Control-Allow-Methods" , " *" );
304
+ return ;
305
+ }
306
+
307
+ // Check if the origin is in our allowed list
308
+ auto it = std::find (allowed_origins.begin (), allowed_origins.end (), origin);
309
+ if (it != allowed_origins.end ()) {
310
+ resp->addHeader (" Access-Control-Allow-Origin" , origin);
311
+ } else if (allowed_origins.empty ()) {
312
+ resp->addHeader (" Access-Control-Allow-Origin" , " *" );
313
+ }
314
+ resp->addHeader (" Access-Control-Allow-Methods" , " *" );
315
+ };
316
+
291
317
drogon::app ().registerPreRoutingAdvice (
292
- [&validate_api_key](
318
+ [&validate_api_key, &handle_cors ](
293
319
const drogon::HttpRequestPtr& req,
294
- std::function<void (const drogon::HttpResponsePtr&)>&& cb,
295
- drogon::AdviceChainCallback&& ccb) {
320
+ std::function<void (const drogon::HttpResponsePtr&)>&& stop,
321
+ drogon::AdviceChainCallback&& pass) {
322
+ // Handle OPTIONS preflight requests
323
+ if (req->method () == drogon::HttpMethod::Options) {
324
+ auto resp = HttpResponse::newHttpResponse ();
325
+ auto handlers = drogon::app ().getHandlersInfo ();
326
+ bool has_ep = [req, &handlers]() {
327
+ for (auto const & h : handlers) {
328
+ if (string_utils::AreUrlPathsEqual (req->path (), std::get<0 >(h)))
329
+ return true ;
330
+ }
331
+ return false ;
332
+ }();
333
+ if (!has_ep) {
334
+ resp->setStatusCode (drogon::HttpStatusCode::k404NotFound);
335
+ stop (resp);
336
+ return ;
337
+ }
338
+
339
+ handle_cors (req, resp);
340
+ std::string supported_methods = [req, &handlers]() {
341
+ std::string methods;
342
+ for (auto const & h : handlers) {
343
+ if (string_utils::AreUrlPathsEqual (req->path (), std::get<0 >(h))) {
344
+ auto m = drogon::to_string_view (std::get<1 >(h));
345
+ if (methods.find (m) == std::string::npos) {
346
+ methods += drogon::to_string_view (std::get<1 >(h));
347
+ methods += " , " ;
348
+ }
349
+ }
350
+ }
351
+ if (methods.size () < 2 )
352
+ return std::string ();
353
+ return methods.substr (0 , methods.size () - 2 );
354
+ }();
355
+
356
+ // Add more info to header
357
+ resp->addHeader (" Access-Control-Allow-Methods" , supported_methods);
358
+ {
359
+ const auto & val = req->getHeader (" Access-Control-Request-Headers" );
360
+ if (!val.empty ())
361
+ resp->addHeader (" Access-Control-Allow-Headers" , val);
362
+ }
363
+ // Set Access-Control-Max-Age
364
+ resp->addHeader (" Access-Control-Max-Age" ,
365
+ " 600" ); // Cache for 10 minutes
366
+ stop (resp);
367
+ return ;
368
+ }
369
+
296
370
if (!validate_api_key (req)) {
297
371
Json::Value ret;
298
372
ret[" message" ] = " Invalid API Key" ;
299
373
auto resp = cortex_utils::CreateCortexHttpJsonResponse (ret);
300
374
resp->setStatusCode (drogon::k401Unauthorized);
301
- cb (resp);
375
+ stop (resp);
302
376
return ;
303
377
}
304
- ccb ();
378
+ pass ();
305
379
});
306
380
307
381
// CORS
308
382
drogon::app ().registerPostHandlingAdvice (
309
- [config_service](const drogon::HttpRequestPtr& req,
310
- const drogon::HttpResponsePtr& resp) {
383
+ [config_service, &handle_cors ](const drogon::HttpRequestPtr& req,
384
+ const drogon::HttpResponsePtr& resp) {
311
385
if (!config_service->GetApiServerConfiguration ()->cors ) {
312
386
CTL_INF (" CORS is disabled!" );
313
387
return ;
314
388
}
315
-
316
- const std::string& origin = req->getHeader (" Origin" );
317
- CTL_INF (" Origin: " << origin);
318
-
319
- auto allowed_origins =
320
- config_service->GetApiServerConfiguration ()->allowed_origins ;
321
-
322
- auto is_contains_asterisk =
323
- std::find (allowed_origins.begin (), allowed_origins.end (), " *" );
324
- if (is_contains_asterisk != allowed_origins.end ()) {
325
- resp->addHeader (" Access-Control-Allow-Origin" , " *" );
326
- resp->addHeader (" Access-Control-Allow-Methods" , " *" );
327
- return ;
328
- }
329
-
330
- // Check if the origin is in our allowed list
331
- auto it =
332
- std::find (allowed_origins.begin (), allowed_origins.end (), origin);
333
- if (it != allowed_origins.end ()) {
334
- resp->addHeader (" Access-Control-Allow-Origin" , origin);
335
- } else if (allowed_origins.empty ()) {
336
- resp->addHeader (" Access-Control-Allow-Origin" , " *" );
337
- }
338
- resp->addHeader (" Access-Control-Allow-Methods" , " *" );
389
+ handle_cors (req, resp);
339
390
});
340
391
341
392
// ssl
0 commit comments