# 6.1 CGI
HTTP協議早期設計是一個通信應答協議,服務器不記錄任何狀態。
簡單來說如下:
客戶端請求服務器上的abc.html,服務器給客戶端返回abc.html,完事兒結束。
想象一下客戶端如果持續請求abc.html 100次,那么服務器傻傻的提供100次,因為服務器根本不記錄任何狀態,所以你要了,我就給就是。
這樣設計的好處是足夠簡單,但是顯然不是那么合理。
但是WWW發展,需要HTTP協議有更加強大的功能,更多需要和服務器的交互。
打個比方,登錄淘寶時,每個用戶進入相同的頁面,但是輸入了不同的用戶名和密碼,然后提交到服務器。
提交到服務器之后,服務器需要對用戶名和密碼進行驗證。這種提交,顯然請求的不能是簡單的請求一個文件資源,而應該是調用服務器的某個方法,某個函數。
這個功能可以通過CGI來實現。
CGI是一個可執行程序,它能響應用戶的請求,這個可執行程序可以使用任何語言來編寫。
## 6.1 .CGI
通用網關接口(Common Gateway Interface/CGI)描述了客戶端和服務器程序之間傳輸數據的一種標準,可以讓一個客戶端,從網頁瀏覽器向執行在網絡服務器上的程序請求數據。CGI 獨立于任何語言的,CGI 程序可以用任何腳本語言或者是完全獨立編程語言實現,只要這個語言可以在這個系統上運行。Unix shell script, Python, Ruby, PHP, perl, Tcl, C/C++, 和 Visual Basic 都可以用來編寫 CGI 程序。
最初,CGI 是在 1993 年由美國國家超級電腦應用中心(NCSA)為 NCSA HTTPd Web 服務器開發的。這個 Web 服務器使用了 UNIX shell 環境變量 來保存從 Web 服務器傳遞出去的參數,然后生成一個運行 CGI 的獨立的進程。cgi的處理流程如下圖所示:

* step1. web 服務器收到客戶端(瀏覽器)的請求Http Request,啟動CGI程序,并通過環境變量、標準輸入傳遞數據
* step2. cgi進程啟動解析器、加載配置(如業務相關配置)、連接其它服務器(如數據庫服務器)、邏輯處理等
* step3. cgi程將處理結果通過標準輸出、標準錯誤,傳遞給web 服務器
* step4. web 服務器收到cgi返回的結果,構建Http Response返回給客戶端,并殺死cgi進程
web服務器與cgi通過環境變量、標準輸入、標準輸出、標準錯誤互相傳遞數據。
>在遇到用戶連接請求:
>1 先要創建cgi子進程,然后cgi子進程處理請求。處理完事退出這個子進程:fork-and-execute
>2 cgi方式是客戶端有多少個請求,就開辟多少個子進程,每個子進程都需要啟動自己的解釋器,加載配置,連接其他服務器等初始化工作,這是cgi進程性能低下的主要原因。當用戶請求非常多的時候,會大量的占用內存、cpu等資源。造成性能低下。
### 環境變量
GET請求,它將數據打包放置在環境變量QUERY_STRING中,CGI從環境變量QUERY_STRING中獲取數據。常見的環境變量如下表所示:
| 環境變數 | 內容 |
| -- | -- |
| AUTH_TYPE |存取認證類型。|
| CONTENT_LENGTH | 由標準輸入傳遞給CGI程序的數據長度,以bytes或字元數來計算。 |
| CONTENT_TYPE | 請求的MIME類型|
| GATEWAY_INTERFACE | 服務器的CGI版本編號。 |
| HTTP_ACCEPT |瀏覽器能直接接收的Content-types, 可以有HTTP Accept header定義. |
| HTTP_USER_AGENT |遞交表單的瀏覽器的名稱、版本 和其他平臺性的附加信息。 |
| HTTP_REFERER| 遞交表單的文本的 URL,不是所有的瀏覽器都發出這個信息,不要依賴它 |
| PATH_INFO | 傳遞給cgi程式的路徑信息|
| QUERY_STRING |傳遞給CGI程式的請求參數,也就是用"?"隔開,添加在URL后面的字串。|
| REMOTE_ADDR | client端的host名稱 |
| REMOTE_HOST | client端的IP位址。 |
| REMOTE_USER |client端送出來的使用者名稱。 |
| REMOTE_METHOD | client端發出請求的方法(如get、post)。 |
| SCRIPT_NAME | CGI程式所在的虛擬路徑,如/cgi-bin/echo。 |
| SERVER_NAME | server的host名稱或IP地址。 |
| SERVER_PORT| 收到request的server端口。 |
| SERVER_PROTOCOL |所使用的通訊協定和版本編號。 |
| SERVER_SOFTWARE | server程序的名稱和版本。|
## 標準輸入
環境變量的大小是有一定的限制的,當需要傳送的數據量大時,儲存環境變量的空間可能會不足,造成數據接收不完全,甚至無法執行CGI程序。因此后來又發展出另外一種方法:POST,也就是利用I/O重新導向的技巧,讓CGI程序可以由STDIN和STDOUT直接跟瀏覽器溝通。
當我們指定用這種方法傳遞請求的數據時,web 服務器收到數據后會先放在一塊輸入緩沖區中,并且將數據的大小記錄在CONTENT_LENGTH這個環境變數,然后調用CGI程式并將CGI程序的STDIN指向這塊緩沖區,于是我們就可以很順利的通過STDIN和環境變數CONTENT_LENGTH得到所有的資料,再沒有資料大小的限制了。
總結:CGI使外部程序與Web服務器之間交互成為可能。CGI程式運行在獨立的進程中,并對每個Web請求建立一個進程,這種方法非常容易實現,但效率很差,難以擴展。面對大量請求,進程的大量建立和消亡使操作系統性能大大下降。此外,由于地址空間無法共享,也限制了資源重用。
- 概要
- 1 分布式存儲fastDFS
- 1.1 fastDFS 通用介紹
- 1.2 fastDFS安裝和使用
- 1.3 基于fastDFS實現分布式
- 2 緩存數據庫redis快速搭建
- 2.1 環境安裝
- 2.2 redis數據類型
- 2.3 redis訂閱發布模式
- 2.4 redis事務
- 2.5 redis備份
- 3 redis詳細攻略
- 3.1 redis簡介
- 3.2 redis使用場景
- 3.3 redis基本操作
- 3.4 redis數據類型
- 3.4.1 字符串
- 3.4.2 HASH-字典
- 3.4.3 List-列表
- 3.4.4 Set-集合
- 3.4.5 Sorted Set-有序集合
- 3.4.6 訂閱-發布
- 3.4.7 事務
- 3.5 redis配置文件
- 3.6 持久化
- 3.7 redis性能測試
- 3.8 redis-C-API
- 3.9 redis-C++-API
- 3.10 總結與建議
- 4 memcache緩存數據庫
- 4.1 什么是memcached
- 4.2 memcached的特征
- 4.3 memcached的內存管理
- 4.4 如何使用memcached
- 4.5 memcached參數詳解
- 4.6 memcached安裝
- 4.7 memcached-C客戶端
- 4.8 memcached-C++客戶端
- 5 Nginx
- 6 FastCGI
- 6.1 CGI
- 6.2 FastCGI
- 6.3 Nginx與FastCGI
- 7 Nginx上部署fastDFS
- 8 項目概要
- 8.1 上傳文件功能
- 8.2 主界面顯示與下載文件功能
- 8.3 注冊功能
- 8.4 登陸功能
- 8.5 文件分類功能
- 8.6 個人網盤功能
- 8.8 秒傳功能