Changeset 44574


Ignore:
Timestamp:
Apr 19, 2008, 1:25:08 PM (10 years ago)
Author:
Darren Garvey
Message:

Small fixes to examples.

Location:
sandbox/SOC/2007/cgi/trunk/libs/cgi/example
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • sandbox/SOC/2007/cgi/trunk/libs/cgi/example/Jamfile.v2

    r43974 r44574  
    3939  ;
    4040
     41alias install : cgi//install acgi//install fcgi//install ;
     42
    4143explicit cgi-install  ;
    4244explicit acgi-install ;
  • sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/doc.qbk

    r43934 r44574  
    11
    22[section aCGI Examples]
     3
     4Things in the `acgi` namespace are 'Asio-enabled' versions of those in the `cgi` namespace. The aCGI (*a* for asynchronous) parts of the library are especially useful if you are writing long-running CGI applications that could benefit from using asynchronous I/O or asynchronous event dispatching.
     5
     6If not, there may be a small speed/size gain to be had from the plain CGI components.
    37
    48[include hello_world/doc.qbk]
  • sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/echo/main.cpp

    r43934 r44574  
    2020using namespace boost::cgi;
    2121
     22//
    2223// This function writes the title and map contents to the ostream in an
    2324// HTML-encoded format (to make them easier on the eye).
     25//
    2426template<typename OStreamT, typename MapT>
    2527void show_map_contents(OStreamT& os, MapT& m, const std::string& title)
    2628{
    2729  os<< "<h3>" << title << "</h3>";
    28   if (m.empty()) os<< "NONE<br />";
    29   for (typename MapT::iterator i = m.begin(); i != m.end(); ++i)
    30   {
    31     os<< "<b>" << i->first << "</b> = <i>" << i->second << "</i><br />";
    32   }
     30 
     31  if (m.empty())
     32    os<< "NONE<br />";
     33  else
     34    for (typename MapT::const_iterator i = m.begin(); i != m.end(); ++i)
     35      os<< "<b>" << i->first << "</b> = <i>"
     36                 << i->second << "</i><br />";
    3337}
    3438
    3539int main()
    3640{
    37   request req;
    38 
    39   req.load(true); // The 'true' means parse STDIN data too.
    40 
     41  request req; // A basic CGI request auto-parses everything (including POST data).
    4142  response resp;
    4243
  • sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/main.cpp

    r43917 r44574  
    2121//
    2222
    23 #include <fstream>
    24 #include <boost/bind.hpp>
    25 #include <boost/date_time/posix_time/posix_time.hpp>
    26 #include <boost/program_options/environment_iterator.hpp>
    27 
    2823#include <boost/cgi/fcgi.hpp>
     24#include "server.hpp"
    2925
    3026using namespace std;
    3127using namespace boost::fcgi;
    3228
    33 // This is a file to put internal logging info into
    34 #define LOG_FILE "/var/www/log/fcgi_server1.txt"
    35 
    3629// This function writes the title and map contents to the ostream in an
    3730// HTML-encoded format (to make them easier on the eye).
    38 template<typename Map, typename OStream>
    39 void format_map(Map& m, OStream& os, const std::string& title)
     31template<typename OStream, typename Map>
     32void format_map(OStream& os, Map& m, const std::string& title)
    4033{
    4134  os<< "<h2>" << title << "</h2>";
     
    4841}
    4942
    50 /// The handle_request member function is used to handle requests.
    51 /**
    52  * A struct is used here just so a single log file can be shared between
    53  * requests. Note that access to the log file isn't synchronised (this doesn't
    54  * matter with this example).
    55  */
    56 struct request_handler
     43/// The handle_request function handles a single request.
     44int handle_request(fcgi::request& req, boost::system::error_code& ec)
    5745{
    58   request_handler(const std::string& file_name)
    59     : log_(file_name.c_str())
    60   {
    61     if (!log_)
    62     {
    63       std::cerr<< "[fcgi] Couldn't open file: \"" LOG_FILE "\"." << endl;
    64       throw std::runtime_error("Couldn't open log file");
    65     }
     46  // Construct a `response` object (makes writing/sending responses easier).
     47  response resp;
    6648
    67     log_<< boost::posix_time::second_clock::local_time() << endl;
    68   }
    69  
    70   int handle_request(fcgi::request& req, boost::system::error_code& ec)
    71   {
    72     std::ofstream log_(LOG_FILE, std::ios::app);
    73     //log_<< "Handling request" << endl
    74     //    << "QUERY_STRING := " << req.query_string() << std::endl;
     49  // Responses in CGI programs require at least a 'Content-type' header. The
     50  // library provides helpers for several common headers:
     51  resp<< content_type("text/html")
     52      // You can also stream text to a response object.
     53      << "Hello there, universe!<p />";
    7554
    76     // Construct a `response` object (makes writing/sending responses easier).
    77     response resp;
     55  // Use the function defined above to show some of the request data.
     56  format_map(resp, req[env_data],    "Environment Variables");
     57  format_map(resp, req[get_data],    "GET Variables");
     58  format_map(resp, req[cookie_data], "Cookie Variables");
     59   // Response headers can be added at any time before send/flushing it:
     60  resp<< "<h3>Response Length</h3>" << resp.content_length()
     61      // response::content_length() returns the length of the *body*
     62      // of the response (ie. not including the headers).
     63      << content_length(resp.content_length());
    7864
    79     // Responses in CGI programs require at least a 'Content-type' header. The
    80     // library provides helpers for several common headers:
    81     resp<< content_type("text/html")
    82     // You can also stream text to a response object.
    83         << "Hello there, universe!<p />";
     65  // This funky macro finishes up:
     66  return_(resp, req, 0);
     67  // It is equivalent to the below, where the third argument is represented by
     68  // `program_status`:
     69  //
     70  // resp.send(req.client());
     71  // req.close(resp.status(), program_status);
     72  // return program_status;
     73  //
     74  // Note: in this case `program_status == 0`.
     75}
    8476
    85     // Use the function defined above to show some of the request data.
    86     format_map(req.env(), resp, "Environment Variables");
    87     format_map(req.GET(), resp, "GET Variables");
    88     format_map(req.cookie(), resp, "Cookie Variables");
    89 
    90     // Response headers can be added at any time before send/flushing it:
    91     resp<< "<content-length == " << content_length(resp.content_length())
    92         << content_length(resp.content_length());
    93 
    94     //log_<< "Handled request, handling another." << std::endl;
    95 
    96     // This funky macro finishes up:
    97     return_(resp, req, 0);
    98     // It is equivalent to the below, where the third argument is represented by
    99     // `program_status`:
    100     //
    101     // resp.send(req.client());
    102     // req.close(resp.status(), program_status);
    103     // return program_status;
    104     //
    105     // Note: in this case `program_status == 0`.
    106   }
    107 
    108 private:
    109   std::ofstream log_;
    110 };
    111 
    112 
    113 /// The server is used to abstract away protocol-specific setup of requests.
    114 /**
    115  * This server only works with FastCGI, but as you can see in the
    116  * request_handler::handle_request() function above, the request in there could
    117  * just as easily be a cgi::request.
    118  *
    119  * Later examples will demonstrate making protocol-independent servers.
    120  * (**FIXME**)
    121  */
    122 class server
    123 {
    124 public:
    125   typedef fcgi::request                         request_type;
    126   typedef boost::function<
    127             int ( request_type&
    128                 , boost::system::error_code&)
    129           >                                     function_type;
    130 
    131   server(const function_type& handler)
    132     : handler_(handler)
    133     , service_()
    134     , acceptor_(service_)
    135   {}
    136 
    137   int run()
    138   {
    139     // Create a new request (on the heap - uses boost::shared_ptr<>).
    140     request_type::pointer new_request = request_type::create(service_);
    141     // Add the request to the set of existing requests.
    142     requests_.insert(new_request);
    143    
    144     int ret(0);
    145     for (;;)
    146     {
    147       boost::system::error_code ec;
    148 
    149       acceptor_.accept(*new_request, ec);
    150 
    151       if (ec)
    152       {
    153         std::cerr<< "Error accepting: " << ec.message() << std::endl;
    154         return 5;
    155       }
    156  
    157       // Load in the request data so we can access it easily.
    158       new_request->load(ec, true); // The 'true' means read and parse POST data.
    159 
    160       ret = handler_(*new_request, ec);
    161 
    162       if (ret)
    163         break;
    164     }
    165     return ret;
    166   }
    167 
    168 private:
    169   function_type handler_;
    170   fcgi::service service_;
    171   fcgi::acceptor acceptor_;
    172   std::set<request_type::pointer> requests_;
    173 };
    174 
     77///////////////////////////////////////////////////////////
    17578int main()
     79///////////////////////////////////////////////////////////
    17680try
    17781{
    178   request_handler rh(LOG_FILE);
    179 
    180   server s(boost::bind(&request_handler::handle_request
    181                       , &rh, _1, _2)
    182           );
     82  server4 s(&handle_request);
    18383
    18484  return s.run();
    185  
    186 }catch(boost::system::system_error& se){
    187   cerr<< "[fcgi] System error: " << se.what() << endl;
     85
     86}
     87catch(boost::system::system_error& se){
     88  cerr<< "[fcgi] System error (" << se.code() << "): "
     89      << se.what() << endl;
    18890  return 1313;
    189 }catch(exception& e){
     91}
     92catch(exception& e){
    19093  cerr<< "[fcgi] Exception: " << e.what() << endl;
    19194  return 666;
    192 }catch(...){
    193   cerr<< "[fcgi] Uncaught exception!" << endl;
     95}
     96catch(...){
     97  cerr<< "[fcgi] Unknown exception!" << endl;
    19498  return 667;
    19599}
    196100//]
     101
Note: See TracChangeset for help on using the changeset viewer.