0

I have implemented all four of the functions required but I am confused because my code doesn't seem to pass many of the check50 tests.

Check50 Results: https://sandbox.cs50.net/checks/f221eea6031b4cdfa88bdc8ba67447a3

EDIT:

I have repeatedly gone through the code with gdb and I have discovered some important things.

  1. I found that my abs_path and query weren't null terminating properly so I had to loop from the end of the abs_path or query until the end string and add '\0' characters to fill in any space.
  2. Now, my Parse Function appears to be handling the request line properly.
  3. cat.html doesn't seem to load, and hello.php doesn't seem to load properly when going from hello.html. I get a lot of favicons displayed on the screen instead.
  4. Load definitely loads something, it stores it in my buffer variable and *content gets assigned its address.
  5. Indexes seems to work now, as I am immediately redirected to index.html, but the html doesn't get displayed (same favicons error as before).
  6. All request lines are met with the 200 OK code.

From here, I'm guessing that the error lies within my lookup function or my load function.

Lookup:

const char* lookup(const char* path)
{

    if (access(path, R_OK) == -1)
    {
        error(403);
        return NULL;
    }

    char* mime = calloc(12, 1);

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

    return mime;
}

Load:

bool load(FILE* file, BYTE** content, size_t* length)
{

    // checks if file was successfully opened.
    if (file == NULL)
    {
        return false;
    }

    BYTE* buffer = malloc(BYTES * sizeof(char));

    int size = 0;

    while (fread(buffer, sizeof(BYTE), 1, file) == 1)
    {
        size++;
        if ((size + 1) % BYTES == 0)
        {
            buffer = realloc(buffer, sizeof(buffer) * (size + 1));
        }
    }

    *content = buffer;
    *length = size;

    return true;

}

Parse (Just in Case):

bool parse(const char* line, char* abs_path, char* query)
{
//no errors in parse.
int length = strlen(line);

int space_count = 0;

for (int i = 0; i < length; i++)
{
    if (line[i] == (char) 32)
    {
        space_count++;
    }
}

if (space_count != 2)
{
    error(400);
    return false;
}

char* method = malloc(5 * sizeof(char));
strncpy(method, line, 4);

if (strstr(method, "GET ") == NULL)
{
    error(405);
    return false;
}

free(method);

if (line[4] != '/')
{
    error(501);
    return false;
}

char* question_mark = strchr(line, '?');
char* slash = strchr(line, '/');
char* HTTP = strstr(line, "HTTP/1.1");

if (question_mark != NULL)
{
    strncpy(abs_path, slash, question_mark - slash);
    for (int i = question_mark - slash; i < strlen(abs_path + 1); i++)
    {
        abs_path[i] = '\0';
    }



    if (question_mark + 1 == NULL)
    {
        query[0] = '\0';
    }
    else
    {
        strncpy(query, question_mark + 1, (HTTP - question_mark - 2));
        query[HTTP - 2 - question_mark] = '\0';

    }
}
else
{
    strncpy(abs_path, slash, HTTP - slash - 1);
    for (int i = HTTP - slash - 1; i < strlen(abs_path + 1); i++)
    {
        abs_path[i] = '\0';
    }
}

char* quot_mark = strchr(line, '\"');

if (quot_mark != NULL)
{
    error(400);
    return false;
}

//if another version of HTTP is used, the server can't handle it. 
if (HTTP == NULL)
{
    error(505);
    return false;
}

return true;
}

Indexes (Just in Case):

char* indexes(const char* path)
{
if (access(path, R_OK) == -1)
{
    error(403);
    return NULL;
}

char* new_path = malloc(sizeof(char) * (strlen(path) + 12));
strcpy(new_path, path);
strcat(new_path, "/index.php");

if (access(new_path, R_OK) != -1)
{
    return new_path;
}

free(new_path);

new_path = malloc(sizeof(char) * (strlen(path) + 12));
strcpy(new_path, path);
strcat(new_path, "/index.html");

if (access(new_path, R_OK) != -1)
{
    return new_path;
}

free(new_path);
return NULL;
}

Hopefully this makes my problem a bit clearer. Sorry if it still sounds too general, but using gdb in a webserver proved to be quite challenging and confusing.

3
  • Possible duplicate of pset6: what does check50 “TODO” error mean?
    – ChrisG
    Aug 18 '16 at 10:35
  • 1
    You are at a point in your programming life that you should start using GDB to debug your own code and see where things get awry. Don't expect from us to run your whole code and find the problems. I'm confident you can solve this yourself. :)
    – ChrisG
    Aug 18 '16 at 10:37
  • @ChrisG Thanks for the advice, I have tried debugging using GDB as you suggested and I hope that my edited question provides a more specific area of focus. Aug 18 '16 at 14:57
1

load

Small problem in load here for (char c = fgetc(file); c != EOF; c = fgetc(file)). See the explanation here.

indexes

This function is, frankly, way off the mark. Reread the instructions. Write up some pseudo code. Try again. You are never checking to see if the files exist! and isn't that the whole point of the exercise? Study up on access. And the allocations do not include a space for the null-byte.

That's just the low-hanging fruit. There may be problems in parse as well. As @ChrisG suggests: time to break out gdb! You will find starter tips here. It may be difficult at first, but it's important, keep at it. You can't be a coder if you cannot troubleshoot and debug. You could start troubleshooting with printfs. Viz. parse, two things are very important. 1) examine abs_path (and query) after you return to main. And make sure they are properly null-terminated. If you are using printfs, one trick is this format "%s<-". That way you will make sure there are no non-printing characters at the end of the string, which will make check50 fail.

2
  • I have taken your advice and altered the indexes function. I have altered the implementation of the load function and used GDB to troubleshoot more effectively. However I still cannot pinpoint the source of these errors after the testing? Aug 18 '16 at 14:58
  • This ` while (fread(buffer, sizeof(BYTE), 1, file) == 1)` will always put result in the first byte of buffer. Somehow, somewhere you have to get all the bytes into buffer if you want to *content = buffer; Next: sizeof(buffer) buffer is a pointer, sizeof a pointer is 4 or 8. How big is buffer so far? size maybe? How many bytes to add? You decide. gdb in webserver is quite challenging and often confusing. It is a very important skill to master. Practice, practice, practice. Questions lose value after many edits. If you still have problems with your next version, add a new question. Aug 18 '16 at 15:24

You must log in to answer this question.

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