Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > dc51c7d3f8a5588a609f484ef81504ee > files > 119

libfastcgipp-devel-1.1-2mdv2010.0.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>fastcgi++: Hello World in Five Languages</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.5.6 -->
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="namespaces.html"><span>Namespaces</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
  <div class="navpath"><a class="el" href="index.html">index</a>
  </div>
</div>
<div class="contents">
<h1><a class="anchor" name="helloWorld">Hello World in Five Languages </a></h1><h2><a class="anchor" name="helloWorldTutorial">
Tutorial</a></h2>
Our goal here will be to make a FastCGI application that responds to clients with a "Hello World" in five different languages. Your going to need the boost C++ libraries for this. At least version 1.35.0. In this example we are going to use boost::asio to handle our timers and callback. Unfortunately because mod_fastcgi buffers the output before sending it to the client by default, we will only get to see the true effects of the timer if you put the following directive in your apache configuration: FastCgiConfig -flush<p>
All code and data is located in the examples directory of the tarball. Make sure to link this with the following library options: -lfastcgipp -lboost_thread<h3><a class="anchor" name="helloWorldError">
Error Logging</a></h3>
Our first step will be setting up an error logging system. Although requests can log errors directly to the HTTP server error log, I like to have an error logging system that's separate from the library when testing applications. Let's set up a function that takes a c style string and logs it to a file with a timestamp. Since everyone has access to the /tmp directory, I set it up to send error messages to /tmp/errlog. You can change it if you want to.<p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include &lt;fstream&gt;</span>
<span class="preprocessor">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt;</span>

<span class="keywordtype">void</span> error_log(<span class="keyword">const</span> <span class="keywordtype">char</span>* msg)
{
   <span class="keyword">using namespace </span>std;
   <span class="keyword">using namespace </span>boost;
   <span class="keyword">static</span> ofstream error;
   <span class="keywordflow">if</span>(!error.is_open())
   {
      error.open(<span class="stringliteral">"/tmp/errlog"</span>, ios_base::out | ios_base::app);
      error.imbue(locale(error.getloc(), <span class="keyword">new</span> posix_time::time_facet()));
   }

   error &lt;&lt; <span class="charliteral">'['</span> &lt;&lt; posix_time::second_clock::local_time() &lt;&lt; <span class="stringliteral">"] "</span> &lt;&lt; msg &lt;&lt; endl;
}
</pre></div><h3><a class="anchor" name="helloWorldRequest">
Request Handler</a></h3>
Now we need to write the code that actually handles the request. Quite simply, all we need to do is derive from <a class="el" href="classFastcgipp_1_1Request.html" title="Request handling class">Fastcgipp::Request</a> and define the <a class="el" href="classFastcgipp_1_1Request.html#b20544d056d5f288bca354b8c996e451" title="Response generator.">Fastcgipp::Request::response()</a> function. Since we've decided to use wide Unicode characters, we need to pass wchar_t as the template parameter to the Request class as opposed to char.<p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include &lt;<a class="code" href="request_8hpp.html" title="Defines the Fastcgipp::Request class.">fastcgi++/request.hpp</a>&gt;</span>

