Пример #1
0
/**
 * The listener thread main function. The listener listens for
 * connections from clients.
 */
static void *listener_main(void *arg_p)
{
    struct http_server_t *self_p = arg_p;
    struct http_server_listener_t *listener_p;
    struct http_server_connection_t *connection_p;
    struct inet_addr_t addr;

    thrd_set_name(self_p->listener_p->thrd.name_p);

    listener_p = self_p->listener_p;

    if (socket_open_tcp(&listener_p->socket) != 0) {
        log_object_print(NULL,
                         LOG_ERROR,
                         FSTR("Failed to open socket."));
        return (NULL);
    }

    if (inet_aton(listener_p->address_p, &addr.ip) != 0) {
        return (NULL);
    }

    addr.port = listener_p->port;

    if (socket_bind(&listener_p->socket, &addr) != 0) {
        log_object_print(NULL,
                         LOG_ERROR,
                         FSTR("Failed to bind socket."));
        return (NULL);

    }

    if (socket_listen(&listener_p->socket, 3) != 0) {
        log_object_print(NULL,
                         LOG_ERROR,
                         FSTR("Failed to listen on socket."));
        return (NULL);

    }

    /* Wait for clients to connect. */
    while (1) {
        /* Allocate a connection. */
        connection_p = allocate_connection(self_p);

        /* Wait for a client to connect. */
        socket_accept(&listener_p->socket,
                      &connection_p->socket,
                      &addr);

        handle_accept(self_p, connection_p);
    }

    return (NULL);
}
Пример #2
0
static int read_initial_request_line(struct socket_t *socket_p,
                                     char *buf_p,
                                     struct http_server_request_t *request_p)
{
    char *action_p = NULL;
    char *path_p = NULL;
    char *proto_p = NULL;

    *buf_p++ = '\0';
    action_p = buf_p;

    while (1) {
        if (socket_read(socket_p,
                        buf_p,
                        sizeof(*buf_p)) != sizeof(*buf_p)) {
            return (-EIO);
        }

        buf_p++;

        /* The line ending is "\r\n". */
        if ((buf_p[-2] == '\r') && (buf_p[-1] == '\n')) {
            buf_p[-2] = '\0';
            break;
        }

        /* Action and path has ' ' as terminator. */
        if (buf_p[-1] == ' ') {
            buf_p[-1] = '\0';

            if (path_p == NULL) {
                path_p = buf_p;
            } else if (proto_p == NULL) {
                proto_p = buf_p;
            }
        }
    }

    /* A path is required. */
    if (path_p == NULL) {
        return (-1);
    }

    log_object_print(NULL,
                     LOG_DEBUG,
                     FSTR("%s %s %s\r\n"), action_p, path_p, proto_p);

    /* Save the action and path in the request struct. */
    strcpy(request_p->path, path_p);

    if (strcmp(action_p, "GET") == 0) {
        request_p->action = http_server_request_action_get_t;
    } else if (strcmp(action_p, "POST") == 0) {
        request_p->action = http_server_request_action_post_t;
    } else {
        return (-1);
    }

    return (0);
}
Пример #3
0
/**
 * The connection thread serves a client for the duration of the
 * socket lifetime.
 */
static void *connection_main(void *arg_p)
{
    struct http_server_connection_t *connection_p = arg_p;
    struct http_server_t *self_p = connection_p->self_p;
    uint32_t mask;

    /* thrd_init_env(buf, sizeof(buf)); */
    /* thrd_set_env("CWD", self_p->root_path_p); */
    thrd_set_name(connection_p->thrd.name_p);

    /* Wait for a connection from the listener. */
    while (1) {
        log_object_print(NULL,
                         LOG_DEBUG,
                         FSTR("Connection thread '%s' waiting for a new connection.\r\n"),
                         thrd_get_name());

        mask = 0x1;
        event_read(&connection_p->events, &mask, sizeof(mask));

        if (mask & 0x1) {
            handle_request(self_p, connection_p);
            socket_close(&connection_p->socket);

            /* Add thread to the free list. */
            sys_lock();
            connection_p->state = http_server_connection_state_free_t;
            sys_unlock();
            mask = 0x1;
            event_write(&self_p->events, &mask, sizeof(mask));
        }
    }

    return (NULL);
}
Пример #4
0
static int read_request(struct http_server_t *self_p,
                        struct http_server_connection_t *connection_p,
                        struct http_server_request_t *request_p)
{
    int res;
    char buf[128];
    char *header_p;
    char *value_p;

    /* Read the intial line in the request. */
    if (read_initial_request_line(&connection_p->socket,
                                  buf,
                                  request_p) != 0) {
        return (-EIO);
    }

