From 24903813d11813f8ff9ac906d23b21e6c33b981d Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 11 Aug 2015 20:11:47 +0200 Subject: Parse http request parameters using CLI --- brep/module | 25 ++++++++++++++++++++++- brep/module.cxx | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- brep/options.cli | 43 +++++++++++++++++++++++++++------------- brep/search | 2 +- brep/search.cxx | 21 +++++++++++++++++--- brep/view | 2 +- brep/view.cxx | 6 +++--- etc/config | 4 ++++ etc/search.conf | 3 +-- web/module | 2 +- 10 files changed, 141 insertions(+), 27 deletions(-) diff --git a/brep/module b/brep/module index e38d60d..08fbfea 100644 --- a/brep/module +++ b/brep/module @@ -92,6 +92,29 @@ namespace brep module (); module (const module& ); + class param_scanner: public cli::scanner + { + public: + param_scanner (const name_values&) noexcept; + + virtual bool + more (); + + virtual const char* + peek (); + + virtual const char* + next (); + + virtual void + skip (); + + private: + const name_values& name_values_; + name_values::const_iterator i_; + bool name_; + }; + private: virtual void handle (request&, response&, log&); @@ -110,7 +133,7 @@ namespace brep { // Just scan options to ensure there is no misspelled ones. // - module_options o (s, cli::unknown_mode::fail, cli::unknown_mode::fail); + options::module o (s, cli::unknown_mode::fail, cli::unknown_mode::fail); } // Diagnostics implementation details. diff --git a/brep/module.cxx b/brep/module.cxx index ceadc23..c52d13a 100644 --- a/brep/module.cxx +++ b/brep/module.cxx @@ -25,6 +25,8 @@ using namespace placeholders; // For std::bind's _1, etc. namespace brep { + // module + // void module:: handle (request& rq, response& rs, log& l) { @@ -111,7 +113,7 @@ namespace brep const_cast (argv.data ()), "conf"); - module_options o (s, cli::unknown_mode::skip, cli::unknown_mode::skip); + options::module o (s, cli::unknown_mode::skip, cli::unknown_mode::skip); verb_ = o.verb (); } catch (const server_error& e) @@ -228,4 +230,60 @@ namespace brep } } } + + // module::param_scanner + // + module::param_scanner:: + param_scanner (const name_values& nv) noexcept + : name_values_ (nv), + i_ (nv.begin ()), + name_ (true) + { + } + + bool module::param_scanner:: + more () + { + return i_ != name_values_.end (); + } + + const char* module::param_scanner:: + peek () + { + if (i_ != name_values_.end ()) + return name_ ? i_->name.c_str () : i_->value.c_str (); + else + throw cli::eos_reached (); + } + + const char* module::param_scanner:: + next () + { + if (i_ != name_values_.end ()) + { + const char* r (name_ ? i_->name.c_str () : i_->value.c_str ()); + + if (!name_) + ++i_; + + name_ = !name_; + return r; + } + else + throw cli::eos_reached (); + } + + void module::param_scanner:: + skip () + { + if (i_ != name_values_.end ()) + { + if (!name_) + ++i_; + + name_ = !name_; + } + else + throw cli::eos_reached (); + } } diff --git a/brep/options.cli b/brep/options.cli index b7c571e..2894979 100644 --- a/brep/options.cli +++ b/brep/options.cli @@ -7,23 +7,38 @@ include ; namespace brep { - class module_options + // Web module configuration options. + // + namespace options { - std::uint16_t verb = 0; - }; + class module + { + std::uint16_t verb = 0; + }; - class db_options - { - std::string db-host = "localhost"; - std::uint16_t db-port = 5432; - }; + class db + { + std::string db-host = "localhost"; + std::uint16_t db-port = 5432; + }; - class search_options: module_options, db_options - { - size_t results-on-page = 10; - }; + class search: module, db + { + size_t results-on-page = 10; + }; + + class view: module, db + { + }; + } - class view_options: module_options, db_options + // Web module request parameters. + // + namespace params { - }; + class search + { + size_t page = 0; + }; + } } diff --git a/brep/search b/brep/search index 078922e..0283859 100644 --- a/brep/search +++ b/brep/search @@ -24,7 +24,7 @@ namespace brep init (cli::scanner&); private: - std::shared_ptr options_; + std::shared_ptr options_; std::shared_ptr db_; }; } diff --git a/brep/search.cxx b/brep/search.cxx index 3aa6503..9185aa5 100644 --- a/brep/search.cxx +++ b/brep/search.cxx @@ -30,9 +30,9 @@ namespace brep { MODULE_DIAG; - options_ = make_shared (s, - cli::unknown_mode::fail, - cli::unknown_mode::fail); + options_ = make_shared (s, + cli::unknown_mode::fail, + cli::unknown_mode::fail); db_ = shared_database (options_->db_host (), options_->db_port ()); @@ -141,6 +141,21 @@ namespace brep o << "
\n" << p.name << "=" << p.value; } + param_scanner s (ps); + unique_ptr prm; + + try + { + prm.reset (new params::search (s, + cli::unknown_mode::fail, + cli::unknown_mode::fail)); + } + catch (const cli::unknown_argument& e) + { + throw invalid_request (400, e.what ()); + } + + o << "
\nPage num: " << prm->page (); o << "

\nCookies:"; for (const auto& c: rq.cookies ()) diff --git a/brep/view b/brep/view index 69c7d3c..280b9ab 100644 --- a/brep/view +++ b/brep/view @@ -24,7 +24,7 @@ namespace brep init (cli::scanner&); private: - std::shared_ptr options_; + std::shared_ptr options_; std::shared_ptr db_; }; } diff --git a/brep/view.cxx b/brep/view.cxx index 2f3bd17..3098e93 100644 --- a/brep/view.cxx +++ b/brep/view.cxx @@ -26,9 +26,9 @@ namespace brep void view:: init (cli::scanner& s) { - options_ = make_shared (s, - cli::unknown_mode::fail, - cli::unknown_mode::fail); + options_ = make_shared (s, + cli::unknown_mode::fail, + cli::unknown_mode::fail); db_ = shared_database (options_->db_host (), options_->db_port ()); } diff --git a/etc/config b/etc/config index 15e6063..70fe961 100644 --- a/etc/config +++ b/etc/config @@ -1,4 +1,5 @@ # Basic settings (used in this file only) +# SCRIPT_DIR=`dirname $0` CONFIG_DIR=`cd $SCRIPT_DIR; pwd` PROJECT_DIR="$CONFIG_DIR/.." @@ -6,6 +7,7 @@ WORKSPACE_DIR="$PROJECT_DIR/var" LIB_DIRS="$PROJECT_DIR/brep:$PROJECT_DIR/../libbutl/butl:$PROJECT_DIR/../libbpkg/bpkg" # PostgreSQL settings (used in pgctl) +# PG_PORT=8432 PG_SCHEMA_DIR="$PROJECT_DIR/brep" PG_DATA_DIR="$WORKSPACE_DIR/lib/pgsql" @@ -13,6 +15,7 @@ PG_LOG_DIR="$WORKSPACE_DIR/log/pgsql" PG_WORKSPACE_DIR="$WORKSPACE_DIR/run/pgsql" # Apache settings (used in apachectl) +# AP_PORT=8080 AP_SERVER_NAME="cppget.org:$AP_PORT" AP_ADMIN_EMAIL=admin@cppget.org @@ -27,6 +30,7 @@ AP_LOG_DIR="$WORKSPACE_DIR/log/httpd" AP_WORKSPACE_DIR="$WORKSPACE_DIR/run/httpd" # brep-loader settings (used in loader) +# LD_DB_HOST="$PG_WORKSPACE_DIR" LD_DB_PORT=$PG_PORT LD_REPOSITORIES="$CONFIG_DIR/repositories.conf" diff --git a/etc/search.conf b/etc/search.conf index f742cda..be86098 100644 --- a/etc/search.conf +++ b/etc/search.conf @@ -4,6 +4,5 @@ verb 1 # brep::search options -results-on-page 20 - #ah 7 +results-on-page 20 diff --git a/web/module b/web/module index 9624877..e1cccf0 100644 --- a/web/module +++ b/web/module @@ -117,7 +117,7 @@ namespace web // virtual std::ostream& content (status_code code = 200, - const std::string& type = "text/html;charset=utf-8", + const std::string& type = "application/xhtml+xml;charset=utf-8", bool buffer = true) = 0; // Set status code without writing any content. On status change, -- cgit v1.1