diff --git a/core/application.cpp b/core/application.cpp index 40886aa..2a7602b 100644 --- a/core/application.cpp +++ b/core/application.cpp @@ -38,22 +38,16 @@ void Application::default_routing_middleware(Object *instance, Request *request) //std::function func; - if (path == "/") { + //if (path == "/") { + if (request->get_path_segment_count() == 0) { //quick shortcut handler_data = index_func; } else { - std::string main_route = ""; - - uint32_t endpos = 1; - for (; endpos < path.size(); ++endpos) { - if (path[endpos] == '/') { - break; - } - } - - main_route = path.substr(1, endpos - 1); + const std::string main_route = request->get_current_path_segment(); handler_data = main_route_map[main_route]; + + request->push_path(); } if (!handler_data.handler_func) { @@ -123,7 +117,6 @@ void Application::send_file(const std::string &path, Request *request) { } void Application::migrate() { - } Application::Application() { diff --git a/core/http_server.cpp b/core/http_server.cpp index 4e41b9e..14d568f 100644 --- a/core/http_server.cpp +++ b/core/http_server.cpp @@ -15,6 +15,8 @@ void HTTPServer::httpEnterCallbackDefault(const HTTPParser &httpParser, const Ht request->http_parser = &httpParser; request->session = &session; + request->setup_url_stack(); + #if LOG_VERBOSE std::cout << "method:" << http_method_str(static_cast(httpParser.method())) << std::endl; #endif diff --git a/core/request.cpp b/core/request.cpp index 17840e2..b0f9a93 100644 --- a/core/request.cpp +++ b/core/request.cpp @@ -5,20 +5,20 @@ void Request::compile_body() { //13 compiled_body += "" - ""; + ""; compiled_body += head; //14 compiled_body += "" - ""; + ""; compiled_body += body; compiled_body += footer; //15 compiled_body += "" - ""; + ""; response->setBody(compiled_body); } @@ -64,6 +64,8 @@ void Request::reset() { session = nullptr; current_middleware_index = 0; middleware_stack = nullptr; + _path_stack.clear(); + _path_stack_pointer = 0; head.clear(); body.clear(); @@ -76,6 +78,77 @@ void Request::reset() { response = new HttpResponse(); } +void Request::setup_url_stack() { + std::string path = http_parser->getPath(); + + size_t pos = 0; + std::string st; + while ((pos = path.find("/")) != std::string::npos) { + st = path.substr(0, pos); + + if (st.size() != 0) + _path_stack.push_back(st); + + path.erase(0, pos + 1); + } + + if (path.size() != 0) + _path_stack.push_back(path); +} + +std::string Request::get_path() const { + std::string path = ""; + + for (uint32_t i = _path_stack_pointer; i < _path_stack.size(); ++i) { + path += _path_stack[i]; + path += "/"; + } + + return path; +} + +const std::string &Request::get_path_full() const { + return http_parser->getPath(); +} + +const std::string &Request::get_path_segment(const uint32_t i) const { + return _path_stack[i]; +} + +const std::string &Request::get_current_path_segment() const { + if (_path_stack_pointer >= _path_stack.size()) { + //for convenience + static const std::string e_str = ""; + return e_str; + } + + return _path_stack[_path_stack_pointer]; +} + +uint32_t Request::get_path_segment_count() const { + return _path_stack.size(); +} + +uint32_t Request::get_current_segment_index() const { + return _path_stack_pointer; +} + +uint32_t Request::get_remaining_segment_count() const { + if (_path_stack_pointer > _path_stack.size()) { + return 0; + } + + return _path_stack.size() - _path_stack_pointer; +} + +void Request::pop_path() { + _path_stack_pointer -= 1; +} + +void Request::push_path() { + _path_stack_pointer += 1; +} + Request::Request() { response = nullptr; diff --git a/core/request.h b/core/request.h index c34a89f..c5297a2 100644 --- a/core/request.h +++ b/core/request.h @@ -19,9 +19,9 @@ public: const HttpSession::Ptr *session; HttpResponse *response; - uint32_t current_middleware_index; - HandlerInstance handler_instance; - std::vector *middleware_stack; + uint32_t current_middleware_index; + HandlerInstance handler_instance; + std::vector *middleware_stack; std::string head; std::string body; @@ -30,12 +30,27 @@ public: void compile_body(); void compile_and_send_body(); - void next_stage(); + void next_stage(); void send(); void reset(); + void setup_url_stack(); + std::string get_path() const; + const std::string &get_path_full() const; + const std::string &get_path_segment(const uint32_t i) const; + const std::string &get_current_path_segment() const; + uint32_t get_path_segment_count() const; + uint32_t get_current_segment_index() const; + uint32_t get_remaining_segment_count() const; + void pop_path(); + void push_path(); + Request(); ~Request(); + +protected: + std::vector _path_stack; + uint32_t _path_stack_pointer; }; class RequestPool {