分类: LINUX
2013-03-25 10:55:11
CGI(The Common Gateway Interface):通用网关接口,定义web服务器和客户脚本进行信息交互的一系列标准。
二 web浏览器
为了了解CGI的概念,让我们来看看当我们单击一个超链接来浏览一个特定的web页或URL的时候,背后会发生什么事?
(1)浏览器首先会链接HTTP web 服务器并且请求一个URL 页面;
(2) WEB服务器将会解析这个URL并且查询请求的文件名,如果找到了请求文件服务器就会将这个文件发送回浏览器,否则发送回一个包含错误信息提示的页面指示你请求的是一个服务器并不包含的文件。
(3)WEB浏览器将接受来自服务器端的响应,并且向发出请求的用户显示接收到的文件。
然而,HTTP服务器也可能会以如何这种方式进行配置,那就是无论什么时候接受到对特定目录下的文件的请求,服务器不会将这个文件发送回客户端,而是它作为一个程序被服务器执行,并产生出输出发送回客户端浏览器进行显示。
CGI(The Common Gateway Interface)是一个标准化的协议,能够使应用程序(通常称为CGI程序或CGI脚本)同web服务器和客户端进行交互。CGI程序能够用 Python, PERL, Shell, C or C++等语言来实现。
三 CGI程序结构图
下图简单的展示了CGI程序架构
四 web服务器配置
在你着手写CGI程序之前,确保你的web服务器支持CGI程序并且配置成处理CGI程序。所有的能够被HTTP服务器执行的CGI程序都被存放在预先配 置好的目录下面,这个目录叫做CGI目录,并且按照约定命名为 /var/www/cgi-bin,并且约定CGI文件的后缀名为.cgi ,尽管它们是c++可执行文件。
一般的,Apache 服务器在/var/www/cgi-bin目录下配置文件来运行CGI程序,如果你想要声明另外的目录来运行CGI脚本,你需要修改httpd.conf 文件中的部分内容:
AllowOverride None Options ExecCGI Order allow,deny Allow from all Options All
五 第一个CGI脚本
以下是一段简短的CGI脚步代码
#includeusing namespace std; int main () { cout << "Content-type:text/html\r\n\r\n"; cout << "\n"; cout << "\n"; cout << " Hello World - First CGI Program \n"; cout << "\n"; cout << "\n"; cout << "Hello World! This is my first CGI program
\n"; cout << " \n"; cout << "\n"; return 0; }
编译上述代码并且将二进制可执行文件命名为cplusplus.cgi,保存路径为/var/www/cgi-bin目录下,运行chmod 755 cplusplus.cgi 命令使得该文件为可执行的。现在,如果你点击然后就会产生如下输出:
Hello World! This is my first CGI program
上面的C++程序是一个将输出写入标准输出文件(stdout)的简单程序。这段代码中有一个很重要的一点那就是第一行代码:Content- type:text/html\r\n\r\n,这行被发送回浏览器,指明浏览器显示的文本类型。现在你应该了解了CGI的基本概念了,你也可以使用 python写出更多复杂的CGI程序,C++ CGI程序能与其他任何外部系统进行信息交互,例如像RDBMS。
六 HTTP报文头部
这行字符串” Content-type:text/html\r\n\r\n”是发送回浏览器的HTTP报文头部的一部分,所有的HTTP报文头部都有如下格式:
HTTP Field Name: Field Content For Example Content-type: text/html\r\n\r\n
下表中包含其他一些重要的HTTP报文信息,这些信息在CGI编程中经常会用到。
Header | Description |
---|---|
Content-type: | A MIME string defining the format of the file being returned. Example is Content-type:text/html |
Expires: Date | The date the information becomes invalid. This should be used by the browser to decide when a page needs to be refreshed. A valid date string should be in the format 01 Jan 1998 12:00:00 GMT. |
Location: URL | The URL that should be returned instead of the URL requested. You can use this filed to redirect a request to any file. |
Last-modified: Date | The date of last modification of the resource. |
Content-length: N | The length, in bytes, of the data being returned. The browser uses this value to report the estimated download time for a file. |
Set-Cookie: String | Set the cookie passed through the string |
七 CGI环境变量
所有的CGI程序将会使用到下列的CGI环境变量,这些变量在CGI程序中起着重要的作用。
Variable Name | Description |
---|---|
CONTENT_TYPE | The data type of the content. Used when the client is sending attached content to the server. For example file upload etc. |
CONTENT_LENGTH | The length of the query information. It's available only for POST requests |
HTTP_COOKIE | Return the set cookies in the form of key & value pair. |
HTTP_USER_AGENT | The User-Agent request-header field contains information about the user agent originating the request. Its name of the web browser. |
PATH_INFO | The path for the CGI script. |
QUERY_STRING | The URL-encoded information that is sent with GET method request. |
REMOTE_ADDR | The IP address of the remote host making the request. This can be useful for logging or for authentication purpose. |
REMOTE_HOST | The fully qualified name of the host making the request. If this information is not available then REMOTE_ADDR can be used to get IR address. |
REQUEST_METHOD | The method used to make the request. The most common methods are GET and POST. |
SCRIPT_FILENAME | The full path to the CGI script. |
SCRIPT_NAME | The name of the CGI script. |
SERVER_NAME | The server's hostname or IP Address |
SERVER_SOFTWARE | The name and version of the software the server is running. |
下面这段代码列出了所有的CGI变量,点击可看结果。
#includeusing namespace std; const string ENV[ 24 ] = { "COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE", "HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING", "HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION", "HTTP_HOST", "HTTP_USER_AGENT", "PATH", "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT", "REQUEST_METHOD", "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_ADDR", "SERVER_ADMIN", "SERVER_NAME","SERVER_PORT","SERVER_PROTOCOL", "SERVER_SIGNATURE","SERVER_SOFTWARE" }; int main () { cout << "Content-type:text/html\r\n\r\n"; cout << "\n"; cout << "\n"; cout << " CGI Envrionment Variables \n"; cout << "\n"; cout << "\n"; cout << ""; for ( int i = 0; i < 24; i++ ) { cout << "
<\n"; cout << "\n"; cout << "\n"; return 0; }\n"; } cout << " " << ENV[ i ] << " "; // attempt to retrieve value of environment variable char *value = getenv( ENV[ i ].c_str() ); if ( value != 0 ){ cout << value; }else{ cout << "Environment variable does not exist."; } cout << "
八 C++CGI库
在该FTP服务器上 提供了C++ CGI库以供下载,我们从上面下载CGI 库并一下步骤进行安装:
$tar xzf cgicc-X.X.X.tar.gz
$cd cgicc-X.X.X/
$./configure --prefix=/usr
$make
$make install
并且你可以阅读相关文档。C++ CGI Lib Documentation 。
九 GET 与POST方法
当你需要从浏览器客户端传递信息至web服务器端并最终送至CGI程序的时候,你将必然会遇到很多的问题。大部分的浏览器使用两种方法发送信息至浏览器:GET方法和POST方法,进行过WEB开发的人应该对其很熟悉。
1. 使用GET方法发送信息
GET方法将编码过的用户信息附加在页面请求上发送,页面请求和这些编码信息使用?进行分割,如下所示:
GET方法是浏览器发送信息之服务器端所采用的默认的方法,采用这种方法发送时,在你的浏览器地址栏上在URL后面会附加上一串字符串,如果你传输密码或 其他敏感信息至服务器端的时候不要使用GET方法,GET方法有长度限制,在一个请求字符串中,最多只能发送1024的字符。
当使用GET方法的时候,HTTP报文头采用QUERY_STRING发送信息,并且将通过QUERY_STRING环境变量进入你的CGI程序。
您能够使用简单的键-值组合附加在URL后传递信息,或者你也可使用HTML中的