- Main Page
- Classes
- Files

- File List

# utils/piond.cpp

    00001 // ---------------------------------------------------------------------
    00002 // pion:  a Boost C++ framework for building lightweight HTTP interfaces
    00003 // ---------------------------------------------------------------------
    00004 // Copyright (C) 2007-2012 Cloudmeter, Inc.  (http://www.cloudmeter.com)
    00005 //
    00006 // Distributed under the Boost Software License, Version 1.0.
    00007 // See http://www.boost.org/LICENSE_1_0.txt
    00008 //
    00009
    00010 #include <vector>
    00011 #include <iostream>
    00012 #include <boost/asio.hpp>
    00013 #include <pion/error.hpp>
    00014 #include <pion/plugin.hpp>
    00015 #include <pion/process.hpp>
    00016 #include <pion/http/plugin_server.hpp>
    00017
    00018 // these are used only when linking to static web service libraries
    00019 // #ifdef PION_STATIC_LINKING
    00020 PION_DECLARE_PLUGIN(EchoService)
    00021 PION_DECLARE_PLUGIN(FileService)
    00022 PION_DECLARE_PLUGIN(HelloService)
    00023 PION_DECLARE_PLUGIN(LogService)
    00024 PION_DECLARE_PLUGIN(CookieService)
    00025
    00026 using namespace std;
    00027 using namespace pion;
    00028
    00029
    00031 void argument_error(void)
    00032 {
    00033     std::cerr << "usage:   piond [OPTIONS] RESOURCE WEBSERVICE" << std::endl
    00034               << "         piond [OPTIONS] -c SERVICE_CONFIG_FILE" << std::endl
    00035               << "options: [-ssl PEM_FILE] [-i IP] [-p PORT] [-d PLUGINS_DIR] [-o OPTION=VALUE] [-v]" << std::endl;
    00036 }
    00037
    00038
    00040 int main (int argc, char *argv[])
    00041 {
    00042     static const unsigned int DEFAULT_PORT = 8080;
    00043
    00044     // used to keep track of web service name=value options
    00045     typedef std::vector<std::pair<std::string, std::string> >   ServiceOptionsType;
    00046     ServiceOptionsType service_options;
    00047
    00048     // parse command line: determine port number, RESOURCE and WEBSERVICE
    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     bool verbose_flag = false;
    00056
    00057     for (int argnum=1; argnum < argc; ++argnum) {
    00058         if (argv[argnum][0] == '-') {
    00059             if (argv[argnum][1] == 'p' && argv[argnum][2] == '\0' && argnum+1 < argc) {
    00060                 // set port number
    00061                 ++argnum;
    00062                 cfg_endpoint.port(strtoul(argv[argnum], 0, 10));
    00063                 if (cfg_endpoint.port() == 0) cfg_endpoint.port(DEFAULT_PORT);
    00064             } else if (argv[argnum][1] == 'i' && argv[argnum][2] == '\0' && argnum+1 < argc) {
    00065                 // set ip address
    00066                 cfg_endpoint.address(boost::asio::ip::address::from_string(argv[++argnum]));
    00067             } else if (argv[argnum][1] == 'c' && argv[argnum][2] == '\0' && argnum+1 < argc) {
    00068                 service_config_file = argv[++argnum];
    00069             } else if (argv[argnum][1] == 'd' && argv[argnum][2] == '\0' && argnum+1 < argc) {
    00070                 // add the service plug-ins directory to the search path
    00071                 try { plugin::add_plugin_directory(argv[++argnum]); }
    00072                 catch (error::directory_not_found&) {
    00073                     std::cerr << "piond: Web service plug-ins directory does not exist: "
    00074                         << argv[argnum] << std::endl;
    00075                     return 1;
    00076                 }
    00077             } else if (argv[argnum][1] == 'o' && argv[argnum][2] == '\0' && argnum+1 < argc) {
    00078                 std::string option_name(argv[++argnum]);
    00079                 std::string::size_type pos = option_name.find('=');
    00080                 if (pos == std::string::npos) {
    00081                     argument_error();
    00082                     return 1;
    00083                 }
    00084                 std::string option_value(option_name, pos + 1);
    00085                 option_name.resize(pos);
    00086                 service_options.push_back( std::make_pair(option_name, option_value) );
    00087             } else if (argv[argnum][1] == 's' && argv[argnum][2] == 's' &&
    00088                        argv[argnum][3] == 'l' && argv[argnum][4] == '\0' && argnum+1 < argc) {
    00089                 ssl_flag = true;
    00090                 ssl_pem_file = argv[++argnum];
    00091             } else if (argv[argnum][1] == 'v' && argv[argnum][2] == '\0') {
    00092                 verbose_flag = true;
    00093             } else {
    00094                 argument_error();
    00095                 return 1;
    00096             }
    00097         } else if (argnum+2 == argc) {
    00098             // second to last argument = RESOURCE
    00099             resource_name = argv[argnum];
    00100         } else if (argnum+1 == argc) {
    00101             // last argument = WEBSERVICE
    00102             service_name = argv[argnum];
    00103         } else {
    00104             argument_error();
    00105             return 1;
    00106         }
    00107     }
    00108
    00109     if (service_config_file.empty() && (resource_name.empty() || service_name.empty())) {
    00110         argument_error();
    00111         return 1;
    00112     }
    00113
    00114     // initialize signal handlers, etc.
    00115     process::initialize();
    00116
    00117     // initialize log system (use simple configuration)
    00118     logger main_log(PION_GET_LOGGER("piond"));
    00119     logger pion_log(PION_GET_LOGGER("pion"));
    00120     if (verbose_flag) {
    00121         PION_LOG_SETLEVEL_DEBUG(main_log);
    00122         PION_LOG_SETLEVEL_DEBUG(pion_log);
    00123     } else {
    00124         PION_LOG_SETLEVEL_INFO(main_log);
    00125         PION_LOG_SETLEVEL_INFO(pion_log);
    00126     }
    00127     PION_LOG_CONFIG_BASIC;
    00128
    00129     try {
    00130         // add the Pion plug-ins installation directory to our path
    00131         try { plugin::add_plugin_directory(PION_PLUGINS_DIRECTORY); }
    00132         catch (error::directory_not_found&) {
    00133             PION_LOG_WARN(main_log, "Default plug-ins directory does not exist: "
    00134                 << PION_PLUGINS_DIRECTORY);
    00135         }
    00136
    00137         // add the directory of the program we're running to our path
    00138         try { plugin::add_plugin_directory(boost::filesystem::path(argv[0]).branch_path().string()); }
    00139         catch (error::directory_not_found&) {
    00140             PION_LOG_WARN(main_log, "Directory of current executable does not exist: "
    00141                 << boost::filesystem::path(argv[0]).branch_path());
    00142         }
    00143
    00144         // create a server for HTTP & add the Hello Service
    00145         http::plugin_server  web_server(cfg_endpoint);
    00146
    00147         if (ssl_flag) {
    00148 #ifdef PION_HAVE_SSL
    00149             // configure server for SSL
    00150             web_server.set_ssl_key_file(ssl_pem_file);
    00151             PION_LOG_INFO(main_log, "SSL support enabled using key file: " << ssl_pem_file);
    00152 #else
    00153             PION_LOG_ERROR(main_log, "SSL support is not enabled");
    00154 #endif
    00155         }
    00156
    00157         if (service_config_file.empty()) {
    00158             // load a single web service using the command line arguments
    00159             web_server.load_service(resource_name, service_name);
    00160
    00161             // set web service options if any are defined
    00162             for (ServiceOptionsType::iterator i = service_options.begin();
    00163                  i != service_options.end(); ++i)
    00164             {
    00165                 web_server.set_service_option(resource_name, i->first, i->second);
    00166             }
    00167         } else {
    00168             // load services using the configuration file
    00169             web_server.load_service_config(service_config_file);
    00170         }
    00171
    00172         // startup the server
    00173         web_server.start();
    00174         process::wait_for_shutdown();
    00175
    00176     } catch (std::exception& e) {
    00177         PION_LOG_FATAL(main_log, pion::diagnostic_information(e));
    00178     }
    00179
    00180     return 0;
    00181 }