patterncppMinor
Minimal webserver in C++
Viewed 0 times
minimalwebserverstackoverflow
Problem
Here's my test question for C++ programmer job:
Here's my code:
- Servers only static content, no cgi
- Single process, multithreaded
- 1000 concurrent request at least
- Valid http status codes and headers
- No external libraries, just STL, POSIX and glibc
Here's my code:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const char *response_200 = "HTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8\n\nHello!";
const char *response_400 = "HTTP/1.1 400 Bad Request\nContent-Type: text/html; charset=utf-8\n\nBad Request!";
const char *response_404 = "HTTP/1.1 404 Not Found\nContent-Type: text/html; charset=utf-8\n\nNot Found!";
void *handle_request(void *pcliefd)
{
int cliefd = *(int*)pcliefd;
delete (int *)pcliefd;
ssize_t n;
char buffer[255];
const char *response;
n = recv(cliefd, buffer, sizeof(buffer), 0);
if(n token_list;
for(int i = 0; i > token;
//printf("token %d %s\n", i, token.c_str());
token_list.push_back(token);
}
if(token_list.size() == 3
&& token_list[0] == "GET"
&& token_list[2].substr(0, 4) == "HTTP") {
if(token_list[1] == "/index.html") {
response = response_200;
} else {
response = response_404;
}
}
n = write(cliefd, response, strlen(response));
if(n sin_addr, s, sizeof(s));
printf("accept() %s\n", s);
int *pcliefd = new int;
*pcliefd = cliefd;
if(true) {
if(pthread_create(&thread, 0, handle_request, pcliefd) < 0) {
perror("pthread_create()");
}
} else {
handle_request(pcliefd);
}
}
return 0;
}Solution
-
The server announces HTTP 1.1, therefore it must support HTTP 1.1 features, most importantly pipelining (client has a right to send multiple requests over the same socket). In any case, if you chose to close the client socket immediately you should inform client with a
-
You expect to consume a complete request with a single
A correct way to read the request is to read it in the loop until the end of headers (i.e. an empty string) is seen.
-
Network program must be defensive. A malicious client can play tricks with your server.
For example, it may never send anything; eventually the server would run out of file descriptors (or pthreads), resulting in denial of service. Another client may close the socket immediately upon sending a request; the server receives a
The server announces HTTP 1.1, therefore it must support HTTP 1.1 features, most importantly pipelining (client has a right to send multiple requests over the same socket). In any case, if you chose to close the client socket immediately you should inform client with a
Connection: close header.-
You expect to consume a complete request with a single
read. In a streaming world of TCP you never know how many bytes has actually been consumed. You should be prepared to get as little as one byte at a time (same goes for send/write).A correct way to read the request is to read it in the loop until the end of headers (i.e. an empty string) is seen.
-
Network program must be defensive. A malicious client can play tricks with your server.
For example, it may never send anything; eventually the server would run out of file descriptors (or pthreads), resulting in denial of service. Another client may close the socket immediately upon sending a request; the server receives a
SIGPIPE and dies with a core dump.Context
StackExchange Code Review Q#83632, answer score: 7
Revisions (0)
No revisions yet.