Exemple #1
0
} END_TEST

/* TODO: find two headers with coliding hash and test it */
START_TEST(test_http_headers)
{
    http_hdr_table *t;

    t = http_headers_init();

    fail_if(http_header_parse(t, "") == 0);
    fail_if(http_header_parse(t, "field") == 0);
    fail_if(http_header_parse(t, "field\r\n") == 0);
    fail_if(http_header_parse(t, "field:") == 0);
    fail_if(http_header_parse(t, "field:\r\n") == 0);
    fail_if(http_header_parse(t, "field:value") == 0);
    fail_if(http_header_parse(t, ":value") == 0);
    fail_if(http_header_parse(t, ":value\r\n") == 0);

    fail_unless(http_header_parse(t, "Host: dsl.sk\r\n") == 0);
    assert_str(http_header_get(t, "Host"), "dsl.sk");
    assert_str(http_header_get(t, "host"), "dsl.sk");
    assert_str(http_header_get(t, "HOST"), "dsl.sk");

    http_headers_destroy(t);
} END_TEST
Exemple #2
0
int http_server_init(struct http_server *server) {
    /*
     * one time global initializers
     */
    if (0 > mime_types_init())
        return LOGGER_ERROR("failed to initialize mime types"), -1;
    if (0 > http_headers_init())
        return LOGGER_ERROR("failed to initialize http headers"), -1;
    /*
     * idle connection handler
     */
    server->idle_ctx = ribs_context_create(SMALL_STACK_SIZE, http_server_idle_handler);
    server->idle_ctx->data.ptr = server;
    /*
     * context pool
     */
    if (0 == server->stack_size || 0 == server->num_stacks) {
        struct rlimit rlim;
        if (0 > getrlimit(RLIMIT_STACK, &rlim))
            return LOGGER_PERROR("getrlimit(RLIMIT_STACK)"), -1;

        long total_mem = sysconf(_SC_PHYS_PAGES);
        if (total_mem < 0)
            return LOGGER_PERROR("sysconf"), -1;
        total_mem *= getpagesize();
        size_t num_ctx_in_one_map = total_mem / rlim.rlim_cur;
        /* half of total mem to start with so we don't need to enable overcommit */
        num_ctx_in_one_map >>= 1;
        LOGGER_INFO("http server pool: initial=%zu, grow=%zu", num_ctx_in_one_map, num_ctx_in_one_map);
        ctx_pool_init(&server->ctx_pool, num_ctx_in_one_map, num_ctx_in_one_map, rlim.rlim_cur, sizeof(struct http_server_context) + server->context_size);
    } else {
Exemple #3
0
int http_server_init(struct http_server *server) {
    /*
     * one time global initializers
     */
    if (0 > mime_types_init())
        return LOGGER_ERROR("failed to initialize mime types"), -1;
    if (0 > http_headers_init())
        return LOGGER_ERROR("failed to initialize http headers"), -1;
    /*
     * idle connection handler
     */
    server->idle_ctx = ribs_context_create(SMALL_STACK_SIZE, sizeof(struct http_server *), http_server_idle_handler);
    struct http_server **server_ref = (struct http_server **)server->idle_ctx->reserved;
    *server_ref = server;
    /*
     * context pool
     */
    if (0 == server->num_stacks)
        server->num_stacks = DEFAULT_NUM_STACKS;
    if (0 == server->stack_size) {
        struct rlimit rlim;
        if (0 > getrlimit(RLIMIT_STACK, &rlim))
            return LOGGER_PERROR("getrlimit(RLIMIT_STACK)"), -1;
        server->stack_size = rlim.rlim_cur;
    }
    LOGGER_INFO("http server pool: initial=%zu, grow=%zu, stack_size=%zu", server->num_stacks, server->num_stacks, server->stack_size);
    ctx_pool_init(&server->ctx_pool, server->num_stacks, server->num_stacks, server->stack_size, sizeof(struct http_server_context) + server->context_size);
    /*
     * listen socket
     */
    const int LISTEN_BACKLOG = 32768;
    LOGGER_INFO("listening on port: %d, backlog: %d", server->port, LISTEN_BACKLOG);
    int lfd = socket(PF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
    if (0 > lfd)
        return -1;

    int rc;
    const int option = 1;
    rc = setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
    if (0 > rc)
        return LOGGER_PERROR("setsockopt, SO_REUSEADDR"), rc;

    rc = setsockopt(lfd, IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option));
    if (0 > rc)
        return LOGGER_PERROR("setsockopt, TCP_NODELAY"), rc;

    struct linger ls;
    ls.l_onoff = 0;
    ls.l_linger = 0;
    rc = setsockopt(lfd, SOL_SOCKET, SO_LINGER, (void *)&ls, sizeof(ls));
    if (0 > rc)
        return LOGGER_PERROR("setsockopt, SO_LINGER"), rc;

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(struct sockaddr_in));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(server->port);
    addr.sin_addr.s_addr = INADDR_ANY;
    if (0 > bind(lfd, (struct sockaddr *)&addr, sizeof(addr)))
        return LOGGER_PERROR("bind"), -1;

    if (0 > listen(lfd, LISTEN_BACKLOG))
        return LOGGER_PERROR("listen"), -1;

    server->accept_ctx = ribs_context_create(ACCEPTOR_STACK_SIZE, sizeof(struct http_server *), http_server_accept_connections);
    server->fd = lfd;
    server_ref = (struct http_server **)server->accept_ctx->reserved;
    *server_ref = server;

    if (server->max_req_size == 0)
        server->max_req_size = DEFAULT_MAX_REQ_SIZE;
    return 0;
}