コード例 #1
0
ファイル: main.c プロジェクト: tomohikoseven/http
static void
respond_to
(
    struct HTTPRequest  *req,   /* HTTP request */
    FILE *out,                  /* output fd    */
    char *docroot               /* docroot path */
)
{
    dbg( "req=%p, out=%p, docroot=%p\n", req, out, docroot );

    if     ( strcmp( req->method, "GET"  ) == 0 )
    {
        do_file_response( req, out, docroot );
    }
    else if( strcmp( req->method, "HEAD" ) == 0 )
    {
        do_file_response( req, out, docroot );
    }
    else if( strcmp( req->method, "POST" ) == 0 )
    {
        method_not_allowed( req, out );
    }
    else
    {
        not_implemented( req, out );
    }
}
コード例 #2
0
ファイル: http_server.c プロジェクト: Darthfett/httpServer
int handle_client_connection() {
    char buffer[8096];
    int buffer_len; // Length of buffer

    char method[256];
    char url[256];
    char version[256];

    int i = 0, // Used to iterate over the first line to get method, url, version
        j = 0;

    // Read first line
    buffer_len = read_line(client_sockfd, buffer, sizeof(buffer));

    // Unable to read from socket, not sure what to do in this case
    if (buffer_len <= 0) {
        return -1;
    }

    fprintf(stderr, "==== Read Next Request ====\n");

    // Get Method (e.g. GET, POST, etc)
    while ((i < (sizeof(method) - 1)) && (!isspace(buffer[i]))) {
        method[i] = buffer[i];
        i++;
    }
    method[i] = '\0';

    // fprintf(stderr, "method: %s\n", method);

    // Skip over spaces
    while (i < buffer_len && isspace(buffer[i])) {
        i++;
    }

    // Get URL
    j = 0;
    while (i < buffer_len && (j < (sizeof(url) - 1)) && !isspace(buffer[i])) {
        url[j] = buffer[i];
        i++;
        j++;
    }
    url[j] = '\0';

    // fprintf(stderr, "url: %s\n", url);

    // Skip over spaces
    while (i < buffer_len && isspace(buffer[i])) {
        i++;
    }

    j = 0;
    while (j < sizeof(version) - 1 && !isspace(buffer[i])) {
        version[j] = buffer[i];
        i++;
        j++;
    }
    version[j] = '\0';

    // fprintf(stderr, "version: %s\n", version);

    read_headers();

    if (header_err_flag) {
        keep_alive = FALSE;
        bad_request();
        return -1;
    }

    if (content_length > 0) {
        content = (char*) malloc(content_length + 1);
        read_socket(client_sockfd, content, content_length);
    }

    // fprintf(stderr, "Content-Length: %d\n", content_length);
    // fprintf(stderr, "Connection (keep_alive): %d\n", keep_alive);
    // fprintf(stderr, "Cookie: %d\n", cookie);
    // fprintf(stderr, "If-Modified-Since Valid Time: %d\n", time_is_valid);
    // fprintf(stderr, "If-Modified-Since Time: %p\n", if_modified_since);
    if (content != NULL) {
        // fprintf(stderr, "Content: %s\n", content);
    }

    /***********************************************************/
    /*       Full message has been read, respond to client     */
    /***********************************************************/

    if (strcmp(method, "GET") != 0) {
        // Inform client we don't support method
        fprintf(stderr, "Method Not Allowed: %s\n", method);
        method_not_allowed();    
        return 0;
    }

    if (cookie) {
        // Inform client we don't support cookies
        not_implemented();
        return 0;
    }

    if (not_eng) {
        // Inform client we only support English
        not_implemented();
        return 0;
    }

    if (!acceptable_text) {
        // Inform client we only support plain text
        not_implemented();
        return 0;
    }

    if (!acceptable_charset) {
        // Inform client we only support ASCII
        not_implemented();
        return 0;
    }

    // Fix filename
    char file_path[512];
    sprintf(file_path, "htdocs%s", url);
    if (file_path[strlen(file_path)-1] == '/') {
        file_path[strlen(file_path)-1] = '\0';
    }

    // fprintf(stderr, "%s\n", file_path);

    int fname_valid = is_valid_fname(file_path);

    struct stat file_info;

    if (!fname_valid) {
        // invalid filename
        fprintf(stderr, "403 Forbidden: Invalid file name\n");
        forbidden();
        return 0;
    }

    if (stat(file_path, &file_info)) {
        fprintf(stderr, "404 Not Found: Stat failed\n");
        // Stat failed
        not_found();
        return 1;
    }

    if (!S_ISREG(file_info.st_mode)) {
        // Not a file
        forbidden();
        fprintf(stderr, "403 Forbidden: Not a regular file\n");
        return 0;
    }


    if (!(file_info.st_mode & S_IRUSR)) {
        // No read permissions
        forbidden();
        fprintf(stderr, "403 Forbidden: No read permissions\n");
        return 0;
    }

    FILE *f = fopen(file_path, "r");
    if (f == NULL) {
        // No file
        not_found();
        fprintf(stderr, "404 Not Found: Unable to open file\n");
        return 0;
    }

    if (if_modified_since != NULL) {
        struct tm *last_modified = gmtime(&file_info.st_mtime);

        time_t last = mktime(last_modified);
        time_t since = mktime(if_modified_since);

        double diff = difftime(last, since);
        if (diff <= 0) {
            fprintf(stderr, "304 Not Modified\n");
            not_modified();
            return 0;
        }
    }

    fprintf(stderr, "All looks good, serving up content in %s\n", file_path);

    char *file_contents = NULL;
    int contents_length = 0;
    char line[512];

    while (fgets(line, sizeof(line), f) != NULL) {
        if (file_contents != NULL) {
            char *new_contents = (char*) malloc(contents_length + strlen(line) + 1);
            strcpy(new_contents, file_contents);
            strcpy(new_contents + strlen(new_contents), line);
            contents_length += strlen(line);

            free(file_contents);
            file_contents = new_contents;
        } else {
            file_contents = (char*) malloc(strlen(line) + 1);
            strcpy(file_contents, line);
            contents_length += strlen(line);
        }
    }
    fclose(f);

    // fprintf(stderr, "File Contents:\n");

    // fprintf(stderr, "%s\n", file_contents);

    ok(file_contents);

    return 0;
}