    memset(&request_p->headers, 0, sizeof(request_p->headers));

    /* Read the header lines. */
    while (1) {
        res = read_header_line(&connection_p->socket,
                               buf,
                               &header_p,
                               &value_p);

        if (res == 1) {
            break;
        } else if (res < 0) {
            return (-EIO);
        }

        log_object_print(NULL, LOG_DEBUG, FSTR("%s: %s\r\n"), header_p, value_p);

        /* Save the header field in the request object. */
        if (strcmp(header_p, "Sec-WebSocket-Key") == 0) {
            request_p->headers.sec_websocket_key.present = 1;
            strncpy(request_p->headers.sec_websocket_key.value,
                    value_p,
                    sizeof(request_p->headers.sec_websocket_key.value));
        } else if (strcmp(header_p, "Content-Type") == 0) {
            request_p->headers.content_type.present = 1;
            strncpy(request_p->headers.content_type.value,
                    value_p,
                    sizeof(request_p->headers.content_type.value));
        } else if (strcmp(header_p, "Content-Length") == 0) {
            if (std_strtol(value_p, &request_p->headers.content_length.value) != NULL) {
                request_p->headers.content_length.present = 1;
            }
        } else if (strcmp(header_p, "Authorization") == 0) {
            request_p->headers.authorization.present = 1;
            strncpy(request_p->headers.authorization.value,
                    value_p,
                    sizeof(request_p->headers.authorization.value));
        }
    }

    return (0);
}
Пример #5
0
Файл: main.c Проект: wuwx/simba
int test_print(struct harness_t *harness_p)
{
    struct log_object_t foo;
    struct log_object_t bar;

    /* Initialize the log objects. */
    BTASSERT(log_object_init(&foo,
                             "foo",
                             LOG_UPTO(INFO)) == 0);
    BTASSERT(log_object_init(&bar,
                             "bar",
                             LOG_UPTO(DEBUG)) == 0);

    /* Write on INFO level. */
    BTASSERT(log_object_print(&foo, LOG_INFO, FSTR("x = %d\r\n"), 1) == 1);
    BTASSERT(log_object_print(&bar, LOG_INFO, FSTR("y = %d\r\n"), 2) == 1);

    /* Write on DEBUG level. */
    BTASSERT(log_object_print(&foo, LOG_DEBUG, FSTR("m = %d\r\n"), 3) == 0);
    BTASSERT(log_object_print(&bar, LOG_DEBUG, FSTR("n = %d\r\n"), 4) == 1);

    /* Write using the thread log mask instead of the log object
       mask. */
    BTASSERT(log_object_print(NULL, LOG_DEBUG, FSTR("k = %d\r\n"), 5) == 0);
    BTASSERT(log_object_print(NULL, LOG_ERROR, FSTR("l = %d\r\n"), 6) == 1);

    return (0);
}
Пример #6
0
Файл: main.c Проект: wuwx/simba
int test_handler(struct harness_t *harness_p)
{
    struct log_object_t foo;
    struct log_handler_t handler;

    /* Initialize the log objects. */
    BTASSERT(log_object_init(&foo,
                             "foo",
                             LOG_UPTO(INFO)) == 0);
    BTASSERT(log_handler_init(&handler, sys_get_stdout()) == 0);

    /* This should be printed once for the default handler. */
    BTASSERT(log_object_print(&foo,
                              LOG_INFO,
                              FSTR("one handler\r\n")) == 1);

    /* Add our handler. */
    BTASSERT(log_add_handler(&handler) == 0);

    /* This should be printed twice, one for the default handler and
       once for our handler. */
    BTASSERT(log_object_print(&foo,
                              LOG_INFO,
                              FSTR("two handlers\r\n")) == 2);

    /* Remove our handler. */
    BTASSERT(log_remove_handler(&handler) == 0);
    BTASSERT(log_remove_handler(&handler) == 1);

    /* This should be printed once for the default handler. */
    BTASSERT(log_object_print(&foo,
                              LOG_INFO,
                              FSTR("one handler again\r\n")) == 1);

    return (0);
}
Пример #7
0
int music_player_set_bits_per_sample(struct music_player_t *self_p,
                                     int value)
{
    uint16_t mask;

    value = (12 - value);
    mask = ~((1 << value) - 1);

    self_p->down_sampling_mask = (((uint32_t)mask << 16) | mask);

    log_object_print(NULL,
                     LOG_INFO,
                     FSTR("down_sampling_mask = 0x%lx\r\n"),
                     self_p->down_sampling_mask);

    return (0);
}