PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 0ms 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. #include <fstream>
  23. ///////////////////////////////////////////////////////////
  24. #include <boost/thread.hpp>
  25. #include <boost/date_time/posix_time/posix_time.hpp>
  26. #include <boost/program_options/environment_iterator.hpp>
  27. ///////////////////////////////////////////////////////////
  28. #include "boost/cgi/fcgi.hpp"
  29. using namespace std;
  30. using namespace boost;
  31. using namespace boost::fcgi;
  32. /// Handle one request and return.
  33. /**
  34. * If it returns != 0 then an error has occurred. Sets ec to the error_code
  35. * corresponding to the error.
  36. */
  37. int handle_request(fcgi::request& req, boost::system::error_code& ec)
  38. {
  39. // Construct a `response` object (makes writing/sending responses easier).
  40. response resp;
  41. // Responses in CGI programs require at least a 'Content-type' header. The
  42. // library provides helpers for several common headers:
  43. resp<< content_type("text/plain")
  44. // You can also stream text to a response object.
  45. << "Hello there, universe!";
  46. //log_<< "Handled request, handling another." << std::endl;
  47. return commit(req, resp);
  48. }
  49. /// The server is used to abstract away protocol-specific setup of requests.
  50. /**
  51. * This server only works with FastCGI, but as you can see in the
  52. * request_handler::handle_request() function above, the request in there could
  53. * just as easily be a cgi::request.
  54. *
  55. * Later examples will demonstrate making protocol-independent servers.
  56. * (**FIXME**)
  57. */
  58. class server
  59. {
  60. public:
  61. typedef fcgi::request request_type;
  62. typedef boost::function<
  63. int ( request_type&
  64. , boost::system::error_code&)
  65. > function_type;
  66. server(const function_type& handler)
  67. : handler_(handler)
  68. , service_()
  69. , acceptor_(service_)
  70. {}
  71. int run()
  72. {
  73. // Create a new request (on the heap - uses boost::shared_ptr<>).
  74. request_type::pointer new_request = request_type::create(service_);
  75. // Add the request to the set of existing requests.
  76. requests_.insert(new_request);
  77. int ret(0);
  78. for (;;)
  79. {
  80. boost::system::error_code ec;
  81. acceptor_.accept(*new_request, ec);
  82. if (ec)
  83. {
  84. std::cerr<< "Error accepting: " << ec.message() << std::endl;
  85. return 5;
  86. }
  87. // Load in the request data so we can access it easily.
  88. new_request->load(parse_all, ec); // Read and parse POST data and cookies.
  89. ret = handler_(*new_request, ec);
  90. if (ret)
  91. break;
  92. }
  93. return ret;
  94. }
  95. private:
  96. function_type handler_;
  97. fcgi::service service_;
  98. fcgi::acceptor acceptor_;
  99. std::set<request_type::pointer> requests_;
  100. };
  101. int main()
  102. try
  103. {
  104. server s(&handle_request);
  105. // Run the server in ten threads.
  106. // => Handle ten requests simultaneously
  107. boost::thread_group tgroup;
  108. for(int i(10); i != 0; --i)
  109. {
  110. tgroup.create_thread(boost::bind(&server::run, &s));
  111. }
  112. tgroup.join_all();
  113. }catch(boost::system::system_error& se){
  114. cerr<< "[fcgi] System error: " << se.what() << endl;
  115. return 1313;
  116. }catch(std::exception* e){
  117. cerr<< "[fcgi] Exception: " << e->what() << endl;
  118. return 666;
  119. }catch(...){
  120. cerr<< "[fcgi] Uncaught exception!" << endl;
  121. return 667;
  122. }
  123. //]