⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fcgi-devel-kit.htm

📁 FastCGI,语言无关的、可伸缩架构的CGI开放扩展
💻 HTM
📖 第 1 页 / 共 3 页
字号:
               &quot;&lt;title&gt;CGI Hello!&lt;/title&gt;&quot;               &quot;&lt;h1&gt;CGI Hello!&lt;/h1&gt;&quot;               &quot;Request number %d running on host &lt;i&gt;%s&lt;/i&gt;\n&quot;,               ++count, getenv(&quot;SERVER_NAME&quot;));    }</PRE>      <P>         The key features of this tiny CGI program are:      </P>      <UL TYPE="square">         <LI>            The program sends data to the Web server by writing to <TT>stdout</TT>, using <TT>printf</TT> in this            example. The CGI program first sends a <TT>Content-type</TT> header, then a small HTML document. The            program includes <TT>stdio.h</TT> in order to get access to the <TT>printf</TT> function.         </LI>         <LI>            The program obtains parameters provided by the Web server by reading environment variables. The CGI program            reads the <TT>SERVER_NAME</TT> variable using <TT>getenv</TT> and includes the value in the HTML document.            The program includes <TT>stdlib.h</TT> in order to get access to the <TT>getenv</TT> function.         </LI>      </UL>      <P>         The <TT>count</TT> variable is degenerate in this example; the CGI program runs a single request, so the         request number is always one. This variable will be more interesting in the FastCGI example.      </P>      <P>         <A NAME="S3.1.1">The</A> corresponding FastCGI program is <TT>examples/tiny-fcgi.c</TT>:      </P><PRE>    #include &quot;fcgi_stdio.h&quot;    #include &lt;stdlib.h&gt;    void main(void)    {        int count = 0;        while(FCGI_Accept() &gt;= 0)            printf(&quot;Content-type: text/html\r\n&quot;                   &quot;\r\n&quot;                   &quot;&lt;title&gt;FastCGI Hello!&lt;/title&gt;&quot;                   &quot;&lt;h1&gt;FastCGI Hello!&lt;/h1&gt;&quot;                   &quot;Request number %d running on host &lt;i&gt;%s&lt;/i&gt;\n&quot;,                    ++count, getenv(&quot;SERVER_NAME&quot;));    }</PRE>      <P>         The key features of this tiny FastCGI program are:      </P>      <UL TYPE="square">         <LI>            The program is structured as a loop that begins by calling the function <TT>FCGI_Accept</TT>. The            <TT>FCGI_Accept</TT> function blocks until a new request arrives for the program to execute. The program            includes <TT>fcgi_stdio.h</TT> in order to get access to the <TT>FCGI_Accept</TT> function.         </LI>         <LI>            Within the loop, <TT>FCGI_Accept</TT> creates a CGI-compatible world. <TT>printf</TT> and <TT>getenv</TT>            operate just as in the CGI program. <TT>stdin</TT> and <TT>stderr</TT>, not used by this tiny program, also            operate just as in a CGI program.         </LI>      </UL>      <P>         The <TT>count</TT> variable increments each time through the loop, so the program displays a new request         number each time. You can use the reload button in your browser to demonstrate this, once you&#39;ve got the         program built and running.      </P>      <H4>         Building the program      </H4>      <P>         If you can build <TT>examples/tiny-cgi.c</TT>, it will be straightforward for you to build         <TT>examples/tiny-fcgi.c</TT>. You need to:      </P>      <UL TYPE="square">         <LI>            Add the directory containing the <TT>fcgi_stdio.h</TT> header to the compiler&#39;s include search path.            The kit calls this directory <TT>include</TT>.         </LI>         <LI>            Add the library <TT>libfcgi.a</TT> to the linker&#39;s command line so that it will be searched when            linking. The <TT>libfcgi.a</TT> library implements the functions defined in <TT>fcgi_stdio.h</TT>. The kit            calls the directory containing this library <TT>libfcgi</TT>.         </LI>         <LI>            Determine whether or not the linker on your platform searches the Berkeley socket library by default, and            if not, add linker directives to force this search.         </LI>      </UL>      <P>         See <TT>examples/Makefile</TT> (created by <TT>configure</TT>) for a Makefile that builds both programs.         Autoconf handles the platform-dependent linking issues; to see how, examine <TT>configure.in</TT> and         <TT>examples/Makefile.in</TT>.      </P>      <H4>         Running the program      </H4>      <P>         <A HREF="#S4">Section 4</A> is all about how to run FastCGI applications.      </P>      <P>         You can use CGI to run application binaries built with the <TT>fcgi_stdio</TT> library. The         <TT>FCGI_Accept</TT> function tests its environment to determine how the application was invoked. If it was         invoked as a CGI program, the first call to FCGI_Accept is essentially a no-op and the second call returns         <TT>-1</TT>. In effect, the request loop disappears.      </P>      <P>         Of course, when a FastCGI application is run using CGI it does not get the benefits of FastCGI. For instance,         the application exits after servicing a single request, so it cannot maintain cached information.      </P>      <H4>         Implementation details      </H4>      <P>         <TT>fcgi_stdio.h</TT> works by first including <TT>stdio.h</TT>, then defining macros to replace essentially         all of the types and procedures defined in <TT>stdio.h</TT>. (<TT>stdio.h</TT> defines a few procedures that         have nothing to do with <TT>FILE *</TT>, such as <TT>sprintf</TT> and <TT>sscanf</TT>; <TT>fcgi_stdio.h</TT>         doesn&#39;t replace these.) For instance, <TT>FILE</TT> becomes <TT>FCGI_FILE</TT> and <TT>printf</TT> becomes         <TT>FCGI_printf</TT>. You&#39;ll only see these new names if you read <TT>fcgi_stdio.h</TT> or examine your C         source code after preprocessing.      </P>      <P>         Here are some consequences of this implementation technique:      </P>      <UL TYPE="square">         <LI>            On some platforms the implementation will break if you include <TT>stdio.h</TT> after including            <TT>fcgi_stdio.h</TT>, because <TT>stdio.h</TT> often defines macros for functions such as <TT>getc</TT>            and <TT>putc</TT>. Fortunately, on most platforms <TT>stdio.h</TT> is protected against multiple includes            by lines near the top of the file that look like <PRE>    #ifndef _STDIO_H    #define _STDIO_H   </PRE>            <P>               The specific symbol used for multiple-include protection, <TT>_STDIO_H</TT> in this example, varies from               platform to platform. As long as your platform protects <TT>stdio.h</TT> against multiple includes, you               can forget about this issue.            </P>         </LI>         <LI>            If your application passes <TT>FILE *</TT> to functions implemented in libraries for which you have source            code, then you&#39;ll want to recompile these libraries with <TT>fcgi_stdio.h</TT> included. Most C            compilers provide a command-line option for including headers in a program being compiled; using such a            compiler feature allows you to rebuild your libraries without making source changes. For instance the gcc            command line <PRE>    gcc -include /usr/local/include/fcgi_stdio.h wonderlib.c   </PRE>            <P>               causes gcc to include <TT>fcgi_stdio.h</TT> before it even begins to read the module               <TT>wonderlib.c</TT>.            </P>         </LI>         <LI>            If your application passes <TT>FILE *</TT> to functions implemented in libraries for which you do not have            source code, then you&#39;ll need to include the headers for these libraries <I>before</I> you include            <TT>fcgi_stdio.h</TT>. You can&#39;t pass the <TT>stdin</TT>, <TT>stdout</TT>, or <TT>stderr</TT> streams            produced by <TT>FCGI_Accept</TT> to any functions implemented by these libraries. You can pass a stream on            a Unix file to a library function by following this pattern: <PRE>    FILE *myStream = fopen(path, &quot;r&quot;);    answer = MungeStream(FCGI_ToFile(myStream));   </PRE>            <P>               Here <TT>MungeStream</TT> is a library function that you can&#39;t recompile and <TT>FCGI_ToFile</TT> is               a macro that converts from <TT>FCGI_FILE *</TT> to <TT>FILE *</TT>. The macro <TT>FCGI_ToFile</TT> is               defined in <TT>fcgi_stdio.h</TT>.            </P>         </LI>      </UL>      <H4>         Converting CGI programs      </H4>      <P>         The main task in converting a CGI program into a FastCGI program is separating the code that needs to execute         once, initializing the program, from the code that needs to run for each request. In our tiny example,         initializing the <TT>count</TT> variable is outside the loop, while incrementing the <TT>count</TT> variable         goes inside.      </P>      <P>         Retained application state may be an issue. You must ensure that any application state created in processing         one request has no unintended effects on later requests. FastCGI offers the possibility of significant         application performance improvements, through caching; it is up to you to make the caches work correctly.      </P>      <P>         Storage leaks may be an issue. Many CGI programs don&#39;t worry about storage leaks because the programs         don&#39;t run for long enough for bloating to be a problem. When converting to FastCGI, you can either use a         tool such as <A HREF="http://www.pure.com/"><I>Purify</I></A> from Pure Software to discover and fix storage         leaks, or you can run a C garbage collector such as <A HREF="http://www.geodesic.com/"><I>Great Circle</I></A>         from Geodesic Systems.      </P>      <H4>         Limitations      </H4>      <P>         Currently there are some limits to the compatibility provided by the <TT>fcgi_stdio</TT> library:      </P>      <UL TYPE="square">         <LI>            The library does not provide FastCGI versions of the functions <TT>fscanf</TT> and <TT>scanf</TT>. If you            wish to apply <TT>fscanf</TT> or <TT>scanf</TT> to <TT>stdin</TT> of a FastCGI program, the workaround is            to read lines or other natural units into memory and then call <TT>sscanf</TT>. If you wish to apply            <TT>fscanf</TT> to a stream on a Unix file, the workaround is to follow the pattern: <PRE>    FILE *myStream = fopen(path, &quot;r&quot;);    count = fscanf(FCGI_ToFile(myStream), format, ...);   </PRE>         </LI>      </UL>      <H4>         Reference documentation      </H4>      <P>         The <A HREF="FCGI_Accept.3"><TT>FCGI_Accept</TT> manpage</A>, <TT>doc/FCGI_Accept.3</TT>, describes the         function in the traditional format.      </P>      <P>         The <A HREF="FCGI_Finish.3"><TT>FCGI_Finish</TT></A> (<TT>doc/FCGI_Finish.3</TT>), <A HREF=         "FCGI_SetExitStatus.3"><TT>FCGI_SetExitStatus</TT></A> (<TT>doc/FCGI_SetExitStatus.3</TT>), and <A HREF=         "FCGI_StartFilterData.3"><TT>FCGI_StartFilterData</TT></A> (<TT>doc/FCGI_StartFilterData.3</TT>) manpages         document capabilities of the <TT>fcgi-stdio</TT> library that are not illustrated above.      </P>      <H4>         <A NAME="S3.2">3.2 Using the <TT>fcgiapp</TT> library</A>      </H4>      <P>         The <TT>fcgiapp</TT> library is a second C library for FastCGI. It does not provide the high degree of source         code compatibility provided by <TT>fcgi_stdio</TT>; in return, it does not make such heavy use of         <TT>#define</TT>. <TT>fcgi_stdio</TT> is implemented as a thin layer on top of <TT>fcgiapp</TT>.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -