Пример #1
0
int main(int argc, char * argv[])
{
    signal(SIGPIPE, SIG_IGN);
    loop = uv_default_loop();
    int result;
    http_server_init(&srv);
    srv.sock_listen_data = NULL; // should be null by default

    http_server_handler_init(&handler);
    handler.on_message_complete = &on_message_complete;

    result = http_server_setopt(&srv, HTTP_SERVER_OPT_HANDLER, &handler);
    result = http_server_setopt(&srv, HTTP_SERVER_OPT_HANDLER_DATA, &srv);

    // Set options
    //result = http_server_setopt(&srv, HTTP_SERVER_OPT_OPEN_SOCKET_DATA, NULL);
    
    //result = http_server_setopt(&srv, HTTP_SERVER_OPT_OPEN_SOCKET_FUNCTION, &_opensocket_function);

    result = http_server_setopt(&srv, HTTP_SERVER_OPT_SOCKET_DATA, NULL);
    result = http_server_setopt(&srv, HTTP_SERVER_OPT_SOCKET_FUNCTION, &_socket_function);

    http_server_start(&srv);
    result = uv_run(loop, UV_RUN_DEFAULT);
    http_server_free(&srv);
    return result;
}
Пример #2
0
void
    http_server_unlink_ (
    http_server_t * ( * self_p ),       //  Reference to object reference
    char * file,                        //  Source file for call
    size_t line                         //  Line number for call
)
{
#if defined (DEBUG) || defined (BASE_HISTORY) || defined (BASE_HISTORY_HTTP_SERVER)
    int
        history_last;
#endif
    http_server_t *
        self = *self_p;                 //  Dereferenced Reference to object reference

    if (self) {
        if (self->links == 0) {
            icl_console_print ("Missing link on http_server object");
            http_server_show_ (self, ICL_CALLBACK_DUMP, stderr, file, line);
        }
        assert (self->links > 0);

#if defined (DEBUG) || defined (BASE_HISTORY) || defined (BASE_HISTORY_HTTP_SERVER)
        //  Track possession operation in history.  Pre-empt value of links
        //  after operation; otherwise race condition can result in writing
        //  to freed memory.
        history_last = icl_atomic_inc32 ((volatile qbyte *) &self->history_last) + 1;
        self->history_file  [history_last % HTTP_SERVER_HISTORY_LENGTH] = file;
        self->history_line  [history_last % HTTP_SERVER_HISTORY_LENGTH] = line;
        self->history_type  [history_last % HTTP_SERVER_HISTORY_LENGTH] = "unlink";
        self->history_links [history_last % HTTP_SERVER_HISTORY_LENGTH] = self->links - 1;
#endif

        if (icl_atomic_dec32 ((volatile qbyte *) &self->links) == 0) {
            if (self->zombie)
                http_server_free (self);
            else {
                //  JS: Have to make the object look like it was called from the
                //      application.  _destroy will decrement links again.
                icl_atomic_inc32 ((volatile qbyte *) &self->links);
                http_server_destroy_ (self_p, file, line);
            }
        }
        else
            *self_p = NULL;
    }
}
Пример #3
0
struct http_server * http_server_new(struct event_base *base, int port)
{
	struct http_server *hs = NULL;
	hs = (struct http_server *)malloc(sizeof(struct http_server));
	if (!hs) {
		printf("Could not create http server\n");
		return NULL;
	}
	memset(hs, 0, sizeof(struct http_server));

	hs->base = base;

	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(port);
	sin.sin_addr.s_addr=INADDR_ANY;

	/* init connection listener */
	hs->listener = evconnlistener_new_bind(base, http_connect_cb, hs,
		LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_EXEC,
		100, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in));
	if (!hs->listener) {
		printf("Could not bind a listener to port %d\n", port);
		goto failed;
	}
	evconnlistener_set_error_cb(hs->listener, http_connect_error_cb);

	/* init connection head node, for convinents */
	hs->hc = http_connection_new(hs, -1, (struct sockaddr *)&sin);
	if (!hs->hc) {
		printf("Could not create a initial connection for http server\n");
		goto failed;
	}

	/* init uris */
	http_uris_init(hs);

	return hs;
failed:
	http_server_free(hs);
	return NULL;
}
Пример #4
0
int
    http_server_destroy_ (
    http_server_t * ( * self_p ),       //  Reference to object reference
    char * file,                        //  Source file
    size_t line                         //  Line number
)
{
    http_server_t *
        self = *self_p;                 //  Dereferenced Reference to object reference
    int
        rc = 0;                         //  Return code

if (self) {
    if (icl_atomic_cas32 (&self->zombie, TRUE, FALSE) == FALSE)
        rc = http_server_annihilate_ (self_p, file, line);
    else
    if (icl_atomic_dec32 ((volatile qbyte *) &self->links) == 0)
        http_server_free (self);
    *self_p = NULL;
}

    return (rc);
}
Пример #5
0
Файл: http.c Проект: snip/aprsc
void http_thread(void *asdf)
{
	sigset_t sigs_to_block;
	struct http_config_t *lc;
	struct timeval http_timer_tv;
	
	http_timer_tv.tv_sec = 0;
	http_timer_tv.tv_usec = 200000;
	
	pthreads_profiling_reset("http");
	
	sigemptyset(&sigs_to_block);
	sigaddset(&sigs_to_block, SIGALRM);
	sigaddset(&sigs_to_block, SIGINT);
	sigaddset(&sigs_to_block, SIGTERM);
	sigaddset(&sigs_to_block, SIGQUIT);
	sigaddset(&sigs_to_block, SIGHUP);
	sigaddset(&sigs_to_block, SIGURG);
	sigaddset(&sigs_to_block, SIGPIPE);
	sigaddset(&sigs_to_block, SIGUSR1);
	sigaddset(&sigs_to_block, SIGUSR2);
	pthread_sigmask(SIG_BLOCK, &sigs_to_block, NULL);
	
	/* start the http thread, which will start server threads */
	hlog(LOG_INFO, "HTTP thread starting...");
	
	/* we allocate a worker structure to be used within the http thread
	 * for parsing incoming packets and passing them on to the dupecheck
	 * thread.
	 */
	http_worker = worker_alloc();
	http_worker->id = 80;
	
	/* we also need a client structure to be used with incoming
	 * HTTP position uploads
	 */
	http_pseudoclient = pseudoclient_setup(80);
	
	http_reconfiguring = 1;
	while (!http_shutting_down) {
		if (http_reconfiguring) {
			http_reconfiguring = 0;
			
			// shut down existing instance
			http_server_free();
			
			// do init
#if 1
			libbase = event_base_new(); // libevent 2.x
#else
                        libbase = event_init(); // libevent 1.x
#endif
			
			// timer for the whole libevent, to catch shutdown signal
			ev_timer = event_new(libbase, -1, EV_TIMEOUT, http_timer, NULL);
			event_add(ev_timer, &http_timer_tv);
			
			for (lc = http_config; (lc); lc = lc->next) {
				hlog(LOG_INFO, "Binding HTTP %s socket %s:%d", lc->upload_port ? "upload" : "status", lc->host, lc->port);
				
				struct evhttp *srvr;
				struct evhttp_bound_socket *handle;
				
				if (lc->upload_port) {
					if (!srvr_upload) {
						srvr_upload = evhttp_new(libbase);
						http_srvr_defaults(srvr_upload);
						evhttp_set_allowed_methods(srvr_upload, EVHTTP_REQ_POST); /* uploads are POSTs, after all */
						evhttp_set_gencb(srvr_upload, http_router, (void *)2);
					}
					srvr = srvr_upload;
				} else {
					if (!srvr_status) {
						srvr_status = evhttp_new(libbase);
						http_srvr_defaults(srvr_status);
						evhttp_set_gencb(srvr_status, http_router, (void *)1);
					}
					srvr = srvr_status;
				}
				
				handle = evhttp_bind_socket_with_handle(srvr, lc->host, lc->port);
				if (!handle) {
					hlog(LOG_ERR, "Failed to bind HTTP socket %s:%d: %s", lc->host, lc->port, strerror(errno));
					// TODO: should exit?
				}
			}
			
			hlog(LOG_INFO, "HTTP thread ready.");
		}
		
		event_base_dispatch(libbase);
	}
	
	hlog(LOG_DEBUG, "HTTP thread shutting down...");
	
	http_server_free();
	
	/* free up the pseudo-client */
	client_free(http_pseudoclient);
	http_pseudoclient = NULL;
	
	/* free up the pseudo-worker structure */
	worker_free_buffers(http_worker);
	hfree(http_worker);
	http_worker = NULL;
}