0

Over the last couple of days, I've managed to turn a few of the failed check50 tests green.

The final 2, however, I'm really struggling with. This place has helped me out in similar circumstances before, so I'm hoping that someone can come to the rescue again, and point me in the right direction before I completely lose my sanity.

Here are the two failed checks:

:( Requesting hello.php?name=Alice returns 200, text/html, and correct   output 
\ expected output, but not "X-Powered-By: PHP/5.5.7\r\nContent-type..."  

:( Requesting two files in a row (cat.html then cat.jpg) succeeds  

I thought the first failed test would be something to do with parse, but I checked parse using dbg and it seems to do what it should be doing. So I guess the problem is somewhere else? Anyway, sorry for the lengthy post, but here's my code for each of the four functions.

Lookup:

const char* lookup(const char* path)
{


    // create new string starting from the file extention in path
    int c = '.';
    char* pathExt = strrchr(path, c);

    if (strcasecmp(pathExt,".css") == 0)
    {
        return "text/css";
    }
    else if (strcasecmp(pathExt,".html") == 0)
    {
        return "text/html";
    }
    else if (strcasecmp(pathExt,".gif") == 0)
    {
        return "image/gif";
    }
    else if (strcasecmp(pathExt,".ico") == 0)
    {
        return "image/x-icon";
    }
    else if (strcasecmp(pathExt,".jpg") == 0)
    {
        return "image/jpeg";
    }
    else if (strcasecmp(pathExt,".js") == 0)
    {
        return "text/javascript";
    }
    else if (strcasecmp(pathExt,".php") == 0)
    {
        return "text/x-php";
    }
    else if (strcasecmp(pathExt,".png") == 0)
    {
        return "image/png";
    }
    else
    {
        return NULL;
    }
}

Parse:

bool parse(const char* line, char* abs_path, char* query)
{

    // malloc space on the heap for 3 string variables used in the function
    char* requestTarget = malloc(sizeof(char)*(strlen(line)));
    char* abs_path_temp = malloc(sizeof(char)*(strlen(line)));
    char* query_temp = malloc(sizeof(char)*(strlen(line)));

    // if method is not "GET " return 501 error and false boolean value
    if (strncmp(line, "GET ", 4) != 0)
    {
        error(405);
        return false;
    } 

    // see if request target begins with '/'
    if (line[4] != '/')
    {
        error(501);
        return false;
    }

    // if HTTP version isn't correct return 505 error and false
    if (strstr(line, "HTTP/1.1") == NULL)
    {
        error(505);
        return false;
    }
    else if (strstr(line, "  HTTP/1.1") != NULL)
    {
        error(505);
        return false;
    }



    // find first instance of a forward slash in 'line' and have 'requestTarget' point to it
    requestTarget = strchr(line, '/');

    // iterate through string and swap out the space at the end for a terminating null char
    for (int i = 0, l = strlen(requestTarget); i < l; i++)
    {
        if (requestTarget[i] == ' ')
        {
        requestTarget[i] = '\0';
        }
    }

    // if requestTarget contains " then return 501 error and false boolean value
    if (strchr(requestTarget, '"') != NULL)
    {
        error(400);
        return false;
    }


    // check to see if 'requestTarget' contains a query (by checking for question mark)
    if (strchr(requestTarget, '?') == NULL)
    {
        // set 'query_temp' to null and copy to 'query' then 'requestTarget' to 'abs_path'
        query_temp[0] = '\0';
        strncpy(query, query_temp, strlen(query_temp));
        strncpy(abs_path, requestTarget, strlen(requestTarget));

        free(query_temp);
    }

    else
    {
        // set 'query_temp' to start at the question mark char
        query_temp = strchr(requestTarget, '?');
        strncpy(query, query_temp, strlen(query_temp));

        // copy 'requestTarget' to a temp string and swap out the question mark for terminating null char
        strncpy(abs_path_temp, requestTarget, strlen(requestTarget));

        for (int j = 0, m = strlen(abs_path_temp); j < m; j++)
        {
            if (abs_path_temp[j] == '?')
            {
                abs_path_temp[j] = '\0';
            }
        }

        // set 'abs_path'
        strncpy(abs_path, abs_path_temp, strlen(abs_path_temp));

        free(abs_path_temp);
    }

    return true;
}

Load:

bool load(FILE* file, BYTE** content, size_t* length)
{
    *content = NULL;
    *length = 0;

    // allocate memory for an initial 1 byte
    *content = malloc(sizeof(BYTE));

    // with each successful read, increase length size and reallocate size of buffer to length + 1
    while(fread((*content+*length),sizeof(BYTE), 1 , file))
    {
        *length += 1;
        *content = realloc(*content , *length  + 1);
    }
    return true;
}

Indexes:

char* indexes(const char* path)
{
    char* html = "/index.html";
    char* php = "/index.php";

    // allocate heap memory for a string of length php + path + a terminating null
    char* phpIndex = malloc(strlen(php) + strlen(path) + 1);

    // copy in path and concatenate with php string
    strcpy(phpIndex, path);
    strcat(phpIndex, php);

    // repeat above process for html
    char* htmlIndex = malloc(strlen(html) + strlen(path) + 1);
    strcpy(htmlIndex, path);
    strcat(htmlIndex, html);


    // check accessibility of php file and return phpIndex if it exists
    if(access(phpIndex, F_OK) == 0) 
    {
        return phpIndex;
    }

    // check accessibility of html file and return htmlIndex if it exists
    else if(access(htmlIndex, F_OK) == 0) {
        return htmlIndex;
    }

    return NULL;
}

Any help at all would be hugely appreciated! This has been way more difficult than the previous pset for me and I'd love to just move on to the next one.

1

:( Requesting hello.php?name=Alice returns 200, text/html, and correct output
\ expected output, but not "X-Powered-By: PHP/5.5.7\r\nContent-type..."

Is because of this:

// set 'query_temp' to start at the question mark char
        query_temp = strchr(requestTarget, '?');
        strncpy(query, query_temp, strlen(query_temp));

The comment says it all. query must not include the '?', as defined here
absolute-path [ "?" query ] in the spec.


:( Requesting two files in a row (cat.html then cat.jpg) succeeds

This problem comes here strncpy(abs_path, requestTarget, strlen(requestTarget));. From man strncpy:

The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.

There is never a null-byte among the first strlen bytes of a string.

You could get a visual if you use gdb and send a curl request for hello.html followed by a curl request for cat.html.

1
  • You are officially my favourite person right now. Thanks a lot! Took me about 30 seconds to fix things after reading that. I guess I should read things more carefully in future. But yeah, again, thanks a bunch.
    – tom-p-uk
    Sep 7 '16 at 8:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .