I am getting a segmentation fault when I try to run access a page using the server, as well as 404 and 403 errors. I used Valgrind, and it states "Conditional jump or move depends on uninitialised value(s)" for needle1, needle2, among many others.
Could someone please give me a clue how to address this?
while (true) { // reset server's state reset();
// wait until client is connected
if (connected())
{
// parse client's HTTP request
ssize_t octets = parse();
if (octets == -1)
{
continue;
}
// extract request's request-line
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
const char* haystack = request;
char* needle = strstr(haystack, "\r\n");
if (needle == NULL)
{
error(400);
continue;
}
else if (needle - haystack + 2 > LimitRequestLine)
{
error(414);
continue;
}
char line[needle - haystack + 2 + 1];
strncpy(line, haystack, needle - haystack + 2);
line[needle - haystack + 2] = '\0';
// log request-line
printf("%s", line);
char* needle1 = strchr(line,32);
if (needle1 == NULL)
{
error(400);
continue;
}
char method[needle1-line+2+1];
strncpy(method,line,needle1-line);
method[needle1-line+2]='\0';
printf("The method is %s. The length is %lu.\n", method,strlen(method));//test line
char* needle2 = strrchr(line,32);
if (needle2 == NULL)
{
error(400);
continue;
}
char requesttarget[needle2-needle1+2];
strncpy(requesttarget,needle1+1,needle2-needle1-1);
requesttarget[needle2-needle1+1]='\0';
printf("The request-target is %s; it is %lu in length.\n", requesttarget,strlen(requesttarget));//test line
char* needle3 = strstr(line,"\r\n");
if (needle3 == NULL)
{
error(400);
continue;
}
char HTTPver[needle3-needle2];
strncpy(HTTPver,needle2+1,needle3-needle2-1);
HTTPver[needle3-needle2-1]='\0';
printf("The version is %s! The length is %lu.\n", HTTPver, strlen(HTTPver));//test line
// Complete?: validate request-line NO
// if method not GET, error 405
if (strcasecmp(method,"GET")!=0)
{
error(405);
printf("length method %lu; the method is %s.\n",strlen(method),method);
printf("length GET %lu\n",strlen("GET"));
}
// if request-target does not begin with /, error 501
if(strncmp(requesttarget,"/",1))
{
printf("Request-target does not being with backslash.\n");//my test comment
error(501);
}
// if request-target contains ", error 400
if(strchr(requesttarget,34)!=NULL)
{
error(400);
}
// if HTTP-version is not HTTP/1.1, error 505
if(strcasecmp(HTTPver,"HTTP/1.1")!=0)
{
printf("The HTTP version is %s-length is %lu. The first character is %c. The last character is %c.\n",HTTPver,strlen(HTTPver),HTTPver[0],HTTPver[strlen(HTTPver)-1]);
printf("The HTTP version is %s-length is %lu\n","HTTP/1.1",strlen("HTTP/1.1"));
error(505);
}
//if absolute-path does not contain ., error 501
char* absolutepath=requesttarget;
if(strchr(requesttarget,63)!=NULL)
{
int abspathlength=(requesttarget-strchr(requesttarget,63)-sizeof(char))/sizeof(char);
strncat(absolutepath,requesttarget,abspathlength);
}
/*if(strchr(requesttarget,46)==NULL)
{
printf("abs-path doesn't contain a period.\n");//my test comment
error(501);
}*/
// Complete?: extract query from request-target
char* s= strchr(requesttarget,63); //check here for an error in server.c
char* query="";
//char query[strchr(requesttarget,0)-s+1];//need to change here, makes no sense if null, can't move to if statement
if((s==NULL)||((s-requesttarget)==strlen(requesttarget)))
{
query= "";
}
else
{
strncpy(query,s+1,strchr(requesttarget,0)-s-1);
query[strchr(requesttarget,0)-s]='\0';
}
// Complete?: concatenate root and absolute-path
char* path = "";
strcat(root,absolutepath);
// Complete?: ensure path exists
if(access(path,F_OK)!=0)
{
error(404);
}
// Complete?: ensure path is readable
if(access(path,R_OK)!=0)
{
error(403);
}
// TODO: extract path's extension
char* ext= strchr(absolutepath,46);
char* extension = ext+sizeof(char);
// dynamic content
if (strcasecmp("php", extension) == 0)
{
// open pipe to PHP interpreter
char* format = "QUERY_STRING=\"%s\" REDIRECT_STATUS=200 SCRIPT_FILENAME=\"%s\" php-cgi";
char command[strlen(format) + (strlen(path) - 2) + (strlen(query) - 2) + 1];
sprintf(command, format, query, path);
file = popen(command, "r");
if (file == NULL)
{
error(500);
continue;
}
// load file
ssize_t size = load();
if (size == -1)
{
error(500);
continue;
}
// subtract php-cgi's headers from body's size to get content's length
haystack = body;
needle = memmem(haystack, size, "\r\n\r\n", 4);
if (needle == NULL)
{
error(500);
continue;
}
size_t length = size - (needle - haystack + 4);
// respond to client
if (dprintf(cfd, "HTTP/1.1 200 OK\r\n") < 0)
{
continue;
}
if (dprintf(cfd, "Connection: close\r\n") < 0)
{
continue;
}
if (dprintf(cfd, "Content-Length: %i\r\n", (int)length) < 0)
{
continue;
}
if (write(cfd, body, size) == -1)
{
continue;
}
}
// static content
else
{
// look up file's MIME type
const char* type = lookup(extension);
if (type == NULL)
{
printf("Mime type is null.");//my test comment
error(501);
continue;
}
// open file
file = fopen(path, "r");
if (file == NULL)
{
error(500);
continue;
}
// load file
ssize_t length = load();
if (length == -1)
{
error(500);
continue;
}
// TODO: respond to client
if (dprintf(cfd, "HTTP/1.1 200 OK\r\n") < 0)
{
continue;
}
if (dprintf(cfd, "Connection: close\r\n") < 0)
{
continue;
}
if (dprintf(cfd, "Content-Length: %i\r\n", (int)length) < 0)
{
continue;
}
if (dprintf(cfd, "Content-Type: %s\r\n", type) < 0)
{
continue;
}
if (write(cfd, body, length) == -1) //size undeclared
{
continue;
}
}
// announce OK
printf("\033[32m");
printf("HTTP/1.1 200 OK");
printf("\033[39m\n");
}
}