I’m trying to write a simple HTTP web server using c, but I keep running into problems when trying to create it. Everything about creating the server socket seems to work fine; basically I just don’t understand how to send stuff to the browser. Here is the excerpt of my code in which the server loops to create socket connections with the client and then send stuff to the webpage:
for (;;) /* Run forever */
{
/* Set the size of the in-out parameter */
clntLen = sizeof(clntAddr);
/* Wait for a client to connect */
if ((clntSock = accept(servSock, (struct sockaddr *) &clntAddr,
&clntLen)) < 0)
DieWithError("accept() failed");
/* clntSock is connected to a client! */
printf("Handling client %s\n", inet_ntoa(clntAddr.sin_addr));
FILE *clientInput = fdopen(clntSock, "r");
char input[1000];
char html[BUFSIZE];
fgets(input, 1000, clientInput);
char *token_separators = "\t \r \n";
char *method = strtok(input, token_separators);
char *requestURI = strtok(NULL, token_separators);
char *httpVersion = strtok(NULL, token_separators);
...
char requestMessage[] = "HTTP/1.0 200 OK\r\n\r\n";
send(clntSock, requestMessage, strlen(requestMessage) + 1, 0);
...
}
I’m pretty sure that my code works for the socket creation and connections, it’s just when I try to send this response header my webpage just keeps trying to download the html. When I don’t send the response header and I jsut try to send normal html, my page works.
I guess what I don’t understand is why my response header will not work.
It is highly unusual to see
FILE *with sockets. It is more typical to useread/recvandwrite/send. This allows you to do error handling a bit more easily.That said, without a header the browser will think your server is running HTTP/0.9 — and everything is HTML. In order to get things working right, add another:
Of course, this is still missing some pieces, but it’s a start and most browsers should accept it without complaints. You can look through the RFC and find the request methods you need to support (GET and HEAD) and the response headers you are required to produce (Server, Date). (I hope you’re doing this for learning purposes, and not for production.)
You can test responses with netcat fairly easily:
Then browse to http://localhost:8000 . Note the above works with BSD netcat, if you have GNU netcat you will need to read the man page.