Ejemplo n.º 1
0
void send_error_response(pConnInfo conn_info) {/*{{{*/
    int status_code = conn_info->status_code;
    bool with_page;
    int return_page_status[4] = {404, 502, 500, 403};
    if(in_int_array(return_page_status, status_code, 4) != -1) {
        with_page = true;
    } else {
        with_page = false;
    }
    char** error_pages = conn_info->running_server->error_page;
    int i;
    char *error_path = NULL;
    char *error_file_path;
    conn_info->status_code = status_code;
    while(*error_pages != NULL) {
        for(i = 0; i < strlen(*error_pages); i++) {
            if((*error_pages)[i] == '=') {
                (*error_pages)[i] = '\0';
                if(atoi(*error_pages) == status_code) {
                    error_path = uws_strdup(*error_pages + i + 1);
                    (*error_pages)[i] = '=';
                    break;
                }
                (*error_pages)[i] = '=';
            }
        }
        if(error_path != NULL) break;
        error_pages++;
    }
    int content_len;
    char *content;
    if(with_page) {
        error_file_path  = uws_strdup("/dev/null"); //just for test
        if(error_path != NULL) {
            char *tmp_path = strlcat(conn_info->running_server->root, error_path);
            if(access(tmp_path, F_OK) == 0) {
                uws_free(error_file_path);
                error_file_path = tmp_path;
                uws_free(error_path);
            } else {
                uws_free(tmp_path);
            }
        }
        FILE* file = fopen(error_file_path, "r");
        fseek(file, 0, SEEK_END);
        content_len = ftell(file);
        rewind(file);
        content = (char*) uws_malloc (content_len * sizeof(char));

        size_t read_size = fread(content, sizeof(char), content_len, file);
        fclose(file);
    } else {
        content_len = 0;
        content = uws_strdup("");
    }

    //go here
    char *time_string = get_time_string(NULL);

    conn_info->response_header->http_ver = "HTTP/1.1";
    conn_info->response_header->status_code = status_code;
    conn_info->response_header->status = get_by_code(status_code);
    add_header_param("Cache-Control", "private", conn_info->response_header);
    add_header_param("Connection", "Keep-Alive", conn_info->response_header);
    add_header_param("Server", UWS_SERVER, conn_info->response_header);
    add_header_param("Date", time_string, conn_info->response_header);
    add_header_param("Content-Type", "text/html", conn_info->response_header);


    if(with_page) {
        char *content_len_str = itoa(content_len);
        add_header_param("Content-Length", content_len_str, conn_info->response_header);
        uws_free(content_len_str);
    }


    struct response header_body;

    header_body.header = conn_info->response_header;
    header_body.content = content;
    header_body.content_len = content_len;

    uws_free(time_string);
    write_response(conn_info, &header_body);
    free_header_params(header_body.header);
    //uws_free(header_body.header); don't free this!!
    uws_free(header_body.content);
    //longjmp(conn_info->error_jmp_buf, 1);
}/*}}}*/
Ejemplo n.º 2
0
/**
 * Sets up a non-blocking socket
 */
static int socket_setup(struct server *s, struct server_cfg **servers) {
    int servers_num = 0;
    int i = 0;
    int ports_num = 0;

    // stat server conf num
    while (servers[servers_num++] != NULL);
    servers_num--;

    // stat distinct listen port num
    int *servers_port = (int *)malloc(sizeof(int) * servers_num);
    for(i = 0; i < servers_num; i++) {
        int listen_port = servers[i]->listen;
        if(in_int_array(servers_port, listen_port, ports_num) == -1) {
            servers_port[ports_num++] = listen_port;
        }
    }

    for(i = 0; i < ports_num; i++) {
        int reuse = 1;
        struct sockaddr_in addr;
        int fd, ret;

        memset(&addr, 0, sizeof(addr));

#if defined __BSD__
        addr.sin_len = sizeof(struct sockaddr_in);
#endif
        addr.sin_family = AF_INET;
        addr.sin_port = htons(servers_port[i]);
        addr.sin_addr.s_addr = INADDR_ANY;

        /* create socket */
        fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (-1 == fd) {
            slog(s, LOG_ERROR, strerror(errno), 0);
            free(servers_port);
            return -1;
        }

        /* reuse address if we've bound to it before. */
        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
            slog(s, LOG_ERROR, strerror(errno), 0);
            free(servers_port);
            return -1;
        }

        /* set socket as non-blocking. */
        ret = fcntl(fd, F_SETFD, O_NONBLOCK);
        if (0 != ret) {
            slog(s, LOG_ERROR, strerror(errno), 0);
            free(servers_port);
            return -1;
        }

        /* bind */
        ret = bind(fd, (struct sockaddr*) &addr, sizeof(addr));
        if (0 != ret) {
            slog(s, LOG_ERROR, "bind", 4);
            slog(s, LOG_ERROR, strerror(errno), 0);
            free(servers_port);
            return -1;
        }

        /* listen */
        ret = listen(fd, SOMAXCONN);
        if (0 != ret) {
            slog(s, LOG_ERROR, strerror(errno), 0);
            free(servers_port);
            return -1;
        }

        /* set keepalive socket option to do with half connection */
        int keep_alive = 1;
        setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *) &keep_alive, sizeof(keep_alive));

        /* start http server */
        struct event *ev = event_new(s->base, fd, EV_READ | EV_PERSIST, server_can_accept, (void*) s);
        ret = event_add(ev, NULL);

        if (ret < 0) {
            slog(s, LOG_ERROR, "Error calling event_add on socket", 0);
            free(servers_port);
            return -1;
        }
    }
    free(servers_port);

    return 0;
}