so I'm doing pset6. My implementation passed every check50 test except the last one, which is:
:( Requesting two files in a row (cat.html then cat.jpg) succeeds
When I test server.c with the public
folder, the server starts, but when I click on something like 'cat.html' or 'cat.jpg', the server gives me seg fault and sometimes even 404 or 405. Like the screenshot below:
I don't know which part of the implementation I did wrong. Here is my implementation of parse
:
bool parse(const char* line, char* abs_path, char* query)
{
int len = strlen(line),
space_count = 0,
first_space_pos,
second_space_pos;
// Check if the form of the request target is valid.
// Also checks the position of the first space.
for (int i = 0; i < len; i++)
{
if (line[i] == ' ')
{
if (space_count == 0)
{
first_space_pos = i;
}
if (space_count == 1)
{
second_space_pos = i;
}
space_count++;
}
else if (line[i] == '"')
{
error(400);
return false;
}
}
// If there are more than 2 spaces.
if (space_count != 2)
{
error(400);
return false;
}
// Get the method!
char* method = malloc(sizeof(char) * (first_space_pos+1));
for (int i = 0; i < first_space_pos; i++)
{
method[i] = toupper(line[i]);
}
// If method is not GET, return false.
if (strcmp(method, "GET") != 0)
{
error(405);
return false;
}
// Get the HTTP version!
char* http_w_space = strrchr(line, ' ');
int http_len = strlen(http_w_space) + 1;
char* http_version = malloc(sizeof(char) * http_len);
for (int i = 0; i < http_len; i++)
{
http_version[i] = http_w_space[i+1];
}
// If HTTP version is not 1.1, return false.
if (strcmp(http_version, "HTTP/1.1\r\n") != 0)
{
error(505);
return false;
}
// Get the request target!
char* req_target_extended = strchr(line, ' ');
char* req_target = malloc(sizeof(char) * (second_space_pos - first_space_pos - 1));
int extended_space_count = 0;
for (int i = 0, n = strlen(req_target_extended); i < n; i++)
{
if (req_target_extended[i+1] == ' ')
{
extended_space_count++;
}
if (extended_space_count == 1)
{
break;
}
req_target[i] = req_target_extended[i+1];
}
// If request-target does not begin with /, respond to the browser with 501 Not Implemented and return false
if (req_target[0] != '/')
{
error(501);
return false;
}
// Query
char* query_flag = NULL;
int question_mark_pos = 0, req_target_len = strlen(req_target);
// Go through request_target.
// Search for the '?' mark.
// Get the query.
for (int i = 0, n = strlen(req_target); i < n; i++)
{
if (req_target[i] == '?')
{
question_mark_pos = i;
break;
}
abs_path[i] = req_target[i];
}
query_flag = strchr(req_target, '?');
if (query_flag == NULL || strlen(query_flag) == 1)
{
query[0] = '\0';
}
else
{
int index = 0;
for (int i = question_mark_pos + 1; i < req_target_len; i++)
{
query[index] = req_target[i];
index++;
}
}
if (abs_path != NULL && query != NULL)
{
return true;
}
error(501);
return false;
}
If anyone had had this problem before, or if anyone knows what went wrong in my code, please do comment and explain. Thanks everyone in advance!