0

Check 50 returns a lot of errors https://sandbox.cs50.net/checks/caefd03d8ac2485b820743724297b846

Edit: New check50 https://sandbox.cs50.net/checks/fa32659c01b742b78c18f1568d48b90d

My load function

    /**
     * Loads a file into memory dynamically allocated on heap.
     * Stores address thereof in *content and length thereof in *length.
     */
    bool load(FILE* file, BYTE** content, size_t* length)
    {
        if(file == NULL)
        {
            return false;
        }
    //Allocate memory on heap
    BYTE* buffer = malloc(sizeof(BYTE)*500);
    *content = NULL;
    int  count = 0;
   int c;

    //Read characters from file
   while((c = fgetc(file)) != EOF)
    {
        if( count%500 == 0)
            {
                buffer = (BYTE* )realloc(buffer, sizeof(BYTE)*(500 +count));
            }
        buffer[count] = c;    
        count++;
    }
     *content = buffer;
    *length = count;

return true;
}  

My indexes function

    /**
     * Checks, in order, whether index.php or index.html exists inside of path.
     * Returns path to first match if so, else NULL.
     */
    char* indexes(const char* path)
    {
      char* php = "index.php";
 char* html = "index.html";
 char* path2 = malloc(strlen(php) + strlen(html) + 1);

 strcpy(path2,path);
 if(strcmp(&path2[strlen(path) - 1],"/") != 0)
    {
        strcat(path2, "/");
    }

 //concatenate "index.php" to the path and check if it exists
 strcat(path2,php);
 if(strstr(path2,php) != NULL)
    {
       if(access(path2,F_OK) != -1)
            {
                free(path2);
                return path2;
            }
    }
    //Concatenate "index.html" to the path and check if it exists
 else 
    { 
       strcpy(path2,path);
       strcat(path2,html);
       if(strstr(path2,html) != NULL)
        {
            if(access(path2,F_OK) != -1)
                {
                    free(path2);
                    return path2;
                }
        }
        else
            {
                return NULL;
            }
    }
  return path2;  
 }

My parse and lookup function(Got it corrected through check50 test 1) Updated parse function

/**
 * Returns MIME type for supported extensions, else NULL.
 */
const char* lookup(const char* path)
{
    // http://www.tutorialspoint.com/c_standard_library/c_function_strchr.htm
    const char ch = '.';

    //Stores string after the .
    char* end =  strchr(path,ch);

    //Initialize string for storing the return value
    char* ret;

    //Check the file extension
    if(strcasecmp(end,".css") == 0)
    {
        ret = "text/css";
        return ret;
    }
    if(strcasecmp(end,".html") == 0)
    {
        ret = "text/html";
        return ret;
    }

    if(strcasecmp(end,".gif") == 0)
    {
        ret = "image/gif";
        return ret;
    }

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

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

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

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

    if(strcasecmp(end,".png") == 0)
    {
        ret = "image/png";
        return ret;
    }
    else
        return NULL;


}

/**
 * Parses a request-line, storing its absolute-path at abs_path
 * and its query string at query, both of which are assumed
 * to be at least of length LimitRequestLine + 1.
 */


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

      // TODO
//Request-line consists of method SP request-target SP HTTP-version CRLF*/
//The request target consists of the absolute path and the query in this form : absolute-path [ "?" query ]
//We will use strtok to store tokens in different strings
//Referenced from stackoverflow and tutorialspoint.com
//Copy the line into  a new string
char* l = malloc(strlen(line) + 1);
l = strdup(line);
strcat(l,"\0");

//Allocating memory for method,request and version
char *method = malloc(strlen(line) + 1);
char *request = malloc(strlen(line) + 1);
char* http = malloc(strlen(line) + 1);
char *abs_path1;
char *query1;

//Token to store method
method = strtok(l, " ");

//Token to store request target
request = strtok(NULL," ");

//Store the HTTP version in a token
 http = strtok(NULL,"\r\n ");

//Store the absolute path in a token abs_path1 = strtok(request,"?");

//Store the query after ? in a token query1 = strtok(NULL,"?"); if(query1 == NULL) { query1 = " "; strcat(query1,"\0"); } strcat(query1,"\0");

strcat(query1,"\0");
strcat(abs_path1,"\0");
strcpy(query,query1);
strcpy(abs_path,abs_path1);

if (strcmp(method, "GET") != 0)
{
    error(405);
    return false;
}
if (strchr(query, '"'))
{
    error(400);
    return false;
}
if (request[0] != '/')
{
    error(501);
    return false;
}
if (strstr(request, "/ ") != 0)
{
    error(404);
    return false;
}  
if (strcmp(http, "HTTP/1.1") != 0)
{
    error(505);
    return false;
}

