Nginx&C++實現簡單的fastcgi程式
1. 安裝spawn-fcgi (FastCGI程序管理器)
spawn-fcgi是一個通用的FastCGI程序管理器,簡單小巧,原先是屬於lighttpd的一部分,後來由於使用比較廣泛,所以就遷移出來作為獨立專案了。spawn-fcgi使用pre-fork 模型,功能主要是開啟監聽埠,繫結地址,然後fork-and-exec建立我們編寫的fastcgi應用程式程序,退出完成工作。fastcgi應用程式初始化,然後進入死迴圈偵聽socket的連線請求。
安裝spawn-fcgi:
- 解壓縮spawn-fcgi-x.x.x.tar.gz包。
- 進入解壓縮目錄,執行./configure。
- 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的程序數(C的CGI用這個)
-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