00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <vector>
00011 #include <iostream>
00012 #include <boost/asio.hpp>
00013 #include <pion/PionPlugin.hpp>
00014 #include <pion/net/WebServer.hpp>
00015 #include "ShutdownManager.hpp"
00016
00017
00018
00019 PION_DECLARE_PLUGIN(EchoService)
00020 PION_DECLARE_PLUGIN(FileService)
00021 PION_DECLARE_PLUGIN(HelloService)
00022 PION_DECLARE_PLUGIN(LogService)
00023 PION_DECLARE_PLUGIN(CookieService)
00024
00025 using namespace std;
00026 using namespace pion;
00027 using namespace pion::net;
00028
00029
00031 void argument_error(void)
00032 {
00033 std::cerr << "usage: PionWebServer [OPTIONS] RESOURCE WEBSERVICE" << std::endl
00034 << " PionWebServer [OPTIONS] -c SERVICE_CONFIG_FILE" << std::endl
00035 << "options: [-ssl PEM_FILE] [-i IP] [-p PORT] [-d PLUGINS_DIR] [-o OPTION=VALUE]" << std::endl;
00036 }
00037
00038
00040 int main (int argc, char *argv[])
00041 {
00042 static const unsigned int DEFAULT_PORT = 8080;
00043
00044
00045 typedef std::vector<std::pair<std::string, std::string> > ServiceOptionsType;
00046 ServiceOptionsType service_options;
00047
00048
00049 boost::asio::ip::tcp::endpoint cfg_endpoint(boost::asio::ip::tcp::v4(), DEFAULT_PORT);
00050 std::string service_config_file;
00051 std::string resource_name;
00052 std::string service_name;
00053 std::string ssl_pem_file;
00054 bool ssl_flag = false;
00055
00056 for (int argnum=1; argnum < argc; ++argnum) {
00057 if (argv[argnum][0] == '-') {
00058 if (argv[argnum][1] == 'p' && argv[argnum][2] == '\0' && argnum+1 < argc) {
00059
00060 ++argnum;
00061 cfg_endpoint.port(strtoul(argv[argnum], 0, 10));
00062 if (cfg_endpoint.port() == 0) cfg_endpoint.port(DEFAULT_PORT);
00063 } else if (argv[argnum][1] == 'i' && argv[argnum][2] == '\0' && argnum+1 < argc) {
00064
00065 cfg_endpoint.address(boost::asio::ip::address::from_string(argv[++argnum]));
00066 } else if (argv[argnum][1] == 'c' && argv[argnum][2] == '\0' && argnum+1 < argc) {
00067 service_config_file = argv[++argnum];
00068 } else if (argv[argnum][1] == 'd' && argv[argnum][2] == '\0' && argnum+1 < argc) {
00069
00070 try { PionPlugin::addPluginDirectory(argv[++argnum]); }
00071 catch (PionPlugin::DirectoryNotFoundException&) {
00072 std::cerr << "PionWebServer: Web service plug-ins directory does not exist: "
00073 << argv[argnum] << std::endl;
00074 return 1;
00075 }
00076 } else if (argv[argnum][1] == 'o' && argv[argnum][2] == '\0' && argnum+1 < argc) {
00077 std::string option_name(argv[++argnum]);
00078 std::string::size_type pos = option_name.find('=');
00079 if (pos == std::string::npos) {
00080 argument_error();
00081 return 1;
00082 }
00083 std::string option_value(option_name, pos + 1);
00084 option_name.resize(pos);
00085 service_options.push_back( std::make_pair(option_name, option_value) );
00086 } else if (argv[argnum][1] == 's' && argv[argnum][2] == 's' &&
00087 argv[argnum][3] == 'l' && argv[argnum][4] == '\0' && argnum+1 < argc) {
00088 ssl_flag = true;
00089 ssl_pem_file = argv[++argnum];
00090 } else {
00091 argument_error();
00092 return 1;
00093 }
00094 } else if (argnum+2 == argc) {
00095
00096 resource_name = argv[argnum];
00097 } else if (argnum+1 == argc) {
00098
00099 service_name = argv[argnum];
00100 } else {
00101 argument_error();
00102 return 1;
00103 }
00104 }
00105
00106 if (service_config_file.empty() && (resource_name.empty() || service_name.empty())) {
00107 argument_error();
00108 return 1;
00109 }
00110
00111
00112 #ifdef PION_WIN32
00113 SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
00114 #else
00115 signal(SIGINT, handle_signal);
00116 #endif
00117
00118
00119 PionLogger main_log(PION_GET_LOGGER("PionWebServer"));
00120 PionLogger pion_log(PION_GET_LOGGER("pion"));
00121 PION_LOG_SETLEVEL_INFO(main_log);
00122 PION_LOG_SETLEVEL_INFO(pion_log);
00123 PION_LOG_CONFIG_BASIC;
00124
00125 try {
00126
00127 try { PionPlugin::addPluginDirectory(PION_PLUGINS_DIRECTORY); }
00128 catch (PionPlugin::DirectoryNotFoundException&) {
00129 PION_LOG_WARN(main_log, "Default plug-ins directory does not exist: "
00130 << PION_PLUGINS_DIRECTORY);
00131 }
00132
00133
00134 try { PionPlugin::addPluginDirectory(boost::filesystem::path(argv[0]).branch_path().string()); }
00135 catch (PionPlugin::DirectoryNotFoundException&) {
00136 PION_LOG_WARN(main_log, "Directory of current executable does not exist: "
00137 << boost::filesystem::path(argv[0]).branch_path());
00138 }
00139
00140
00141 WebServer web_server(cfg_endpoint);
00142
00143 if (ssl_flag) {
00144 #ifdef PION_HAVE_SSL
00145
00146 web_server.setSSLKeyFile(ssl_pem_file);
00147 PION_LOG_INFO(main_log, "SSL support enabled using key file: " << ssl_pem_file);
00148 #else
00149 PION_LOG_ERROR(main_log, "SSL support is not enabled");
00150 #endif
00151 }
00152
00153 if (service_config_file.empty()) {
00154
00155 web_server.loadService(resource_name, service_name);
00156
00157
00158 for (ServiceOptionsType::iterator i = service_options.begin();
00159 i != service_options.end(); ++i)
00160 {
00161 web_server.setServiceOption(resource_name, i->first, i->second);
00162 }
00163 } else {
00164
00165 web_server.loadServiceConfig(service_config_file);
00166 }
00167
00168
00169 web_server.start();
00170 main_shutdown_manager.wait();
00171
00172 } catch (std::exception& e) {
00173 PION_LOG_FATAL(main_log, e.what());
00174 }
00175
00176 return 0;
00177 }