free(l);
return true; 
}

2 Answers 2

3

Here are specific things to look at:

load Declare c as an int instead of size_t, since size_t is unsigned.

indexes

  1. Your allocation for path2 is wrong
    char* path2 = (char*)malloc(sizeof(strlen(php) + strlen(html) + 1)); First, the sizeof has got to go. It will probably return 4, since the argument will be an integer. Next, path2 is going to be either path + index.php OR path + index.html. Therefore strlen(path) + strlen(html) + 1 is sufficient. And no reason to cast it as a char*, that's implicit.
  2. If it doesn't pass the php test (if(access(path2,F_OK) != -1)) it's never going to pass the html test because you are just appending index.html to what's already in path2. You need to start fresh, ie strcpy(path2, path) again.

parse You have not allocated any memory to l.

There maybe other problems in these functions. Hopefully this info will help you look at your code with a more critical eye.

6
  • I caught a very subtle error. I was incorrectly using the strrchr(). tutorialspoint.com/c_standard_library/c_function_strrchr.htm I wasn't comparing with '.' in the cases of lookup function. Fortunately, this small error resolved most of my checks. I am left with small changes now. Thanks for being so cooperative, @DinoCOderSaurus. Commented Jul 16, 2016 at 4:59
  • A final error. I am null terminating both query and abs_path but it still gives me an erroneous message. Commented Jul 16, 2016 at 5:33
  • Big problem here: sizeof(line). line is a pointer, size of a pointer is 8. l should be the same length as line (plus one for the null terminator of course). On further review, looks like you are not allocating memory to any of the char* you use in parse. Commented Jul 16, 2016 at 11:11
  • I have applied all the suggested changes but to no avail. Returns the same 2 checks. Commented Jul 17, 2016 at 5:08
  • Last comment. Your allocation for path2 is still wrong (though that may not effect the outcome of check50). More glaring is this: free(path2); return path2; Commented Jul 17, 2016 at 16:39
1

gdb to the rescue!

  1. Open two terminals.
  2. In the first, call gdb ./server. There's a guide here. Of course, you will set a breakpoint at load instead of parse.

  3. In the second terminal, cd to your document root directory (public?).

  4. Send a curl request to your server. Something like this:
    curl -i http://localhost:8080/hello.html. (Don't request an image file, keep it simple).

  5. Back in the first terminal, gdb should be waiting at load(). (If it's not, verify your breakpoint; you might have to start over).

  6. Set a breakpoint here *content = buffer ; and continue.

  7. Inspect the contents of buffer. (Assuming you're requesting hello.html, you know what to expect as the first character, as a char '<', as an int 60)

  8. Let the debugging begin!

The art of programming requires good troubleshooting and debugging skills. Troubleshooting and debugging require patience, practice and perseverance.

Other things from a quick readthrough:

This didn't work in parse, it's not gonna work in indexes.

char* path2 = NULL;    
    strcpy(path2,path); 

Which, frankly, confuses me because that should cause Requesting /test redirects to /test/ to fail. Hmmmm. Maybe a different version of the source code?

There are (other) fundamental problems in indexes. You need to go through it carefully and critically because it is not doing what the spec requires. Plus you need to read the man page for access and pay special attention to the RETURN section.

6
  • Thanks a ton, @DinoCoderSaurus. I have implemented everything as you have instructed. I am encountering this error. ~/workspace/pset6/public $ curl -i localhost:8080/hello.html curl: (7) Failed to connect to localhost port 8080: Connection refused Commented Jul 12, 2016 at 3:58
  • Look carefully at the curl I suggested and the curl in your comment. The difference between them will absolutely give the error you received. Commented Jul 12, 2016 at 11:16
  • After applying your suggestions, I now get this fatal error. ~/workspace/pset6/public $ curl -i localhost:8080/hello.html curl: (7) Failed to connect to localhost port 8080: Connection refused I have also edited the code a bit. Please help. Commented Jul 14, 2016 at 6:09
  • My bad, I ignored the fact that the comment converted your curl command to a link. Make sure server is running. In the gdb terminal, after you set the breakpoint, make sure you run /path/to/root and see Listening on port 8080. Your new load fixed a major bug. Did it change your check50 result? (which is not to say you should give up on gdb!) Commented Jul 14, 2016 at 14:34
  • Unfortunately, this has not resolved any of my problem. I am getting the same erroneous messages as before. Do you suggest I start off with this pset again? Commented Jul 15, 2016 at 3:43

You must log in to answer this question.

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