コード例 #1
0
ファイル: server.c プロジェクト: chen19921212/mongrel2
void Server_queue_cleanup()
{
    if(darray_end(SERVER_QUEUE) < SERVER_ACTIVE) {
        // skip it, not enough to care about
        return;
    }

    // pop the last one off to make sure it's never deleted
    Server *cur_srv = darray_pop(SERVER_QUEUE);
    uint32_t too_old = time(NULL) - SERVER_TTL;
    int i = 0;

    // TODO: kind of a dumb way to do this since it reorders the list
    // go through all but the max we want to keep
    for(i = 0; i < darray_end(SERVER_QUEUE) - SERVER_ACTIVE; i++) {
        Server *srv = darray_get(SERVER_QUEUE, i);

        if(srv->created_on < too_old) {
            Server *replace = darray_pop(SERVER_QUEUE);
            darray_set(SERVER_QUEUE, i, replace);

            srv->listen_fd = -1; // don't close it
            Server_destroy(srv);
        }
    }

    // put the sacred server back on the end
    darray_push(SERVER_QUEUE, cur_srv);

    return;
}
コード例 #2
0
ファイル: server.c プロジェクト: chen19921212/mongrel2
static inline int Server_copy_active_handlers(Server *srv, Server *copy_from)
{
    int i = 0;
    for(i = 0; i < darray_end(copy_from->handlers); i++) {
        Handler *from = darray_get(copy_from->handlers, i);

        int j = 0;
        for(j = 0; j < darray_end(srv->handlers); j++) {
            Handler *to = darray_get(srv->handlers, j);

            if(same_handler(from, to))
            {
                debug("Swapping %p original for %p replacement", to, from);
                RouteUpdater update = {.original = to, .replacement = from};
                tst_traverse(srv->hosts->routes, update_host_routes, &update);

                darray_set(srv->handlers, j, from);
                // swap them around so that the darrays stay full
                darray_set(copy_from->handlers, i, to);
                to->running = 0;
                break;
            }
        }
    }

    return 0;
}
コード例 #3
0
ファイル: db.c プロジェクト: 304471720/mongrel2
int DB_valid_schema(tns_value_t *res, int row, int ncols, ...)
{
    va_list argp;
    va_start(argp, ncols);
    int i = 0;

    check(tns_get_type(res) == tns_tag_list, "Invalid result set, must be a list.");
    int rows = darray_end(res->value.list);
    check(rows != -1, "Result isn't in a table format.");
    check(row < rows, "Row is past end of result set: %d > %d", row, rows);

    // get the row they ask for
    tns_value_t *row_data = darray_get(res->value.list, row);

    // make sure it's got the right number of columns
    check(tns_get_type(row_data) == tns_tag_list, "Invalid row %d, must be a list.", row);
    int cols = darray_end(row_data->value.list);
    check(cols == ncols, "Expected %d columns, but result set has %d.", cols, ncols);

    for(i = 0; i < ncols; i++) {
        tns_type_tag expecting = va_arg(argp, tns_type_tag);
        tns_value_t *cell = DB_get(res, row, i);
        check(tns_get_type(cell) == expecting,
                "Row %d, Column %d has wrong type.", row, i);
    }

    va_end(argp);
    return 1;
error:

    va_end(argp);
    return 0;
}
コード例 #4
0
ファイル: darray.c プロジェクト: duaneg/mongrel2
void *darray_pop(darray_t *array)
{
    check(array->end - 1 > 0, "Attempt to pop from empty array.");

    void *el = darray_remove(array, array->end - 1);
    array->end--;

    if(darray_end(array) > (int)array->expand_rate && darray_end(array) % array->expand_rate) {
        darray_contract(array);
    }

    return el;
error:
    return NULL;
}
コード例 #5
0
ファイル: handler.c プロジェクト: ttuna/mongrel2
static inline void handler_process_extended_request(int fd, Connection *conn, bstring payload)
{
    char *x;
    tns_value_t *data = NULL;
    darray_t *l = NULL;
    
    data = tns_parse(bdata(payload),blength(payload),&x);

    check((x-bdata(payload))==blength(payload), "Invalid extended response: extra data after tnetstring.");
    check(data->type==tns_tag_list, "Invalid extended response: not a list.");
    l = data->value.list;
    check(darray_end(l)==2, "Invalid extended response: odd number of elements in list.");
    tns_value_t *key=darray_get(l,0);
    check(key->type==tns_tag_string, "Invalid extended response: key is not a string");
    check(key->value.string != NULL,, "Invalid extended response: key is NULL");

    if(!bstrcmp(key->value.string, &XREQ_CTL)) {
        check (0 == handler_process_control_request(conn, data),
                "Control request processing returned non-zero: %s", bdata(key->value.string));
    } else {
        check (0 == dispatch_extended_request(conn, key->value.string, data),
                "Extended request dispatch returned non-zero: %s",bdata(key->value.string));
    }

    return;
error:
    tns_value_destroy(data);
    Register_disconnect(fd); // return ignored
    return;
}
コード例 #6
0
ファイル: io.c プロジェクト: daogangtang/monserver
static int simple_set_session( ssl_context *ssl )
{
    time_t t = THE_CURRENT_TIME_IS;
    int i = 0;
    ssl_session *cur = NULL;
    int make_new = 1;
    check(setup_ssl_session_cache() == 0, "Failed to initialize SSL session cache.");

    for(i = 0; i < darray_end(SSL_SESSION_CACHE); i++) {
        cur = darray_get(SSL_SESSION_CACHE, i);

        if( ssl->timeout != 0 && t - cur->start > ssl->timeout ) {
            make_new = 0;
            break; /* expired, reuse this slot */
        }

        if( memcmp( ssl->session->id, cur->id, cur->length ) == 0 ) {
            make_new = 0;
            break; /* client reconnected */
        }
    }

    if(make_new) {
        cur = (ssl_session *) darray_new(SSL_SESSION_CACHE);
        check_mem(cur);
        darray_push(SSL_SESSION_CACHE, cur);
    }

    *cur = *ssl->session;

    return 0;
error:
    return 1;
}
コード例 #7
0
ファイル: io.c プロジェクト: daogangtang/monserver
static int simple_get_session( ssl_context *ssl )
{
    time_t t = THE_CURRENT_TIME_IS;
    int i = 0;

    check(setup_ssl_session_cache() == 0, "Failed to initialize SSL session cache.");

    if( ssl->resume == 0 ) return 1;
    ssl_session *cur = NULL;

    for(i = 0; i < darray_end(SSL_SESSION_CACHE); i++) {
        cur = darray_get(SSL_SESSION_CACHE, i);

        if( ssl->timeout != 0 && t - cur->start > ssl->timeout ) {
            continue;
        }

        if( ssl->session->ciphersuite != cur->ciphersuite ||
            ssl->session->length != cur->length ) 
        {
            continue;
        }

        if( memcmp( ssl->session->id, cur->id, cur->length ) != 0 ) {
            continue;
        }

        // TODO: odd, why 48? this is from polarssl
        memcpy( ssl->session->master, cur->master, 48 );
        return 0;
    }

error: // fallthrough
    return 1;
}
コード例 #8
0
ファイル: server.c プロジェクト: chen19921212/mongrel2
int Server_start_handlers(Server *srv, Server *copy_from)
{
    int i = 0;
    int rc = 0;

    if(copy_from != NULL) {
        rc = Server_copy_active_handlers(srv, copy_from);
        check(rc != -1, "Failed to copy old handlers to new server config.");
    }

    for(i = 0; i < darray_end(srv->handlers); i++) {
        Handler *handler = darray_get(srv->handlers, i);
        check(handler != NULL, "Invalid handler, can't be NULL.");

        if(!handler->running) {
            log_info("LOADING Handler %s", bdata(handler->send_spec));
            rc = taskcreate(Handler_task, handler, HANDLER_STACK);
            check(rc != -1, "Failed to start handler task.");
            handler->running = 1;
        }
    }

    return 0;
error:
    return -1;
}
コード例 #9
0
ファイル: server.c プロジェクト: chen19921212/mongrel2
int Server_stop_handlers(Server *srv)
{
    int i = 0;
    for(i = 0; i < darray_end(srv->handlers); i++) {
        Handler *handler = darray_get(srv->handlers, i);
        check(handler != NULL, "Invalid handler, can't be NULL.");

        if(handler->running) {
            log_info("STOPPING HANDLER %s", bdata(handler->send_spec));
            if(handler->task != NULL) {
                tasksignal(handler->task, SIGINT);
                handler->running = 0;
                taskdelay(1);
            }
        }

        if(handler->recv_socket) zmq_close(handler->recv_socket);
        if(handler->send_socket) zmq_close(handler->send_socket);
        handler->recv_socket = NULL;
        handler->send_socket = NULL;
    }

    return 0;
error:
    return -1;
}
コード例 #10
0
ファイル: db.c プロジェクト: 304471720/mongrel2
/**
 * Gets the tns_value_t at this result's row/col point,
 * or NULL (which will be tns_get_type == tns_tag_invalid)
 * if that row isn't possible.
 */
