Before I begin, I would like to say that I have no idea what I'm doing in this pset. By far it is the most complicated pset I have ever encountered.
When I check my solution with check50
this is what I get
:) 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
:( Requesting /test redirects to /test/
:( Requesting /test/ outputs /test/index.html
:( Requesting directory containing index.php outputs index.php
\ expected output, but not "HTTP/1.1 501 Not Implemented\r\nConnect..."
https://sandbox.cs50.net/checks/ec0dff122b7448cdaec90d5e50956a27
5 green lines and the rest are red. I don't understand what's going on.
This is my implementation for lookup()
const char* lookup(const char* extension)
{
if (extension != NULL)
{
if (strcasecmp("css", extension) == 0)
return "text/css";
if (strcasecmp("html", extension) == 0)
return "text/html";
if (strcasecmp("gif", extension) == 0)
return "image/gif";
if (strcasecmp("ico", extension) == 0)
return "image/x-icon";
if (strcasecmp("jpg", extension) == 0)
return "image/jpeg";
if (strcasecmp("js", extension) == 0)
return "text/javascript";
if (strcasecmp("png", extension) == 0)
return "image/png";
}
return NULL;
}
This is parse()
ssize_t parse(void)
{
// ensure client's socket is open
if (cfd == -1)
{
return -1;
}
// ensure request isn't already parsed
if (request != NULL)
{
return -1;
}
// buffer for octets
octet buffer[OCTETS];
// parse request
ssize_t length = 0;
while (true)
{
// read from socket
ssize_t octets = read(cfd, buffer, sizeof(octet) * OCTETS);
if (octets == -1)
{
error(500);
return -1;
}
// if octets have been read, remember new length
if (octets > 0)
{
request = realloc(request, length + octets);
if (request == NULL)
{
return -1;
}
memcpy(request + length, buffer, octets);
length += octets;
}
// else if nothing's been read, socket's been closed
else
{
return -1;
}
// search for CRLF CRLF
int offset = (length - octets < 3) ? length - octets : 3;
char* haystack = request + length - octets - offset;
char* needle = memmem(haystack, request + length - haystack, "\r\n\r\n", 4);
if (needle != NULL)
{
// trim to one CRLF and null-terminate
length = needle - request + 2 + 1;
request = realloc(request, length);
if (request == NULL)
{
return -1;
}
request[length - 1] = '\0';
break;
}
// if buffer's full and we still haven't found CRLF CRLF,
// then request is too large
if (length - 1 >= LimitRequestLine + LimitRequestFields * LimitRequestFieldSize)
{
error(413);
return -1;
}
}
return length;
}
This is load()
ssize_t load(void)
{
// ensure file is open
if (file == NULL)
{
return -1;
}
// ensure body isn't already loaded
if (body != NULL)
{
return -1;
}
// buffer for octets
octet buffer[OCTETS];
// read file
ssize_t size = 0;
while (true)
{
// try to read a buffer's worth of octets
ssize_t octets = fread(buffer, sizeof(octet), OCTETS, file);
// check for error
if (ferror(file) != 0)
{
if (body != NULL)
{
free(body);
body = NULL;
}
return -1;
}
// if octets were read, append to body
if (octets > 0)
{
body = realloc(body, size + octets);
if (body == NULL)
{
return -1;
}
memcpy(body + size, buffer, octets);
size += octets;
}
// check for EOF
if (feof(file) != 0)
{
break;
}
}
return size;
}