0

The parse function has 3 pointers that come into it; *line, *abs_path, and *query.

I think I successfully manipulate the values at these addresses but when the function returns, *query is empty. *abs_path is fine (how!?!?).

Check50 gives me:

gerardrafferty@ide50:~/workspace/pset6 $ check50 2015.fall.pset6.server2 server.c
Checking...........................................................................:) server.c exists
:) server compiles
:) Requesting cat.jpg returns 200, image/jpeg, and correct image
:) Requesting cat.html returns 200, text/html, and correct file
:) Requesting cat2.HTML returns 200, text/html, and correct file
:) Requesting cat3.HtMl returns 200, text/html, and correct file
:) Requesting cat.gif returns 200, image/gif, and correct file
:) Requesting favicon.ico returns 200, image/x-icon, and correct file
:) Requesting test.css returns 200, text/css, and correct file
:) Requesting test.js returns 200, text/javascript, and correct file
:) Requesting hello.php returns 200, text/html, and correct output
:) Requesting hello.php? returns 200, text/html, and correct output
**:( Requesting hello.php?name=Alice returns 200, text/html, and correct output
   \ expected output, but not "X-Powered-By: PHP/5.5.7\r\nContent-type..."**
:) Requesting /test redirects to /test/
**:( Requesting /test/ outputs /test/index.html**
:) Requesting directory containing index.php outputs index.php
:) Requesting two files in a row (cat.html then cat.jpg) succeeds
https://sandbox.cs50.net/checks/dfadcfd7f3a741b7a82a49f055c70c5b

My parse code is:

bool parse(const char* line, char* abs_path, char* query)
{   
    //example line - "GET /hello.php?name=derek HTTP/1.1"
    int len = strlen(line);
    char* lines = calloc(len+1, sizeof(char));
    lines = strdup(line);
int flag1 = -1;
int flag2 = -1;
int flagq = -1;

for (int i=0; i<len; i++)
{
    if ((lines[i] == ' ') && (flag1 == -1)) flag1 = i;
    else if ((lines[i] == ' ') && (flag1 != -1) && (flag2 == -1)) flag2 = i;
    else if ((lines[i] == '?') && (flag1 != -1) && (flag2 == -1)) flagq = i;
}
// Determine the length of veraious char arrays
int methodlen = flag1+1;
int reqtarlen = flag2-flag1;
int verlen = len-flag2;
int aplen = flagq-flag1;


//char* method = calloc((methodlen), sizeof(char));
//strncpy(method, lines, flag1);
char method[methodlen];
strncpy(method, lines, flag1);
method[flag1] = '\0';
//char* reqtar = calloc(reqtarlen, sizeof(char));
char reqtar[reqtarlen];
strncpy(reqtar, &lines[flag1+1], reqtarlen);
reqtar[reqtarlen-1] = '\0';
//char* ver = calloc(verlen, sizeof(char));
char ver[verlen];
strncpy(ver, &lines[flag2+1], verlen);
ver[verlen-1] = '\0';

if (strchr(reqtar,'?') != NULL)
{
    query = strchr(reqtar, '?');
    strncpy(abs_path, reqtar, aplen);
    abs_path[aplen-1]='\0';
}
else
{
    strcpy(abs_path, reqtar);
}

if (strcmp(method, "GET") != 0)
{
    error(405);
    return false;
}
if (abs_path[0] != '/')
{
    error(501);
    return false;
}
if (strchr(reqtar, '"') != NULL)
{
    error(400);
    return false;
}
if (strcmp(ver, "HTTP/1.1\r\n") != 0)
{
    error(505);
    return false;
}

char fpath[LimitRequestLine] = "";
strcpy(fpath, root);
strcat(fpath, abs_path);
if((access(fpath, R_OK) !=0) && (strchr(reqtar, '?') == NULL))
{
    error(404);
    return false;
}
return true;

error(501);
return false;
}

The gdb output is:

(gdb) print abs_path
$23 = 0x7fffffffbce0 "/hello.php"
(gdb) print query
$24 = 0x7fffffff7a6a "?name=a"
(gdb) n
768     }
(gdb) 
main (argc=2, argv=0x7fffffffdeb8) at server.c:193
193                         char* p = urldecode(abs_path);
(gdb) print abs_path
$25 = "/hello.php", '\000' <repeats 5518 times>...
(gdb) print query
$26 = '\000' <repeats 8190 times>
(gdb) 

Note printing query gives $24 = 0x7fffffff7a6a "?name=a" in parse but $26 = '\000' <repeats 8190 times> in main.

1

Scope. Pointers. Look at the difference between the way you create abs_path and the way you create query. This strncpy(abs_path, reqtar, aplen); changes the contents of the memory that abs_path points to, while this query = strchr(reqtar, '?'); changes the value of the pointer. When function returns to main, it is pointing to the same chunk of memory as when it left, and those contents have not changed.

The second check50 error likely indicates a different problem (in load). Since index.php test passes check50, is it possible you are not allocating enough memory for index.html (since it is "one byte longer")?

2
  • Thanks. I got the pointer to query working. The servers are busy so I can't get check50 to work but my implementation matches the staff's with the exception of the hello.html link. I press the link and enter a name but the output is identical to what I get when I click on hello.php - "hello, world". Without the benefit of check50, any idea how to fix the next step? Does this have anything to do with test outputing index.html? – Brendan Rafferty Jun 1 '16 at 21:49
  • query should not include the "?". From the spec: And if request-target is /hello.php?q=Alice, then query should have a value of q=Alice. – DinoCoderSaurus Jun 2 '16 at 1:04

You must log in to answer this question.

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