Xiao Jia's Blog

Learning Poco: A simple HTTP server

September 11th 2011

In this tutorial, we will write a simple HTTP server by using useful components provided by Poco.

For listening on a specific port, we need a HTTPServer and pass a ServerSocket and a HTTPRequestHandlerFactory to its constructor. Once a request is accepted, a new thread is created (possibly from a pool) to serve it. For serving a request, the HTTPRequestHandlerFactory is responsible to create a HTTPRequestHandler to handle it. After the request is served, the corresponding HTTPRequestHandler is destroyed.

The whole process is simple enough to learn directly from the following code. Note that we make use of Poco::Util::ServerApplication, especially waitForTerminationRequest, to ease the burden of writing a server skeleton.

#include <Poco/Net/ServerSocket.h>
#include <Poco/Net/HTTPServer.h>
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPRequestHandlerFactory.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <Poco/Util/ServerApplication.h>
#include <iostream>
#include <string>
#include <vector>

using namespace Poco::Net;
using namespace Poco::Util;
using namespace std;

class MyRequestHandler : public HTTPRequestHandler
{
public:
  virtual void handleRequest(HTTPServerRequest &req, HTTPServerResponse &resp)
  {
    resp.setStatus(HTTPResponse::HTTP_OK);
    resp.setContentType("text/html");

    ostream& out = resp.send();
    out << "<h1>Hello world!</h1>"
        << "<p>Count: "  << ++count         << "</p>"
        << "<p>Host: "   << req.getHost()   << "</p>"
        << "<p>Method: " << req.getMethod() << "</p>"
        << "<p>URI: "    << req.getURI()    << "</p>";
    out.flush();

    cout << endl
         << "Response sent for count=" << count
         << " and URI=" << req.getURI() << endl;
  }

private:
  static int count;
};

int MyRequestHandler::count = 0;

class MyRequestHandlerFactory : public HTTPRequestHandlerFactory
{
public:
  virtual HTTPRequestHandler* createRequestHandler(const HTTPServerRequest &)
  {
    return new MyRequestHandler;
  }
};

class MyServerApp : public ServerApplication
{
protected:
  int main(const vector<string> &)
  {
    HTTPServer s(new MyRequestHandlerFactory, ServerSocket(9090), new HTTPServerParams);

    s.start();
    cout << endl << "Server started" << endl;

    waitForTerminationRequest();  // wait for CTRL-C or kill

    cout << endl << "Shutting down..." << endl;
    s.stop();

    return Application::EXIT_OK;
  }
};

int main(int argc, char** argv)
{
  MyServerApp app;
  return app.run(argc, argv);
}

Save these lines into something like http_server.cc and compile it:

$ g++ -o http_server http_server.cc -lPocoNet -lPocoUtil

Then start the server: (We listen on port 9090 so there’s no need to become root)

$ ./http_server

Now open up your favorite browser and navigate to localhost:9090, you will see the server up and running!

RSS Feed Fork me on GitHub