1. 程式人生 > >Nginx&C++實現簡單的fastcgi程式

Nginx&C++實現簡單的fastcgi程式

1. 安裝spawn-fcgi (FastCGI程序管理器)

spawn-fcgi是一個通用的FastCGI程序管理器,簡單小巧,原先是屬於lighttpd的一部分,後來由於使用比較廣泛,所以就遷移出來作為獨立專案了。spawn-fcgi使用pre-fork 模型,功能主要是開啟監聽埠,繫結地址,然後fork-and-exec建立我們編寫的fastcgi應用程式程序,退出完成工作。fastcgi應用程式初始化,然後進入死迴圈偵聽socket的連線請求。

安裝spawn-fcgi:

  1. 解壓縮spawn-fcgi-x.x.x.tar.gz包。
  2. 進入解壓縮目錄,執行./configure。
  3. make & make install

如果遇到以下錯誤:“ ./autogen.sh: x: autoreconf: not found”,因為沒有安裝automake 工具,ubuntu用下面的命令安裝好就可以了:sudo apt-get install autoconf automake libtool 。

spawn-fcgi的幫助資訊可以通過man spawn-fcgi或spawn-fcgi –h獲得,下面是部分常用spawn-fcgi引數資訊:

-f <fcgiapp> 指定呼叫FastCGI的程序的執行程式位置
-a <addr> 繫結到地址addr。
-p <port> 繫結到埠port。
-s <path> 繫結到unix domain socket -C <childs> 指定產生的FastCGI的程序數,預設為5。(僅用於PHP-P <path> 指定產生的程序的PID檔案路徑。 -F <childs> 指定產生的FastCGI的程序數(CCGI用這個) -u和-g FastCGI使用什麼身份(-u 使用者 -g 使用者組)執行,CentOS下可以使用apache使用者,其他的根據情況配置,如nobody、www-data等。

2. 安裝fastcgi庫
sudo apt-get install libfcgi-dev

3. 編寫cgi程式
main.cpp

#include <iostream>  
#include <fcgi_stdio.h>  
#include "fcgi_config.h"  
#include <stdlib.h>
#include <sys/types.h>  

#ifdef HAVE_UNISTD_H  
#include <unistd.h>  
#endif  

using namespace std;  

int main(void)  
{  
    int i;  

    while(FCGI_Accept() >= 0){  

        printf("Content-type: text/html\r\n\r\n" \  
                "<html><head><title>Test</title></head>" \  
                "<body>%s %d " \
                "<br> SERVER_SOFTWARE:%s " \
                "<br> QUERY_STRING: %s " \
                "<br> REQUEST_METHOD: %s " \
                "<br> CONTENT_TYPE: %s " \
                "<br> CONTENT_LENGTH: %s " \
                "<br> SCRIPT_FILENAME: %s " \
                "<br> SCRIPT_NAME: %s " \
                "<br> REQUEST_URI: %s " \
                "<br> DOCUMENT_URI: %s " \
                "<br> DOCUMENT_ROOT: %s " \
                "<br> SERVER_PROTOCOL: %s " \
                "<br> REMOTE_ADDR: %s " \
                "<br> REMOTE_PORT: %s " \
                "<br> SERVER_ADDR: %s " \
                "<br> SERVER_PORT: %s " \
                "<br> SERVER_NAME: %s " \
                "</body></html>",
                "Hello World", i++,
                getenv("SERVER_SOFTWARE"),  
                getenv("QUERY_STRING"),  
                getenv("REQUEST_METHOD"),  
                getenv("CONTENT_TYPE"),  
                getenv("CONTENT_LENGTH"),  
                getenv("SCRIPT_FILENAME"),  
                getenv("SCRIPT_NAME"),  
                getenv("REQUEST_URI"),  
                getenv("DOCUMENT_URI"),  
                getenv("DOCUMENT_ROOT"),  
                getenv("SERVER_PROTOCOL"),  
                getenv("REMOTE_ADDR"),  
                getenv("REMOTE_PORT"),  
                getenv("SERVER_ADDR"),  
                getenv("SERVER_PORT"),  
                getenv("SERVER_NAME"));  
    }  

    return 0;  
} 

編譯:g++ -o main.cgi main.cpp -lfcgi
程式複雜當然可以寫一個makefile

編譯生成main.cgi後,執行spawn
spawn-fcgi -a 127.0.0.1 -p 8080 -f ./main.cgi

修改Nginx的配置檔案

        location ~ \.cgi$ {
            fastcgi_pass 127.0.0.1:8080;
            fastcgi_index index.fcgi;
            fastcgi_param SCRIPT_FILENAME /$fastcgi_script_name;
            include fastcgi_params;
        }

任何帶cgi的URL訪問都會指向main.cgi
然後用瀏覽器訪問127.0.0.1/test.cgi,就可以看到結果了

fastcgi監聽–>nginx連線上來–>fastcgi read,取得url和cookie這樣引數,寫到environ變數–>fastcgi以getenv方式取得引數

對於get請求來說,直接getenv(“QUERY_STRING”)就可以拿到,而對於post請求來說,引數是寫到標準輸入流中的,需要從stdin中讀取,或者 cin >> content