示例#1
0
文件: xBlog.cpp 项目: iomato/xblog
void xBlog::SetRouteTable(evhttp * http)
{
    evhttp_set_cb(http, "/download",     xBlogPage::DownloadCallback, this);        // 测试
    evhttp_set_cb(http, "/post",         xBlogPage::PostRequestCallback, this);     // 请求文章
    evhttp_set_cb(http, "/guestbook",    xBlogPage::GuestbookCallback, this);       // 查看-留言
    evhttp_set_cb(http, "/postmessage",  xBlogPage::GuestPostCallback, this);       // 添加-评论留言
    evhttp_set_cb(http, "/catalog",      xBlogPage::CatalogRequestCallback, this);  // 分类
    evhttp_set_cb(http, "/",             xBlogPage::IndexRequestCallback, this);    // 首页
    evhttp_set_cb(http, "/page",         xBlogPage::PageRequestCallback, this);     // 页面

    // 管理后台功能
    evhttp_set_cb(http, "/admin",        xBlogPage::AdminCallback, this);            // 管理后台
    evhttp_set_cb(http, "/checklogin",   xBlogPage::AdminCheckLoginCallback, this);  // 权限验证
    evhttp_set_cb(http, "/shell",        xBlogPage::AdminShellCallback, this);       // 测试
    evhttp_set_cb(http, "/status",       xBlogPage::AdminStatusCallback, this);      // 测试
    evhttp_set_cb(http, "/postmanager",  xBlogPage::AdminPostManagerCallback, this); // 文章管理
    evhttp_set_cb(http, "/siteconfig",   xBlogPage::AdminSiteConfigCallback, this);  // 网站配置参数管理
    evhttp_set_cb(http, "/links",        xBlogPage::AdminLinksCallback, this);       // 链接管理
    evhttp_set_cb(http, "/catalogset",   xBlogPage::AdminCatalogCallback, this);     // 链接管理
    evhttp_set_cb(http, "/comments",     xBlogPage::AdminCommentsCallback, this);    // 留言评论管理
    evhttp_set_cb(http, "/system",       xBlogPage::AdminSystemCallback, this);      // 系统配置
    evhttp_set_cb(http, "/user",         xBlogPage::AdminUserCallback, this);        // 系统配置

    evhttp_set_timeout(http, Config::GetInstance()->xBlogAppConfig.HttpdTimeOut);

    evhttp_set_gencb(http, xBlogPage::SendDocumentCallback, this);
}
示例#2
0
void *CHttpServer::http_start_server(void *arg)
{
	CHttpServer *pthis = (CHttpServer *)arg;
	struct evhttp *httpd = NULL;
    	
	event_init();
	httpd = evhttp_start(pthis->m_http_addr, pthis->m_http_port);
	if (NULL == httpd) {
           printf("http server unable to listen on %s:%d\n\n", pthis->m_http_addr, pthis->m_http_port);
	   return NULL; 
    }
    evhttp_set_timeout(httpd, pthis->m_timeout);       
    evhttp_set_gencb(httpd, http_handle_postdata, arg);

#ifdef DEBUG
	printf("http_server start:%s:%d timeout:%u\n", 
			pthis->m_http_addr, 
			pthis->m_http_port, 
			pthis->m_timeout);
#else
	logrun("http_server start:%s:%d timeout:%u", 
			pthis->m_http_addr, 
			pthis->m_http_port, 
			pthis->m_timeout);
#endif
	event_dispatch();
	evhttp_free(httpd);
	
	return NULL;
}
示例#3
0
static void playlistcontainer_loaded(sp_playlistcontainer *pc, void *userdata) {
  syslog(LOG_DEBUG, "playlistcontainer_loaded\n");
  sp_session *session = userdata;
  struct state *state = sp_session_userdata(session);

  sp_playlistcontainer_remove_callbacks(pc, &playlistcontainer_callbacks, session);

  state->http = evhttp_new(state->event_base);
  evhttp_set_timeout(state->http, 60);
  evhttp_set_gencb(state->http, &handle_request, state);

  // Bind HTTP server
  int bind = evhttp_bind_socket(state->http, state->http_host,
                                state->http_port);

  if (bind == -1) {
    syslog(LOG_WARNING, "Could not bind HTTP server socket to %s:%d",
           state->http_host, state->http_port);
    sp_session_logout(session);
    return;
  }

  syslog(LOG_DEBUG, "HTTP server listening on %s:%d", state->http_host,
         state->http_port);
}
示例#4
0
static void
http_close_detection(int with_delay)
{
	short port = -1;
	struct evhttp_connection *evcon = NULL;
	struct evhttp_request *req = NULL;
	
	test_ok = 0;
	fprintf(stdout, "Testing Connection Close Detection%s: ",
		with_delay ? " (with delay)" : "");

	http = http_setup(&port, NULL);

	/* 2 second timeout */
	evhttp_set_timeout(http, 2);

	evcon = evhttp_connection_new("127.0.0.1", port);
	if (evcon == NULL) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	delayed_client = evcon;

	/*
	 * At this point, we want to schedule a request to the HTTP
	 * server using our make request method.
	 */

	req = evhttp_request_new(close_detect_cb, evcon);

	/* Add the information that we care about */
	evhttp_add_header(req->output_headers, "Host", "somehost");

	/* We give ownership of the request to the connection */
	if (evhttp_make_request(evcon,
	    req, EVHTTP_REQ_GET, with_delay ? "/largedelay" : "/test") == -1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	event_dispatch();

	if (test_ok != 1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/* at this point, the http server should have no connection */
	if (TAILQ_FIRST(&http->connections) != NULL) {
		fprintf(stdout, "FAILED (left connections)\n");
		exit(1);
	}

	evhttp_connection_free(evcon);
	evhttp_free(http);
	
	fprintf(stdout, "OK\n");
}
示例#5
0
bool InitHTTPServer()
{
    if (!InitHTTPAllowList())
        return false;

    if (gArgs.GetBoolArg("-rpcssl", false)) {
        uiInterface.ThreadSafeMessageBox(
            "SSL mode for RPC (-rpcssl) is no longer supported.",
            "", CClientUIInterface::MSG_ERROR);
        return false;
    }

    // Redirect libevent's logging to our own log
    event_set_log_callback(&libevent_log_cb);
    // Update libevent's log handling. Returns false if our version of
    // libevent doesn't support debug logging, in which case we should
    // clear the BCLog::LIBEVENT flag.
    if (!UpdateHTTPServerLogging(g_logger->WillLogCategory(BCLog::LIBEVENT))) {
        g_logger->DisableCategory(BCLog::LIBEVENT);
    }

#ifdef WIN32
    evthread_use_windows_threads();
#else
    evthread_use_pthreads();
#endif

    raii_event_base base_ctr = obtain_event_base();

    /* Create a new evhttp object to handle requests. */
    raii_evhttp http_ctr = obtain_evhttp(base_ctr.get());
    struct evhttp* http = http_ctr.get();
    if (!http) {
        LogPrintf("couldn't create evhttp. Exiting.\n");
        return false;
    }

    evhttp_set_timeout(http, gArgs.GetArg("-rpcservertimeout", DEFAULT_HTTP_SERVER_TIMEOUT));
    evhttp_set_max_headers_size(http, MAX_HEADERS_SIZE);
    evhttp_set_max_body_size(http, MAX_SIZE);
    evhttp_set_gencb(http, http_request_cb, nullptr);

    if (!HTTPBindAddresses(http)) {
        LogPrintf("Unable to bind any endpoint for RPC server\n");
        return false;
    }

    LogPrint(BCLog::HTTP, "Initialized HTTP server\n");
    int workQueueDepth = std::max((long)gArgs.GetArg("-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1L);
    LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth);

    workQueue = new WorkQueue<HTTPClosure>(workQueueDepth);
    // transfer ownership to eventBase/HTTP via .release()
    eventBase = base_ctr.release();
    eventHTTP = http_ctr.release();
    return true;
}
示例#6
0
文件: http.c 项目: snip/aprsc
static void http_srvr_defaults(struct evhttp *srvr)
{
	// limit what the clients can do a bit
	evhttp_set_allowed_methods(srvr, EVHTTP_REQ_GET);
	evhttp_set_timeout(srvr, 30);
	evhttp_set_max_body_size(srvr, 10*1024);
	evhttp_set_max_headers_size(srvr, 10*1024);
	
	// TODO: How to limit the amount of concurrent HTTP connections?
}
示例#7
0
/*
 * main loop - construct the event_base and start the loop
 */
int run_server(char* ip, short port, int timeout_s, int backlog) {
  struct event_base           *ev_base;
  struct event_config         *ev_cfg;
  struct evhttp               *ev_httpd;
  evutil_socket_t             socket_fd;
  int                         socket_opts_flag = 1;
  int                         worker_id, socket_opts_results;

  openlog("Backend", LOG_PID|LOG_NDELAY, LOG_LOCAL0);  

  ev_cfg = event_config_new();
  //event_config_set_flag(ev_cfg, EV_TIMEOUT|EV_PERSIST);
  ev_base = event_base_new_with_config(ev_cfg);
  
  if (!ev_base) {
    printf("ERROR: Failed to initialize HTTP event loop!\n");
    return -1;
  }
     
  // Set up httpd interface event
  ev_httpd = evhttp_new(ev_base);
  evhttp_set_timeout(ev_httpd, timeout_s);
  routes(ev_httpd, ev_base);

  socket_fd = create_socket(ip, port, timeout_s, backlog);
  socket_opts_results = setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY,
                                  (char *) socket_opts_flag, sizeof(int));

  if ( socket_opts_results < 0 ) {
    syslog( LOG_INFO, "Nagle DISABLED");
  } else {
    syslog( LOG_INFO, "Nagle ENABLED");
  }

  evhttp_accept_socket(ev_httpd, socket_fd);
  
  for (worker_id = 0; worker_id < WORKERS; worker_id++) {
    if (fork() == 0) {
      printf("Starting worker_id %d ... ", worker_id);
      worker(ev_base);
      printf("done.\n");
      exit(0);
    }
  }

  closelog();
  return 0;
}
示例#8
0
static void playlistcontainer_loaded(sp_playlistcontainer *pc, void *userdata) {
  syslog(LOG_DEBUG, "playlistcontainer_loaded\n");
  sp_session *session = userdata;
  struct state *state = sp_session_userdata(session);

  sp_playlistcontainer_remove_callbacks(pc, &playlistcontainer_callbacks, session);

  state->http = evhttp_new(state->event_base);
  evhttp_set_timeout(state->http, 60);
  evhttp_set_gencb(state->http, &handle_request, state);

  // TODO(liesen): Make address and port configurable
  if (evhttp_bind_socket(state->http, "0.0.0.0", 1337) == -1) {
    syslog(LOG_WARNING, "Could not bind HTTP server socket");
    sp_session_logout(session);
  }
}
示例#9
0
文件: main.c 项目: rainkid/httrack
static void et_init(void) {
	event_init();
	struct httpd_cfg httpd_config;
	httpd_config.listen = "0.0.0.0";
	httpd_config.port = 2688;
	httpd_config.timeout = 60;

	httpd = evhttp_start(httpd_config.listen, httpd_config.port);
	if (httpd == NULL) {
		fprintf(stderr, "\nUnable to listen on %s:%d\n\n", httpd_config.listen,
				httpd_config.port);
		kill(0, SIGTERM);
		exit(1);
	}
	evhttp_set_timeout(httpd, httpd_config.timeout);

	/* Set a callback for all other requests. */
	evhttp_set_gencb(httpd, httpd_handler, NULL);
}
示例#10
0
文件: ehc.c 项目: houzhenggang/MT
static int l_start(lua_State *L) {
	if (!lua_isstring(L, 1) || !lua_isstring(L, 2) || !lua_isstring(L, 3)) {
		lua_pushnil(L);
		lua_pushfstring(L, "invalid input type %s %s", lua_typename(L, lua_type(L, 1)), 
			lua_typename(L, lua_type(L, 2)), lua_typename(L, lua_type(L, 3)));
		return 2;
	}
	int timeout = -1;
	if (lua_isnumber(L, 4)) {
		timeout = lua_tonumber(L, 4);
		printf("reset timeout to %d\n", timeout);
	}
	struct ev_http *ins = evhttp_create();
	if (timeout > 0)
		evhttp_set_timeout(ins, timeout);
	evhttp_set_header(ins,  "Content-Type", "application/octet-stream"); 
	evhttp_set_header(ins,  "Content-Length", lua_tostring(L, 3)); 
	evhttp_post(ins, lua_tostring(L, 1), lua_tostring(L, 2), res_cb);
	return 0;
}
示例#11
0
int main(int argc, char **argv)
{
	int c;
	/* 默认参数设置 */
	char *httpsqs_settings_listen = "0.0.0.0";
	int httpsqs_settings_port = 2789;
    char *redis_settings_listen = "127.0.0.1";
    int redis_settings_port = 6379;
	bool httpsqs_settings_daemon = false;
	int httpsqs_settings_timeout = 3; /* 单位:秒 */
	httpsqs_settings_pidfile = "/tmp/httpredisq.pid";

    /* process arguments */
    while ((c = getopt(argc, argv, "l:p:r:o:i:t:dh")) != -1) {
        switch (c) {
        case 'l':
            httpsqs_settings_listen = strdup(optarg);
            break;
        case 'p':
            httpsqs_settings_port = atoi(optarg);
            break;
        case 'r':
            redis_settings_listen = strdup(optarg);
            break;
        case 'o':
            redis_settings_port = atoi(optarg);
            break;
        case 'i':
            httpsqs_settings_pidfile = strdup(optarg);
            break;			
        case 't':
            httpsqs_settings_timeout = atoi(optarg);
            break;
        case 'd':
            httpsqs_settings_daemon = true;
            break;
		case 'h':
        default:
            show_help();
            return 1;
        }
    }

    redis_client = redisConnect(redis_settings_listen, redis_settings_port);
    if (redis_client -> err) {
        fprintf(stderr, "Connect redis server error:%s\n", redis_client->errstr);
        return 1;
    }
    
	/* 如果加了-d参数,以守护进程运行 */
	if (httpsqs_settings_daemon == true){
        pid_t pid;

        /* Fork off the parent process */       
        pid = fork();
        if (pid < 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid > 0) {
                exit(EXIT_SUCCESS);
        }
	}
	
	/* 将进程号写入PID文件 */
	FILE *fp_pidfile;
	fp_pidfile = fopen(httpsqs_settings_pidfile, "w");
	fprintf(fp_pidfile, "%d\n", getpid());
	fclose(fp_pidfile);
	
	/* 忽略Broken Pipe信号 */
	signal(SIGPIPE, SIG_IGN);
	
	/* 处理kill信号 */
	signal (SIGINT, kill_signal);
	signal (SIGKILL, kill_signal);
	signal (SIGQUIT, kill_signal);
	signal (SIGTERM, kill_signal);
	signal (SIGHUP, kill_signal);
	
	/* 请求处理部分 */
    struct evhttp *httpd;

    event_init();
    httpd = evhttp_start(httpsqs_settings_listen, httpsqs_settings_port);
	if (httpd == NULL) {
		fprintf(stderr, "Error: Unable to listen on %s:%d\n\n", httpsqs_settings_listen, httpsqs_settings_port);		
		exit(1);		
	}
	evhttp_set_timeout(httpd, httpsqs_settings_timeout);

    /* Set a callback for requests to "/specific". */
    /* evhttp_set_cb(httpd, "/select", select_handler, NULL); */

    /* Set a callback for all other requests. */
    evhttp_set_gencb(httpd, httpsqs_handler, NULL);

    event_dispatch();

    /* Not reached in this code as it is now. */
    evhttp_free(httpd);

    return 0;
}
示例#12
0
int main(int argc, char **argv)
{
	int c;
	/* 默认参数设置 */
	char *httpcws_settings_listen = "0.0.0.0";
	int httpcws_settings_port = 1985;
	char *httpcws_settings_datapath = NULL; /*中文词典数据库路径 */
	bool httpcws_settings_daemon = false;
	int httpcws_settings_timeout = 120; /* 单位:秒 */

    /* process arguments */
    while ((c = getopt(argc, argv, "l:p:x:t:dh")) != -1) {
        switch (c) {
        case 'l':
            httpcws_settings_listen = strdup(optarg);
            break;
        case 'p':
            httpcws_settings_port = atoi(optarg);
            break;
        case 'x':
            httpcws_settings_datapath = strdup(optarg); /* 词库文件存储路径 */
            break;
        case 't':
            httpcws_settings_timeout = atoi(optarg);
            break;			
        case 'd':
            httpcws_settings_daemon = true;
            break;
		case 'h':			
        default:
            show_help();
            return 1;
        }
    }
	
	/* 判断是否加了必填参数 -x */
	if (httpcws_settings_datapath == NULL) {
		show_help();
		fprintf(stderr, "Attention: Please use the indispensable argument: -x <path>\n\n");		
		exit(1);
	}

	/* 初始化分词组件 */
	if(!ICTCLAS_Init(httpcws_settings_datapath))
	{
		printf("%s\n", httpcws_settings_datapath);
		fprintf(stderr, "ERROR: Count not open the Chinese dictionary!\n\n");		
		exit(1);
	}
	ICTCLAS_SetPOSmap(ICT_POS_MAP_SECOND);

	fprintf(stderr, "Loading Chinese dictionary 'httpcws_dict.txt' into memory, please waitting ......\n");
	char *httpcws_settings_dataname = (char *)malloc(1024);
	memset (httpcws_settings_dataname, '\0', 1024);
	sprintf(httpcws_settings_dataname, "%s/httpcws_dict.txt", httpcws_settings_datapath);
	int nCount = ICTCLAS_ImportUserDict(httpcws_settings_dataname);
	ICTCLAS_SaveTheUsrDic();
	free(httpcws_settings_dataname);
	printf("OK! %d words has loaded into memory.\n\n", nCount);
	printf("HTTPCWS Server running on %s:%d\n", httpcws_settings_listen, httpcws_settings_port);

	/* 如果加了-d参数,以守护进程运行 */
	if (httpcws_settings_daemon == true){
        pid_t pid;

        /* Fork off the parent process */       
        pid = fork();
        if (pid < 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid > 0) {
                exit(EXIT_SUCCESS);
        }
	}
	
	/* 请求处理部分 */
	struct evhttp *httpd;

	event_init();
	httpd = evhttp_start(httpcws_settings_listen, httpcws_settings_port);
	evhttp_set_timeout(httpd, httpcws_settings_timeout);

	/* Set a callback for all other requests. */
	evhttp_set_gencb(httpd, httpcws_handler, NULL);

	event_dispatch();

	/* Not reached in this code as it is now. */
	evhttp_free(httpd);

    return 0;
}
示例#13
0
 static void HHVM_METHOD(EventHttp, setTimeout, int64_t value) {
     EventHttpResourceData *resource_data = FETCH_RESOURCE(this_, EventHttpResourceData, s_event_http);
     evhttp_set_timeout((evhttp_t *)resource_data->getInternalResourceData(), value);
 }
示例#14
0
static void http_server_main (void *pDummy)
{
	short resthttp_port = (short)((size_t)pDummy);

	//const char *resthttpd_addr = DPS_REST_LISTEN_DEFAULT_IP;
	struct event_base *base;
	//struct evhttp_bound_socket *handle;
	
	int nfd=-1;
	int afd=-1;

	Py_Initialize();
	base = event_base_new();
	if (!base) 
	{
		show_print("ERROR! Couldn't create an event_base: exiting\n");
		return;
	}
	resthttpd_server = evhttp_new(base);
	if (!resthttpd_server)
	{
		show_print("ERROR! couldn't create evhttp. Exiting.\n");
		return;
	}

	/* The original version */
	/*
	handle = evhttp_bind_socket_with_handle(resthttpd_server, resthttpd_addr, resthttp_port);
	if (!handle) 
	{
		show_print("ERROR! Couldn't bind to port %d. Exiting.\n",
		           (int)resthttp_port);
		return;
	}
	*/

	nfd = event_bind_socket(resthttp_port);
	if (nfd < 0)
	{
		show_print("evhttp_bind_socket failed\n");
		return;
	}

	afd = evhttp_accept_socket(resthttpd_server, nfd);
	if (afd != 0)
	{
		printf("evhttp_accept_socket failed\n");
		return;
	}
	//Initialize Global REST port variable
	dps_rest_port = resthttp_port;
	show_print("DCS HTTP Server started on Port %d", dps_rest_port);

	helper_evhttp_set_cb_pattern(DPS_DOMAINS_URI, DPS_REST_FWD_FLAG_POST_TO_AVAIL,
	                             dps_req_handler_domains, NULL);
	helper_evhttp_set_cb_pattern(DPS_DOMAIN_URI, DPS_REST_FWD_FLAG_PUT_TO_AVAIL|DPS_REST_FWD_FLAG_DELETE_TO_ALL,
	                             dps_req_handler_domain, NULL);
	helper_evhttp_set_cb_pattern(DPS_DVGS_URI, DPS_REST_FWD_FLAG_POST_TO_ALL,
	                             dps_req_handler_dvgs, NULL);
	helper_evhttp_set_cb_pattern(DPS_DVG_URI, DPS_REST_FWD_FLAG_PUT_TO_ALL|DPS_REST_FWD_FLAG_DELETE_TO_ALL,
	                             dps_req_handler_dvg, NULL);
	helper_evhttp_set_cb_pattern(DPS_POLICIES_URI, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_policies, NULL);
	helper_evhttp_set_cb_pattern(ODCS_POLICY_URI, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_policy, NULL);
	helper_evhttp_set_cb_pattern(DPS_EXTERNAL_GATEWAYS_URI, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_gateways, NULL);
	helper_evhttp_set_cb_pattern(DPS_EXTERNAL_GATEWAY_URI, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_gateway, NULL);
	helper_evhttp_set_cb_pattern(DPS_STATISTICS_LOAD_BALANCING_URI, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_statistics_load_balancing, NULL);
	helper_evhttp_set_cb_pattern(DPS_STATISTICS_GENERAL_STATISTICS_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_statistics_general_statistics, NULL);
	helper_evhttp_set_cb_pattern(DPS_DOMAIN_IPV4SUBNET_URI, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_ipsubnet, NULL);
	helper_evhttp_set_cb_pattern(ODCS_DVG_IPV4SUBNET_URI, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_ipsubnet, NULL);
	helper_evhttp_set_cb_pattern(ODCS_SERVICE_ROLE_ASSIGNMENT_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_service_role, NULL);
	helper_evhttp_set_cb_pattern(DPS_CLUSTER_LOCAL_DOMAINS_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_local_domain_mapping, NULL);
	helper_evhttp_set_cb_pattern(DPS_CLUSTER_STATISTICS_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_node_statistics, NULL);
	helper_evhttp_set_cb_pattern(DPS_CLUSTER_HEARTBEAT_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_node_heartbeat, NULL);
	helper_evhttp_set_cb_pattern(DPS_CLUSTER_HEARTBEAT_REQUEST_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_node_heartbeat_request, NULL);
	helper_evhttp_set_cb_pattern(DPS_CLUSTER_NODE_STATUS_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_node_status, NULL);
	helper_evhttp_set_cb_pattern(ODCS_CLUSTER_INFO_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_query_cluster_nodes, NULL);
	helper_evhttp_set_cb_pattern(DPS_DOMAIN_TO_NODE_MAPPING_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_dcslist, NULL);
	helper_evhttp_set_cb_pattern(DPS_CLUSTER_TRANSFER_DOMAIN_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_transfer_domain, NULL);
	helper_evhttp_set_cb_pattern(DPS_CONTROLLER_LOCATION_UPDATE_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_set_dmc_location, NULL);
	helper_evhttp_set_cb_pattern(DPS_NODE_GET_READY, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_get_ready, NULL);
	helper_evhttp_set_cb_pattern(DPS_NODE_DOMAIN_ACTIVATE, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_domain_activate, NULL);
	helper_evhttp_set_cb_pattern(DPS_NODE_DOMAIN_DEACTIVATE, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_domain_deactivate, NULL);
	helper_evhttp_set_cb_pattern(DPS_NODE_DOMAIN_RECOVER, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_domain_recover, NULL);
	helper_evhttp_set_cb_pattern(DPS_NODE_DOMAIN_VNID_LIST, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_domain_vnid_listing, NULL);
	helper_evhttp_set_cb_pattern(DOVE_CLUSTER_BULK_POLICY_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_domain_bulk_policy, NULL);
	helper_evhttp_set_cb_pattern(DOVE_CLUSTER_BULK_SUBNET4_URI, DPS_REST_FWD_FLAG_DENY,
	                             dps_req_handler_domain_bulk_ip4subnets, NULL);

	/*  DPS DEBUG for DMC */
	helper_evhttp_set_cb_pattern(DPS_DEBUG_VNID_ENDPOINTS_URI, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_vnid_endpoints, NULL);
	helper_evhttp_set_cb_pattern(DPS_DEBUG_VNID_TUNNEL_ENDPOINTS_URI, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_vnid_tunnel_endpoints, NULL);
	helper_evhttp_set_cb_pattern(DPS_DEBUG_VNID_DOMAIN_MAPPING, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_vnid_get_domain_mapping, NULL);
	helper_evhttp_set_cb_pattern(DPS_DEBUG_VNID_ALLOW_POLICIES, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_vnid_get_allow_policies, NULL);
	helper_evhttp_set_cb_pattern(DPS_DEBUG_VNID_SUBNETS, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_vnid_get_subnets, NULL);
	/*TODO: The remaining 2 items to do */
	/*
	helper_evhttp_set_cb_pattern(DPS_DEBUG_VNID_DPS_CLIENTS_URI, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_vnid_dps_clients, NULL);
	helper_evhttp_set_cb_pattern(DPS_DEBUG_VNID_MULTICAST_URI, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_vnid_multicast, NULL);
	*/
	helper_evhttp_set_cb_pattern(DPS_DEBUG_CLUSTER_DISPLAY, DPS_REST_FWD_FLAG_GENERIC,
	                             dps_req_handler_cluster_display, NULL);

#ifdef _DPS_REST_DEBUG
	evhttp_set_cb(resthttpd_server, "/test1", http_test, (void *)1);
	evhttp_set_cb(resthttpd_server, "/test2", http_test, (void *)2);
	evhttp_set_cb(resthttpd_server, "/test4", http_test, (void *)4);
#endif
	evhttp_set_gencb(resthttpd_server, http_request_handler, NULL);
	evhttp_set_timeout(resthttpd_server, 20);
	event_base_dispatch(base);
	Py_Finalize();

	return;
}
示例#15
0
int main(int argc, char **argv)
{
	//自定义信号处理函数
#ifndef __WIN32
	signal(SIGHUP, signal_handler);
	signal(SIGQUIT, signal_handler);
#endif
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	//默认参数
	char *event_option_listen = "127.0.0.1";
	int event_option_port = 8706;
	int event_option_daemon = 0;
	int event_option_timeout = 60;
	int event_option_socket = 0;

	//获取参数
	int c;
	while ((c = getopt(argc, argv, "l:p:dst:vh")) != -1) {
		switch (c) {
			case 'l' :
				event_option_listen = optarg;
				break;
			case 'p' :
				event_option_port = atoi(optarg);
				break;
			case 'd' :
				event_option_daemon = 1;
				break;
			case 's' :
				event_option_socket = 1;
				break;
			case 't' :
				event_option_timeout = atoi(optarg);
				break;
			case 'v' :
				show_version();
				exit(EXIT_SUCCESS);
			case 'h' :
			default :
				show_help();
				exit(EXIT_SUCCESS);
		}
	}

	//判断是否设置了-d,以daemon运行
	if (event_option_daemon) {
		pid_t pid = 0;
#ifndef __WIN32
		pid = fork();
#endif
		if (pid < 0) {
			perror("Failed to fork\n");
			exit(EXIT_FAILURE);
		}
		if (pid > 0) {
			//生成子进程成功,退出父进程
			exit(EXIT_SUCCESS);
		}
	}

	//初始化event API
    event_init();

	//判断是否设置了-s,以socket运行
	if (event_option_socket) {
		int socketlisten;
		struct sockaddr_in addresslisten;
		struct event accept_event;

#ifdef __WIN32
		unsigned short ver;
		WSADATA wsaData;
		ver = MAKEWORD(1, 1);
		WSAStartup(ver, &wsaData);
#endif
		socketlisten = socket(AF_INET, SOCK_STREAM, 0);
		if (socketlisten < 0) {
			fprintf(stderr, "Failed to create listen socket\n");
			exit(1);
		}

		memset(&addresslisten, 0, sizeof(addresslisten));
		addresslisten.sin_family = AF_INET;
		addresslisten.sin_addr.s_addr = inet_addr(event_option_listen);
		addresslisten.sin_port = htons(event_option_port);
		if (bind(socketlisten, (struct sockaddr *)&addresslisten, sizeof(addresslisten)) < 0) {
			fprintf(stderr, "Failed to bind socket %s:%d\n", event_option_listen, event_option_port);
			exit(1);
		}

		if (listen(socketlisten, 5) < 0) {
			fprintf(stderr, "Failed to listen to socket\n");
			exit(1);
		}
#ifdef __WIN32
		char reuse = 1;
#else
		int reuse = 1;
#endif
		setsockopt(socketlisten, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
		set_nonblock(socketlisten);

		event_set(&accept_event, socketlisten, EV_READ|EV_PERSIST, on_accept, NULL);
		event_add(&accept_event, NULL);
		event_dispatch();

		close(socketlisten);
#ifdef __WIN32
		WSACleanup();
#endif
		return 0;
	}

    // 绑定IP和端口
#ifdef __WIN32
	unsigned short ver;
	WSADATA wsaData;
	ver = MAKEWORD(1, 1);
	WSAStartup(ver, &wsaData);
#endif
    struct evhttp *httpd;
	httpd = evhttp_start(event_option_listen, event_option_port);

    if (httpd == NULL) {
        fprintf(stderr, "Failed to listen on %s:%d\n", event_option_listen, event_option_port);
        exit(1);
    }

    // 设置请求超时时间
    evhttp_set_timeout(httpd, event_option_timeout);

    // 设置请求的处理函数
    evhttp_set_gencb(httpd, http_handler, NULL);
    event_dispatch();
    evhttp_free(httpd);
#ifdef __WIN32
	WSACleanup();
#endif

    return 0;
}
示例#16
0
int main(int argc, char *argv[], char *envp[]) {

	int c;
	char *synchttp_settings_listen = "0.0.0.0";
	int synchttp_settings_port = 2688;
	char *synchttp_settings_datapath = NULL;
	bool synchttp_settings_daemon = false;
	int synchttp_settings_timeout = 60; /* 单位:秒 */
	synchttp_settings_syncinterval = 5; /* 单位:秒 */
	int synchttp_settings_cachenonleaf = 1024; /* 缓存非叶子节点数。单位:条 */
	int synchttp_settings_cacheleaf = 2048; /* 缓存叶子节点数。叶子节点缓存数为非叶子节点数的两倍。单位:条 */
	int synchttp_settings_mappedmemory = 104857600; /* 单位:字节 */
	synchttp_settings_pidfile = "/tmp/synchttp.pid";
	synchttp_settings_auth = NULL; /* 验证密码 */

	/* 启动选项 */
	while ((c = getopt(argc, argv, "l:p:x:t:s:c:m:i:a:w:dh")) != -1) {
		switch (c) {
		case 'l':
			synchttp_settings_listen = strdup(optarg);
			break;
		case 'p':
			synchttp_settings_port = atoi(optarg);
			break;
		case 'x':
			synchttp_settings_datapath = strdup(optarg); /* synchttp数据库文件存放路径 */
			if (access(synchttp_settings_datapath, W_OK) != 0) { /* 如果目录不可写 */
				if (access(synchttp_settings_datapath, R_OK) == 0) { /* 如果目录可读 */
					chmod(synchttp_settings_datapath, S_IWOTH); /* 设置其他用户具可写入权限 */
				} else { /* 如果不存在该目录,则创建 */
					create_multilayer_dir(synchttp_settings_datapath);
				}
				if (access(synchttp_settings_datapath, W_OK) != 0) { /* 如果目录不可写 */
					fprintf(stderr, "synchttp database directory not writable\n");
				}
			}
			break;
		case 't':
			synchttp_settings_timeout = atoi(optarg);
			break;
		case 's':
			synchttp_settings_syncinterval = atoi(optarg);
			break;
		case 'c':
			synchttp_settings_cachenonleaf = atoi(optarg);
			synchttp_settings_cacheleaf = synchttp_settings_cachenonleaf * 2;
			break;
		case 'm':
			synchttp_settings_mappedmemory = atoi(optarg) * 1024 * 1024; /* 单位:M */
			break;
		case 'i':
			synchttp_settings_pidfile = strdup(optarg);
			break;
		case 'a':
			synchttp_settings_auth = strdup(optarg);
			break;
		case 'd':
			synchttp_settings_daemon = true;
			break;
		case 'h':
		default:
			show_help();
			return 1;
		}
	}

	/* 判断是否加了必填参数 -x */
	if (synchttp_settings_datapath == NULL) {
		show_help();
		fprintf(stderr, "Attention: Please use the indispensable argument: -x <path>\n\n");
		exit(1);
	}

	/*curl初始化全局信息*/
	if ((curl_global_init(CURL_GLOBAL_ALL)) != CURLE_OK) {
		fprintf(stderr, "Curl global init fail.\n");
		exit(1);
	}

	/* 数据表路径 */
	int synchttp_settings_dataname_len = 1024;
	char *synchttp_settings_dataname = (char *) tccalloc(1, synchttp_settings_dataname_len);
	sprintf(synchttp_settings_dataname, "%s/synchttp.db", synchttp_settings_datapath);

	/* 打开数据表 */
	synchttp_db_tcbdb = tcbdbnew();
	tcbdbsetmutex(synchttp_db_tcbdb); /* 开启线程互斥锁 */
	tcbdbtune(synchttp_db_tcbdb, 1024, 2048, 50000000, 8, 10, BDBTLARGE);
	tcbdbsetcache(synchttp_db_tcbdb, synchttp_settings_cacheleaf,
			synchttp_settings_cachenonleaf);
	tcbdbsetxmsiz(synchttp_db_tcbdb, synchttp_settings_mappedmemory); /* 内存缓存大小 */

	/* 判断表是否能打开 */
	if (!tcbdbopen(synchttp_db_tcbdb, synchttp_settings_dataname, BDBOWRITER | BDBOCREAT)) {
		fprintf(stderr, "Attention: Unable to open the database.\n\n");
		exit(1);
	}
	/* 释放变量所占内存 */
	free(synchttp_settings_dataname);

	/* 如果加了-d参数,以守护进程运行 */
	if (synchttp_settings_daemon == true) {
		pid_t pid;

		/* Fork off the parent process */
		pid = fork();
		if (pid < 0) {
			exit(EXIT_FAILURE);
		}
		/* If we got a good PID, then
		 we can exit the parent process. */
		if (pid > 0) {
			exit(EXIT_SUCCESS);
		}
	}

	/* 将进程号写入PID文件 */
	FILE *fp_pidfile;
	fp_pidfile = fopen(synchttp_settings_pidfile, "w");
	fprintf(fp_pidfile, "%d\n", getpid());
	fclose(fp_pidfile);

	/* 派生synchttp子进程(工作进程) */
	pid_t synchttp_worker_pid_wait;
	pid_t synchttp_worker_pid = fork();
	/* 如果派生进程失败,则退出程序 */
	if (synchttp_worker_pid < 0) {
		fprintf(stderr, "Error: %s:%d\n", __FILE__, __LINE__);
		exit(EXIT_FAILURE);
	}

	/* synchttp父进程内容 */
	if (synchttp_worker_pid > 0) {
		/* 处理父进程接收到的kill信号 */

		/* 忽略Broken Pipe信号 */
		signal(SIGPIPE, SIG_IGN);

		/* 处理kill信号 */
		signal(SIGINT, kill_signal_master);
		signal(SIGKILL, kill_signal_master);
		signal(SIGQUIT, kill_signal_master);
		signal(SIGTERM, kill_signal_master);
		signal(SIGHUP, kill_signal_master);

		/* 处理段错误信号 */
		signal(SIGSEGV, kill_signal_master);

		/* 如果子进程终止,则重新派生新的子进程 */
		while (1) {
			synchttp_worker_pid_wait = wait(NULL);
			if (synchttp_worker_pid_wait < 0) {
				continue;
			}
			usleep(100000);
			synchttp_worker_pid = fork();
			if (synchttp_worker_pid == 0) {
				break;
			}
		}
	}

	/*****************************************子进程处理************************************/
	/* 忽略Broken Pipe信号 */
	signal(SIGPIPE, SIG_IGN);

	/* 处理kill信号 */
	signal(SIGINT, kill_signal_worker);
	signal(SIGKILL, kill_signal_worker);
	signal(SIGQUIT, kill_signal_worker);
	signal(SIGTERM, kill_signal_worker);
	signal(SIGHUP, kill_signal_worker);

	/* 处理段错误信号 */
	signal(SIGSEGV, kill_signal_worker);

	/*创建消息队列监听进程*/
	pthread_t synchttp_dispatch_tid;
	pthread_create(&synchttp_dispatch_tid, NULL, (void *) synchttp_dispatch, NULL);

	/* 创建定时同步线程,定时将内存中的内容写入磁盘 */
	pthread_t synchttp_worker_tid;
	pthread_create(&synchttp_worker_tid, NULL, (void *) synchttp_worker, NULL);

	/* 外部请求处理部分 */
	struct evhttp *synchttpd;
	event_init();
	synchttpd = evhttp_start(synchttp_settings_listen, synchttp_settings_port);
	if (synchttpd == NULL) {
		fprintf(stderr, "Error: Unable to listen on %s:%d\n\n", synchttp_settings_listen, synchttp_settings_port);
		kill(0, SIGTERM);
		exit(1);
	}
	evhttp_set_timeout(synchttpd, synchttp_settings_timeout);
	evhttp_set_gencb(synchttpd, synchttp_handler, NULL);
	event_dispatch();
	evhttp_free(synchttpd);
}
示例#17
0
bool InitHTTPServer()
{
    struct evhttp* http = 0;
    struct event_base* base = 0;

    if (!InitHTTPAllowList())
        return false;

    if (GetBoolArg("-rpcssl", false)) {
        uiInterface.ThreadSafeMessageBox(
            "SSL mode for RPC (-rpcssl) is no longer supported.",
            "", CClientUIInterface::MSG_ERROR);
        return false;
    }

    // Redirect libevent's logging to our own log
    event_set_log_callback(&libevent_log_cb);
    // Update libevent's log handling. Returns false if our version of
    // libevent doesn't support debug logging, in which case we should
    // clear the BCLog::LIBEVENT flag.
    if (!UpdateHTTPServerLogging(logCategories & BCLog::LIBEVENT)) {
        logCategories &= ~BCLog::LIBEVENT;
    }

#ifdef WIN32
    evthread_use_windows_threads();
#else
    evthread_use_pthreads();
#endif

    base = event_base_new(); // XXX RAII
    if (!base) {
        LogPrintf("Couldn't create an event_base: exiting\n");
        return false;
    }

    /* Create a new evhttp object to handle requests. */
    http = evhttp_new(base); // XXX RAII
    if (!http) {
        LogPrintf("couldn't create evhttp. Exiting.\n");
        event_base_free(base);
        return false;
    }

    evhttp_set_timeout(http, GetArg("-rpcservertimeout", DEFAULT_HTTP_SERVER_TIMEOUT));
    evhttp_set_max_headers_size(http, MAX_HEADERS_SIZE);
    evhttp_set_max_body_size(http, MAX_SIZE);
    evhttp_set_gencb(http, http_request_cb, NULL);

    if (!HTTPBindAddresses(http)) {
        LogPrintf("Unable to bind any endpoint for RPC server\n");
        evhttp_free(http);
        event_base_free(base);
        return false;
    }

    LogPrint(BCLog::HTTP, "Initialized HTTP server\n");
    int workQueueDepth = std::max((long)GetArg("-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1L);
    LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth);

    workQueue = new WorkQueue<HTTPClosure>(workQueueDepth);
    eventBase = base;
    eventHTTP = http;
    return true;
}
示例#18
0
bool InitHTTPServer()
{
    struct evhttp* http = 0;
    struct event_base* base = 0;

    if (!InitHTTPAllowList())
        return false;

    if (GetBoolArg("-rpcssl", false)) {
        uiInterface.ThreadSafeMessageBox(
            "SSL mode for RPC (-rpcssl) is no longer supported.",
            "", CClientUIInterface::MSG_ERROR);
        return false;
    }

    // Redirect libevent's logging to our own log
    event_set_log_callback(&libevent_log_cb);
#if LIBEVENT_VERSION_NUMBER >= 0x02010100
    // If -debug=libevent, set full libevent debugging.
    // Otherwise, disable all libevent debugging.
    if (LogAcceptCategory("libevent"))
        event_enable_debug_logging(EVENT_DBG_ALL);
    else
        event_enable_debug_logging(EVENT_DBG_NONE);
#endif
#ifdef WIN32
    evthread_use_windows_threads();
#else
    evthread_use_pthreads();
#endif

    base = event_base_new(); // XXX RAII
    if (!base) {
        LogPrintf("Couldn't create an event_base: exiting\n");
        return false;
    }

    /* Create a new evhttp object to handle requests. */
    http = evhttp_new(base); // XXX RAII
    if (!http) {
        LogPrintf("couldn't create evhttp. Exiting.\n");
        event_base_free(base);
        return false;
    }

    evhttp_set_timeout(http, GetArg("-rpcservertimeout", DEFAULT_HTTP_SERVER_TIMEOUT));
    evhttp_set_max_headers_size(http, MAX_HEADERS_SIZE);
    evhttp_set_max_body_size(http, MAX_SIZE);
    evhttp_set_gencb(http, http_request_cb, NULL);

    if (!HTTPBindAddresses(http)) {
        LogPrintf("Unable to bind any endpoint for RPC server\n");
        evhttp_free(http);
        event_base_free(base);
        return false;
    }

    LogPrint("http", "Initialized HTTP server\n");
    int workQueueDepth = std::max((long)GetArg("-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1L);
    LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth);

    workQueue = new WorkQueue<HTTPClosure>(workQueueDepth);
    eventBase = base;
    eventHTTP = http;
    return true;
}
示例#19
0
static int
serve_threads(int nthreads, int port, const char *db_path, void *zmq_ctx,
              const char *send_endpoint, const char *recv_endpoint,
              const char *log_base_path)
{
  int nfd;
  uint32_t i;
  thd_data thds[nthreads];

  if ((nfd = bind_socket(port)) < 0) {
    print_error("cannot bind socket. please check port number with netstat.");
    return -1;
  }

  for (i = 0; i < nthreads; i++) {
    memset(&thds[i], 0, sizeof(thds[i]));
    if (!(thds[i].base = event_init())) {
      print_error("error in event_init() on thread %d.", i);
    } else {
      if (!(thds[i].httpd = evhttp_new(thds[i].base))) {
        print_error("error in evhttp_new() on thread %d.", i);
      } else {
        int r;
        if ((r = evhttp_accept_socket(thds[i].httpd, nfd))) {
          print_error("error in evhttp_accept_socket() on thread %d.", i);
        } else {
          if (send_endpoint) {
            if (!(thds[i].zmq_sock = zmq_socket(zmq_ctx, ZMQ_PUB))) {
              print_error("cannot create zmq_socket.");
            } else if (zmq_connect(thds[i].zmq_sock, send_endpoint)) {
              print_error("cannot connect zmq_socket.");
              zmq_close(thds[i].zmq_sock);
              thds[i].zmq_sock = NULL;
            } else {
              uint64_t hwm = 1;
              zmq_setsockopt(thds[i].zmq_sock, ZMQ_HWM, &hwm, sizeof(uint64_t));
            }
          } else {
            thds[i].zmq_sock = NULL;
          }
          if (!(thds[i].ctx = grn_ctx_open(0))) {
            print_error("error in grn_ctx_open() on thread %d.", i);
          } else if (grn_ctx_use(thds[i].ctx, db)) {
            print_error("error in grn_db_open() on thread %d.", i);
          } else {
            GRN_TEXT_INIT(&(thds[i].cmd_buf), 0);
            thds[i].log_base_path = log_base_path;
            thds[i].thread_id = i;
            evhttp_set_gencb(thds[i].httpd, generic_handler, &thds[i]);
            evhttp_set_timeout(thds[i].httpd, 10);
            {
              struct timeval tv = {1, 0};
              evtimer_set(&(thds[i].pulse), timeout_handler, &thds[i]);
              evtimer_add(&(thds[i].pulse), &tv);
            }
            if ((r = pthread_create(&(thds[i].thd), NULL, dispatch, thds[i].base))) {
              print_error("error in pthread_create() on thread %d.", i);
            }
          }
        }
      }
    }
  }

  /* recv thread from learner */
  if (recv_endpoint) {
    recv_thd_data rthd;
    rthd.db_path = db_path;
    rthd.recv_endpoint = recv_endpoint;
    rthd.zmq_ctx = zmq_ctx;

    if (pthread_create(&(rthd.thd), NULL, recv_from_learner, &rthd)) {
      print_error("error in pthread_create() on thread %d.", i);
    }
    pthread_join(rthd.thd, NULL);
  } else {
    while (loop) { sleep(1000); }
  }

  /* join all httpd thread */
  for (i = 0; i < nthreads; i++) {
    if (thds[i].thd) {
      pthread_join(thds[i].thd, NULL);
    }
    cleanup_httpd_thread(&(thds[i]));
  }
  return 0;
}
示例#20
0
文件: owl.c 项目: eliasson/owl
int main(int argc, char **argv) {
    short http_port = 8080;
    char* http_addr = "0.0.0.0";

    int arg;

    while( (arg = getopt(argc, argv, "b:p:r:d:h")) != -1) {
        switch(arg) {
        case 'b':
            http_addr = optarg;
            break;

        case 'p':
            http_port = atoi(optarg);
            break;

        case 'r':
            doc_root = optarg;

        case 'd':
            if(strcmp(optarg, "TRACE") == 0)
                OWL_ACTIVE_LOG_LEVEL = OWL_TRACE;
            else if(strcmp(optarg, "DEBUG") == 0)
                OWL_ACTIVE_LOG_LEVEL = OWL_DEBUG;
            else if(strcmp(optarg, "INFO") == 0)
                OWL_ACTIVE_LOG_LEVEL = OWL_INFO;
            else if(strcmp(optarg, "WARN") == 0)
                OWL_ACTIVE_LOG_LEVEL = OWL_WARNING;
            else
                OWL_ACTIVE_LOG_LEVEL = OWL_OFF;
            break;

        case 'h':
        default:
            usage();
            exit(1);
        }
    }

    // Initialize application
    int status = 0;
    struct owl_state* state = malloc(sizeof(struct owl_state));
    state->spotify_state = new_spotify_state();

    state->state = OWL_STATE_NOT_STARTED;

    // Setup application handlers
    {
        state->event_base = event_base_new();

        // Unix signal handlers
        state->sigint = evsignal_new(state->event_base, SIGINT, &sigint_handler, state);
        state->sigterm = evsignal_new(state->event_base, SIGTERM, &sigint_handler, state);
        state->sigsegv = evsignal_new(state->event_base, SIGSEGV, &sigint_handler, state);
        evsignal_add(state->sigint, NULL);
        evsignal_add(state->sigterm, NULL);
        evsignal_add(state->sigsegv, NULL);

        // Periodic callback
        state->timer = evtimer_new(state->event_base, &timer_handler, state);

        // Applications programatic callback
        state->app = evtimer_new(state->event_base, &timer_handler, state);

        // HTTP Server
        state->http = evhttp_new(state->event_base);
        evhttp_set_timeout(state->http, 60);
        evhttp_set_gencb(state->http, &http_handler, state);
        status = evhttp_bind_socket(state->http, http_addr, http_port);
    }

    if(status != 0) {
        ERROR("Could not bind owl server on IP (%s) or port (%d)\n", http_addr, http_port);
        goto shutdown;
    }

    status = initialize_spotify(state);
    if(status != 0) {
        ERROR("Could not initalize Spotify\n");
        goto shutdown;
    }

    state->state = OWL_STATE_INITIALIZED;
    INFO("Owl started, connect to http://%s:%d\n", http_addr, http_port);

    // Kick off event loop
    event_base_dispatch(state->event_base);

shutdown:
    INFO("Owl is shutting down\n");

    event_free(state->sigint);
    event_free(state->sigterm);
    event_free(state->sigsegv);
    event_free(state->timer);
    evhttp_free(state->http);
    event_base_free(state->event_base);

    free_spotify_state(state->spotify_state);
    free(state);

    return status;
}