00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 #include <boost/exception/diagnostic_information.hpp>
00011 #include <pion/error.hpp>
00012 #include <pion/http/plugin_server.hpp>
00013 #include <pion/http/request.hpp>
00014 #include <pion/http/request_reader.hpp>
00015 #include <pion/http/response_writer.hpp>
00016 #include <pion/http/basic_auth.hpp>
00017 #include <pion/http/cookie_auth.hpp>
00018 #include <fstream>
00019 
00020 
00021 namespace pion {    
00022 namespace http {    
00023 
00024 
00025 
00026 
00027 void plugin_server::add_service(const std::string& resource, http::plugin_service *service_ptr)
00028 {
00029     plugin_ptr<http::plugin_service> plugin_ptr;
00030     const std::string clean_resource(strip_trailing_slash(resource));
00031     service_ptr->set_resource(clean_resource);
00032     m_services.add(clean_resource, service_ptr);
00033     http::server::add_resource(clean_resource, boost::ref(*service_ptr));
00034     PION_LOG_INFO(m_logger, "Loaded static web service for resource (" << clean_resource << ")");
00035 }
00036 
00037 void plugin_server::load_service(const std::string& resource, const std::string& service_name)
00038 {
00039     const std::string clean_resource(strip_trailing_slash(resource));
00040     http::plugin_service *service_ptr;
00041     service_ptr = m_services.load(clean_resource, service_name);
00042     http::server::add_resource(clean_resource, boost::ref(*service_ptr));
00043     service_ptr->set_resource(clean_resource);
00044     PION_LOG_INFO(m_logger, "Loaded web service plug-in for resource (" << clean_resource << "): " << service_name);
00045 }
00046 
00047 void plugin_server::set_service_option(const std::string& resource,
00048                                  const std::string& name, const std::string& value)
00049 {
00050     const std::string clean_resource(strip_trailing_slash(resource));
00051     m_services.run(clean_resource, boost::bind(&http::plugin_service::set_option, _1, name, value));
00052     PION_LOG_INFO(m_logger, "Set web service option for resource ("
00053                   << resource << "): " << name << '=' << value);
00054 }
00055 
00056 void plugin_server::load_service_config(const std::string& config_name)
00057 {
00058     std::string config_file;
00059     if (! plugin::find_config_file(config_file, config_name))
00060         BOOST_THROW_EXCEPTION( error::file_not_found() << error::errinfo_file_name(config_name) );
00061     
00062     
00063     std::ifstream config_stream;
00064     config_stream.open(config_file.c_str(), std::ios::in);
00065     if (! config_stream.is_open())
00066         BOOST_THROW_EXCEPTION( error::open_file() << error::errinfo_file_name(config_name) );
00067     
00068     
00069     http::auth_ptr my_auth_ptr;
00070     enum ParseState {
00071         PARSE_NEWLINE, PARSE_COMMAND, PARSE_RESOURCE, PARSE_VALUE, PARSE_COMMENT, PARSE_USERNAME
00072     } parse_state = PARSE_NEWLINE;
00073     std::string command_string;
00074     std::string resource_string;
00075     std::string username_string;
00076     std::string value_string;
00077     std::string option_name_string;
00078     std::string option_value_string;
00079     int c = config_stream.get();    
00080     
00081     while (config_stream) {
00082         switch(parse_state) {
00083         case PARSE_NEWLINE:
00084             
00085             if (c == '#') {
00086                 
00087                 parse_state = PARSE_COMMENT;
00088             } else if (isalpha(c)) {
00089                 
00090                 parse_state = PARSE_COMMAND;
00091                 
00092                 command_string += tolower(c);
00093             } else if (c != '\r' && c != '\n') {    
00094                 BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) );
00095             }
00096             break;
00097             
00098         case PARSE_COMMAND:
00099             
00100             if (c == ' ' || c == '\t') {
00101                 
00102                 if (command_string=="path" || command_string=="auth" || command_string=="restrict") {
00103                     value_string.clear();
00104                     parse_state = PARSE_VALUE;
00105                 } else if (command_string=="service" || command_string=="option") {
00106                     resource_string.clear();
00107                     parse_state = PARSE_RESOURCE;
00108                 } else if (command_string=="user") {
00109                     username_string.clear();
00110                     parse_state = PARSE_USERNAME;
00111                 } else {
00112                     BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) );
00113                 }
00114             } else if (! isalpha(c)) {
00115                 
00116                 BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) );
00117             } else {
00118                 
00119                 command_string += tolower(c);
00120             }
00121             break;
00122 
00123         case PARSE_RESOURCE:
00124             
00125             if (c == ' ' || c == '\t') {
00126                 
00127                 if (! resource_string.empty()) {
00128                     
00129                     value_string.clear();
00130                     parse_state = PARSE_VALUE;
00131                 }
00132             } else if (c == '\r' || c == '\n') {
00133                 
00134                 BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) );
00135             } else {
00136                 
00137                 resource_string += c;
00138             }
00139             break;
00140         
00141         case PARSE_USERNAME:
00142             
00143             if (c == ' ' || c == '\t') {
00144                 
00145                 if (! username_string.empty()) {
00146                     
00147                     value_string.clear();
00148                     parse_state = PARSE_VALUE;
00149                 }
00150             } else if (c == '\r' || c == '\n') {
00151                 
00152                 BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) );
00153             } else {
00154                 
00155                 username_string += c;
00156             }
00157             break;
00158         
00159         case PARSE_VALUE:
00160             
00161             if (c == '\r' || c == '\n') {
00162                 
00163                 if (value_string.empty()) {
00164                     
00165                     BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) );
00166                 } else if (command_string == "path") {
00167                     
00168                     try { plugin::add_plugin_directory(value_string); }
00169                     catch (std::exception& e) {
00170                         PION_LOG_WARN(m_logger, boost::diagnostic_information(e));
00171                     }
00172                 } else if (command_string == "auth") {
00173                     
00174                     user_manager_ptr user_mgr(new user_manager);
00175                     if (value_string == "basic"){
00176                         my_auth_ptr.reset(new http::basic_auth(user_mgr));
00177                     }
00178                     else if (value_string == "cookie"){
00179                         my_auth_ptr.reset(new http::cookie_auth(user_mgr));
00180                     }
00181                     else {
00182                         
00183                         BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) );
00184                     }
00185                 } else if (command_string == "restrict") {
00186                     
00187                     if (! my_auth_ptr)
00188                         
00189                         BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) );
00190                     else if (value_string.empty())
00191                         
00192                         BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) );
00193                     my_auth_ptr->add_restrict(value_string);
00194                 } else if (command_string == "user") {
00195                     
00196                     if (! my_auth_ptr)
00197                         
00198                         BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) );
00199                     else if (value_string.empty())
00200                         
00201                         BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) );
00202                     my_auth_ptr->add_user(username_string, value_string);
00203                 } else if (command_string == "service") {
00204                     
00205                     load_service(resource_string, value_string);
00206                 } else if (command_string == "option") {
00207                     
00208                     std::string::size_type pos = value_string.find('=');
00209                     if (pos == std::string::npos)
00210                         BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) );
00211                     option_name_string = value_string.substr(0, pos);
00212                     option_value_string = value_string.substr(pos + 1);
00213                     set_service_option(resource_string, option_name_string,
00214                                      option_value_string);
00215                 }
00216                 command_string.clear();
00217                 parse_state = PARSE_NEWLINE;
00218             } else if (c == ' ' || c == '\t') {
00219                 
00220                 if (! value_string.empty())
00221                     value_string += c;
00222             } else {
00223                 
00224                 value_string += c;
00225             }
00226             break;
00227         
00228         case PARSE_COMMENT:
00229             
00230             if (c == '\r' || c == '\n')
00231                 parse_state = PARSE_NEWLINE;
00232             break;
00233         }
00234 
00235         
00236         c = config_stream.get();
00237     }
00238     
00239     
00240     set_authentication(my_auth_ptr);
00241 }
00242 
00243 }   
00244 }