0

I've been stuck for a few days. My implementation passed check50 server1 except for the non-existant file test, but it failed all check50 server2 test. I am guessing it is due to the load function. But I've check for many times and couldn't figure out what went wrong. Please can anyone point out a direction for me. Many thanks in advance!

:( Requesting non-existant file returns error code 404 \ expected output, but not "HTTP/1.1 501 Not Implemented\r\nContent..."

The following are my implementation of the functions:

load

int i = 0;

char* buffer = malloc(BYTES);
if (buffer == NULL)
{
    printf("Memory allocation error!\n");
    return false;
}

for (int c = fgetc(file); c != EOF; c = fgetc(file))
{
    buffer[i] = (char) c;
    i++;

    if (i % BYTES == 0)
    {
        buffer = (char*) realloc(buffer, i + BYTES);
        if (buffer == NULL)
        {
            printf("Memory reallocation error!\n");
            return false;
        }    
    }

}
buffer[i] = '\0';
i++;

*content = buffer;
*length = i;
return true;

lookup

char filetype[5];
char* pch;

// to find the last occurring '.' sign and extract the file name to filetype
pch = strrchr(path, '.');
if (pch == NULL)
{
    return NULL;
}

strcpy(filetype, pch + 1);

if (strcasecmp(filetype, "css") == 0)
{
    return "text/css";
}

if (strcasecmp(filetype, "html") == 0)
{
    return "text/html";
}

if (strcasecmp(filetype, "gif") == 0)
{
    return "image/gif";
}

if (strcasecmp(filetype, "ico") == 0)
{
    return "image/x-icon";
}

if (strcasecmp(filetype, "jpg") == 0)
{
    return "image/jpeg";
}

if (strcasecmp(filetype, "js") == 0)
{
    return "text/javascript";
}

if (strcasecmp(filetype, "php") == 0)
{
    return "text/x-php";
}

if (strcasecmp(filetype, "png") == 0)
{
    return "image/png";
}

return NULL;

parse

// check if CRLF is at the end of the string
char* pch1 = strchr(line, '\0');
char* pch2 = strchr(line, '\n');
char* pch3 = strchr(line, '\r');

if ((pch1 - pch2 != 1) || (pch2 - pch3 != 1))
{
    error(400);
    return false;        
}

// check if are there only two spaces and appropriately positioned.
char* pch4 = strchr(line, ' ');     // position of the first space 

if ((pch4 == NULL) || (pch4 - line == 0))
{
    error(400);
    return false;
}

char* pch5 = strchr(pch4 + 1, ' ');    // position of the second space 
if ((pch5 == NULL) || (pch5 - pch4 == 1) || (pch3 - pch5 == 1))
{
    error(400);
    return false;
}    

// make sure there is no third space
if (strchr(pch5 + 1, ' ') != NULL)
{
    error(400);
    return false;
}

// check if the method is GET
if (strstr(line, "GET ") != line)
{
    error(405);
    return false;
}

// check if the request-target begins with /
if (*(pch4 + 1) != '/')
{
    error(501);
    return false;
}

// check if the request-target contains a "
if (strchr(pch4 + 1, '"') != NULL)
{
    error(400);
    return false;
}

// check if the HTTP-version is HTTP/1.1
if (strstr(line, "HTTP/1.1") != pch5 + 1)
{
    error(505);
    return false;
}

// recorder the position of the question mark, if any
char* pch6 = strchr(pch4 + 1, '?');

// copy the string to abs_path till the '?' sign and the query from the '?' to the second space
if (pch6 != NULL)
{
    strncpy(abs_path, pch4 + 1, pch6 - pch4 - 1);
    abs_path[pch6 - pch4 - 1] = '\0';

    strncpy(query, pch6 + 1, pch5 - pch6 - 1);
    query[pch5 - pch6 - 1] = '\0';
}

// copy the string to abs_path till the second space and the query assigned with '\0'
else
{
    strncpy(abs_path, pch4 + 1, pch5 - pch4 - 1);
    abs_path[pch5 - pch4 - 1] = '\0';

    query[0] = '\0';
}


return false;

indexes

// dynamically allocates memory for index
char* index = malloc(strlen(path) + 12);
if (index == NULL)
{
    printf("Memory allocation error!\n");
    return NULL;
}

// to see if index.php exists
strcpy(index, path);
strcat(index, "/index.php");

if (access(index, F_OK) == 0)
{
    return index;
}

// to see if index.html exists
strcpy(index, path);
strcat(index, "/index.html");
if (access(index, F_OK) == 0)
{
    return index;
}

free(index);

return NULL;
1

It's generally a good idea to pass all the check50/server1 tests before proceeding with the pset. Also to check results with browser and/or curl.

parse always returns false.

Low hanging fruit from load:

  1. Don't cast c here buffer[i] = (char) c; image data cannot be cast as char data because a char byte only handles the ascii range of 0 to 127, but an image byte can be 0 to 255.
  2. buffer[i] = '\0'; Don't modify or add any bytes to content or length. load needs to return the exact content (and length) of the file.

The best way to "check" server is with gdb (or the new debug50!). Find tips here.

1
  • Thank you for pointing out my mistakes! You've saved tremendous number of hours for me to debug it. I am very grateful for that!
    – Ross Shaw
    Sep 12 '16 at 17:15

You must log in to answer this question.

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