Exemplo n.º 1
0
static inline int Server_accept(int listen_fd)
{
    int cfd = -1;
    int rport = -1;
    char remote[IPADDR_SIZE];
    int rc = 0;
    Connection *conn = NULL;

    cfd = netaccept(listen_fd, remote, &rport);
    check(cfd >= 0, "Failed to accept on listening socket.");

    Server *srv = Server_queue_latest();
    check(srv != NULL, "Failed to get a server from the configured queue.");

    conn = Connection_create(srv, cfd, rport, remote);
    check(conn != NULL, "Failed to create connection after accept.");

    rc = Connection_accept(conn);
    check(rc == 0, "Failed to register connection, overloaded.");

    return 0;

error:

    if(conn != NULL) Connection_destroy(conn);
    return -1;
}
Exemplo n.º 2
0
int Server_run()
{
    int rc = 0;
    Server *srv = Server_queue_latest();
    check(srv != NULL, "Failed to get a server from the configured queue.");
    int listen_fd = srv->listen_fd;

    taskname("SERVER");

    while(RUNNING) {
        rc = Server_accept(listen_fd);

        if(rc == -1 && RUNNING) {
            log_err("Server accept failed, attempting to clear out dead weight: %d", RUNNING);
            int cleared = Register_cleanout();

            if(cleared == 0) {
                taskdelay(1000);
            }
        }
    }

    return 0;
error:
    return -1;
}
Exemplo n.º 3
0
int connection_route_request(Connection *conn)
{
    Host *host = NULL;
    Route *route = NULL;

    bstring path = Request_path(conn->req);
    check_debug(path != NULL, "No path given, in request, ignoring.");

    Server *server = Server_queue_latest();
    check(server != NULL, "No server in the server queue, tell Zed.");

    if(conn->req->host_name) {
        host = Server_match_backend(server, conn->req->host_name);
    } else {
        host = server->default_host;
    }

    error_unless(host, conn, 404, "Request for a host we don't have registered: %s", bdata(conn->req->host_name));

    Backend *found = Host_match_backend(host, path, &route);
    error_unless(found, conn, 404, "Handler not found: %s", bdata(path));

    Request_set_action(conn->req, found);

    conn->req->target_host = host;
    conn->req->pattern = route->pattern;
    conn->req->prefix = route->prefix;

    return Connection_backend_event(found, conn);

error:
    return CLOSE;
}
Exemplo n.º 4
0
void terminate(int s)
{
    MURDER = s == SIGTERM;

    switch(s)
    {
        case SIGHUP:
            if(!RELOAD) {
                RELOAD = 1;
                if(RELOAD_TASK) {
                    tasksignal(RELOAD_TASK, s);
                }
            }
            break;
        default:
            if(!RUNNING) {
                log_info("SIGINT CAUGHT AGAIN, ASSUMING MURDER.");
                MURDER = 1;
            } else {
                RUNNING = 0;
                log_info("SHUTDOWN REQUESTED: %s", MURDER ? "MURDER" : "GRACEFUL (SIGINT again to EXIT NOW)");
                Server *srv = Server_queue_latest();

                if(srv != NULL) {
                    fdclose(srv->listen_fd);
                }
            }
            break;
    }
}
Exemplo n.º 5
0
void reload_task(void *data)
{
    RELOAD_TASK = taskself();
    struct ServerTask *srv = data;

    while(1) {
        taskswitch();
        task_clear_signal();

        if(RELOAD) {
            log_info("Reload requested, will load %s from %s", bdata(srv->db_file), bdata(srv->server_id));
            Server *old_srv = Server_queue_latest();
            Server *new_srv = reload_server(old_srv, bdata(srv->db_file), bdata(srv->server_id));
            check(new_srv, "Failed to load the new configuration, exiting.");

            // for this to work handlers need to die more gracefully
            Server_queue_push(new_srv);
        } else {
            log_info("Shutdown requested, goodbye.");
            break;
        }
    }

    taskexit(0);
error:
    taskexit(1);
}
Exemplo n.º 6
0
void final_setup()
{
    start_terminator();
    Server_init();
    bstring end_point = bfromcstr("inproc://access_log");
    Server *srv = Server_queue_latest();
    Log_init(bstrcpy(srv->access_log), end_point);
    Control_port_start();
    taskdelay(500);
    log_info("-- " VERSION " Running. Copyright (C) Zed A. Shaw. Licensed BSD.");
}
Exemplo n.º 7
0
void taskmain(int argc, char **argv)
{
    L = luaL_newstate();

    dbg_set_log(stderr);
    int rc = 0;

    check(argc == 3, "usage: mongrel2 config.lua server_name");

    //if(argc == 4) {
    //    log_info("Using configuration module %s to load configs.", argv[3]);
    //    rc = Config_module_load(argv[3]);
    //    check(rc != -1, "Failed to load the config module: %s", argv[3]);
    //}

    Server_queue_init();

    Server *srv = load_server(L, argv[1], argv[2], NULL);
    check(srv != NULL, "Aborting since can't load server.");
    Server_queue_push(srv);

    SuperPoll_get_max_fd();

//    rc = clear_pid_file(srv);
//    check(rc == 0, "PID file failure, aborting rather than trying to start.");

//    rc = attempt_chroot_drop(srv);
//    check(rc == 0, "Major failure in chroot/droppriv, aborting.");

    final_setup();

    taskcreate(tickertask, NULL, TICKER_TASK_STACK);

    struct ServerTask *srv_data = calloc(1, sizeof(struct ServerTask));
    srv_data->db_file = bfromcstr(argv[1]);
    srv_data->server_id = bfromcstr(argv[2]);

//    taskcreate(reload_task, srv_data, RELOAD_TASK_STACK);

    rc = Server_run();
    check(rc != -1, "Server had a failure and exited early.");
    log_info("Server run exited, goodbye.");

    srv = Server_queue_latest();
    complete_shutdown(srv);

    return;

error:
    log_err("Exiting due to error.");
    taskexitall(1);
}