I have a problem in my parse()
function of server.c
It took me almost 2 days to get to the specifics of the problem,
the problem is in the abs_path
when the request target
is:
/hello.html
,abs_path
andquery
is empty/hello.php?q=alice
,abs_path
is/hello.p
andquery
isq=alice
request target and query are fine the problem is in abs_path.
Due to this I am getting two errors in check50:
:) server.c exists
:) server compiles
:) HTTP/1.0 returns error code 505
:) Method of 'abcGET' returns error code 405
:) Method of 'GETabc' returns error code 405
:) request-target without starting '/' returns error code 501
:) request-target of abc/hello.php returns error code 501
:( Requesting cat.exe returns error code 501
\ expected output, but not "HTTP/1.1 301 Moved Permanently\r\nLocat..."
:( Requesting non-existant file returns error code 404
\ expected output, but not "HTTP/1.1 301 Moved Permanently\r\nLocat..."
:) Requesting request-target with " returns error code 400
:) Two spaces after GET returns error code
:) A space within the request target returns error code
:) Two spaces before HTTP/1.1 returns error code
here's my parse function:
bool parse(const char* line, char* abs_path, char* query)
{
// copy line to new string
char* temp = malloc(strlen(line) + 1);
if(temp == NULL)
{
free(temp);
return false;
}
memset(temp, 0, strlen(line) + 1);
strcpy(temp, line);
// Find method in the request line
if(strncmp(temp, "GET ", 4) != 0)
{
error(405);
return false;
}
char* haystack = NULL;
haystack = temp;
char* needle = strstr(haystack, " ");
if(needle == NULL)
{
return false;
}
// get request-target from the request line
haystack = needle + 1;
needle = strstr(haystack, " ");
if(needle == NULL)
return false;
char* reqt = malloc(needle - haystack + 1);
if(reqt == NULL)
return false;
memset(reqt, 0, needle - haystack + 1);
strncpy(reqt, haystack, needle - haystack);
*(reqt + (needle - haystack)) = '\0';
for(int i = 0; strcmp(&reqt[i], "\0") != 0; i++)
{
if(strcmp(&reqt[i], "\"") == 0)
{
error(400);
return false;
}
}
if(reqt[0] != 47) //request target must start with a '/'
{
error(501);
return false;
}
// get HTTP version from the request line
haystack = needle + 1;
needle = strstr(haystack, "\r\n");
if(needle == NULL)
return false;
if(strncmp(haystack, "HTTP/1.1", needle - haystack) != 0)
{
error(505);
return false;
}
// reading abs_path and query from request target
int i = 0;
haystack = reqt;
needle = strstr(haystack, "?");
if(needle == NULL)
{
needle = strstr(haystack, "\0");
i = 1;
if(needle == NULL)
return false;
}
memset(abs_path, 0, needle - haystack + 1);
strncpy(abs_path, haystack, needle - haystack);
if(abs_path == NULL)
{
return false;
}
*(abs_path + (needle - haystack)) = '\0';
printf("abs=\n");
for(int i = 0; i < sizeof(abs_path); i++)
{
printf("%c", abs_path[i]);
}
printf("\nend\n");
if(i == 1)
{
*query = '\0';
}
else
{
needle++;
if(strncmp(needle, "\0", 1) == 0)
{
*query = '\0';
}
else
{
strcpy(query, needle);
if(query == NULL)
return false;
}
}
for(int i = 0; i < sizeof(query); i++)
{
printf("%c", query[i]);
}
printf("\n%s\n", reqt);
free(temp);
free(reqt);
return true;
}