PageRenderTime 103ms CodeModel.GetById 61ms app.highlight 9ms RepoModel.GetById 31ms app.codeStats 0ms

/libs/cgi/example/fcgi/server3/main.cpp

http://github.com/darrengarvey/cgi
C++ | 142 lines | 75 code | 19 blank | 48 comment | 5 complexity | 84950de0dda07ed6db67c1d97db8a6e4 MD5 | raw file
  1//                 -- server3/main.hpp --
  2//
  3//           Copyright (c) Darren Garvey 2007.
  4// Distributed under the Boost Software License, Version 1.0.
  5//    (See accompanying file LICENSE_1_0.txt or copy at
  6//          http://www.boost.org/LICENSE_1_0.txt)
  7//
  8////////////////////////////////////////////////////////////////
  9//
 10//[fcgi_server3
 11//
 12// This example simply echoes all variables back to the user. ie.
 13// the environment and the parsed GET, POST and cookie variables.
 14// Note that GET and cookie variables come from the environment
 15// variables QUERY_STRING and HTTP_COOKIE respectively.
 16//
 17// It is a demonstration of how a 'server' can be used to abstract
 18// away the differences between FastCGI and CGI requests.
 19//
 20// This is very similar to the fcgi_echo example.
 21//
 22
 23#include <fstream>
 24///////////////////////////////////////////////////////////
 25#include <boost/thread.hpp>
 26#include <boost/date_time/posix_time/posix_time.hpp>
 27#include <boost/program_options/environment_iterator.hpp>
 28///////////////////////////////////////////////////////////
 29#include "boost/cgi/fcgi.hpp"
 30
 31using namespace std;
 32using namespace boost;
 33using namespace boost::fcgi;
 34
 35/// Handle one request and return.
 36/**
 37 * If it returns != 0 then an error has occurred. Sets ec to the error_code
 38 * corresponding to the error.
 39 */
 40int handle_request(fcgi::request& req, boost::system::error_code& ec)
 41  {
 42    // Construct a `response` object (makes writing/sending responses easier).
 43    response resp;
 44
 45    // Responses in CGI programs require at least a 'Content-type' header. The
 46    // library provides helpers for several common headers:
 47    resp<< content_type("text/plain")
 48    // You can also stream text to a response object. 
 49        << "Hello there, universe!";
 50
 51    //log_<< "Handled request, handling another." << std::endl;
 52
 53    return commit(req, resp);
 54  }
 55
 56/// The server is used to abstract away protocol-specific setup of requests.
 57/**
 58 * This server only works with FastCGI, but as you can see in the
 59 * request_handler::handle_request() function above, the request in there could
 60 * just as easily be a cgi::request.
 61 *
 62 * Later examples will demonstrate making protocol-independent servers.
 63 * (**FIXME**)
 64 */
 65class server
 66{
 67public:
 68  typedef fcgi::request                         request_type;
 69  typedef boost::function<
 70            int ( request_type&
 71                , boost::system::error_code&)
 72          >                                     function_type;
 73
 74  server(const function_type& handler)
 75    : handler_(handler)
 76    , service_()
 77    , acceptor_(service_)
 78  {}
 79
 80  int run()
 81  {
 82    // Create a new request (on the heap - uses boost::shared_ptr<>).
 83    request_type::pointer new_request = request_type::create(service_);
 84    // Add the request to the set of existing requests.
 85    requests_.insert(new_request);
 86    
 87    int ret(0);
 88    for (;;)
 89    {
 90      boost::system::error_code ec;
 91
 92      acceptor_.accept(*new_request, ec);
 93
 94      if (ec) 
 95      {
 96        std::cerr<< "Error accepting: " << ec.message() << std::endl;
 97        return 5;
 98      }
 99  
100      // Load in the request data so we can access it easily.
101      new_request->load(parse_all, ec); // Read and parse POST data and cookies.
102
103      ret = handler_(*new_request, ec);
104
105      if (ret)
106        break;
107    }
108    return ret;
109  }
110
111private:
112  function_type handler_;
113  fcgi::service service_;
114  fcgi::acceptor acceptor_;
115  std::set<request_type::pointer> requests_;
116};
117
118int main()
119try
120{
121  server s(&handle_request);
122
123  // Run the server in ten threads.
124  // => Handle ten requests simultaneously
125  boost::thread_group tgroup;
126  for(int i(10); i != 0; --i)
127  {
128    tgroup.create_thread(boost::bind(&server::run, &s));
129  }
130  tgroup.join_all();
131  
132}catch(boost::system::system_error& se){
133  cerr<< "[fcgi] System error: " << se.what() << endl;
134  return 1313;
135}catch(std::exception* e){
136  cerr<< "[fcgi] Exception: " << e->what() << endl;
137  return 666;
138}catch(...){
139  cerr<< "[fcgi] Uncaught exception!" << endl;
140  return 667;
141}
142//]