0

I'm lost on server.c. I passed the first check. When trying to run my server after completing the program, I get an internal server error. I ran valgrind and fixed multiple memory issues. I thought that might help, but I still get the error.

I tried to read other QA with similar problems. I'm thinking it is in my parse function (possibly null terminator?). strtok and strcpy are supposed to included null characters, so I didn't think I needed to add anything (and if I do I'm not sure how to add it to the end of the string when I don't know its length). Maybe I'm not on the right track with this but here is my code:

Load:

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

    //setup byte counter starting at one since one byte allocated to start buffer
    int counter = 1;

    //setup buffer in memory
    BYTE* buffer = malloc(sizeof(BYTE)); //was a char* but per another QA images can cause problems when allocating with char

    //return false if buffer not loaded
    if(buffer == NULL)
    {
        return false;
    }

    //reads through file and gets chars one at a time until the end of the file
    for (int c = fgetc(file); c != EOF; c = fgetc(file))
    {
        buffer[counter - 1] = c; //adds the char to the buffer starting at 0
        counter++; //increase the byte counter
        buffer = realloc(buffer, counter + 1); //adds new memory to buffer by adding a byte to the current number of bytes
    }

    *content = buffer; //updates content pointer to buffer sector of memory?
    *length = counter;
    free(buffer);
    return false;
}

Lookup:

const char* lookup(const char* path)
{
    // TODO - function is inputed the path, need to scan it for file type and return supported extension

    //declare period so can search for in path
    const char period = '.';

    //strchr sets pointer at the location of the period, effectively truncating string to start at file extension
    char* pathext = strchr(path,period);

    //declare the 8 extensions and corresponding MIME types
    char* extension[8] = {".css",".html",".gif",".ico",".jpg",".js",".php",".png"};
    char* mimetype[8] = {"text/css","text/html","image/x-icon","image/gif","image/jpeg","text/javascript","text/x-php","image/png"};

    //function to check if the path extension is equal to any of the given extension and if so return corresponding MIME
    for(int i = 0; i < 8; i++)
    {
        if(strcasecmp(pathext,extension[i])==0)
        {
          return mimetype[i];
        }        
    }

    //lookup returns NULL if the path does not end in one of the 8 extensions
    return NULL;
}

Parse:

bool parse(const char* line, char* abs_path, char* query)
{
    //create copy of line in memory so it can be manipulated
    char* templine = malloc(sizeof(char) * (LimitRequestLine + 1));
    strcpy(templine,line);

    //use strtok function to split line into words http://stackoverflow.com/questions/26330219/split-line-into-array-of-words-c
    char* method = strtok(templine, " ");
    char* absolute_path = strtok(NULL, " ");
    char* httpver = strtok(NULL, "\r\n");

    //checks format of line, aka that method absolute_path and httpver exist
    //do I also need to ensure line ends after hpp or does \r\n take care of that?
    if(method == NULL || absolute_path == NULL || httpver == NULL)
    {
        error(400);
        free(templine);
        return false;
    }
    //checks that path starts with /
    else if(absolute_path[0] != '/')
    {
        error(501);
        free(templine);
        return false;
    }
    //checks that path does not contain quotes by moving pointer to it if it exists - null if doesn't exist
    else if(strchr(absolute_path,'\"') != NULL)
    {
        error(400);
        free(templine);
        return false;
    }
    //checks that method equals GET
    else if(strcasecmp("GET", method) != 0)
    {
        error(405);
        free(templine);
        return false;
    }
    else if(strcasecmp(httpver,"HTTP/1.1") != 0)
    {
        error(505);
        free(templine);
        return false;
    }
    else
    {

        //code to transfer absolute_path to abs_path - strcpy should transfer null pointer?
        strcpy(abs_path,absolute_path);


        //copy query by allocating memory and setting pointer to character after the question mark

       //if path doesn't contain a question mark, query blank
        if(strchr(absolute_path, '?') == NULL)
        {
            query = "";
        }
        //if path contains a question mark but terminates after question mark, query blank
        else if(strcmp(strchr(absolute_path, '?') + 1, "\0") == 0)
        {
            query = "";
        }
        //in all other cases, use strchr to start "query" at the point after the question mark
        else
        {
            query = strchr(absolute_path, '?') + 1;
        }

        printf("Query: %s\n", query); //check on query
        free(templine);
        return true;

    }
}

