@@ -93,7 +93,8 @@ class http_request {
9393 * @return a vector of strings containing all pieces
9494 **/
9595 const std::vector<std::string> get_path_pieces () const {
96- return http::http_utils::tokenize_url (path);
96+ ensure_path_pieces_cached ();
97+ return cache->path_pieces ;
9798 }
9899
99100 /* *
@@ -102,9 +103,9 @@ class http_request {
102103 * @return the selected piece in form of string
103104 **/
104105 const std::string get_path_piece (int index) const {
105- std::vector<std::string> post_path = get_path_pieces ();
106- if (static_cast <int >(post_path .size ()) > index) {
107- return post_path [index];
106+ ensure_path_pieces_cached ();
107+ if (static_cast <int >(cache-> path_pieces .size ()) > index) {
108+ return cache-> path_pieces [index];
108109 }
109110 return EMPTY;
110111 }
@@ -474,7 +475,11 @@ class http_request {
474475 std::string_view get_connection_value (std::string_view key, enum MHD_ValueKind kind) const ;
475476 const http::header_view_map get_headerlike_values (enum MHD_ValueKind kind) const ;
476477
477- // Cache certain data items on demand so we can consistently return views
478+ // http_request objects are owned by a single connection and are not
479+ // shared across threads. Lazy caching (path_pieces, args, etc.) is
480+ // safe without synchronization under this invariant.
481+
482+ // Cache certain data items on demand so we can consistently return views
478483 // over the data. Some things we transform before returning to the user for
479484 // simplicity (e.g. query_str, requestor), others out of necessity (arg unescaping).
480485 // Others (username, password, digested_user) MHD returns as char* that we need
@@ -488,10 +493,19 @@ class http_request {
488493 std::string digested_user;
489494#endif // HAVE_DAUTH
490495 std::map<std::string, std::vector<std::string>, http::arg_comparator> unescaped_args;
496+ std::vector<std::string> path_pieces;
491497
492498 bool args_populated = false ;
499+ bool path_pieces_cached = false ;
493500 };
494501 std::unique_ptr<http_request_data_cache> cache = std::make_unique<http_request_data_cache>();
502+ void ensure_path_pieces_cached () const {
503+ if (!cache->path_pieces_cached ) {
504+ cache->path_pieces = http::http_utils::tokenize_url (path);
505+ cache->path_pieces_cached = true ;
506+ }
507+ }
508+
495509 // Populate the data cache unescaped_args
496510 void populate_args () const ;
497511
0 commit comments