1 #include <ctime>
    2 #include <iostream>
    3 #include <sstream>
    4 #include <string>
    5 #include <cstdio>
    6 #include <unistd.h>
    7 
    8 // Network related includes
    9 #include <netinet/in.h> // sockaddr_in
   10 #include <sys/socket.h>
   11 #include <sys/types.h>
   12 
   13 using namespace std;
   14 
   15 // Returns UTC time in particular format.
   16 // e.g. Date: Thu, 03 Jun 2010 05:34:52 UTC
   17 string getHeaderTime() {
   18   time_t now = time(NULL);
   19   struct tm* timeinfo;
   20   timeinfo = gmtime(&now);
   21 
   22   char buff[80];
   23   memset(buff, 0, sizeof(buff));
   24   strftime(buff, 80, "Date: %a, %d %b %Y %X %Z", timeinfo);
   25   string s(buff);
   26   return s;
   27 }
   28 
   29 string get200Header() {
   30   stringstream head;
   31   head.clear();
   32   head << "HTTP/1.0 200 OK" << endl
   33        << getHeaderTime() << endl
   34        << "Expires: -1" << endl
   35        << "Cache-Control: private, max-age=0" << endl
   36        << "Content-Type: text/html; charset=ISO-8859-1\r\n\n";
   37   return head.str();
   38 }
   39 
   40 string getSimpleDoc() {
   41   stringstream resp;
   42   resp.clear();
   43   resp << "<html><head><title>47 Ways to Fun</title></head>"
   44        << "<body>Sample Document</body></html>"
   45        << "\r\n";
   46   return resp.str();
   47 }
   48 
   49 int main(int argc, char* argv[]) {
   50   static const int kBacklog = 50;
   51   static const int kPort = 8000;
   52   const string CRLF = "\r\n";
   53 
   54   int listenfd = socket(AF_INET, SOCK_STREAM, 0);
   55 
   56   struct sockaddr_in servaddr;
   57   memset(&servaddr, '\0', sizeof(servaddr));
   58   servaddr.sin_family = AF_INET;
   59   servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
   60   servaddr.sin_port = htons(kPort);
   61 
   62   if (bind(listenfd, (sockaddr *) &servaddr, sizeof(servaddr)) == -1) {
   63     cerr << "Error binding to port: " << kPort << endl;
   64     perror("bind error");
   65     exit(1);
   66   }
   67   listen(listenfd, kBacklog);
   68 
   69   int connfd;
   70   char buff[1024*8];
   71   while (true) {
   72     connfd = accept(listenfd, (struct sockaddr *) NULL, NULL);
   73     memset(buff, 0, sizeof(buff));
   74     recv(connfd, buff, 1024*8, 0);
   75     cout << "========================================================" << endl;
   76     cout << buff << endl;
   77 
   78     string head = get200Header();
   79     write(connfd, head.c_str(), head.length());
   80 
   81     string doc = getSimpleDoc();
   82     write(connfd, doc.c_str(), doc.length());
   83 
   84     close(connfd);
   85   }
   86   return 0;
   87 }