Server is functional and gives the correct output using the curl requests individually. However, using gdb, if I use curl to request hello.html after I've requested cat.html (specifically), I get a seg fault on this line(in load):
buffer = malloc(sizeof(BYTE) * size);
and using gdb, if I use curl to request cat.html and then request cat.html again (specifically), I get a seg fault on this line(in main):
path = malloc(strlen(root) + strlen(p) + 1);
which is what follows the parse function, so I assume it's seg faulting because of how I implemented parse.
Can someone please help me out?
Here's my load:
#define CHUNK 1024
bool load(FILE* file, BYTE** content, size_t* length)
{
BYTE *buffer, *buffer2;
size_t size, temp;
size = CHUNK;
temp = size;
buffer = malloc(sizeof(BYTE) * size);
size_t cur_len = 0;
while ((cur_len = fread(buffer, sizeof(BYTE), CHUNK, file)) > 0)
{
size += cur_len;
if (temp - size < CHUNK)
{
// buffer is too small, the next read could overflow!
temp *= 2;
buffer2 = malloc(sizeof(BYTE) * temp);
memcpy(buffer2, buffer, size * sizeof(BYTE));
free(buffer);
buffer = buffer2;
}
}
strcat(buffer, "\0");
*content = buffer;
*length = size;
return true;
}
and here's my parse:
bool parse(const char* line, char* abs_path, char* query)
{
// Extract 'method' string from 'line' string
int line_len = strlen(line);
char* temp = malloc(line_len);
char* method = malloc(line_len);
strcpy(temp, line);
strcpy(method, temp);
method = strtok(temp, " ");
// method spec
if((strlen(method)) != 3)
{
error(405);
return false;
}
if((strcasecmp(method, "get")) != 0)
{
error(405);
return false;
}
int j = 0;
while(j < line_len)
{
// only one space separating strings
if((line[j] == ' ') && (line[j + 1] == ' '))
{
error(400);
return false;
}
// filename must not have "
if (line[j] == '"')
{
error(400);
return false;
}
j++;
}
// HTTP Version spec
char* version = strcasestr(line, "HTTP/1.1");
if(version == NULL)
{
error(505);
return false;
}
// .exe is not valid
char* exe_file = strcasestr(line, ".exe");
if(exe_file != NULL)
{
error(501);
return false;
}
// Extract 'request-target' string from 'line' string
char* temp1 = malloc(line_len);
char* req_target = malloc(line_len);
strcpy(temp1, line);
strcpy(req_target, temp1);
req_target = strtok(temp1, " ");
if(strstr(line, "?") != NULL)
{
req_target = strtok(NULL, "?");
}
else
{
req_target = strtok(NULL, " ");
}
int tar_len = (strlen(req_target)) + 1;
char* temp2 = malloc(tar_len);
strcpy(temp2, req_target);
strcat(temp2, "\0");
// req_target spec
if(temp2[0] != '/')
{
error(501);
return false;
}
// CRCF spec
char* CRCF = strstr(line, "\r\n");
if(CRCF == NULL)
{
error(400);
return false;
}
// set new abs_path
strcpy(abs_path, temp2);
// Extract 'query' string from 'line' string
char* temp3 = malloc(line_len);
char* the_query = malloc(line_len);
strcpy(temp3, line);
strcpy(the_query, temp3);
char* quest_m = strchr(the_query, '?');
if(quest_m != NULL)
{
the_query = strtok(temp3, " ");
the_query = strtok(NULL, "?");
the_query = strtok(NULL, " ");
}
int qry_len = strlen(the_query) + 2;
// check if query exists
if(the_query != NULL)
{
char* char_eq = strchr(the_query, '=');
if(char_eq != NULL)
{
char* qry = malloc(qry_len);
strcpy(qry, the_query);
strcat(qry, "\0");
strcpy(query, qry);
}
else
{
char* qry = malloc(1);
strcpy(qry, "\0");
}
}
else
{
char* qry = malloc(1);
strcpy(qry, "\0");
}
return true;
}
valgrind -v --leak-check=full --show-leak-kinds=all --track-origins=yes ./server ./public
. Your parse is big onmalloc
.free
? not so much. When you find the solution, write it up as an answer so others might benefit from your work. You will be able to "accept" the answer after 2 days.mallocs
without correspondingfrees
in the parse function, I stopped reading and assumed (!) that was the problem. Shame on me. It's definitely part of the problem. I also chose to ignore the fact that l'il old cat.html at 156 bytes can slip under the memory leak radar, but it calls big bad cat.jpg at 26860 bytes, which will not. Working on a more complete analysis now. A leading indicator of problems with load: there is no realloc.