// file : brep/module -*- C++ -*- // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #ifndef BREP_MODULE #define BREP_MODULE #include #include // move() #include #include #include #include namespace brep { // Bring in commonly used names from the web namespace. // // @@ Maybe doing using namespace is the right way to handle this. // There will, however, most likely be a conflict between // web::module and our module. Or maybe not, need to try. // using web::status_code; using web::invalid_request; using web::sequence_error; using web::name_value; using web::name_values; using web::request; using web::response; using web::log; // This exception indicated a server error (5XX). In particular, // it is thrown by the fail diagnostics stream and is caught by the // module implementation where it is both logged as an error and // returned to the user with the 5XX status code. // struct server_error { diag_data data; server_error (diag_data&& d): data (std::move (d)) {} }; // Every module member function that needs to produce any diagnostics // shall begin with: // // MODULE_DIAG; // // This will instantiate the fail, error, warn, info, and trace // diagnostics streams with the function's name. // #define MODULE_DIAG \ const fail_mark fail (__PRETTY_FUNCTION__); \ const basic_mark error (severity::error, \ this->log_writer_, \ __PRETTY_FUNCTION__); \ const basic_mark warn (severity::warning, \ this->log_writer_, \ __PRETTY_FUNCTION__); \ const basic_mark info (severity::info, \ this->log_writer_, \ __PRETTY_FUNCTION__); \ const basic_mark trace (severity::info, \ this->log_writer_, \ __PRETTY_FUNCTION__) // Adaptation of the web::module to our needs. // class module: public web::module { // Diagnostics. // protected: // Trace verbosity level. // // 0 - tracing disabled. // 1 - @@ TODO: document // 2 - @@ TODO: document // // While uint8 is more than enough, use uint16 for the ease of printing. // std::uint16_t verb_ {0}; template void level1 (const F& f) const {if (verb_ >= 1) f ();} template void level2 (const F& f) const {if (verb_ >= 2) f ();} // Implementation details. // protected: module (); module (const module& ); // Can be used by module implementation to parse HTTP request parameters. // 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&); virtual void handle (request&, response&) = 0; virtual void init (const name_values&, log&); // Can be overriden by module implementation which has configuration // options. // virtual void init (cli::scanner& s) { // Just scan options to ensure there is no misspelled ones. // options::module o (s, cli::unknown_mode::fail, cli::unknown_mode::fail); } // Diagnostics implementation details. // private: log* log_ {nullptr}; // Diagnostics backend provided by the web server. private: // Extract function name from a __PRETTY_FUNCTION__. // Throw std::invalid_argument if fail to parse. // static std::string func_name (const char* pretty_name); void log_write (const diag_data&) const; protected: const diag_epilogue log_writer_; }; } #endif // BREP_MODULE