tns_value_t *DB_get(tns_value_t *res, int row, int col)
{
    check(tns_get_type(res) == tns_tag_list, "Result should be a list.");
    check(row < darray_end(res->value.list),
            "Row %d past end of result set length: %d", row, 
            darray_end(res->value.list));

    tns_value_t *r = darray_get(res->value.list, row);
    check(tns_get_type(r) == tns_tag_list, "Row %d should be a list.", row);
    check(col < darray_end(r->value.list),
            "Column %d past end of result set length: %d", col, 
            darray_end(r->value.list));

    return darray_get(r->value.list, col);
error:
    return NULL;
}
コード例 #11
0
ファイル: access.c プロジェクト: 304471720/mongrel2
int Command_access_logs(Command *cmd)
{
    bstring log_filename = option(cmd, "log", "logs/access.log");
    check(log_filename, "Invalid log file given.");

    FILE *log_file = fopen(bdata(log_filename), "r");
    check(log_file != NULL, "Failed to open log file: %s", bdata(log_filename));

    int line_number = 0;
    bstring line;

    while ((line = bgets((bNgetc) fgetc, log_file, '\n')) != NULL) {
        line_number++;

        tns_value_t *log_item = tns_parse(bdata(line), blength(line), NULL);

        if (log_item == NULL ||
                tns_get_type(log_item) != tns_tag_list || 
                darray_end(log_item->value.list) < 9
                )
        {
            log_warn("Malformed log line: %d.", line_number);
            continue;
        }

        darray_t *entries = log_item->value.list;

        bstring hostname = darray_get_as(entries, 0, string);
        bstring remote_addr = darray_get_as(entries, 1, string);
        long remote_port = darray_get_as(entries, 2, number);
        long timestamp = darray_get_as(entries, 3, number);
        bstring request_method = darray_get_as(entries, 4, string);
        bstring request_path = darray_get_as(entries, 5, string);
        bstring version = darray_get_as(entries, 6, string);
        long status = darray_get_as(entries, 7, number);
        long size = darray_get_as(entries, 8, number);

        printf("[%ld] %s:%ld %s \"%s %s %s\" %ld %ld\n",
               timestamp,
               bdata(remote_addr),
               remote_port,
               bdata(hostname),
               bdata(request_method),
               bdata(request_path),
               bdata(version),
               status,
               size);

        tns_value_destroy(log_item);
    }

    return 0;

error:
    return -1;
}
コード例 #12
0
ファイル: server.c プロジェクト: chen19921212/mongrel2
static inline void Server_destroy_handlers(Server *srv)
{
    int i = 0;
    for(i = 0; i < darray_end(srv->handlers); i++) {
        Handler *handler = darray_get(srv->handlers, i);
        Handler_destroy(handler);
    }

    darray_destroy(srv->handlers);
}
コード例 #13
0
ファイル: darray.c プロジェクト: duaneg/mongrel2
int darray_push(darray_t *array, void *el)
{
    array->contents[array->end] = el;
    array->end++;

    if(darray_end(array) >= darray_max(array)) {
        return darray_expand(array);
    } else {
        return 0;
    }
}
コード例 #14
0
ファイル: hashmap.c プロジェクト: rumblesan/bclib
static inline int hashmap_get_node(Hashmap *map, uint32_t hash, DArray *bucket, void *key) {
    int i = 0;
    for (i = 0; i < darray_end(bucket); i += 1) {
        debug("TRY: %d", i);
        HashmapNode *node = darray_get(bucket, i);
        if (node->hash == hash && map->compare(node->key, key) == 0) {
            return i;
        }
    }

    return -1;
}
コード例 #15
0
ファイル: db.c プロジェクト: 304471720/mongrel2
/**
 * Used to iterate through a result set using rows by columns.
 * It returns the number of rows, or -1 if this result set isn't
 * valid (like it's not a table form).  It sets the *cols as an
 * out parameter for the number of cols that each row should have.
 */
