Skip to content

Commit d4a89d8

Browse files
Protect webserver::registered_resources_*
1 parent ba2234d commit d4a89d8

File tree

2 files changed

+43
-35
lines changed

2 files changed

+43
-35
lines changed

src/httpserver/webserver.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <map>
4444
#include <memory>
4545
#include <set>
46+
#include <shared_mutex>
4647
#include <string>
4748

4849
#include "httpserver/http_utils.hpp"
@@ -174,6 +175,7 @@ class webserver {
174175
const render_ptr not_found_resource;
175176
const render_ptr method_not_allowed_resource;
176177
const render_ptr internal_error_resource;
178+
std::shared_mutex registered_resources_mutex;
177179
std::map<details::http_endpoint, http_resource*> registered_resources;
178180
std::map<std::string, http_resource*> registered_resources_str;
179181

src/webserver.cpp

+41-35
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <iosfwd>
4444
#include <cstring>
4545
#include <memory>
46+
#include <mutex>
4647
#include <stdexcept>
4748
#include <utility>
4849
#include <vector>
@@ -192,6 +193,7 @@ bool webserver::register_resource(const std::string& resource, http_resource* hr
192193

193194
details::http_endpoint idx(resource, family, true, regex_checking);
194195

196+
std::unique_lock registered_resources_lock(registered_resources_mutex);
195197
pair<map<details::http_endpoint, http_resource*>::iterator, bool> result = registered_resources.insert(map<details::http_endpoint, http_resource*>::value_type(idx, hrm));
196198

197199
if (!family && result.second) {
@@ -361,6 +363,7 @@ bool webserver::stop() {
361363
void webserver::unregister_resource(const string& resource) {
362364
// family does not matter - it just checks the url_normalized anyhow
363365
details::http_endpoint he(resource, false, true, regex_checking);
366+
std::unique_lock registered_resources_lock(registered_resources_mutex);
364367
registered_resources.erase(he);
365368
registered_resources.erase(he.get_url_complete());
366369
registered_resources_str.erase(he.get_url_complete());
@@ -626,51 +629,54 @@ MHD_Result webserver::finalize_answer(MHD_Connection* connection, struct details
626629

627630
bool found = false;
628631
struct MHD_Response* raw_response;
629-
if (!single_resource) {
630-
const char* st_url = mr->standardized_url->c_str();
631-
fe = registered_resources_str.find(st_url);
632-
if (fe == registered_resources_str.end()) {
633-
if (regex_checking) {
634-
map<details::http_endpoint, http_resource*>::iterator found_endpoint;
635-
636-
details::http_endpoint endpoint(st_url, false, false, false);
637-
638-
map<details::http_endpoint, http_resource*>::iterator it;
639-
640-
size_t len = 0;
641-
size_t tot_len = 0;
642-
for (it = registered_resources.begin(); it != registered_resources.end(); ++it) {
643-
size_t endpoint_pieces_len = (*it).first.get_url_pieces().size();
644-
size_t endpoint_tot_len = (*it).first.get_url_complete().size();
645-
if (!found || endpoint_pieces_len > len || (endpoint_pieces_len == len && endpoint_tot_len > tot_len)) {
646-
if ((*it).first.match(endpoint)) {
647-
found = true;
648-
len = endpoint_pieces_len;
649-
tot_len = endpoint_tot_len;
650-
found_endpoint = it;
632+
{
633+
std::shared_lock registered_resources_lock(registered_resources_mutex);
634+
if (!single_resource) {
635+
const char* st_url = mr->standardized_url->c_str();
636+
fe = registered_resources_str.find(st_url);
637+
if (fe == registered_resources_str.end()) {
638+
if (regex_checking) {
639+
map<details::http_endpoint, http_resource*>::iterator found_endpoint;
640+
641+
details::http_endpoint endpoint(st_url, false, false, false);
642+
643+
map<details::http_endpoint, http_resource*>::iterator it;
644+
645+
size_t len = 0;
646+
size_t tot_len = 0;
647+
for (it = registered_resources.begin(); it != registered_resources.end(); ++it) {
648+
size_t endpoint_pieces_len = (*it).first.get_url_pieces().size();
649+
size_t endpoint_tot_len = (*it).first.get_url_complete().size();
650+
if (!found || endpoint_pieces_len > len || (endpoint_pieces_len == len && endpoint_tot_len > tot_len)) {
651+
if ((*it).first.match(endpoint)) {
652+
found = true;
653+
len = endpoint_pieces_len;
654+
tot_len = endpoint_tot_len;
655+
found_endpoint = it;
656+
}
651657
}
652658
}
653-
}
654659

655-
if (found) {
656-
vector<string> url_pars = found_endpoint->first.get_url_pars();
660+
if (found) {
661+
vector<string> url_pars = found_endpoint->first.get_url_pars();
657662

658-
vector<string> url_pieces = endpoint.get_url_pieces();
659-
vector<int> chunks = found_endpoint->first.get_chunk_positions();
660-
for (unsigned int i = 0; i < url_pars.size(); i++) {
661-
mr->dhr->set_arg(url_pars[i], url_pieces[chunks[i]]);
662-
}
663+
vector<string> url_pieces = endpoint.get_url_pieces();
664+
vector<int> chunks = found_endpoint->first.get_chunk_positions();
665+
for (unsigned int i = 0; i < url_pars.size(); i++) {
666+
mr->dhr->set_arg(url_pars[i], url_pieces[chunks[i]]);
667+
}
663668

664-
hrm = found_endpoint->second;
669+
hrm = found_endpoint->second;
670+
}
665671
}
672+
} else {
673+
hrm = fe->second;
674+
found = true;
666675
}
667676
} else {
668-
hrm = fe->second;
677+
hrm = registered_resources.begin()->second;
669678
found = true;
670679
}
671-
} else {
672-
hrm = registered_resources.begin()->second;
673-
found = true;
674680
}
675681

676682
if (found) {

0 commit comments

Comments
 (0)