int main(int argc, char *argv[]) { auto config_file = Yb::StrUtils::xgetenv("CONFIG_FILE"); if (!config_file.size()) config_file = "/etc/card_proxy_keykeeper2/card_proxy_keykeeper2.cfg.xml"; Yb::ILogger::Ptr logger; try { theApp::instance().init( IConfig::Ptr(new XmlConfig(config_file)), false); logger.reset(theApp::instance().new_logger("main").release()); } catch (const std::exception &ex) { std::cerr << "exception: " << ex.what() << "\n"; return 1; } try { std::string bind_host = theApp::instance().cfg() .get_value("HttpListener/Host"); int bind_port = theApp::instance().cfg() .get_value_as_int("HttpListener/Port"); std::string listen_at = "http://" + bind_host + ":" + Yb::to_string(bind_port) + "/"; logger->error("listen at: " + listen_at); key_keeper = new KeyKeeper(theApp::instance().cfg(), *logger); const std::string prefix = "/" + theApp::instance().cfg() .get_value("HttpListener/Prefix"); Yb::String secret = theApp::instance().cfg().get_value("KK2Secret"); XmlHttpWrapper handlers_array[] = { WRAP("/", ping), SECURE_WRAP(prefix, secret, read), SECURE_WRAP(prefix, secret, get), SECURE_WRAP(prefix, secret, write), SECURE_WRAP(prefix, secret, set), SECURE_WRAP(prefix, secret, unset), SECURE_WRAP(prefix, secret, cleanup), }; int n_handlers = sizeof(handlers_array)/sizeof(handlers_array[0]); typedef HttpServer<XmlHttpWrapper> MyHttpServer; MyHttpServer::HandlerMap handlers; for (int i = 0; i < n_handlers; ++i) { std::string prefix = handlers_array[i].prefix(); handlers[prefix + handlers_array[i].name()] = handlers_array[i]; } std::string error_content_type = "application/xml"; std::string error_body = "<result><status>internal_error</status></result>"; MyHttpServer server( bind_host, bind_port, 30, handlers, &theApp::instance(), error_content_type, error_body); server.serve(); } catch (const std::exception &ex) { logger->error(std::string("exception: ") + ex.what()); return 1; } return 0; }
int main() { try { logger = theApp::instance().new_logger("main"); } catch (const std::exception &ex) { std::cerr << "exception: " << ex.what() << "\n"; return 1; } try { //int port = 19090; // TODO: read from config typedef std::string (*Handler)(const Yb::StringDict &); typedef HttpServer<Handler> ScheduleHttpServer; ScheduleHttpServer::HandlerMap handlers; handlers["/main"] = main_handler; /* handlers["/adm/login"] = adm_login; handlers["/adm/session_info"] = adm_session_info; handlers["/adm/logout"] = adm_logout; handlers["/adm/add_activity"] = adm_add_activity; handlers["/adm/list_activities"] = adm_list_activities; handlers["/adm/schedule"] = adm_get_schedule_items; */ ScheduleHttpServer server( theApp::instance().get_settings().get_port(), handlers, &theApp::instance(), _T("text/xml"), _T("<status>NOT</status>")); server.serve(); } catch (const std::exception &ex) { logger->error(string("exception: ") + ex.what()); return 1; } return 0; }
inline int run_server_app(const std::string &config_name, HttpHandler *handlers_array, int n_handlers) { randomize(); Yb::ILogger::Ptr logger; try { theApp::instance().init(IConfig::Ptr(new XmlConfig(config_name))); logger.reset(theApp::instance().new_logger("main").release()); } catch (const std::exception &ex) { std::cerr << "exception: " << ex.what() << "\n"; return 1; } try { std::string bind_host = theApp::instance().cfg() .get_value("HttpListener/Host"); int bind_port = theApp::instance().cfg() .get_value_as_int("HttpListener/Port"); std::string listen_at = "http://" + bind_host + ":" + Yb::to_string(bind_port) + "/"; logger->error("listen at: " + listen_at); typedef HttpServer<HttpHandler> MyHttpServer; typename MyHttpServer::HandlerMap handlers; for (int i = 0; i < n_handlers; ++i) { std::string prefix = handlers_array[i].prefix(); handlers[prefix + handlers_array[i].name()] = handlers_array[i]; } std::string error_content_type = "text/xml"; std::string error_body = "{\"status\": \"internal_error\"}"; MyHttpServer server( bind_host, bind_port, 30, handlers, &theApp::instance(), error_content_type, error_body); server.serve(); } catch (const std::exception &ex) { logger->error(std::string("exception: ") + ex.what()); return 1; } return 0; }
string main_handler(const Yb::StringDict &content) { try { ContentChecker contentChecker; if (!contentChecker.contentIsValid(content)) throw std::runtime_error(contentChecker.err()); BaseCommand *command = createCommand(contentChecker.requestType(), contentChecker.parsedParams()); std::string response = command->execute(); delete command; return response; } catch(const exception &err) { logger->error(err.what()); cout << err.what() << endl; return "<status>EXCEPTION</status>"; } }
void HttpServer::process(SOCKET cl_s, Yb::ILogger *log_ptr, const HttpHandlerMap *handlers) { TcpSocket cl_sock(cl_s); Yb::ILogger::Ptr logger = log_ptr->new_logger("worker"); // read and process request try { // read request header string buf = cl_sock.readline(); logger->debug(buf); int cont_len = -1; string cont_type = ""; while (1) { // skip to request's body string s = cl_sock.readline(); if (s == "\r\n" || s == "\n") break; logger->debug(s); if (starts_with(str_to_upper(s), "CONTENT-LENGTH: ")) { try { Strings parts; split_str_by_chars(s, " ", parts, 2); cont_len = boost::lexical_cast<unsigned>( trim_trailing_space(parts[1])); } catch (const std::exception &ex) { logger->warning( string("couldn't parse CONTENT-LENGTH: ") + ex.what()); } } if (starts_with(str_to_upper(s), "CONTENT-TYPE: ")) { try { Strings parts; split_str_by_chars(s, ":", parts, 2); cont_type = trim_trailing_space(parts[1]); } catch (const std::exception &ex) { logger->warning( string("couldn't parse CONTENT-TYPE: ") + ex.what()); } } } // parse request StringMap rez = parse_http(buf); rez["&content-type"] = cont_type; if (rez["&method"].compare("GET") && rez["&method"].compare("POST")) { logger->error("unsupported method \"" + rez["&method"] + "\""); send_response(cl_sock, *logger, 400, "Bad request", BAD_RESP); } else { if (!rez["&method"].compare("POST") && cont_len > 0) { string post_data = cl_sock.read(cont_len); logger->debug("Post data: " + post_data); if (!cont_type.compare("application/x-www-form-urlencoded")) { StringMap params = parse_params(post_data); for (StringMap::iterator i = params.begin(); i != params.end(); ++i) rez[i->first] = i->second; } else rez["&post-data"] = post_data; } HttpHandlerMap::const_iterator it = handlers->find(rez["&uri"]); if (it == handlers->end()) { logger->error("URI " + rez["&uri"] + " not found!"); send_response(cl_sock, *logger, 404, "Not found", BAD_RESP); } else { // handle the request HttpHandler func_ptr = it->second; send_response(cl_sock, *logger, 200, "OK", func_ptr(rez)); } } } catch (const SocketEx &ex) { logger->error(string("socket error: ") + ex.what()); //if connection is closed by peer - this is killing the whole process: //send_response(cl_sock, *logger, 400, "Short read", BAD_RESP); cl_sock.close(true); } catch (const ParserEx &ex) { logger->error(string("parser error: ") + ex.what()); send_response(cl_sock, *logger, 400, "Bad request", BAD_RESP); } catch (const std::exception &ex) { logger->error(string("exception: ") + ex.what()); send_response(cl_sock, *logger, 500, "Internal server error", BAD_RESP); } }