1

Every time I input a query on the HTML form, I get a 404 Error even though the query appears in the URL, and printf seem to indicate that my Parse function is correctly extracting the right substring. My terminal output is as follows:

gege019@ide50:~/workspace/pset6 $ ./server public
Using /home/ubuntu/workspace/pset6/public for server's root
Listening on port 8080
GET / HTTP/1.1
Abs_path = /
HTTP/1.1 200 OK
GET /hello.html HTTP/1.1
Abs_path = /hello.html
path is /home/ubuntu/workspace/pset6/public/hello.html
type is text/html
Data: <!DOCTYPE html>

<html>
    <head>
        <title>hello</title>
    </head>
    <body>
        <form action="hello.php" method="get">
            <input autocomplete="off" autofocus name="name" placeholder="Name" type="text"/>
            <input type="submit" value="Say Hello"/>
        </form>
    </body>
</html>

Length: 316
HTTP/1.1 200 OK
GET /hello.php?name=gege019 HTTP/1.1
Query = name=gege019
Abs_path = /hello.php?name=gege019
HTTP/1.1 404 Not Found

Regardless, GDB seems to indicate the error is stemming from my parse function (below) but I'll paste my code for all the functions we had to work on just in case you guys have other ideas. I also looked at this previous question but couldn't determine if we're experiencing the same issue. I would sincerely appreciate any help and guidance on this you can provide. I've spent the past 2 months on this pset and would really like to be able to move on, but would feel terrible submitting it in it's current incomplete form. Thank you so much!!

Parse:

bool parse(const char* line, char* abs_path, char* query)
{
     // TODO
    //eg: GET /hello.php?name=test HTTP/1.1 

    //accept only GET as method
    if (strncmp("GET ", line, 4) != 0)
    {
        error(405);
        return false;
    }

    //check that only 2 spaces in request-line 
    char* space = strchr(line,' ');

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

    int i = 0;
    while (space != NULL)
    {

        //check for '/' after first space i.e. request-target starts with /
         if (i == 0)
         {

            if (strncmp(" /", space, 2) != 0)
            {
                error(501);
                return false;
            }

            //check for '"' in request-target and after 2nd space
            if (strchr(space, '"') != NULL && (strchr(space+1,' ') != NULL && strchr(strchr(space+1,' '), '"') != NULL ))
            {
                error(400);
                return false;
            }

            //assuming '?name=variable' can only come after ".php"
           //"GET /hello.php?q=test HTTP/1.1\r\n"
           int n = strlen(space+1) - strlen(strchr(space+1,' '));
           char numq[n + 1];
           // numq = "/hello.php?q=test"
           strncpy(numq, space+1, n);
           numq[n] = '\0';

           if (strchr(numq, '?') != NULL)
           {
              // only ".php" can have query
              if (strstr(numq, ".php") == NULL)
              {
                  error(400);
                  return false;
              }

              //verify that '?'comes right after ".php"
             char* numq3 = strstr(numq, ".php" );
             // '.php?name=variable'

             if (strncmp(".php?", numq3, 5) !=0)
             {
                  error(400);
                  return false;
             }

             //store query "name=variable" in char* query
            strcpy(query, (strchr(numq, '?' ) + 1));
            printf("Query = %s\n",query);

           }   

            //if ".php" file type but no query, then set query to " "
            else if (strstr(numq, ".php") != NULL)
              {
                  //set query to " " ie '\0'
                  strcpy(query, (strstr(numq, ".php" ) + 1));
                  printf("Query = %s\n",query);
              }
         }

        if (i == 1) 
        {
             //check for 'HTTP' after 2nd space
            if (strncmp(" HTTP", space, 5) != 0)
            {
            error(400);
            return false;
            }

            //check for CRLF
            if (strstr(space,"\r\n\0") == NULL)
            {
               error(400);
                return false;
            }

            //store abs path in abs_path
            int p = strlen(strchr(line,' ') + 1) - strlen(space);
            strncpy(abs_path, strchr(line,' ') + 1, p);
            abs_path[p] = '\0';
            printf("Abs_path = %s\n", abs_path);

        }

        i++;
        space = strchr(space+1, ' ');
    }


    //check for at most 2 spaces
    if (i != 2)
    {
        error(400);
        return false; 
    }

    return true;
}

Lookup:

const char* lookup(const char* path)
{
    // TODO
    //find the last 'dot'
    char* dot = strrchr(path,'.');

    if (path != NULL)
    {
        if (strcasecmp(dot,".css") == 0)
        {
            return "text/css";
        }

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

    }
    return NULL;
}

Load:

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

    if (*content == NULL)
    {
        return false;
    }
    char* buffer = malloc(sizeof(char));
    if(buffer == NULL) 
    {
        return false; 
    }

    int counter = 0;
    int c = fgetc(file);

    while(c != EOF)
    {

        buffer[counter] = (char) c;
        counter++;
        buffer = (char*) realloc(buffer, counter+1);
        c = fgetc(file);

    *content = buffer; // stores the address of the first of those bytes
    *length = counter;     // stores the number of bytes
    printf("Data: %s\n", *content);     // debugging - this works
    printf("Length: %zu\n", *length);   // debugging - this works
    return true;
}

Indexes

char* indexes(const char* path)
{
     //malloc space to contain directory path + index file name + null terminator
    char* buffer = malloc(sizeof(char) * (strlen(path) + strlen("/index.html") + 1));
    strcpy(buffer, path);
    strcat(buffer,"/index.php");

    FILE* fp = (fopen(buffer, "r"));
    if (fp != NULL)
    {
        return buffer;
    }
    strcpy(buffer, path);
    strcat(buffer,"/index.html");

    if (fp != NULL)
    {
        return buffer;
    }
    free(buffer);
    return NULL;

}
3

According to your terminal output, abs_path is wrong. Unless you have a file named hello.php?name=gege019, 404 is the right answer. abs_path should not include the ? or anything that follows.

1
  • Wow, thank you so so much! I can't believe I totally missed that. I guess I got so sick and tired of debugging that my brain completely missed this obvious error. Thank you again for you help!!!
    – user9805
    Mar 13 '16 at 4:48

You must log in to answer this question.

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