Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions conf/web_athena.conf
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,15 @@ print_req_res: off
// Allow GIF images to be uploaded as guild emblem?
allow_gifs: yes

// Allow HTTP requests from specified origin
// This enables Cross-Origin Resource Sharing (CORS) for browser compatibility.
// Only requests from the configured origin will be accepted.
//
// Format: allowed_origin_cors: <protocol>://<host>:<port>
// Example: allowed_origin_cors: http://mywebsite.com:8080
//
// Security Note: Only configure origins you trust,
// as this allows cross-origin requests to your web API.
allowed_origin_cors:

import: conf/import/web_conf.txt
37 changes: 36 additions & 1 deletion src/web/web.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,41 @@ bool web_config_read(const char* cfgName, bool normal) {
web_config_read(w2, normal);
else if (!strcmpi(w1, "allow_gifs"))
web_config.allow_gifs = config_switch(w2) == 1;
else if (!strcmpi(w1, "allowed_origin_cors"))
web_config.allowed_origin_cors = w2;
}
fclose(fp);
ShowInfo("Finished reading %s.\n", cfgName);
return true;
}

/*==========================================
* CORS for browser requests
*------------------------------------------*/
void set_cors_headers(Response& res, const std::string& origin) {
res.set_header("Access-Control-Allow-Origin", origin);
res.set_header("Vary", "Origin");
res.set_header("Access-Control-Allow-Methods", "POST");
res.set_header("Access-Control-Allow-Headers", "Content-Type, Authorization");
}

static httplib::Server::HandlerResponse cors_handler(const httplib::Request& req, httplib::Response& res) {
if (web_config.allowed_origin_cors.empty()) {
// CORS not allowed
return httplib::Server::HandlerResponse::Unhandled;
}
std::string origin = req.get_header_value("Origin");

if (origin.empty())
return httplib::Server::HandlerResponse::Unhandled;

if (origin != web_config.allowed_origin_cors)
return httplib::Server::HandlerResponse::Unhandled;

set_cors_headers(res, origin);
return httplib::Server::HandlerResponse::Unhandled;
}

/*==========================================
* read config file
*------------------------------------------*/
Expand Down Expand Up @@ -259,9 +288,11 @@ int32 inter_config_read(const char* cfgName)
void web_set_defaults() {
web_config.web_ip = "0.0.0.0";
web_config.web_port = 8888;
web_config.print_req_res = false;
safestrncpy(web_config.webconf_name, "conf/web_athena.conf", sizeof(web_config.webconf_name));
safestrncpy(web_config.msgconf_name, "conf/msg_conf/web_msg.conf", sizeof(web_config.msgconf_name));
web_config.print_req_res = false;
web_config.allow_gifs = true;
web_config.allowed_origin_cors = "";

inter_config.emblem_transparency_limit = 100;
inter_config.emblem_woe_change = true;
Expand Down Expand Up @@ -446,6 +477,10 @@ bool WebServer::initialize( int32 argc, char* argv[] ){
ShowStatus("Starting server...\n");

http_server = std::make_shared<httplib::Server>();

// hook func to set up CORS for browsers
http_server->set_pre_routing_handler(cors_handler);

// set up routes
http_server->Post("/charconfig/load", charconfig_load);
http_server->Post("/charconfig/save", charconfig_save);
Expand Down
2 changes: 2 additions & 0 deletions src/web/web.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ struct Web_Config {
char webconf_name[256]; /// name of main config file
char msgconf_name[256]; /// name of msg_conf config file
bool allow_gifs;

std::string allowed_origin_cors; // allowed origin for CORS
};

struct Inter_Config {
Expand Down
Loading