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 }