2013年11月27日 星期三

[懷舊] 開發 cgi 程式 (0)

你一定會說 cgi 落伍了吧, 現在的 web 系統用 cgi 來開發可能不太實際, 目前的 (2013) 網頁程式複雜度已經和十年前有所不同, 我是很認同這些觀念的, 除了落伍這個詞, 我比較喜歡用少用來代替落伍。

CGI 是我唯一學過的 web 技術, 從 cgi, isapi, nsapi, asp, jsp, php, asp.net, python framework, ruby on rails, 有些紅過, 有些已經被淘汰, 有些目前當紅, 未來還有哪些新星, 不知道, 不過 cgi 還是活得好好的就是, 所以就算經過十年了, 我現在還是可以用上 cgi。

以目前的網站生態來說, 用 cgi 開發可能是苦了點, 我也不是鼓勵使用 cgi 來開發目前的網站系統, 畢竟新東西還是有他厲害/方便的地方。

但是在某些資源比較緊的嵌入式系統, 還是有可能會需要用上以 c 來撰寫 cgi 程式, 所以這個老東西還是有發揮的地方。

我們來懷舊一下。

evn: ubuntu 12.04

install apache2
apt-get install apache2

cgi 麻煩的一點是它的設定, apache2 的設定很煩雜, 使用 ubuntu 預設值就好。不過似乎每個 web framework 都需要這耶煩雜的設定, apache2/cgi 的設定算是簡單。

查看系統預設的 cgi 設定值
/etc/apache2/sites-enabled/000-default

從 L16~22 可以得知, cgi 設定, cgi 程式放在 /usr/lib/cgi-bin/, url 則為: http://127.0.0.1/cgi-bin/cgi1

000-default
 1 <VirtualHost *:80>
 2     ServerAdmin webmaster@localhost
 3 
 4     DocumentRoot /var/www
 5     <Directory />
 6         Options FollowSymLinks
 7         AllowOverride None
 8     </Directory>
 9     <Directory /var/www/>
10         Options Indexes FollowSymLinks MultiViews
11         AllowOverride None
12         Order allow,deny
13         allow from all
14     </Directory>
15 
16     ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
17     <Directory "/usr/lib/cgi-bin">
18         AllowOverride None
19         Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
20         Order allow,deny
21         Allow from all
22     </Directory>
23 
24     ErrorLog ${APACHE_LOG_DIR}/error.log
25 
26     # Possible values include: debug, info, notice, warn, error, crit,
27     # alert, emerg.
28     LogLevel warn
29 
30     CustomLog ${APACHE_LOG_DIR}/access.log combined
31 
32     Alias /doc/ "/usr/share/doc/"
33     <Directory "/usr/share/doc/">
34         Options Indexes MultiViews FollowSymLinks
35         AllowOverride None
36         Order deny,allow
37         Deny from all
38         Allow from 127.0.0.0/255.0.0.0 ::1/128
39     </Directory>
40 
41 </VirtualHost>

cgi1 為我寫的 cgi 測試程式
/usr/lib/cgi-bin/cgi1.c
1 #include <stdio.h>
2 
3 int main(int argc, char *argv[])
4 {
5   printf("Content-type: text/plain\n\n");
6   printf("cgi test\n");
7 
8   return 0;
9 }

在瀏覽器打上:
http://127.0.0.1/cgi-bin/cgi1
就可看到結果。

讓使用者可以用自己的目錄來寫 cgi 程式, 這需要修改一點東西:
/etc/apache2/mods-enabled/userdir.conf
 1 <IfModule mod_userdir.c>
 2         UserDir public_html
 3         UserDir disabled root
 4 
 5         <Directory /home/*/public_html>
 6                 AllowOverride FileInfo AuthConfig Limit Indexes
 7                 Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec 
 8                 <Limit GET POST OPTIONS>
 9                         Order allow,deny
10                         Allow from all
11                 </Limit>
12                 <LimitExcept GET POST OPTIONS>
13                         Order deny,allow
14                         Deny from all
15                 </LimitExcept>
16         </Directory>
17         <Directory /home/*/public_html/cgi-bin>
18                 SetHandler cgi-script
19                 Options ExecCGI
20 
21         </Directory>
22 </IfModule>

L17 ~ 21 是我加入的, 這樣可以使用這樣的 url 執行 cgi:

http://127.0.0.1/~descent/cgi-bin/cgi1

cgi1 放在 /home/descent/public_html/cgi-bin/

如果有問題的話, 那就是哪裡沒設定好, 我前面提過, 設定 apache/cgi 並不是一件容易的事情。

在大學時期, cgi 是很流行的技術, 那時候是 isapi, nsapi 還存在的時代 (這個相對難很多, 而且 linux 不能用), 學習 cgi 讓我吃足了苦頭, 因為程式本身就有點難度, 而架設 web server 則是另外的關卡, 那時候查到的資料大多是使用 perl, 不容易找到使用 c 的 cgi 程式, 而解說 cgi 原理的資料就更少了。

我那時候堅持使用 c 來完成 cgi, 以我當時的功力簡直就是找死, cgi 需要處理很多字串, c style string 的能力很原始, 剛學習 c 的我根本無法掌控好這部份。

通常寫 c cgi 會去找個 cgi library 來使用, 省去煩雜的 html 編碼轉換, 我用過的是 c++ cgicc, 這是 c++ 的 cgi library, 不錯用。

ref:
http://blog.jangmt.com/2010/08/apache2-cgiperlpythonbash-shell.html

2 則留言:

  1. 可以試試 eserv,懷舊一下: https://github.com/tjjh89017/eserv

    回覆刪除
  2. 我不過要寫個 cgi, 你搬出個 web server 等級差太多了。

    回覆刪除

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

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