2025年10月30日 星期四

測試 fastcgi

幫助別人很容易, 請人家來幫助我們卻很困難。
網站技術我只會 cgi, 當然也聽過 fastcgi, 但直到 20251027, 靠著 chatgpt, 才成功使用 c 寫出 fastcgi 程式, 包含架設 lighttpd 大概花了 30 分鐘左右。參考: fastcgi by chatgpt

寫 cgi 免不了要架設 web server, 以前使用 apache2, 設定並不容易, 現在 Nginx 是主流, 但我不熟悉, 不想搞這個, chatgpt 列出了 lighttpd, 就你了,
sudo apt-get install lighttpd spawn-fcgi libfcgi-dev
輕鬆搞定 web server。

lighthttpd root 在 /etc/lighttpd/lighttpd.conf 定義
server.document-root = "/var/www/html"
sudo lighty-enable-mod fastcgi
輕鬆掛入 fastcgi 模組。

再來就是 list 1 fastcgi 的設定, 指定 fastcgi path。

最後就是 c 寫的 fastcgi 程式。

一般比較少用 c 寫 cgi 程式, 但我從接觸 cgi 以來, 就是用 c/c++ 寫, 那時候 perl 是最流行的 cgi 語言, 用 c/c++ 還真是難倒當時的我, 花了很多力氣才搞定。我用 cgicc 來幫忙處理 cgi 的輸入, 簡化許多操作。

把這些都集合起來, 就完成了 fastcgi, 多年來想做的終於完成。

在 debian unstable 上測試, 除了 list 1 的設定檔錯誤之外, 大多沒問題, 照這做就成功了。chatgpt 說明要編輯 15-fastcgi.conf, 但在我的系統上, 是編輯 list 1 這個檔案, 貼上 L5 ~ L17 內容即可。

list 1. /etc/lighttpd/conf-available/10-fastcgi.conf
 1 # /usr/share/doc/lighttpd/fastcgi.txt.gz
 2 # http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ConfigurationOptions#mod_fastcgi-fastcgi
 3
 4 server.modules += ( "mod_fastcgi" )
 5 fastcgi.server = (
 6     "/fcgi" => (
 7         (
 8             "socket" => "/tmp/hello_fcgi.socket",
 9             "bin-path" => "/usr/lib/cgi-bin/hello_fcgi",
10             "check-local" => "disable",
11             "max-procs" => 1,
12             "bin-environment" => (
13                 "LD_LIBRARY_PATH" => "/lib/x86_64-linux-gnu/"
14             )
15         )
16     )
17 )


hello_fcgi.c 是 fastcgi 範例, 使用了 libfcgi, 編譯指令:
gcc hello_fcgi.c -o hello_fcgi -lfcgi
hello_fcgi 放到 /usr/lib/cgi-bin/hello_fcgi
hello_fcgi.c
 1 #include <fcgi_stdio.h>
 2 #include <stdlib.h>
 3 
 4 int main(void) {
 5     int count = 0;
 6     while (FCGI_Accept() >= 0) {
 7         count++;
 8         printf("Content-Type: text/html\r\n\r\n");
 9         printf("<h1>Hello FastCGI</h1>\n");
10         printf("<p>Request #%d</p>\n", count);
11     }
12     return 0;
13 }


最後在瀏覽器貼上 http://localhost/fcgi 即可。

要使用 c++ 時, 發現問題蠻多的, 「只要 include 就 500 Internal Server Error」, 「發生 500 Internal Server Error」一般是類似 segmentation fault 之類的錯誤。但程式並沒有發生 segmentation fault。只要在 include fcgi_stdio.h 之前 include string, iostream 就可以避開。另外也不能用 cout, 一樣會「發生 500 Internal Server Error」, 似乎有個 fastcgipp 可以處理, 但我不想嘗試了。用 printf 沒什麼不好。include vector 就沒這問題, 可以放在 fcgi_stdio.h 之後。

d.cpp
 1 #include <string>
 2 #include <iostream>
 3
 4 #include <fcgi_stdio.h>
 5
 6 using namespace std;
 7
 8 int main() {
 9     int count = 0;
10     while (FCGI_Accept() >= 0) {
11         printf("Content-type: text/html\r\n\r\n");
12         printf("<h1>Hello from C++ FastCGI!</h1>\n");
13         #if 0
14         std::cout << "Content-type: text/html\r\n\r\n";
15         std::cout << "<html><body>";
16         std::cout << "<h1>Hello from C++ FastCGI!</h1>";
17         std::cout << "<p>Request #" << ++count << "</p>";
18         std::cout << "</body></html>" << std::endl;
19         #endif
20     }
21     return 0;
22 }

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。