1、CGI环境变量
在/usr/local/apache/cgi-bin/下新建CGI脚本env.cpp:
#include <iostream>
#include <stdlib.h>
using 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<<"<html>\n";
cout<<"<head>\n";
cout<<"<title>CGI Envrionment Variables</title>\n";
cout<<"</head>\n";
cout<<"<body>\n";
cout<<"<table border=\"0\"cellspacing=\"2\">";
for(int i=0;i<24;i++)
{
cout<<"<tr><td>"<<ENV[i]<<"</td><td>";
char *value = getenv(ENV[i].c_str());
if(value!= 0)
{
cout << value;
}
else
{
cout<<"Environment variable does not exist.";
}
cout<<"</td></tr>\n";
}
cout<<"</table><\n";
cout<<"</body>\n";
cout<<"</html>\n";
return 0;
}
g++ -o env env.cpp
本地执行是获取不到环境变量的,只有放到cgi-bin下,在浏览器执行才可以。
开启http服务,浏览器输入以下内容
http://192.168.122.1/cgi-bin/env
2、GET方式获取参数
在 GET 方法下,CGI 程序无法直接从服务器的标准输入中获取数据, 因为服务器把它
从标准输入接收到 的数据编码到环境变量 QUERY_STRING (或 PATH_INFO )。采用 GET 方法时 , 只需将把这些数据附加到 URL 的末尾,如
http://192.168.122.1/cgi-bin/get?a=l&b=2&c=3 ,
这时候 QUERY_STRING 的值为 a=l&b=2&c=3
编写测试脚本
#include<iostream>
#include<stdlib.h>
#include<vector>
#include<string>
using namespace std;
/*分离字符串的函数
sData 是源字符串, sDelim 是分隔符,
返回值是分隔好的字符串列表*/
vector<string> StringSplit(const string& sData, const string& sDelim)
{
vector<string>vItems;
vItems.clear();
string::size_type bpos = 0;
string::size_type epos = 0;
string::size_type nlen = sDelim.size();
while ((epos=sData.find(sDelim, epos)) != string::npos)
{
vItems.push_back(sData.substr(bpos, epos-bpos));
epos += nlen;
bpos = epos;
}
vItems.push_back(sData.substr(bpos, sData.size()-bpos));
return vItems;
}
int main()
{
cout << "Content-type:text/html\r\n\r\n";
cout << "<html>\n";
cout << "<head>\n";
cout << "<title>Hello World - First CGI Program</title>\n";
cout << "</head>\n";
cout << "<body>\n";
cout<<"get parameter:<br/>";
char *value = getenv("QUERY_STRING");
if(value!= 0)
{
/*"a=1&b=2&c=3"*/
/*这里是获取 GET 参数的代码,先根据“&”符分隔,然后再根据“=”符进行二次分隔,
即可得到参数的内容 */
vector<string>paras=StringSplit((const string)value,"&");
vector<string>::iterator iter=paras.begin();
for(;iter!=paras.end();iter++)
{
vector<string>singlepara=StringSplit(*iter,"=");
cout<<singlepara[0]<<" "<<singlepara[1]<<"<br/>";
}
cout << "</body>\n";
cout << "</html>\n";
return 0;
}
}
编译好之后放到 apache/cgi-bin/ 目录下
在浏览器输入:
http://192.168.122.1/cgi-bin/get?a=1&b=2&c=3&d=4
3、POST方式获取参数
在 POST 方法下, CGI 程序可以直接从服务器的标准输入中获取数据,不过要先从
CONTENT_LENGTH 这个环境变量中得到 POST 参数的长度,然后再读取相应长度的内容。
编写测试脚本post.html
<html>
<head>
<title>CGI Post</title>
</head>
<body>
<tr><td>
<div style="font-weight:bold; font-size:15px">Method: POST</div>
<div>lease input two number:<div>
<form method="post" action="./cgi-bin/post">
<input type="txt" size="3" name="m">*
<input type="txt" size="3" name="n">=
<input type="submit" value="result">
</form>
</td></tr>
</table>
</body>
</html>
编写测试程序post.cpp
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
int main()
{
cout << "Content-type:text/html\r\n\r\n";
cout << "<html>\n";
cout << "<head>\n";
cout << "<title>Testing Post</title>\n";
cout << "</head>\n";
cout << "<body>\n";
char *lenstr =getenv("CONTENT_LENGTH");
if(lenstr==NULL)
{
cout<<"Error, CONTENT_LENGTH should be entered!"<<"<br/>";
}
else
{
int len=atoi(lenstr);
char poststr[20];
fgets(poststr,len+1,stdin);
cout<<"poststr:"<<poststr<<"<br/>";
char m[10],n[10];
//m=3&n=4
if(sscanf(poststr,"m=%[^&]&n=%s",m,n)!=2)//????
{
cout<<"Error: Parameters are not right!<br/>";
}
else
{
cout<<"m * n = "<<atoi(m)*atoi(n)<<"<br/>";
}
}
cout << "</body>\n";
cout << "</html>\n";
return 0;
}
g++ -o post post.cpp
拷贝post到/usr/local/apache/cgi-bin/ 下
拷贝post.html到/usr/local/apache/htdocs/ 下
浏览器输入:
http://192.168.122.1/post.html
输入数据,点击result
4、获取访问用户的IP
有时候定位问题时,需要知道用户的 IP 地址, 获取用户 IP 地址有两个环境变量 :
HTTP_VIA 和 REMOTE_ADDR。 当用户使用代理服务器访问时, HTTP_QVIA 环境变量的值不为空,用户的 IP 也就是代理服务器的 IP 了 。 用户没有用代理服务器访问时,则 IP 地址就在 REMOTE_ADDR 环境变量中了
#include<iostream>
#include<stdlib.h>
#include<cstring>
#include<stdio.h>
using namespace std;
//获取用户IP
std::string GetClientIP()
{
const char * p = getenv("REMOTE_ADDR");
if(p)
{
return p;
}
return "0.0.0.0";
}
int main()
{
cout << "Content-type:text/html\r\n\r\n";
cout << "<html>\n";
cout << "<head>\n";
cout << "<title>Testing Post</title>\n";
cout << "</head>\n";
cout << "<body>\n";
char *lenstr =getenv("CONTENT_LENGTH");
if(lenstr==NULL)
{
cout<<"Error, CONTENT_LENGTH should be entered!"<<"<br/>";
}
else
{
int len=atoi(lenstr);
char poststr[20];
fgets(poststr,len+1,stdin);
cout<<"poststr:"<<poststr<<"<br/>";
char m[10],n[10];
//m=3&n=4
if(sscanf(poststr,"m=%[^&]&n=%s",m,n)!=2)//????
{
cout<<"Error: Parameters are not right!<br/>";
}
else
{
cout<<"m * n = "<<atoi(m)*atoi(n)<<"<br/>";
}
}
cout<<"usr ip="<< GetClientIP() <<"<br/>";
cout << "</body>\n";
cout << "</html>\n";
return 0;
}
修改post.cpp后,再次运行