CGI的一些知識點
CGI(Common Gateway Interface)是能讓web伺服器和CGI指令碼共同處理客戶的請求的協議。它的協議定義文件是http://www.ietf.org/rfc/rfc3875。
其中Web伺服器負責管理連線,資料傳輸,網路互動等。至於CGI指令碼就負責管理具體的業務邏輯。
Web伺服器的功能是將客戶端請求(HTTP Request)轉換成CGI指令碼請求,然後執行指令碼,接著將CGI指令碼回復轉換為客戶端的回覆(HTTP Response)。
CGI的指令碼請求有兩部分:請求後設資料(request meta-variables)和相關的訊息體(message-body)。
請求後設資料
包含:
"AUTH_TYPE" | "CONTENT_LENGTH" | "CONTENT_TYPE" | "GATEWAY_INTERFACE" | "PATH_INFO" | "PATH_TRANSLATED" | "QUERY_STRING" | "REMOTE_ADDR" | "REMOTE_HOST" | "REMOTE_IDENT" | "REMOTE_USER" | "REQUEST_METHOD" | "SCRIPT_NAME" | "SERVER_NAME" | "SERVER_PORT" | "SERVER_PROTOCOL" | "SERVER_SOFTWARE" | scheme | protocol-var-name | extension-var-name
下面一個一個看:
AUTH_TYPE是唯一標識了使用者的認證方式,比如basic,Digest等
CONTENT_LENGTH是請求訊息體的長度
CONTENT_TYPE是標識訊息體的格式
GATEWAY_INTERFACE標識使用的CGI的版本,比如CGI/1.1
PATH_INFO說明了解釋CGI指令碼的地址
PATH_TRANSLATED就是可以被訪問的cgi的路徑,它對應CGI指令碼的路徑,比如
http://somehost.com/cgi-bin/somescript/this%2eis%2epath%3binfo
對應的PATH_INFO就是/this.is.the.path;info
QUERY_STRING 請求引數(GET的引數就是放在這個裡面的)
REMOTE_ADDR標識客戶端的ip地址
REMOTE_HOST標識的是客戶端的域名
REMOTE_IDENT是發出請求的使用者標示,大多數服務端選擇忽略這個屬性
REMOTE_USER是使用者的合法名稱
REQUEST_METHOD是請求方法,包括GET/POST/PUT/DELETE等
SCRIPT_NAME是指令碼程式的虛擬路徑,比如是/test/test.php
SERVER_NAME是WEB伺服器的域名
SERVER_PORT是WEB伺服器埠名
SERVER_PROTOCOL是WEB伺服器與客戶端的互動請求協議
SERVER_SOFTWARE傳送給客戶端的response的Web伺服器的標識,比如nginx/1.0.6
請求訊息體
就是直接將客戶端的請求訊息體轉發,將訊息體放在stdin中傳遞給script的
相關知識點
引數傳遞
下面的問題就是web伺服器獲取了http請求後,由於http請求是有分GET和POST等方法的。引數怎麼傳遞給可執行程式呢?
比如GET方法,CGI程式就會從環境變數QUERY_STRING中獲取資料。
POST呢?Web伺服器會通過stdin(標準輸入)想CGI中傳送資料的。而傳送的資料長度就是放在CONTENT_LENGTH中的。
對應於HTTP請求,QUERY_STRING存放http的GET引數,stdin存放HTTP的BODY引數
現在流行的nginx+php的方法就是使用nginx(web伺服器)將請求變成cgi請求到php-cgi上,然後php-cgi程式執行php,將返回值變成cgi response返回給nginx。nginx再將它變成http回覆返回給客戶端。
但是這裡有個問題,cgi是單程式的,一個程式的生命期就只是請求進來,處理,返回回覆這幾個階段。但是web伺服器都是需要接受多個web請求的,這裡就需要在後端開啟多個cgi了。一般的cgi伺服器都會設定允許開啟多少個cgi的數量的。
這裡要明確一點,cgi是有分服務端和客戶端的區別的,cgi客戶端是放在web伺服器一側,像nginx,apache這樣的web伺服器就已經是實現了這個客戶端。伺服器端需要另外重啟。像nginx+cgi+php這樣的配合就需要啟動php-cgi服務,當然你也可以想到這樣的服務一定是以deamon的形式在後臺執行,然後會fork出很多個cgi程式。
複用
當然有人會問,cgi程式不能複用是個問題,為什麼不呢,fastcgi出現就是解決了這個問題。它的一個程式可以處理多個請求。這樣速度當然就升上去了。然後還有一種cgi是scgi(simple cgi),scgi和fastcgi相似,只能說它定義的協議更簡單(所以才叫做simple)。scgi的客戶端是c寫的,服務端是perl寫的。
就最常見的nginx+cgi+php來說,要明確一點php中$_SERVER中獲取的資訊實際都是從cgi中獲取的,當然這個和nginx中獲取的客戶端資訊是一致的。另外由於cgi是有客戶端和服務端的區別的,因此很容易想到cgi客戶端需要使用tcp與客戶端連線,每個連線當然需要佔用一個埠,因此還是會有埠限制的。所以從這個角度上說,並不是cgi開的越多越好(當然6w的埠限制是遠遠夠的了)。
安全
關於開啟的cgi安全問題,曾經鳥哥就爆出了一個bug:http://www.laruence.com/2010/05/20/1495.html
有興趣的讀者可以看看。
還有cgi伺服器不是在監聽埠嗎?怎麼防止外網的請求執行cgi呢?我們一般的辦法就是直接繫結在127.0.0.1的ip地址上,保證只有本機才能訪問
本文轉自軒脈刃部落格園部落格,原文連結:http://www.cnblogs.com/yjf512/archive/2012/12/24/2830730.html,如需轉載請自行聯絡原作者
相關文章
- 一些cookie的知識點Cookie
- mysql的一些知識點MySql
- PLSQL一些常用的知識點SQL
- 關於AP的一些知識點
- vue的一些基礎知識點Vue
- python3 numpy的一些小知識點Python
- 一些關於IO流的知識點
- 關於Async、Await的一些知識點AI
- DIM中的一些知識點(慢更)
- jQuery常用的一些知識點總結jQuery
- 關於網頁的一些小知識點網頁
- hadoop的一些知識點 配置步驟Hadoop
- Vue一些知識點總結Vue
- java中的介面一些知識點———— 程式碼Java
- 一些有點奇怪的知識(持續更新)
- java NIO和Concurrent包的一些知識點Java
- PHP知識筆記:CGI,FastCGI,PHP-CGI,PHP-FPM,Spawn-FCGI區別PHP筆記AST
- cocos creator螢幕適配的一些知識點
- vue-router 一些容易被忽略的知識點Vue
- 簡歷表面的一些知識點(一)
- 關於高防伺服器的一些知識點伺服器
- 關於umijs+dva+antDesign 一些知識點的梳理JS
- GC(Allocation Failure)引發的一些JVM知識點梳理GCAIJVM
- 作業系統併發的一些知識點梳理作業系統
- 一些知識點的整理以及面試題記錄面試題
- day1 java concurrent包一些知識點Java
- 跨域資源共享 CORS 一些知識點跨域CORS
- JQuery的一些基本知識jQuery
- 整理一些CSS的知識CSS
- JS知識點:ES6 中常見的知識點JS
- app的知識點APP
- Linux 一些重點知識,整理的很全面,有必要收藏Linux
- 關於集合中一些常考的知識點總結
- Linux,Mac下MySQL的安裝及一些知識點的整理LinuxMacMySql
- JavaScript學習筆記 - 值的型別的一些知識點JavaScript筆記型別
- 知識點
- 初識python必知的6個知識點Python
- clickhouse的一些相關知識
- 域名防封的一些知識