FastCGI軟件開發套件,開源的WebServer 2.0服務器包含I/O函數包用與簡化把已存在的CGI程序轉成FastCGI程序或者編寫FastCGI程序
I/O函數包
FastCGI軟件開發套件,開源的WebServer 2.0服務器包含I/O函數包用與簡化把已存在的CGI程序轉成FastCGI程序或者編寫FastCGI程序,在開發套件中有兩個函數包:fcgi_stdio 和 fcgiapp,在你的程序中必須包含這些包中的一個:
fcgi_stdio.h fcgiapp.h fcgi_stdio包,是fcgiapp包的頂層包,在轉化CGI程序或者是寫新的FastCGI程序是,我們強烈推薦你用它,fcgi_stdio包有以下幾個優點:
簡單:只要有三個性的API需要學。
易懂:如果你正包CGI程序轉化為FastCGI程序,你會發現CGI程序與FastCGI程序之間只有很少的區別。在我們設計函數庫的時候我們盡可能的 把FastCGI應用程序變得容易理解,以至於我們在建立新FastCGI程序的時候我們使用相同的環境變量,相同的解析查詢字符串的技術,以及相同的 I/O程序等。
方便:這個庫函數提供了CGI和FastCGI二進制的文件的完美兼容。因此不管是CGI還是FastCGI,都同樣運行。
代碼結構
FastCGI的代碼構成,把你的代碼分成兩個獨立部分:
1.初始化部分:只執行一次
2.應答循環部分:FastCGI腳本每被調用一次,這部分九被執行一次
一個應答循環的典型格式如下:
while (FCGI_Accept() >= 0) {//循環條件
# 應答循環體
}
知道一個客戶端請求來的時候FCGI_Accept塊才執行,並返回0。如果有一個系統故障,或是系統管理員終止進程,Accept將返回-1。
如果應用程序作為一個CGI程序被調用,那麼第一次調用Accept時,返回0,第二次總是返回-1,產生CGI行為。(請詳見20頁的"FCGI_Accept (3)" )
注意,在CGI中鼓勵用小腳本,然而在FastCGI中則鼓勵使用組合式的腳本。你可以在從新構想你的程序的全局結構,來獲得FastCGI的高性能。
例1: TinyFastCGI
這是一個用C語言寫的一個簡單FastCGI應答程序例子:
#include "fcgi_stdio.h"
#include <stdlib.h>
int count;
void initialize(void)
{
count=0;
}
void main(void)
{
initialize();
while (FCGI_Accept() >= 0) {
printf("Content-type: text/html\r\n"
"\r\n"
"<title>FastCGI Hello! (C, fcgi_stdio library)</title>"
"<h1>FastCGI Hello! (C, fcgi_stdio library)</h1>"
"Request number %d running on host <i>%s</i>\n",
++count, getenv("SERVER_HOSTNAME"));
}
}
例2:原始數據產生器
思考一下,一個應答應用程序產生第N次原始數據。
一個CGI應用程序將沒有有效的方法來解決這個問題。例如,如果用戶訪問第50000次的原始數據,那麼CGI應用程序就不許從第一條原始數據開始計算,知道第50000條的,要是應用程序終止,伴隨著她辛苦積累的數據也會隨之消失。
如果一個客戶端想訪問第4900條原始數據,那麼服務器必須重新開始積累。
由於我們能維持這個狀態,FastCGI應用程序對與這樣的問題就更有效。一個FastCGI應用程序在初始化階段能夠計算一個擴展的源數據的表,並保持表的不同范圍。當客戶端請求一個特別原始數據的時候,循環應答需要從表裡查詢。
這裡有一個原始數據代碼事例:
#include "fcgi_stdio.h"
#include <stdlib.h>
#include <string.h>
#define POTENTIALLY_PRIME 0
#define COMPOSITE 1
#define VALS_IN_SIEVE_TABLE 1000000
#define MAX_NUMBER_OF_PRIME_NUMBERS 78600
long int sieve_table[VALS_IN_SIEVE_TABLE];
long int prime_table[MAX_NUMBER_OF_PRIME_NUMBERS];
void
initialize_prime_table(void)
{
long int prime_counter=1;
long int current_prime=2, c, d;
prime_table[prime_counter]=current_prime;
while (current_prime < VALS_IN_SIEVE_TABLE) {
for (c = current_prime; c <= VALS_IN_SIEVE_TABLE;
c += current_prime) {
sieve_table[c] = COMPOSITE;
}
for (d=current_prime+1; sieve_table[d] == COMPOSITE; d++);
prime_table[++prime_counter]=d;
current_prime=d;
}
}
void main(void)
{
char *query_string;
long int n;
initialize_prime_table();
while(FCGI_Accept() >= 0) {
printf("Content-type: text/html\r\n"
"\r\n");
printf("<title>Prime FastCGI</title>\n"
"<h1>Prime FastCGI</h1>\n");
query_string = getenv("QUERY_STRING");
if(query_string == NULL) {
printf("Usage: Specify a positive number in the query string.\n");
} else {
query_string = strchr(query_string, `=') + 1;
n = strtol(query_string);
if(n < 1) {
printf("The query string `%s' is not a positive number.\n",
query_string);
} else if(n > MAX_NUMBER_OF_PRIME_NUMBERS) {
printf("The number %d is too large for this program.\n", n);
} else{
printf("The %ldth prime number is %ld.\n", n, prime_table[n]);
}
}
}
}
這個應用程序在初始化時有一個顯而意見的開銷,但是後來的訪問是快速的。
*