Esempio n. 1
0
void *request_handler(void *ptr) {
    #ifdef DEBUG
    printf("enter request_handler\n");
    #endif

    int client_fd = ((Thread_Input*)ptr)->client_fd; 
    Request request;
    Response response;
    parse_request_header(client_fd, &request);
    modify_request_header(&request);
    
    if (check_cache(&request, &response)) {
        send_client(client_fd, &response);
    } else {
        if (forward_request(client_fd, &request, &response) < 0) {
            Close(client_fd);
            return NULL;
        } else {
            if (response.content_size <= MAX_OBJECT_SIZE)
                save_to_cache(&request, &response);
        }
    }
    free(ptr);
    Close(client_fd);
    #ifdef DEBUG
    printf("connection close\n\n");
    printf("leave request_handler\n");
    #endif
    return NULL; 
}
Esempio n. 2
0
File: kweb.c Progetto: klueska/kweb
static int extract_request(struct http_connection *c,
                           struct http_request *r)
{
    int ret = 0;
    while(1) {
        /* Parse a request header from the connection buf. */
        parse_request_header(r, c->buf, c->buf_length);

        /* If we found one, extract the rest of the request based on the length,
         * and return to process it. */
        int len = r->length;
        if(len > 0) {
            /* Prepare r->buf to receive the extracted request. */
            if (len > sizeof(r->static_buf))
                r->buf = malloc(len);

            /* If the length is <= the size of the connection buffer, we can just
             * copy it out into the request buffer, and we are done. */
            if (len <= c->buf_length) {
                memcpy(r->buf, c->buf, len);
                c->buf_length = c->buf_length - len;
                memmove(c->buf, &c->buf[len], c->buf_length);
                /* Otherwise, we need to read in the rest of the request from the wire. */
            } else {
                memcpy(r->buf, c->buf, c->buf_length);
                len -= c->buf_length;
                c->buf_length = 0;
                while (len) {
                    ret = timed_read(c, &r->buf[r->length - len], len);
                    len -= ret;
                    if(ret <= 0)
                        return ret;
                }
                return r->length;
            }

            /* Honor some non-persistent clients */
            if (strstr(r->buf, "Connection: close"))
                c->should_close = 1;

            return len;
        }

        /* Otherwise, try and read in the next request from the socket */
        ret = timed_read(c, &c->buf[c->buf_length], sizeof(c->buf) - c->buf_length);

        /* If the return code is invalid or marks the end of a connection, just
         * return it. */
        if(ret <= 0)
            return ret;

        /* Otherwise, update the buf_length and loop back around to try and
         * extract the request again. */
        c->buf_length += ret;
    }
}
Esempio n. 3
0
/** @brief Handles HTTP GET requests.
 *  Reads and parses the request, the uri, and dispatches the appropriate
 *  functions to serve content.
 *  @param conn_fd The connection file descriptor.
 *  @return none.
 */
void handle_request(int conn_fd)
{
	rio_t rio;
	char request[MAXLINE], uri[MAXLINE];
	char file_name[MAXLINE], cgi_args[MAXLINE];
	int is_static;
	struct stat st_buf;

	Rio_readinitb(&rio, conn_fd);

	/* Read first header line of incoming request. */
	if (rio_readlineb(&rio, request, MAXLINE) < 0) {
		dbg_printf("rio_readlineb error\n");
		return;
	}
	dbg_printf("Request: %s", request);

	if (parse_request_header(conn_fd, request, uri) != SUCCESS) {
		return;
	}

	if (read_request_headers(&rio) != SUCCESS) {
		return;
	}

	find_file(uri, file_name, cgi_args, &is_static);

	if (stat(file_name, &st_buf) < 0) {
		dbg_printf("404: File not found: %s\n", file_name);
		send_error_msg(conn_fd, "404", "File not found");
		return;
	}

	/* Handle static content */
	if (is_static) {
		if (!(S_ISREG(st_buf.st_mode)) || !(S_IRUSR & st_buf.st_mode)) {
			dbg_printf("403: Can't read the file: %s\n", file_name);
			send_error_msg(conn_fd, "403", "Can't read the file.");
			return;
		}
		serve_static(conn_fd, file_name, st_buf.st_size);
	}
	/* Handle dynamic content */
	else {
		if (!(S_ISREG(st_buf.st_mode)) || !(S_IXUSR & st_buf.st_mode)) {
			dbg_printf("403: Can't run the CGI program: %s\n", file_name);
			send_error_msg(conn_fd, "403", "Can't run the CGI program.");
	 		return;
		}
		serve_dynamic(conn_fd, file_name, cgi_args);
	}
}
Esempio n. 4
0
/* 
 * request_handler - general function to handler each client request 
 */
void *request_handler(int client_fd) {
    #ifdef DEBUG
    printf("enter request_handler\n");
    #endif

    Request request;
    Response response;
    parse_request_header(client_fd, &request);
    modify_request_header(&request);
    
    if (check_cache(&request, &response)) {
        #ifdef DEBUG
        printf("in cache ! \n");
        #endif
        send_client(client_fd, &response);
    } else {
        #ifdef DEBUG
        printf("not in cache !\n");
        #endif
        if (forward_request(client_fd, &request, &response) < 0) {
            close(client_fd);
            return NULL;
        } else {
            /* save to cache if status code 2XX and < max size */
            if (response.content_size <= MAX_OBJECT_SIZE &&
                    response.header[state_ofs] == '2')
                save_to_cache(&request, &response);
        }
    }

    close(client_fd);
    #ifdef DEBUG
    printf("connection close\n");
    printf("leave request_handler\n");
    #endif
    return NULL; 
}