<span class="keyword">class </span>HelloWorld: <span class="keyword">public</span> Fastcgipp::Request&lt;wchar_t&gt;
{
</pre></div><p>
Now we can define our response function. It is this function that is called to generate a response for the client. It isn't a good idea to define the response() function inline as it is called from numerous spots, but for the examples readability we will make an exception.<p>
<div class="fragment"><pre class="fragment">   <span class="keywordtype">bool</span> response()
   {
</pre></div><p>
Let's define our hello world character strings we are going to send to the client. Unfortunately C++ doesn't yet support Unicode string literals, but it is just around the corner. Obviously we could have read this data in from a UTF-8 file, but in this example I found it easier to just use these arrays.<p>
<div class="fragment"><pre class="fragment">      <span class="keywordtype">wchar_t</span> russian[]={ 0x041f, 0x0440, 0x0438, 0x0432, 0x0435, 0x0442, 0x0020, 0x043c, 0x0438, 0x0440, 0x0000 };
      <span class="keywordtype">wchar_t</span> chinese[]={ 0x4e16, 0x754c, 0x60a8, 0x597d, 0x0000 };
      <span class="keywordtype">wchar_t</span> greek[]={ 0x0393, 0x03b5, 0x03b9, 0x03b1, 0x0020, 0x03c3, 0x03b1, 0x03c2, 0x0020, 0x03ba, 0x03cc, 0x03c3, 0x03bc, 0x03bf, 0x0000 };
      <span class="keywordtype">wchar_t</span> japanese[]={ 0x4eca, 0x65e5, 0x306f, 0x4e16, 0x754c, 0x0000 };
      <span class="keywordtype">wchar_t</span> runic[]={ 0x16ba, 0x16d6, 0x16da, 0x16df, 0x0020, 0x16b9, 0x16df, 0x16c9, 0x16da, 0x16de, 0x0000 };
</pre></div><p>
Any data we want to send to the client just get's inserted into the requests <a class="el" href="classFastcgipp_1_1Fcgistream.html" title="Stream class for output of client data through FastCGI.">Fastcgipp::Fcgistream</a> "out" stream. It works just the same as cout in almost every way. We'll start by outputting an HTTP header to the client. Note the "charset=utf-8" and keep in mind that proper HTTP headers are to be terminated with "\r\n\r\n"; not just "\n\n".<p>
<div class="fragment"><pre class="fragment">      out &lt;&lt; <span class="stringliteral">"Content-Type: text/html; charset=utf-8\r\n\r\n"</span>;
</pre></div><p>
Now we're ready to insert all the HTML data into the stream.<p>
<div class="fragment"><pre class="fragment">      out &lt;&lt; <span class="stringliteral">"&lt;html&gt;&lt;head&gt;&lt;meta http-equiv='Content-Type' content='text/html; charset=utf-8' /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"&lt;title&gt;fastcgi++: Hello World in UTF-8&lt;/title&gt;&lt;/head&gt;&lt;body&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"English: Hello World&lt;br /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"Russian: "</span> &lt;&lt; russian &lt;&lt; <span class="stringliteral">"&lt;br /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"Greek: "</span> &lt;&lt; greek &lt;&lt; <span class="stringliteral">"&lt;br /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"Chinese: "</span> &lt;&lt; chinese &lt;&lt; <span class="stringliteral">"&lt;br /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"Japanese: "</span> &lt;&lt; japanese &lt;&lt; <span class="stringliteral">"&lt;br /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"Runic English?: "</span> &lt;&lt; runic &lt;&lt; <span class="stringliteral">"&lt;br /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"&lt;/body&gt;&lt;/html&gt;"</span>;
</pre></div><p>
We'll also output a little hello to the HTTP server error log just for fun as well.<p>
<div class="fragment"><pre class="fragment">      err &lt;&lt; <span class="stringliteral">"Hello apache error log"</span>;
</pre></div><p>
And we're basically done defining our response! All we need to do is return a boolean value. Always return true if you are done. This will let apache and the manager know we are done so they can destroy the request and free it's resources. Return false if you are not finished but want to relinquish control and allow other requests to operate. You would do this if the request needed to wait for a message to be passed back to it through the task manager.<p>
<div class="fragment"><pre class="fragment">      <span class="keywordflow">return</span> <span class="keyword">true</span>;
   }
};
</pre></div><h3><a class="anchor" name="helloWorldManager">
Requests Manager</a></h3>
Now we need to make our main() function. Really all one needs to do is create a <a class="el" href="classFastcgipp_1_1Manager.html" title="General task and protocol management class.">Fastcgipp::Manager</a> object with the new class we made as a template parameter, then call it's handler. Let's go one step further though and set up a try/catch loop in case we get any exceptions and log them with our error_log function.<p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include &lt;<a class="code" href="manager_8hpp.html" title="Defines the Fastcgipp::Manager class.">fastcgi++/manager.hpp</a>&gt;</span>
<span class="keywordtype">int</span> main()
{
   <span class="keywordflow">try</span>
   {
      <a class="code" href="classFastcgipp_1_1Manager.html" title="General task and protocol management class.">Fastcgipp::Manager&lt;HelloWorld&gt;</a> fcgi;
      fcgi.<a class="code" href="classFastcgipp_1_1Manager.html#578c8468166d892d1858ad6f4d953d8d" title="General handling function to be called after construction.">handler</a>();
   }
   <span class="keywordflow">catch</span>(std::exception&amp; e)
   {
      error_log(e.what());
   }
}
</pre></div><p>
And that's it! About as simple as it gets.<h2><a class="anchor" name="helloWorldCode">
Full Source Code</a></h2>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt;</span>
<span class="preprocessor">#include &lt;fstream&gt;</span>
<span class="preprocessor">#include &lt;<a class="code" href="request_8hpp.html" title="Defines the Fastcgipp::Request class.">fastcgi++/request.hpp</a>&gt;</span>
<span class="preprocessor">#include &lt;<a class="code" href="manager_8hpp.html" title="Defines the Fastcgipp::Manager class.">fastcgi++/manager.hpp</a>&gt;</span>

<span class="keywordtype">void</span> error_log(<span class="keyword">const</span> <span class="keywordtype">char</span>* msg)
{
   <span class="keyword">using namespace </span>std;
   <span class="keyword">using namespace </span>boost;
   <span class="keyword">static</span> ofstream error;
   <span class="keywordflow">if</span>(!error.is_open())
   {
      error.open(<span class="stringliteral">"/tmp/errlog"</span>, ios_base::out | ios_base::app);
      error.imbue(locale(error.getloc(), <span class="keyword">new</span> posix_time::time_facet()));
   }

   error &lt;&lt; <span class="charliteral">'['</span> &lt;&lt; posix_time::second_clock::local_time() &lt;&lt; <span class="stringliteral">"] "</span> &lt;&lt; msg &lt;&lt; endl;
}

<span class="keyword">class </span>HelloWorld: <span class="keyword">public</span> Fastcgipp::Request&lt;wchar_t&gt;
{
   <span class="keywordtype">bool</span> response()
   {
      <span class="keywordtype">wchar_t</span> russian[]={ 0x041f, 0x0440, 0x0438, 0x0432, 0x0435, 0x0442, 0x0020, 0x043c, 0x0438, 0x0440, 0x0000 };
      <span class="keywordtype">wchar_t</span> chinese[]={ 0x4e16, 0x754c, 0x60a8, 0x597d, 0x0000 };
      <span class="keywordtype">wchar_t</span> greek[]={ 0x0393, 0x03b5, 0x03b9, 0x03b1, 0x0020, 0x03c3, 0x03b1, 0x03c2, 0x0020, 0x03ba, 0x03cc, 0x03c3, 0x03bc, 0x03bf, 0x0000 };
      <span class="keywordtype">wchar_t</span> japanese[]={ 0x4eca, 0x65e5, 0x306f, 0x4e16, 0x754c, 0x0000 };
      <span class="keywordtype">wchar_t</span> runic[]={ 0x16ba, 0x16d6, 0x16da, 0x16df, 0x0020, 0x16b9, 0x16df, 0x16c9, 0x16da, 0x16de, 0x0000 };

      out &lt;&lt; <span class="stringliteral">"Content-Type: text/html; charset=utf-8\r\n\r\n"</span>;

      out &lt;&lt; <span class="stringliteral">"&lt;html&gt;&lt;head&gt;&lt;meta http-equiv='Content-Type' content='text/html; charset=utf-8' /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"&lt;title&gt;fastcgi++: Hello World in UTF-8&lt;/title&gt;&lt;/head&gt;&lt;body&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"English: Hello World&lt;br /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"Russian: "</span> &lt;&lt; russian &lt;&lt; <span class="stringliteral">"&lt;br /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"Greek: "</span> &lt;&lt; greek &lt;&lt; <span class="stringliteral">"&lt;br /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"Chinese: "</span> &lt;&lt; chinese &lt;&lt; <span class="stringliteral">"&lt;br /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"Japanese: "</span> &lt;&lt; japanese &lt;&lt; <span class="stringliteral">"&lt;br /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"Runic English?: "</span> &lt;&lt; runic &lt;&lt; <span class="stringliteral">"&lt;br /&gt;"</span>;
      out &lt;&lt; <span class="stringliteral">"&lt;/body&gt;&lt;/html&gt;"</span>;

      err &lt;&lt; <span class="stringliteral">"Hello apache error log"</span>;

      <span class="keywordflow">return</span> <span class="keyword">true</span>;
   }
};

<span class="keywordtype">int</span> main()
{
   <span class="keywordflow">try</span>
   {
      <a class="code" href="classFastcgipp_1_1Manager.html" title="General task and protocol management class.">Fastcgipp::Manager&lt;HelloWorld&gt;</a> fcgi;
      fcgi.<a class="code" href="classFastcgipp_1_1Manager.html#578c8468166d892d1858ad6f4d953d8d" title="General handling function to be called after construction.">handler</a>();
   }
   <span class="keywordflow">catch</span>(std::exception&amp; e)
   {
      error_log(e.what());
   }
}
</pre></div> </div>
<hr size="1"><address style="text-align: right;"><small>Generated on Tue Sep 16 15:17:47 2008 for fastcgi++ by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.6 </small></address>
</body>
</html>