diff --git a/src/tawashi/main.cpp b/src/tawashi/main.cpp index 61fa12e..e84555d 100644 --- a/src/tawashi/main.cpp +++ b/src/tawashi/main.cpp @@ -160,7 +160,10 @@ int main (int parArgc, char* parArgv[], char* parEnvp[]) { resp_factory.register_maker("error.cgi", &make_response); resp_factory.register_jolly_maker(&make_response); - std::unique_ptr response = resp_factory.make_response(cgi_env->path_info()); + std::unique_ptr response = resp_factory.make_response( + cgi_env->path_info(), + cgi_env->request_method() + ); response->send(); } catch (const std::exception& e) { diff --git a/src/tawashi_implem/cgi_env.cpp b/src/tawashi_implem/cgi_env.cpp index 9e2b2e0..284e60f 100644 --- a/src/tawashi_implem/cgi_env.cpp +++ b/src/tawashi_implem/cgi_env.cpp @@ -111,7 +111,8 @@ namespace cgi { Env::Env(const char* const* parEnvList, const boost::string_ref& parBasePath) : m_cgi_env(cgi_environment_vars(parEnvList)), - m_skip_path_info(calculate_skip_path_length(m_cgi_env[CGIVars::PATH_INFO], parBasePath)) + m_skip_path_info(calculate_skip_path_length(m_cgi_env[CGIVars::PATH_INFO], parBasePath)), + m_request_method_type(RequestMethodType::_from_string(m_cgi_env[CGIVars::REQUEST_METHOD].data())) { } @@ -165,8 +166,8 @@ namespace cgi { return m_cgi_env[CGIVars::REMOTE_USER]; } - const std::string& Env::request_method() const { - return m_cgi_env[CGIVars::REQUEST_METHOD]; + RequestMethodType Env::request_method() const { + return m_request_method_type; } const std::string& Env::script_name() const { diff --git a/src/tawashi_implem/cgi_env.hpp b/src/tawashi_implem/cgi_env.hpp index 7b25eb9..9fda7c7 100644 --- a/src/tawashi_implem/cgi_env.hpp +++ b/src/tawashi_implem/cgi_env.hpp @@ -21,6 +21,7 @@ #include "duckhandy/compatibility.h" #include "escapist.hpp" #include "kakoune/safe_ptr.hh" +#include "request_method_type.hpp" #include #include #include @@ -55,7 +56,7 @@ namespace tawashi { const std::string& remote_host() const; const std::string& remote_ident() const; const std::string& remote_user() const; - const std::string& request_method() const; + RequestMethodType request_method() const; const std::string& script_name() const; const std::string& server_name() const; bool https() const; @@ -71,6 +72,7 @@ namespace tawashi { std::vector m_cgi_env; Escapist m_houdini; std::size_t m_skip_path_info; + RequestMethodType m_request_method_type; }; } //namespace cgi } //namespace tawashi diff --git a/src/tawashi_implem/request_method_type.hpp b/src/tawashi_implem/request_method_type.hpp new file mode 100644 index 0000000..510b5fc --- /dev/null +++ b/src/tawashi_implem/request_method_type.hpp @@ -0,0 +1,27 @@ +/* Copyright 2017, Michele Santullo + * This file is part of "tawashi". + * + * "tawashi" is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * "tawashi" is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with "tawashi". If not, see . + */ + +#pragma once + +#include "enum.h" + +namespace tawashi { + BETTER_ENUM(RequestMethodType, int, + GET, + POST + ) +} //namespace tawashi diff --git a/src/tawashi_implem/response.cpp b/src/tawashi_implem/response.cpp index f832ee4..61b9934 100644 --- a/src/tawashi_implem/response.cpp +++ b/src/tawashi_implem/response.cpp @@ -165,7 +165,7 @@ namespace tawashi { auto statuslog = spdlog::get("statuslog"); assert(statuslog); statuslog->info("Preparing response for {} request; query_string=\"{}\"; size={}", - cgi_env().request_method(), + cgi_env().request_method()._to_string(), cgi_env().query_string(), cgi_env().content_length() ); diff --git a/src/tawashi_implem/response_factory.cpp b/src/tawashi_implem/response_factory.cpp index 04fd4a4..3069f42 100644 --- a/src/tawashi_implem/response_factory.cpp +++ b/src/tawashi_implem/response_factory.cpp @@ -28,7 +28,8 @@ namespace tawashi { struct ResponseFactory::LocalData { Kakoune::SafePtr settings; - boost::container::flat_map makers; + boost::container::flat_map makers_get; + boost::container::flat_map makers_post; ResponseMakerFunc jolly_maker; Kakoune::SafePtr cgi_env; }; @@ -42,12 +43,17 @@ namespace tawashi { ResponseFactory::~ResponseFactory() noexcept = default; - std::unique_ptr ResponseFactory::make_response (const boost::string_ref& parName) { + std::unique_ptr ResponseFactory::make_response (const boost::string_ref& parName, RequestMethodType parReqType) { std::string name(parName.data(), parName.size()); - spdlog::get("statuslog")->info("making response object for \"{}\"", name); + spdlog::get("statuslog")->info( + "making response object for \"{}\" method {}", + name, + parReqType._to_string() + ); - auto maker_it = m_local_data->makers.find(name); - if (m_local_data->makers.end() != maker_it) { + const auto& makers = (static_cast(RequestMethodType::POST) == parReqType ? m_local_data->makers_post : m_local_data->makers_get); + auto maker_it = makers.find(name); + if (makers.end() != maker_it) { return maker_it->second(m_local_data->settings, m_local_data->cgi_env); } else if (m_local_data->jolly_maker) { @@ -62,7 +68,19 @@ namespace tawashi { } void ResponseFactory::register_maker (std::string&& parName, ResponseMakerFunc parMaker) { - m_local_data->makers[std::move(parName)] = parMaker; + m_local_data->makers_get[parName] = parMaker; + m_local_data->makers_post[std::move(parName)] = parMaker; + } + + void ResponseFactory::register_maker (std::string&& parName, RequestMethodType parReqType, ResponseMakerFunc parMaker) { + switch (parReqType) { + case RequestMethodType::GET: + m_local_data->makers_get[std::move(parName)] = parMaker; + break; + case RequestMethodType::POST: + m_local_data->makers_post[std::move(parName)] = parMaker; + break; + }; } void ResponseFactory::register_jolly_maker (ResponseMakerFunc parMaker) { diff --git a/src/tawashi_implem/response_factory.hpp b/src/tawashi_implem/response_factory.hpp index bc42e92..87269b0 100644 --- a/src/tawashi_implem/response_factory.hpp +++ b/src/tawashi_implem/response_factory.hpp @@ -19,6 +19,7 @@ #include "response.hpp" #include "kakoune/safe_ptr.hh" +#include "request_method_type.hpp" #include namespace tawashi { @@ -35,8 +36,9 @@ namespace tawashi { explicit ResponseFactory (const Kakoune::SafePtr& parSettings, const Kakoune::SafePtr& parCgiEnv); ~ResponseFactory() noexcept; - std::unique_ptr make_response(const boost::string_ref& parName); + std::unique_ptr make_response(const boost::string_ref& parName, RequestMethodType parReqType); void register_maker (std::string&& parName, ResponseMakerFunc parMaker); + void register_maker (std::string&& parName, RequestMethodType parReqType, ResponseMakerFunc parMaker); void register_jolly_maker (ResponseMakerFunc parMaker); private: