Skip to content

Commit

Permalink
[http_server] Make default hanlder for the base path in the "add_subapi"
Browse files Browse the repository at this point in the history
...as the title says but in fact the code change is done by @samkpo in
PR #127. I am just adding test coverage, making change in the right file
with all files generated.
  • Loading branch information
cong1920 committed Dec 30, 2024
1 parent 9ce90b1 commit 9ba895b
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 38 deletions.
2 changes: 2 additions & 0 deletions libraries/http_client/http_client/http_client.hh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once
#ifndef CURL_STATICLIB
#define CURL_STATICLIB
#endif // CURL_STATICLIB
#pragma comment(lib, "crypt32")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Wldap32.lib")
Expand Down
19 changes: 10 additions & 9 deletions libraries/http_server/http_server/api.hh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ template <typename Req, typename Resp> struct api {

typedef api<Req, Resp> self;

api(): is_global_handler(false), global_handler_(nullptr) { }
api() : is_global_handler(false), global_handler_(nullptr) {}

using H = std::function<void(Req&, Resp&)>;
struct VH {
Expand Down Expand Up @@ -65,7 +65,9 @@ template <typename Req, typename Resp> struct api {

void add_subapi(std::string prefix, const self& subapi) {
subapi.routes_map_.for_all_routes([this, prefix](auto r, VH h) {
if (!r.empty() && r.back() == '/')
if (r.empty() || r == "/")
h.url_spec = prefix;
else if (r.back() == '/')
h.url_spec = prefix + r;
else
h.url_spec = prefix + '/' + r;
Expand All @@ -83,13 +85,11 @@ template <typename Req, typename Resp> struct api {
std::cout << std::endl;
}
auto call(std::string_view method, std::string_view route, Req& request, Resp& response) const {
if(is_global_handler)
{
global_handler_(request, response);
return;
if (is_global_handler) {
global_handler_(request, response);
return;
}
if (route == last_called_route_)
{
if (route == last_called_route_) {
if (last_handler_.verb == ANY or parse_verb(method) == last_handler_.verb) {
request.url_spec = last_handler_.url_spec;
last_handler_.handler(request, response);
Expand All @@ -100,7 +100,8 @@ template <typename Req, typename Resp> struct api {

// skip the last / of the url and trim spaces.
std::string_view route2(route);
while (route2.size() > 1 and (route2[route2.size() - 1] == '/' || route2[route2.size() - 1] == ' '))
while (route2.size() > 1 and
(route2[route2.size() - 1] == '/' || route2[route2.size() - 1] == ' '))
route2 = route2.substr(0, route2.size() - 1);

auto it = routes_map_.find(route2);
Expand Down
26 changes: 15 additions & 11 deletions libraries/http_server/tests/subapi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,24 @@ using namespace li;

int main() {

http_api my_api;
my_api.get("/") = [&](http_request& request, http_response& response) {
response.write("hello world.");
http_api root;
root.get("/") = [&](http_request& request, http_response& response) { response.write("root"); };

http_api subapi;
subapi.get("/") = [&](http_request& request, http_response& response) {
response.write("hello");
};

http_api my_api2;
my_api2.get("/hello_world") = [&](http_request& request, http_response& response) {
response.write("hello world2.");
subapi.get("/world") = [&](http_request& request, http_response& response) {
response.write("hello world");
};

my_api.add_subapi("/sub", my_api2);
root.add_subapi("/hello", subapi);

http_serve(my_api, 12334, s::non_blocking);
assert(http_get("http://localhost:12334").body == "hello world.");
assert(http_get("http://localhost:12334/").body == "hello world.");
assert(http_get("http://localhost:12334/sub/hello_world").body == "hello world2.");
http_serve(root, 12334, s::non_blocking);
assert(http_get("http://localhost:12334").body == "root");
assert(http_get("http://localhost:12334/").body == "root");
assert(http_get("http://localhost:12334/hello").body == "hello");
assert(http_get("http://localhost:12334/hello/").body == "hello");
assert(http_get("http://localhost:12334/hello/world").body == "hello world");
}
21 changes: 12 additions & 9 deletions single_headers/lithium.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1821,7 +1821,9 @@ struct sqlite_database {

#ifndef LITHIUM_SINGLE_HEADER_GUARD_LI_HTTP_CLIENT_HTTP_CLIENT_HH
#define LITHIUM_SINGLE_HEADER_GUARD_LI_HTTP_CLIENT_HTTP_CLIENT_HH
#ifndef CURL_STATICLIB
#define CURL_STATICLIB
#endif // CURL_STATICLIB
#pragma comment(lib, "crypt32")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Wldap32.lib")
Expand Down Expand Up @@ -6834,7 +6836,7 @@ template <typename Req, typename Resp> struct api {

typedef api<Req, Resp> self;

api(): is_global_handler(false), global_handler_(nullptr) { }
api() : is_global_handler(false), global_handler_(nullptr) {}

using H = std::function<void(Req&, Resp&)>;
struct VH {
Expand Down Expand Up @@ -6875,7 +6877,9 @@ template <typename Req, typename Resp> struct api {

void add_subapi(std::string prefix, const self& subapi) {
subapi.routes_map_.for_all_routes([this, prefix](auto r, VH h) {
if (!r.empty() && r.back() == '/')
if (r.empty() || r == "/")
h.url_spec = prefix;
else if (r.back() == '/')
h.url_spec = prefix + r;
else
h.url_spec = prefix + '/' + r;
Expand All @@ -6893,13 +6897,11 @@ template <typename Req, typename Resp> struct api {
std::cout << std::endl;
}
auto call(std::string_view method, std::string_view route, Req& request, Resp& response) const {
if(is_global_handler)
{
global_handler_(request, response);
return;
if (is_global_handler) {
global_handler_(request, response);
return;
}
if (route == last_called_route_)
{
if (route == last_called_route_) {
if (last_handler_.verb == ANY or parse_verb(method) == last_handler_.verb) {
request.url_spec = last_handler_.url_spec;
last_handler_.handler(request, response);
Expand All @@ -6910,7 +6912,8 @@ template <typename Req, typename Resp> struct api {

// skip the last / of the url and trim spaces.
std::string_view route2(route);
while (route2.size() > 1 and (route2[route2.size() - 1] == '/' || route2[route2.size() - 1] == ' '))
while (route2.size() > 1 and
(route2[route2.size() - 1] == '/' || route2[route2.size() - 1] == ' '))
route2 = route2.substr(0, route2.size() - 1);

auto it = routes_map_.find(route2);
Expand Down
2 changes: 2 additions & 0 deletions single_headers/lithium_http_client.hh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@

#ifndef LITHIUM_SINGLE_HEADER_GUARD_LI_HTTP_CLIENT_HTTP_CLIENT_HH
#define LITHIUM_SINGLE_HEADER_GUARD_LI_HTTP_CLIENT_HTTP_CLIENT_HH
#ifndef CURL_STATICLIB
#define CURL_STATICLIB
#endif // CURL_STATICLIB
#pragma comment(lib, "crypt32")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Wldap32.lib")
Expand Down
19 changes: 10 additions & 9 deletions single_headers/lithium_http_server.hh
Original file line number Diff line number Diff line change
Expand Up @@ -3654,7 +3654,7 @@ template <typename Req, typename Resp> struct api {

typedef api<Req, Resp> self;

api(): is_global_handler(false), global_handler_(nullptr) { }
api() : is_global_handler(false), global_handler_(nullptr) {}

using H = std::function<void(Req&, Resp&)>;
struct VH {
Expand Down Expand Up @@ -3695,7 +3695,9 @@ template <typename Req, typename Resp> struct api {

void add_subapi(std::string prefix, const self& subapi) {
subapi.routes_map_.for_all_routes([this, prefix](auto r, VH h) {
if (!r.empty() && r.back() == '/')
if (r.empty() || r == "/")
h.url_spec = prefix;
else if (r.back() == '/')
h.url_spec = prefix + r;
else
h.url_spec = prefix + '/' + r;
Expand All @@ -3713,13 +3715,11 @@ template <typename Req, typename Resp> struct api {
std::cout << std::endl;
}
auto call(std::string_view method, std::string_view route, Req& request, Resp& response) const {
if(is_global_handler)
{
global_handler_(request, response);
return;
if (is_global_handler) {
global_handler_(request, response);
return;
}
if (route == last_called_route_)
{
if (route == last_called_route_) {
if (last_handler_.verb == ANY or parse_verb(method) == last_handler_.verb) {
request.url_spec = last_handler_.url_spec;
last_handler_.handler(request, response);
Expand All @@ -3730,7 +3730,8 @@ template <typename Req, typename Resp> struct api {

// skip the last / of the url and trim spaces.
std::string_view route2(route);
while (route2.size() > 1 and (route2[route2.size() - 1] == '/' || route2[route2.size() - 1] == ' '))
while (route2.size() > 1 and
(route2[route2.size() - 1] == '/' || route2[route2.size() - 1] == ' '))
route2 = route2.substr(0, route2.size() - 1);

auto it = routes_map_.find(route2);
Expand Down

0 comments on commit 9ba895b

Please sign in to comment.