boa伺服器實現CGI功能

2021-08-20 13:29:40 字數 2925 閱讀 4923

cgi 是web 伺服器執行時外部程式的規範,按cgi 編寫的程式可以擴充套件伺服器功能。cgi 應用程式能與瀏覽器進行互動,還可通過資料庫api 與資料庫伺服器等外部資料來源進行通訊,從資料庫伺服器中獲取資料。格式化為html文件後,傳送給瀏覽器,也可以將從瀏覽器獲得的資料放到資料庫中。幾乎所有伺服器都支援cgi,可用任何語言編寫cgi,包括流行的c、c ++、vb 和delphi 等。cgi 分為標準cgi 和間接cgi兩種。標準cgi 使用命令列引數或環境變數表示伺服器的詳細請求,伺服器與瀏覽器通訊採用標準輸入輸出方式。間接cgi 又稱緩衝cgi,在cgi 程式和cgi 介面之間插入乙個緩衝程式,緩衝程式與cgi 介面間用標準輸入輸出進行通訊。

簡而言之:cgi就是web伺服器可以呼叫的其他程式,該程式將輸出重定向,在該程式中通過printf生成html,通過管道將資料發給web伺服器,完成互動。

boa cgi實現

1.boa獲取到資料時,執行process_requests()-->讀取http頭read_header()--->process_header_end();根據頭部資訊,獲取到該請求為cgi

2.執行init_cgi()

int init_cgi(request * req)

}#ifdef fascist_logging

#endif

if (req->is_cgi == cgi || 1)

/* set the read end of the socket to non-blocking */

if (set_nonblock_fd(pipes[0]) == -1)

}child_pid = fork();        //建立子程序,用於啟動cgi程式,程式執行完成後退出boa

switch(child_pid)

send_r_error(req);

/* fixme: there is aproblem here. send_r_error would work

for nph and cgi, but not for gunzip. fix that. */

/* i'd like to send_r_error, but.... */

return 0;

break;

case 0:

/* child */

if (req->is_cgi == cgi || req->is_cgi == nph)

c = strrchr(foo, '/');

if (c) else

if (chdir(foo) != 0)

}if (use_pipes)

close(pipes[1]);

if (set_block_fd(stdout_fileno) == -1)

} else

/* switch socket flags back to blocking */

if (set_block_fd(req->fd) == -1)

}/* tie post_data_fd to post stdin */

if (req->method == m_post)

/* close access log, so cgi program can't scribble

* where it shouldn't

*/close_access_log();

/** tie stderr to cgi_log_fd

* cgi_log_fd will automatically close, close-on-exec rocks!

* if we don't tied stderr (current log_error) to cgi_log_fd,

* then we ought to close it.

*/if (!cgi_log_fd)

dup2(devnullfd, stderr_fileno);

else

dup2(cgi_log_fd, stderr_fileno);

if (req->is_cgi) else

/* execve failed */

warn(req->pathname);

_exit(1);

break;

default:

/* parent */

/* if here, fork was successful */

if (verbose_cgi_logs)

if (req->method == m_post)

/* nph, gunzip, etc... all go straight to the fd */

if (!use_pipes)

return 0;

close(pipes[1]);

req->data_fd = pipes[0];            //儲存讀管道的fd

req->status = pipe_read;            //狀態置為pipe_read

if (req->is_cgi == cgi) else

/* reset req->filepos for logging (it's used in pipe.c) */

/* still don't know why req->filesize might be reset though */

req->filepos = 0;

break;

}return 1;                //more to do

}

3.下一次輪詢中,程式回到process_request,狀態為

pipe_read,準備讀取管道中的資料。讀取後,繼續輪詢,直至全部讀取完畢,狀態置為

pipe_write,將資料傳送給客戶端。(正是由於boa的這種輪詢機制,使得它可以處理多個請求而不會卡住)

BOA伺服器的搭建

本教程基於4412開發板 第一步 解壓原始碼 tar vxf boa 0.94.13.tar.gz 第二步 生成makefile編譯檔案 切換到src目錄 cd boa 0.94.13 src 執行.configure 這樣就可以生成 makefile檔案 第三步 修改makefile引數 修改編譯...

boa伺服器的搭建

www.boa.orgtar xvf boa 0.94 13.tar gz第二步 進入解壓後的資料夾 boa src執行 configure命令 生成makefile檔案 版本為第一步所示的版本,版本不對過程中可能會出現錯誤 configure error cannot guess build ty...

CGI伺服器原理

cgi伺服器原理 include include include include include include include intmain struct sockaddr in s add,c add unsigned short portnum 12345 char ip 192.168.3...