boa是乙個單程序的web伺服器,支援cgi互動,瀏覽器每次傳送乙個poat請求,boa會對應fork乙個cgi程序,資料傳送完成後,cgi程序退出,儘管存在這樣的程序建立和銷毀的開銷,但boa仍然是一款輕量級的web伺服器,適用於需要較為簡單的web頁面訪問。下面對boa的主要部分進行**分析,包含get和post兩種方法。
get和post對客戶端請求資料的解析過程都差不多,get主要的函式為init_get,而post主要為init_cgi
1 get
1.1 get呼叫過程原始碼分析
if
(request_block)
fdset_update()
;process_requests
(server_s)
;read_header
(current)
;read()
//讀取客戶端發來的資料到req->client_stream
//解析請求行,獲取http版本和請求方法,url
process_logline()
process_option_line()
//解析每一行請求頭並儲存屬性值
process_header_end()
unescape_uri()
//如果請求行中有query_string,則解析
clean_pathname()
//確保url中路徑分隔符是'/'
translate_uri()
//解析出req->pathname,絕對路徑
req->status = write;
init_get
(req)
;//獲取請求的檔案並傳送
//如果在init_get中已經傳送完,則req->status = done;
//process_get就不會執行了
process_get()
//write 狀態機
呼叫系統write
()傳送get的檔案
free_request //釋放這次請求
release_mmap
(req->mmap_entry_var)
;munmap()
close()
//關閉fd
init_get
(req)
//pathname是路徑,一般會返回index.html
//如果是檔案,直接開啟檔案
open
(req->pathname, o_rdonly)
;fstat
(data_fd,
&statbuf)
;//獲取檔案資訊if(
s_isdir
(statbuf.st_mode)
)//路徑
data_fd =
get_dir
(req,
&statbuf)
;//獲取index.html
req->filesize = statbuf.st_size;
//mmap對映檔案
req->mmap_entry_var =
find_mmap
(data_fd,
&statbuf)
; req->data_mem = req->mmap_entry_var->mmap;
send_r_request_ok
(req)
;//copy響應行和頭到req->buffer
//copy響應體,也就是get的檔案內容
memcpy
(req->buffer + req->buffer_end, req->data_mem, bytes)
;req_flush
(req)
;//傳送響應行,響應頭,響應體
1.2 get呼叫過程記憶體資料傳輸圖
boa針對post方法會fork乙個子程序進行cgi的輸出,父子程序通過pipe進行通訊,程式主要呼叫過程如下所示
2.1 post**執行過程
process_requests
read_header
(current)
;//read_header狀態機
process_header_end()
unescape_uri()
//如果請求行中有query_string,則解析
clean_pathname()
//確保url中路徑分隔符是'/'
translate_uri()
//解析出req->pathname,絕對路徑
//建立臨時檔案
req->post_data_fd =
create_temporary_file(1
,null,0
);req->status = body_write;
req->header_line //執行請求體內容的開始
req->header_end //執行請求體內容的結束
write_body
(current)
;//body_write狀態機
write
(req->post_data_fd)
//向臨時檔案中傳送client的請求體
req->header_line = req->header_end = req->buffer;
init_cgi
(req)
; req->status = pipe_read;
req->header_line = req->header_end =
(req->buffer + buffer_size /2)
;read_from_pipe
(current)
;//pipe_read狀態機,從pipe中讀取cgi寫入的資料
bytes_read =
read
(req->data_fd,req->header_end)
header_end +
= bytes_read
req->status = pipe_write;
process_cgi_header
(req)
;send_r_request_ok
(req)
;//響應行和頭寫入req->buffer
dest = req->buffer + req->buffer_end;
howmuch = req->header_end - req->header_line;
memmove
(dest, req->header_line, howmuch)
; req->buffer_end +
= howmuch;
req->header_line = req->buffer + req->buffer_end;
req->header_end = req->header_line;
req_flush
(req)
;//傳送響應行、頭、體
write_from_pipe //pipe_write狀態機
write()
return0;
init_cgi
(req)
;pipe
(pipes)
child_pid =
fork()
; child
close
(pipes[0]
);dup2
(pipes[1]
, stdout_fileno)
close
(pipes[1]
);//從標準輸入中讀取臨時檔案的內容,即client的請求體
dup2
(req->post_data_fd, stdin_fileno)
;close
(req->post_data_fd)
;execve
(req->pathname, aar**, req->cgi_env)
;//執行cgi
parent
close
(req->post_data_fd)
; eq->post_data_fd =0;
close
(pipes[1]
);req->data_fd = pipes[0]
;//可以從pipe中讀取cgi寫入的響應體
req->status = pipe_read;
2.2 post程式執行過程中記憶體中資料流圖
交叉編譯嵌入式web伺服器boa
步驟大部分都一樣吧,只是交叉編譯器會有不同.第一步boa 程式的移植 目標板為xscale pxa270 交叉編譯器arm linux gcc 去網上下了乙份源 http www.boa.org cgipath the value of the path environment variable g...
嵌入式linux部署boa伺服器
在web伺服器中,較為常用的是tomcat,nigix。但是這種伺服器比較大,占用資源比較多,並不適合於嵌入式裝置中。而boa是乙個很輕便的web伺服器,部署簡單,占用資源少,支援多種語言。2.配置boa的編譯環境 安裝bison sudo apt get install bison安裝flex s...
嵌入式Web伺服器Boa的移植及其應用
隨著嵌入式技術的發展和高速寬頻網路的普及,利用網路實現遠端監控已為人們廣泛接受,嵌入式網路監控技術正是在此條件下逐步發展成熟起來的.1 嵌入式web 伺服器boa 的特點 boa 是一款單任務的http 伺服器,與其他傳統的web 伺服器不同的是當有連線請求到來時,它並不為每個連線單獨建立程序,也不...