Index

char* indexes(const char* path)
{
    // TODO
    //copying path into new sect of memory so it can be manipulated. left room for php or html file to be added
    char* phppath = malloc(strlen(path)*sizeof(BYTE) + 9 + 1);
    phppath = strcpy(phppath,path);
    char* htmlpath = malloc(strlen(path)*sizeof(BYTE) + 10 + 1);
    htmlpath = strcpy(htmlpath,path);

    //setup string to be found in directory
    char* phpfile = "index.php";
    char* htmlfile = "index.html";

    //combine path with index file to check in directory
    phppath = strcat(phppath, phpfile);
    htmlpath = strcat(htmlpath, htmlfile);

    //check if php or html exist (in that order) and returns respective path or null if doesn't exist
    //access function F_OK checks that file exists in directory and returns 0 if true
    if (access(phppath, F_OK) == 0)
    {
        free(htmlpath);
        return phppath;
    }
    else if (access(htmlpath, F_OK) == 0)
    {
        free(phppath);
        return htmlpath;
    }
    else
    {
        free(htmlpath);
        free(phppath);
        return NULL;
    }

}

Any help is appreciated. I think I get more confused the more I look back at the code.

To give further information. When I run GDB, I get:

(gdb) n
Abolute path is '/cat.jpg'Query: 
798             printf("The query is ?%s\n", query); //check on query
(gdb) n
799             free(templine);
(gdb) n
802         }
(gdb) n
main (argc=2, argv=0x7fffffffde88) at server.c:189
189                         char* p = urldecode(abs_path);
(gdb) n
190                         if (p == NULL)
(gdb) n
197                         path = malloc(strlen(root) + strlen(p) + 1);
(gdb) n
198                         if (path == NULL)
(gdb) n
203                         strcpy(path, root);
(gdb) n
204                         strcat(path, p);
(gdb) n
205                         free(p);
(gdb) n
208                         if (access(path, F_OK) == -1)
(gdb) n
216                         if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode))
(gdb) n
245                         const char* type = lookup(path);
(gdb) n
246                         if (type == NULL)
(gdb) n
253                         if (strcasecmp("text/x-php", type) == 0)
(gdb) n
261                             transfer(path, type);
(gdb) n
HTTP/1.1 500 Internal Server Error
263                     }
(gdb) 

I'm not sure exactly what to make of this. I started with a breakpoint at my parse function and it appears to report (printf) the "absolute_path correctly." Since the crash is part of main function that deals with abs_path, I think the problem is there but can't pinpoint it.

0

Good:) *content = buffer; //updates content pointer to buffer sector of memory?
Bad:( free(buffer);

You are pointing the content pointer to the "buffer sector of memory" Then you are essentially erasing the buffer sector of memory. So back in main, content is like empty. You can check this out with gdb.

I know, I know. The rule is: if you malloc you must free. main frees content (in a couple of places, lines 505, 519, 1120 depending on conditions). *content in load is content in main, because in load its a pointer-to-a-pointer.

5
  • I still get the same error. But thank you for clearing that part up, guess I got carried away clearing memory when working with valgrind! I'm thinking it may have to do with how I return abs_path because the server will "HTTP/1.1 200 OK" the main folder (although it lists the directory and doesn't load the index.php) and then it crashes with a 500 error after the call to favicon.ico Sep 9 '16 at 14:49
  • After investigating further, if I try to call anything directly other than the root folder, it gets a 500 error immediately. Sep 9 '16 at 15:00
  • I added GDB results to the original post. Sep 9 '16 at 15:26
  • Your arrays in lookup are misaligned. .ico is affected, so "500 error after the call to favicon.ico......." Keep at it with my BFF gdb. There are several spots in transfer that throw a 500. Once you find out which one, you can back it up from there and you will find the problem. Sep 9 '16 at 17:19
  • Thanks. I found a few errors through GDB (including accidentally making load automatically return false). Now my server is working for the most part, but it fails the check50 and query isn't working appropriately. GDB doesn't throw errors since most of the code "works", so I'm having trouble navigating it. I'll consider this question solved and post a new question on using GDB. Thanks for the help Sep 10 '16 at 13:27

You must log in to answer this question.

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