`
ruilinruirui
  • 浏览: 1046669 次
文章分类
社区版块
存档分类
最新评论

CGI(Common Gateway Interface)技术

 
阅读更多

一.提出
  CGI是外部扩展应用程序与WWW服务器交互的一个标准接口。按照CGI标准编写的外部扩展应用程序可以处理客户端(一般是WWW浏览器)输入的协同工作数据,完成 客户端与服务器的交互操作。这在实际应用中非常有用,如可以编写CGI外部扩展 程序来访问外部数据库,客户端用户可以通过它和WWW服务器来进行数据查询。CGI 一般分两种:标准CGI和缓冲CGI。所有的WWW服务器均应支持标准CGI,按标准CGI 编写的程序与具体的WWW服务器无关。而按缓冲CGI编写的程序与WWW服务器有关。

什么是CGI
1. 定义:
CGI(Common Gateway Interface)是HTTP服务器与你的或其它机器
上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上。

2. 功能:
绝大多数的CGI程序被用来解释处理杰自表单的输入信息,并在服
务器产生相应的处理,或将相应的信息反馈给浏览器。CGI程序使
网页具有交互功能。

3. 运行环境:
CGI程序在UNIX操作系统上CERN或NCSA格式的服务器上运行。
在其它操作系统(如:windows NT及windows95等)的服务器上
也广泛地使用CGI程序,同时它也适用于各种类型机器。

4. CGI处理步骤:
⑴通过Internet把用户请求送到服务器。
⑵服务器接收用户请求并交给CGI程序处理。
⑶CGI程序把处理结果传送给服务器。
⑷服务器把结果送回到用户。

5. CGI服务器配置:
CGI程序不是放在服务器上就能顺利运行,如果要想使其在服务器
上顺利的运行并准确的处理用户的请求,则须对所使用的服务器进
行必要的设置。
配置:根据所使用的服务器类型以及它的设置把CGI程序放在某一
特定的目录中或使其带有特定的扩展名。
⑴CREN格式服务器的配置:
编辑CREN格式服务器的配置文件通常为/etc/httpd.conf/
在文件中加入:Exec cgi-bin/*/home/www/cgi-bin/*.exec
命令中出现的第一个参数cgi-bin/*指出了在URL中出现的目录
名字,并表示它出
现在系统主机后的第一个目录中,如:
http://edgar.stern.nyn.edu/cgi-bin/
命令中的第二个参数表示CGI程序目录放在系统中的真实路径。
CGI目录除了可以点网络文件放在同一目录中,也可以放在系统
的其它目录中,但必须保证在你的系统中也具有同样的目录。在
对服务器完成设置后,须重新启动服务器(除非HTTP服务器是用
inetd启动的)。
⑵NCSA格式服务器的配置
在NCSA格式服务器上有两种方法进行设置:
①在srm.conf文件(通常在conf目录下)中加入:
Script Alias/cgi-bin/cgi-bin/
Script Alias命令指出某一目录下的文件是可执行程序,且这
个命令是用来执行
这些程序的;此命令的两个参数与CERN格式服务器中的Exec命
令的参数的含意一样。
②在srm.conf文件加入:
Add type application/x-httpd-cgi.cgi
此命令表示在服务器上增加了一种新的文件类型,其后第一个
参数为CGI程序的MIME类型,第二个参数是文件的扩展名,表
示以这一扩展名为扩展名的文件是CGI程序。
在用上述方法之一设置服务器后,都得重新启动服务器(除非
HTTP服务器是用inetd启动的)。

6. CGI的编写语言
CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和
环境变量。对初学者来说,最好选用易于归档和能有效表示大量数据
结构的语言,例如
UNIX环境中:
· Perl (Practical Extraction and Reporting Language)
· Bourne Shed或者Tcl (Tool Command Language)
Windows环境中:
· C和C++
由于Internet上大部分服务器使用的是UNIX操作系统,且几乎任
一UNIX操作系统中都有Bourne Shell,因而后面讲述的例子中大部
分是用Bourne Shell编写的。

7. CGI环境变量列表
用 好易环境变量探针 来查看CGI环境变量
SERVER-NAME:运行CGI序为机器名或IP地址。
SEUVER-INTERFACE:WWW服务器的类型,如:CERN型或NCSA型。
SERVER-PROTOCOL:通信协议,应当是HTTP/1.0。
SERVER-PORT:TCP端口,一般说来web端口是80。
HTTP-ACCEPT:HTTP定义的浏览器能够接受的数据类型。
HTTP-REFERER: 发送表单的文件URL。
(并非所有的浏览器都传送这一变量)
HTTP-USER-AGENT:发送表单的浏览器的有关信息。
GETWAY-INTERFACE:CGI程序的版本,在UNIX下为 CGI/1.1。
PATH-TRANSLATED: PATH-INFO中包含的实际路径名。
PATH-INFO:浏览器用GET方式发送数据时的附加路径。
SCRIPT-NAME: CGI程序的路径名。
QUERY-STRING:表单输入的数据,URL中间号后的内容。
REMOTE-NOST:发送程序的主机名,不能确定该值。
REMOTE-ADDR:发送程序的机器的IP地址。
REMOTE-USBR:发送程序的人名。
CONTENT-TYPE:POST发送,一般为applioation/xwww-form-urlencoded。
CONTENT-LENGTH:POST方法输入的数据的字节数。

二 ASP、CGI、ISAPI、ODBC之间的差别

ASP赋予你在标准的HTML文档中嵌入脚本的能力。使用这些脚本可执行应用程序逻辑和调用执行特定任务的软件组件,如数据库查询、文件输入/输出(I/O)、交易规则和工作流程。ASP将INTERNET数据库连接器(IDC)的简单性与ISAPI的灵活性结合在一起,而且由于支持JAVA虚拟主机,因此可以用多种编程语言编写ASP应用组件。

CGI是最常用的WEB服务器扩展。CGI可以使你能够运行在不属于WEB服务器的应用程序。许多CGI应用程序是用脚本语言编写的。由于这种语言的可移植性,因此这些语言是扩展WEB服务器性能的流行方法。经过CGI具有灵活性和可移植性,但是由于CGI必须对每个CGI请求重新启动一个新的进程,所以,PERL应用程序对大流量的WEB站点不是最佳解决方案。在CGI完成对该请求的服务后,将取消该进程以及与它相关的任何信息。现在国内外的虚拟主机服务商,在NT SERVER下已经不提供支持PERL的服务。

ISAPI是由MS创建的作为CGI补充的INTERNET服务器应用程序编程接口,是一组常规可扩展例程,用于调用外部应用程序并处理浏览器和服务器之间的数据流。
ISAPI是一个开放式规范,WINDOWNS NT和其他操作系统上的第三方WEB服务器支持该规范。通过将ISAPI与IIS和NT SERVER结合,可以创建一个高性能、低成本并且可扩展的超文本传输协议(HTTP)平台。ISAPI开发以ISAPI应用程序的形式出现,用于克服CGI性能不足的问题。ISAPI的过滤器可以对传入和传出IIS的信息进行预处理和后处理。虽然ISAPI比CGI更快更灵活,但是程序员必须十分熟悉MS VC++开发系统才行。

ODBC IDC是IIS中的另一个可扩展的选项。IDC是一个ISAPI应用程序,它使你可以把WEB页面与支持ODBC的任何后端数据库结合。IDC使用简单的脚本语言创建数据库连接这个事实使IDC成为特别受欢迎的服务器扩展。了解结构化查询语言(SQL)可以帮助你创建IDC应用程序。

三.在CGI中实现session的想法和实现

对于客户端的每一次登陆,在服务器生成一个session,作为一个文件存储在服务器上,例如在“/tmp”下。
文件命名为sess_开头,在加上一个随机的字符串,这个字符串称之为session_id。
在文件中存储的内容包括:
1、用户的最后一次活动时间。(用来检查用户是否长时间没有操作,视为已经退出登陆)。
2、一个随机的字符串。(用来验证客户端的身份,这个字符串同时作为cookie发往客户端)。
3、客户端的IP.
4、实际要存储的数据。例如用户的ID,密码等。

在用户登陆时,生成这个文件,并且,将那个随机字符串发到客户端的cookie.
在以后的每个页面的超连接,或是FORM中的要跟入session_id.
每个页面开始,要:
1、检查是否超时。
2、对比cookie中的字符串和session文件中的,验证客户身份。
3、对比客户端IP和session文件中的IP,验证客户身份。
4、读出数据,供下面程序使用

5、刷新最后活动时间
6、生成新的随机字符串,刷新session中对应部分,并将其作为cookie发往客户端。

下面是我的部分实现代码:

set_session()在登陆是调用。
start_session()在每个页面的前面调用。
kill_session()在退出登陆是调用。
clean_session() 用来删除过期的session文件。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>

#define REMOTE_ADDR1 getenv("REMOTE_ADDR")
#define HTTP_COOKIE getenv("HTTP_COOKIE")

char *sess_user_name;
char *sess_user_pwd;

static void print_session_error(char *);
static void clean_session_file();

char *set_session(char *name,char *pwd)
{
char str_now[11];
char hash_key[17];
char *session_id;
time_t now;

FILE *sf;
char sfp[32];

int i,temp,r;

time(&now);
/**
* clean time out session file
*/
clean_session_file();

/**
* get str_now
*/
sprintf(str_now,"%10d",now);

/**
* get random hash_key
*/
srand(now);
r = rand();
for(i=0;i<16;i++)
{
srand(r);
r = rand();
hash_key[i] = r%26 + 'a';
}
hash_key[16] = '/0';

/**
* get more random session_id;
*/
temp = rand();
srand(temp);
r = rand();
session_id = (char*) malloc(17*sizeof(char));
for(i=0;i<16; i++)
{
srand(r);
r = rand();
session_id[i] = r%26 + 'A';
}
session_id[16] = '/0';
/**
* create session file
*/
strcpy(sfp,"/tmp");
strcat(sfp,"/sess_");
strcat(sfp,session_id);

sf = fopen(sfp,"w");
chmod(sfp,06777);

if( sf == NULL )
{
tc_error_page("can't creat session file");
}

/**
* fputs session file
*/
fputs(str_now,sf);
fputs("/n",sf);
fputs(hash_key,sf);
fputs("/n",sf);
fputs(REMOTE_ADDR1,sf);
fputs("/n",sf);
fputs(name,sf); //sess_user_name
fputs("/n",sf);
fputs(pwd,sf); // sess_user_pwd_
fputs("/n",sf);
fclose(sf);

/**
* set cookie
*/
printf("Set-Cookie:hash_key=%s/n",hash_key);

return session_id;
}

void start_session()
{
int i,j,k;

char *session_id;
FILE *sf;
char sfp[32];
time_t now;
int r;

char buffer[256];
char temp[64];
char str_time[16];
char str_hash_key[20];
char str_client_ip[20];
char *str_array[6];
sess_user_name = (char*)malloc(32*sizeof(char));
sess_user_pwd = (char*)malloc(32*sizeof(char));


str_array[0] = str_time;
str_array[1] = str_hash_key;
str_array[2] = str_client_ip;
str_array[3] = sess_user_name;
str_array[4] = sess_user_pwd;


session_id = cgi_val(entries,"session_id");
/**
* open session file
*/
strcpy(sfp,"/tmp");
strcat(sfp,"/sess_");
strcat(sfp,session_id);
sf = fopen(sfp,"rb+");
if( sf == NULL )
/** can't open session file,maybe session has time out **/
{
print_session_error("1");
exit(1);
}
/**
* read session var
*/
bzero(buffer,256);
fread(buffer,1,256,sf);
for(i=0,j=0,k=0;k<5 && i<strlen(buffer);i++)
{
if( buffer[i] == '/n' )
{
temp[j] = '/0';
strcpy(str_array[k],temp);
j = 0;
k ++;
}
else
{
temp[j++] = buffer[i];
}
}
/**
* check active time
*/
time(&now);
if( now - atoi(str_time) > atoi(parse_config_file("session_live_time")) )
{
print_session_error("2");
exit(1);
}

/**
* compare client hash_key to session hash_key
*/
if( HTTP_COOKIE == "" || strcmp( HTTP_COOKIE+9 , str_hash_key ) != 0 )
{
print_session_error("3");
exit(1);
}

/**
* compare client ip to session ip
*/
if( strcmp( REMOTE_ADDR, str_client_ip ) != 0 )
{
print_session_error("4");
exit(1);
}

/**
* refresh session active time
*/
time(&now);
sprintf(str_time,"%10d/n",now);
fseek(sf,0,SEEK_SET);
fputs(str_time,sf);

/**
* get new hash_key
*/
srand(now);
r = rand();
for(i=0;i<16;i++)
{
srand(r);
r = rand();
str_hash_key[i] = r % 26 + 'a';
}
str_hash_key[16] = '/n';
str_hash_key[17] = '/0';

/**
* refresh session hash_key
*/
fseek(sf,11,SEEK_SET);
fputs(str_hash_key,sf);

fclose(sf);

/**
* send cookie refresh client hash_key
*/
printf("Set-Cookie:hash_key=%s",str_hash_key);
}

void kill_session()
{
char *session_id;
char *session_path;
char sfp[128];

session_id = cgi_val(entries,"session_id");

strcpy(sfp,"/tmp");
strcat(sfp,"/sess_");
strcat(sfp,session_id);

remove(sfp);
}

void clean_session_file()
{
DIR *pdir;
struct dirent *ent;
char *path;
char *filename;
char filepath[64];
int fd;
char str_time[11];
time_t now;

path = "/tmp";
pdir = opendir(path);
if(pdir != NULL)
{
while( ent =readdir(pdir) )
{
filename = ent->d_name;
if( strncmp(filename,"sess_",5)==0 )
{
strcpy(filepath,path);
strcat(filepath,"/");
strcat(filepath,filename);

fd = open(filepath,O_RDONLY);
read(fd,str_time,10);
time(&now);
if( now - atoi(str_time) > atoi(parse_config_file("session_live_time")) )
{
remove(filepath);
}
close(fd);
}
}
}
closedir(pdir);
}

void print_session_error(char *n)
{
printf("Content-type:text/html/n/n");
printf("<html><head>";
print_title("请重新登陆!");
printf("</head>/n");

printf("<body>/n");
printf("对不起,请重新登陆。<p>/n");
printf("你长时间没有操作,登陆已经超时。或者是系统发生了错误。<p>/n");
printf("如果是后者,请与管理人员联系。/n");
printf("<!--%s-->",n);
printf("</body>");
printf("</html>/n");
}

分享到:
评论

相关推荐

    CGI入门 Common Gateway Interface

    CGI 意思为 Common Gateway Interface, 一种基于浏览器的输入、在Web服务器上运行的程序方法. CGI脚本 使你的浏览器与用户能交互,为了在数据库中 寻找一个名词, 提供你写入的评论,或者从一个表单中选择几个条目...

    The Common Gateway Interface (CGI) Version 1.1.pdf

    有需要的没有积分的,可以发邮件h5ru@qq.com,我发给你。 The Common Gateway Interface (CGI) Version 1.1,CGI规范

    CGI.rar_cgi_cgi pdf_gateway

    C G I又称通用网关接口(Common Gateway Interface),是外部程序和We b服务器之间的标 准编程接口, P H P隐藏了其中的大部分复杂性,但是,了解一些它的基本内容对设计应用程 序和进行调试都有很大帮助。

    Linux开发基础-c-c -CGI.ppt

    CGI(Common Gateway Interface: 公用网关接口)规定了Web服务器调用其他可执行程序(CGI 程序)的接口协议标准。Web服务器通过调用CGI程序实现和Web浏览器的交互,也就是CGI程序接受Web浏览器发送给Web服务器的信息,进行...

    动态网页技术的发展

    (1)cgi(common gateway interface) 特点: a:cgi技术是早期动态技术使用最多,发展比较成熟并且功能强大 b:效率比较低,编程比较困难 c:cgi可以用不同的语言编写(vb,delphi,c/c++,perl)常用的c/c++和...

    ASP技术访问WEB数据库

    公共网关接口CGI(Common Gateway Interface)  CGI是较早实现的技术。适用于多种服务器平台,如UNIX、WINDOWS等,但CGI的开发成本高、维护困难、功能有限、不具备事务处理功能、占用服务器资源较多。  2. INTERNET...

    CGI编程指南

    CGI(Common Gateway Interface)HTTP服务器与或其机器 上程序进行交谈种工具其程序须运行网络服务器上.

    ASP技术详解

    ASP(Active Server Pages)动态网页,是微软公司推出的一种用以取代CGI(Common Gateway Interface)通用网关接口的技术。我们可以通过ASP结合HTML语言、ASP指令和ActiveX组件以及数据库等方面知识,使用自己的 Web ...

    JavaWeb面试题

    JavaWeb面试题说出Servlet的生命周期,并说出Servlet和CGI[CGI(Common Gateway Interface,公用网关接口)是较早用来建立动态网页的技术。当客户端向Web服务器上指定的CGI程序发出请求时,Web服务器会启动一个新的...

    学习用c、c++写cgi程序

    CGI全称Common Gateway Interface(共同编程接口),是一种编程接口,不论什么语言,只要按照该接口的标准编写出来的程序,即可叫做CGI程序。CGI 程序的输入/输出是使用编程语言的标准输入/标准输出,所以用C/C++来...

    PHP运行模式的深入理解

    fast-cgi 常驻 (long-live) 型的 CGI3) cli 命令行运行 (Command Line Interface)4)web模块模式 (apache等web服务器运行的模块模式)1.CGI(Common Gateway Interface)CGI即通用网关接口(Common Gateway ...

    cgi课件及代码

    CGI——Common Gateway Interface它是Web服务器生成动态页面的原始方法,是应用程序和Web服务器之间的接口标准.CGI程序允许用户通过网页把数据输入数据库,也允许数据从数据库流向用户.CGI通常和HTML表单一起使用.CGI...

    ASP技术在交互式网页设计中的运用

    ASP技术 ASP(Active Server Pages动态网页)是微软公司推出的一种用以取代CGI(Common Gateway Interface通用网关接口)的技术。目前,Internet上的许多基于Windows平台的Web站点已开始应用ASP来替换CGI。 简单地讲...

    CGI编程完全个人手册

    通用网关接口(Common Gateway Interface)是一个Web服务器主机提供信息服务的标准接口。通过CGI接口,Web服务器就能够获取客户端提交的信息,转交给服务器端的CGI程序进行处理,最后返回结果给客户端

    Web应用安全:web数据库访问技术.pptx

    CGI(Common Gateway Interface,通用网关界面)是一种Web服务器上运行的基于Web浏览器输入程序的方法,是最早的访问数据库的解决方案。CGI程序可以建立网页与数据库之间的连接,将用户的查询要求转换成数据库的查询...

    ASP技术在交互式网页设计中的运用毕业论文

    ASP技术 ASP(Active Server Pages动态网页)是微软公司推出的一种用以取代CGI(Common Gateway Interface通用网关接口)的技术。,Internet上的许多基于Windows平台的Web站点已开始ASP来替换CGI。

    ​ActivePerl5.28版本下载、ActivePerl下载

    CGI(Common Gateway Interface)公共网关接口,是外部扩展应用程序与 Web 服务器交互的一个标准接口。服务器端与客户端进行交互的常见方式多,CGI 技术就是其中之一。根据CGI标准,编写外部扩展应用程序,可以对...

    C语言“Console Graphic Interface”开发工具包

    此“CGI”并非指“公共网关接口”(Common Gateway Interface),也与相关的技术无关。此处的CGI(Console Graphic Interface),即“控制台图形界面”,是自定义的一套控制台应用程序“图形化”界面开发解决方案。...

    Sams Teach Yourself CGI in 24 Hours, 2nd Edition

    In this book, you will learn how to build interactive Web applications using the Common Gateway Interface (CGI)—which is the predominant platform for deploying Web applications today.

    ASP.NET之表单和控件详解

    action属性指明当前表单提交之后由哪个程序来处理,这个处理程序可以是任何动态网页或者servlet或者CGI(Common Gateway Interface),在asp.net里面一般都是都aspx页面来处理。 method属性指明form表单的提交方式。...

Global site tag (gtag.js) - Google Analytics