int DB_counts(tns_value_t *res, int *cols)
{
    int rows = 0;

    if(tns_get_type(res) == tns_tag_null) {
        *cols = 0;
    } else {
        check(tns_get_type(res) == tns_tag_list, "Result should get a list.");
        rows = darray_end(res->value.list);

        if(rows) {
            tns_value_t *first_row = darray_get(res->value.list, 0);
            check(tns_get_type(first_row) == tns_tag_list,
                    "Wrong column type, should be list.");
            *cols = darray_end(first_row->value.list);
        } else {
            *cols = 0;
        }
    }

    return rows;
error:
    return -1;
}
コード例 #16
0
ファイル: server.c プロジェクト: chen19921212/mongrel2
int Server_queue_destroy()
{
    int i = 0;
    Server *srv = NULL;

    for(i = 0; i < darray_end(SERVER_QUEUE); i++) {
        srv = darray_get(SERVER_QUEUE, i);
        check(srv != NULL, "Got a NULL value from the server queue.");
        Server_destroy(srv);
    }

    darray_destroy(SERVER_QUEUE);

    return 0;
error:
    return -1;
}
コード例 #17
0
ファイル: filter.c プロジェクト: 304471720/mongrel2
int Filter_run(StateEvent next, Connection *conn)
{
    int i = 0;
    StateEvent res = next;
    check(REGISTERED_FILTERS != NULL, "No filters loaded yet, don't call this.");

    darray_t *filters = Filter_lookup(next);

    if(filters != NULL) {
        for(i = 0; i < darray_end(filters) && res == next; i++) {
            Filter *filter = darray_get(filters, i);
            check(filter != NULL, "Expected to get a filter record but got NULL.");

            res = filter->cb(next, conn, filter->config);
            check(res >= CLOSE && res < EVENT_END,
                    "Filter %s returned invalid event: %d", bdata(filter->load_path), res);
        }
    }

    return res;

error:
    return -1;
}