天天看點

重拾cgi——cgi dispatcher

java網頁寫多了,沒事用c++寫着玩。cgi,應該算是非常老了,它的最大好處,就是弄成可執行程式放進去就ok了。

因為平時隻會用apache,這裡使用的http伺服器都是apache2。

為了使用類似java servlet方式,自己來綁定uri和執行方法,通過寫一個dispatcher和rewrite來搞定。

首先,需要将所有通路重寫到這個dispatcher上,這裡是一個簡單的rewrite規則:

[cce]

rewriteengine on

rewriterule ^/cgi-bin/(.*)$ /cgi-bin/cppweb/$1 [l,pt,qsa]

[/cce]

這裡cppweb是一個編譯出來的可執行程式,rewrite後面的參數:

l:最後一條比對的規則

pt:執行完成後繼續執行其他處理(這裡主要是為了應用alias配置)

qsa:追加query string

這樣,如果請求/cgi-bin/a,内部會被重寫成/cgi-bin/cppweb/a。

後面就是cppweb的實作了。為了友善,對于cgi的處理,采用了gnu的cgicc庫,它對很對cgi操作進行了封裝。

大緻實作:

[cce lang=”cpp”]

int main(int argc, char **argv) {

register_url("/list", list, handle);

register_url("/video/new", videonew, handle);

cgicc::cgicc cgi;

cgicc::cgienvironment env = cgi.getenvironment();

cgicc::cgiinput input = cgicc::cgiinput();

ctemplate::template::settemplaterootdirectory(input.getenv("template_path"));

context ctx = {cgi, input, std::cout};

handler::instance().handlefunc(env.getpathinfo(), ctx);

return 0;

}

前面兩行暫時忽略,是用來對url和處理的函數進行綁定用的,後面進行介紹。這裡先建立cgicc對象,它主要封裝了cgi環境變量和輸入、輸出。這裡後面可以參考cgicc裡面的執行個體,将cgi改造成fastcgi。剛剛重寫的url,這裡可以通過cgi中的環境變量path info來或者,cgicc中将這個環境變量封裝成了一個獨立的方法。如剛才重寫後的url /cgi-bin/cppweb/a,這裡擷取到的path info就是/a,然後就可以通過/a和最終處理業務邏輯的函數綁定在一起就搞定了。

這裡還介紹下自定義環境變量的用法。上面的代碼裡面擷取了環境變量template_path,最為輸出模闆的查詢根路徑,直接在apache配置中增加:

setenv template_path /tmp/mycppweb/templates

這樣就能在運作時擷取到這個模闆路徑了,網站可以通過類似的方式定義其他參數,類似j2ee裡面的web.xml差不多吧。

轉載自:https://coolex.info/blog/338.html